Problem with FBO, target depthTexture and stencil not good.

Hi I tried to link target textures to an FBO but it’s not working.

To create the textures I do like this :

bool Texture::create(unsigned int width, unsigned int height, bool depthTexture, bool stencilTexture)
        {
            // Check if texture parameters are valid before creating it
            if ((width == 0) || (height == 0))
            {
                err() << "Failed to create texture, invalid size (" << width << "x" << height << ")" << std::endl;
                return false;
            }

            // Compute the internal texture dimensions depending on NPOT textures support
            Vector2u actualSize(getValidSize(width), getValidSize(height));

            // Check the maximum texture size
            unsigned int maxSize = getMaximumSize();
            if ((actualSize.x > maxSize) || (actualSize.y > maxSize))
            {
                err() << "Failed to create texture, its internal size is too high "
                      << "(" << actualSize.x << "x" << actualSize.y << ", "
                      << "maximum is " << maxSize << "x" << maxSize << ")"
                      << std::endl;
                return false;
            }

            // All the validity checks passed, we can store the new texture settings
            m_size.x        = width;
            m_size.y        = height;
            m_actualSize    = actualSize;
            m_pixelsFlipped = false;
            ensureGlContext();

            // Create the OpenGL texture if it doesn't exist yet
            if (!m_texture)
            {
                GLuint texture;
                glCheck(glGenTextures(1, &texture));
                m_texture = static_cast<unsigned int>(texture);
                glCheck(glBindImageTextures(0, 1, &m_texture));
            }

            // Make sure that the current texture binding will be preserved
            priv::TextureSaver save;

            // Initialize the texture
            glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
            if (!stencilTexture && !depthTexture) {
                glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));

            } else if (depthTexture) {
                glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL));

            } else {
                glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX16, width, height, 0, GL_STENCIL, GL_FLOAT, NULL));
            }
            glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : GL_CLAMP_TO_EDGE));
            glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : GL_CLAMP_TO_EDGE));
            glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST));
            glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST));
            m_cacheId = getUniqueId();

            return true;
        }

And then I create the FBO here :

////////////////////////////////////////////////////////////
            bool RenderTextureImplFBO::create(unsigned int width, unsigned int height, ContextSettings settings, unsigned int textureId, unsigned int depthTextureId, unsigned int stencilTextureId)
            {
                // Create the context
                m_context = new Context(settings, width, height);
                // Create the framebuffer object
                GLuint frameBuffer = 0;
                glCheck(glGenFramebuffersEXT(1, &frameBuffer));
                m_frameBuffer = static_cast<unsigned int>(frameBuffer);
                if (!m_frameBuffer)
                {
                    err() << "Impossible to create render texture (failed to create the frame buffer object)" << std::endl;
                    return false;
                }
                glCheck(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_frameBuffer));
                // Create the depth buffer if requested
                if (settings.depthBits > 0)
                {
                    GLuint depth = 0;
                    glCheck(glGenRenderbuffersEXT(1, &depth));
                    m_depthBuffer = static_cast<unsigned int>(depth);
                    if (!m_depthBuffer)
                    {
                        err() << "Impossible to create render texture (failed to create the attached depth buffer)" << std::endl;
                        return false;
                    }
                    glCheck(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer));
                    glCheck(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height));
                    glCheck(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer));
                }
                if (settings.stencilBits > 0) {
                    GLuint stencil = 0;
                    glCheck(glGenRenderbuffersEXT(1, &stencil));
                    m_stencilBuffer = static_cast<unsigned int>(stencil);
                    if (!m_stencilBuffer) {
                        err() << "Impossible to create render texture (failed to create the attached stencil buffer)" << std::endl;
                        return false;
                    }
                    glCheck(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,m_stencilBuffer));
                    glCheck(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, width, height));
                    glCheck(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencilBuffer));
                }
                // Link the texture to the frame buffer
                glCheck(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0));
                if (stencilTextureId != 0) {
                    glCheck(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, stencilTextureId, 0));
                }
                if (depthTextureId != 0) {
                    glCheck(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthTextureId, 0));
                }
                // A final check, just to be sure...
                if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
                {
                    glCheck(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
                    err() << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
                    return false;
                }
                return true;
            }

But the z values in the depthTexture are not good, when I’m trying to display the depthTexture it gives me this.
Capture%20du%202019-01-18%2013%3A20%3A52

And when I want to compare the z values in the fragment shader that’s not good.


const std::string addSrcColorFragShader =
                "#version 130 
"
                "in mat4 projMat;"
                "uniform vec3 resolution;"
                "uniform sampler2D frontBuffer;"
                "uniform sampler2D depthBuffer;"
                "uniform sampler2D texture;"
                "uniform float haveTexture;"
                "void main() {"
                    "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                    "vec4 front_color = texture2D(frontBuffer, position);"
                    "float max_z = texture2D(depthBuffer, position).z;"
                    "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                    "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                    "vec4 colors[2];"
                    "colors[1] = texel * gl_Color;"
                    "colors[0] = gl_Color;"
                    "bool b = (haveTexture > 0.9);"
                    "vec4 color = colors[int(b)];"
                    "colors[1] = vec4(color.rgb * (1 - front_color.a), color.a * (1 - front_color.a));"
                    "colors[0] = vec4(0, 0, 0, 0);"
                    "b = (z < max_z);"
                    "gl_FragColor = colors[int(b)];"
                "}";

And when I display the stencil texture it’s a full white texture.

Use GL_DEPTH24_STENCIL8 instead. That’s a much more common way to allocate and attach both a depth buffer and a stencil buffer.