Hello,
I'm working on a 3D maze game using the BGFX API!
I'm trying to display decal textures, but it's not working!
First, I'm rendering them using a static projection view matrix.
I can see red, but it's not in the right places! The view matrix clipping for the decals isn't even working!
The depth texture consists of float values ranging from 0.0f to 1.0f.
ChatGPT isn’t qualified to help with this kind of thing!
Here is the C++ code on the CPU side:
if (matdbg == NULL)
{HANDLE f = CreateFileA(sftmp, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (f != INVALID_HANDLE_VALUE) { matdbg = new float[16]; //float* fv = glm::value_ptr(vvd); //float fv[16]; ReadFile(f, matdbg, 16 * sizeof(float), NULL, NULL); CloseHandle(f); }}
if (matdbg != NULL)
{
bgfx::setViewFrameBuffer(1, opengl.bgfx_buffertxtrenduwithdepth1);
bgfx::setTexture(0, opengl.u_decalTex, testdecals->texture);
bgfx::setTexture(1, opengl.u_depthTex, opengl.bgfx_htxtrendudepthReadable);glm::mat4 mat = glm::make_mat4(matdbg); glm::mat4 invmat = mat;// glm::inverse(mat); bgfx::setUniform(opengl.u_decalInvMatrix, glm::value_ptr(invmat)); float f4[4] = { opengl.Width,opengl.Heigth,opengl.Width / 2.0f,opengl.Heigth / 2.0f }; bgfx::setUniform(opengl.u_scr, f4);glm::mat4 m = glm::make_mat4(opengl.matmodel); glm::mat4 v = glm::make_mat4(opengl.matview); glm::mat4 p = (opengl.Projection); glm::mat4 vvd = p * v*m; glm::mat4 invvvd = glm::inverse(vvd); glm::mat4 chk = invvvd * vvd; bgfx::setUniform(opengl.u_custominvViewProj, glm::value_ptr(invvvd)); uint64_t state = 0 | BGFX_STATE_WRITE_RGB // Écriture dans le buffer de couleur | BGFX_STATE_WRITE_A // Écriture dans le canal alpha //| BGFX_STATE_WRITE_Z // Écriture dans le buffer de profondeur //| BGFX_STATE_DEPTH_TEST_LESS // Test de profondeur (équivalent de GL_DEPTH_TEST) // | BGFX_STATE_CULL_CW | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); // Blending alpha bgfx::setState(state); /*float nx = opengl.Width / 2.0f; float ny = opengl.Heigth / 2.0f; internal_drawinternal2d(opengl.bgfx_m_programdecals, 1, (char*)"T1", -nx, -ny, nx, ny, 0.01, 0);*/ internal_drawinternal2d_0(opengl.bgfx_m_programdecals, 1, (char*)"T1", 0.01, 0); //bgfx_settransform(1); //internal_submitcube(1, opengl.bgfx_m_programdecals, testdecals->position.x, testdecals->position.y, testdecals->position.z, 1.0f, 1.0f, 1.00f);}
int internal_drawinternal2d_0(bgfx::ProgramHandle shader, int level, char* nom, float z, float rot)
{
//return -1;
int width = opengl.Width;
int height = opengl.Heigth;// Définir les sommets et indices
TTVERTEX0 tv[4] = { 0 };
initrgb(tv, 4);
/float nxde = -2;
float nyde = -2;
float nxa = 2;
float nya = 2;/
float nxde = -1;
float nyde = 1;
float nxa = 1;
float nya = -1;
/tv[0].x = nxde; tv[0].y = nyde; tv[0].u = 0.0f; tv[0].v = 1.0f;
tv[1].x = nxde; tv[1].y = nya; tv[1].u = 0.0f; tv[1].v = 0.0f;
tv[2].x = nxa; tv[2].y = nya; tv[2].u = 1.0f; tv[2].v = 0.0f;
tv[3].x = nxa; tv[3].y = nyde; tv[3].u = 1.0f; tv[3].v = 1.0f;/
//tv[0].x = nxde; tv[0].y = nyde; tv[0].u = 0.0f; tv[0].v = 0.0f;
//tv[1].x = nxde; tv[1].y = nya; tv[1].u = 0.0f; tv[1].v = 1.0f;
//tv[2].x = nxa; tv[2].y = nya; tv[2].u = 1.0f; tv[2].v = 1.0f;
//tv[3].x = nxa; tv[3].y = nyde; tv[3].u = 1.0f; tv[3].v = 0.0f;
tv[0].x = nxde; tv[0].y = nyde; tv[0].u = 0.0f; tv[0].v = 0.0f;
tv[1].x = nxde; tv[1].y = nya; tv[1].u = 0.0f; tv[1].v = 1.0f;
tv[2].x = nxa; tv[2].y = nya; tv[2].u = 1.0f; tv[2].v = 1.0f;
tv[3].x = nxa; tv[3].y = nyde; tv[3].u = 1.0f; tv[3].v = 0.0f;
if (forcez2d)
{
for (int c = 0; c < 4; c++)
tv[c].z = z;// 0.8;
}
int indices[6] = { 0, 1, 2, 0, 2, 3 };
submitdata(level, shader, indices, 6, tv, 4);
return e3d_ok;}
void submitdata(int level, bgfx::ProgramHandle shader, int* indices, int nbindices, TTVERTEX0* tv,int nbtv)
{
// Allouer des buffers transitoires
bgfx::TransientVertexBuffer tvb;
bgfx::TransientIndexBuffer tib;// Vérifier si assez d'espace est disponible bgfx::allocTransientVertexBuffer(&tvb, 4, PosTVertex::ms_layout); bgfx::allocTransientIndexBuffer(&tib, 6); { // Copier les données dans les buffers transitoires bgfx::VertexBufferHandle vbh = tvb.handle; bgfx::IndexBufferHandle ibh = tib.handle;
// Copier les sommets float* vertexData = (float*)tvb.data; for (int i = 0; i < nbtv; i++) { vertexData[i * 11 + 0] = tv[i].x; vertexData[i * 11 + 1] = tv[i].y; vertexData[i * 11 + 2] = tv[i].z; vertexData[i * 11 + 3] = tv[i].u; vertexData[i * 11 + 4] = tv[i].v; vertexData[i * 11 + 5] = tv[i].r; vertexData[i * 11 + 6] = tv[i].g; vertexData[i * 11 + 7] = tv[i].b; vertexData[i * 11 + 8] = tv[i].nx; vertexData[i * 11 + 9] = tv[i].ny; vertexData[i * 11 + 10] = tv[i].nz; } // Copier les indices uint16_t* indexData = (uint16_t*)tib.data; for (int i = 0; i < nbindices; i++) { indexData[i] = indices[i]; } // Configurer le rendu /*bgfx::setTexture(0, opengl.bgfx_s_texColor, txt);*/ enablefunc(true, true, true, true, true, 0); bgfx::setVertexBuffer(0, &tvb); bgfx::setIndexBuffer(&tib); bgfx::submit(level, shader, 0, flagsubmit);
}}
On the GPU side:
Vertex shader decals :
$input a_position, a_color0, a_texcoord0, a_normal
$output v_texCoord#include "common.sh"
void main()
{//gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0)); gl_Position=vec4(a_position,1.0); v_texCoord = a_texcoord0;}
fragment shader decals :
$input v_texCoord#include "common.sh"
SAMPLER2D(u_decalTex, 0);
SAMPLER2D(u_depthTex, 1);
//uniform mat4 u_decalProjMtx; // Matrice de projection du decal
//uniform mat4 u_decalViewMtx; // Matrice de vue du decal
uniform mat4 u_decalInvMatrix;
uniform mat4 u_custominvViewProj;
uniform vec4 u_scr;
void main()
{//gl_FragColor=vec4(1.0,0.5,1.0,1.0); //return; // 1. Calculer la position du pixel dans l'espace du decal
/float fx=gl_FragCoord.x;
float fy=gl_FragCoord.y;
fx/=u_scr[0];
fy/=u_scr[1];/// float fx=(v_texCoord.x2.0)-1.0;
//float fy=(v_texCoord.y2.0)-1.0;
float fx=(v_texCoord.x);
float fy=(v_texCoord.y);//fx-=1; //fy-=1;// vec4 decalSpacePos = mul(u_decalViewMtx , vec4(v_worldPos, 1.0));
vec2 uv = vec2(fx,fy);//gl_FragCoord.xy / vec2(878,716);
//float depth = gl_FragCoord.z; //texture2D(u_depthTex, uv).r;
float depth = texture2D(u_depthTex, uv).r;
//depth=(depth*2)-1.0;//depth=0.9f;
// gl_FragColor = vec4(depth, depth, depth, 1.0);
// return;vec4 world = mul(u_custominvViewProj, vec4(uv.x,uv.y,depth,1.0)); if (world.w!=0) { world.xyz /= world.w;
/gl_FragColor =
vec4(world.xyz * 0.5 + 0.5, 1.0);
return;/
vec4 local = mul(u_decalInvMatrix, vec4(world.xyz, 1.0));
//vec4 local = mul(vec4(world.xyz, 1.0),u_decalInvMatrix);
if (local.w!=0)
{
local.xyz/=local.w;/gl_FragColor = vec4(local.xyz * 0.5 + 0.5, 1.0); return;/
bool visiblet =
local.w > 0.0f &&
local.x >= -1.0f && local.x <= 1.0f &&
local.y >= -1.0f && local.y <= 1.0f &&
local.z >= -1.0f && local.z <= 1.0f;
if (visiblet==false)
{
discard;
return;
}vec2 decalUV = local.xy * 0.5 + 0.5; //gl_FragColor = vec4(0.33, 0.0, 0.0, 1.0); //color decals gl_FragColor = vec4(uv.x/4, uv.y/4, 0.0, 1.0); return; } else { gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); //debuggage return; }
}
else
{
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); //debuggage
return;
}}