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.
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.