I’ve encountered a problem. I have a few custom shaders working beautifully to render a nice gradient sky, bumpmapped clouds (procedural) and the sun but when I come to draw the world to a FBO (because I want to downscale the image and then blend according to depth to produce a simplistic focal blur later on) it seemingly ignores the FBO and renders straight out to the viewport. The framebuffer appears to be complete according to the test function. I have bound the out variable properly. ( glBindFragDataLocation( gluiTerrainShader, 0, “v4DiffuseOut” ); ) I can confirm that aside from going straight to the viewport rather than into my texture the shader works properly. My shaders are as follows:
uint8_t ui8Shader_Terrain_Vertex[] =
"#version 140
"
"in vec3 v3Vertex;"
"uniform mat4 m4Transform;"
"void main()"
"{"
" gl_Position = m4Transform * vec4( v3Vertex, 1.0 );"
"}";
uint8_t ui8Shader_Terrain_Fragment[] =
"#version 140
"
"out vec4 v4DiffuseOut;"
"void main()"
"{"
v4DiffuseOut = vec4( 1, 0, 0, 1.0 );
}
I am enabling the VBO like this at render time:
glBindFramebuffer( GL_FRAMEBUFFER, gluiPipelineFBO );
GLuint gluiBuffersToUse[ 1 ] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers( 1, gluiBuffersToUse );
The FBO is being setup like this:
glGenTextures( 1, &gluiPipelineDiffuse );
if( gluiPipelineDiffuse == 0 )
{
RETURN_FAILURE FAILURE_LOW_MEMORY;
}
glGenFramebuffers( 1, &gluiPipelineFBO );
if( gluiPipelineFBO == 0 )
{
RETURN_FAILURE FAILURE_LOW_MEMORY;
}
glBindFramebuffer( GL_FRAMEBUFFER, gluiPipelineFBO );
glGenRenderbuffers( 1, &gluiPipelineDepth );
if( gluiPipelineDepth == 0 )
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
RETURN_FAILURE FAILURE_LOW_MEMORY;
}
uiPOTScreenWidth = 1;
while( uiPOTScreenWidth < tsCurrentConfiguration.uiScreenWidth )
{
uiPOTScreenWidth <<= 1;
}
uiPOTScreenHeight = 1;
while( uiPOTScreenHeight < tsCurrentConfiguration.uiScreenHeight )
{
uiPOTScreenHeight <<= 1;
}
glBindRenderbuffer( GL_RENDERBUFFER, gluiPipelineDepth );
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tsCurrentConfiguration.uiScreenWidth, tsCurrentConfiguration.uiScreenHeight );
glBindTexture( GL_TEXTURE_2D, gluiPipelineDiffuse );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, uiPOTScreenWidth, uiPOTScreenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gluiPipelineDiffuse, 0 );
glBindTexture( GL_TEXTURE_2D, 0 );
printf( "%d %d
", uiPOTScreenWidth, uiPOTScreenHeight );
//glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gluiPipelineSpecular, 0 );
//glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gluiPipelineNormal, 0 );
//glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gluiPipelineNormalised, 0 );
//glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gluiPipelineDiffuseLight, 0 );
//glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gluiPipelineSpecularLight, 0 );
if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
RETURN_FAILURE FAILURE_GENERIC;
}
//Celestial shader...
gluiTerrainVertex = glCreateShader( GL_VERTEX_SHADER );
if( gluiTerrainVertex == 0 )
{
RETURN_FAILURE FAILURE_LOW_MEMORY;
}
gluiTerrainFragment = glCreateShader( GL_FRAGMENT_SHADER );
if( gluiTerrainFragment == 0 )
{
RETURN_FAILURE FAILURE_LOW_MEMORY;
}
gluiTerrainShader = glCreateProgram();
if( gluiTerrainShader == 0 )
{
RETURN_FAILURE FAILURE_LOW_MEMORY;
}
const GLchar * glcAltVertex = ( GLchar * ) ui8Shader_Terrain_Vertex;
const GLchar * glcAltFragment = ( GLchar * ) ui8Shader_Terrain_Fragment;
//Now let's add the source code...
glShaderSource( gluiTerrainVertex, 1, &glcAltVertex, NULL );
glShaderSource( gluiTerrainFragment, 1, &glcAltFragment, NULL );
glCompileShader( gluiTerrainVertex );
glCompileShader( gluiTerrainFragment );
//Put them all together...
glAttachShader( gluiTerrainShader, gluiTerrainVertex );
glAttachShader( gluiTerrainShader, gluiTerrainFragment );
glBindFragDataLocation( gluiTerrainShader, 0, "v4DiffuseOut" );
glLinkProgram( gluiTerrainShader );
#ifdef DEBUG_COMMENTS_RENDERER
ShaderDebug( gluiTerrainVertex );
ShaderDebug( gluiTerrainFragment );
ProgramDebug( gluiTerrainShader );
#endif
glUseProgram( gluiTerrainShader );
glUniform1i( glGetUniformLocation( gluiTerrainShader, "s2DNormal" ), 0 );
gliTerrainVarVertex = glGetAttribLocation( gluiTerrainShader, "v3Vertex" );
gliTerrainVarTexCoord = glGetAttribLocation( gluiTerrainShader, "v2TexCoord" );
gliTerrainVarTransform = glGetUniformLocation( gluiTerrainShader, "m4Transform" );
gliTerrainVarNormal = glGetUniformLocation( gluiTerrainShader, "v3Normal" );
gliTerrainVarTangent = glGetUniformLocation( gluiTerrainShader, "v3Tangent" );
gliTerrainVarBitangent = glGetUniformLocation( gluiTerrainShader, "v3Bitangent" );
glUseProgram( 0 );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
I presumed the framebuffer had to be bound when binding the output. Is this the case?
It just ignores the FBO. I have no explanation. I can’t understand it.
Oh, and thanks for your posts. They were quite insightful.