Hello. I am trying to write some code that does the following:
- In a 1st pass, do a computation in a shader.
- Have the result stored in a texture.
- In a 2nd pass, query values from that texture in a different shader.
I read that I should use a frame buffer object. I wrote some code but it’s not working for me (simplified version is below). I use glslDevil to debug my shader and view result of texelFetch2D which is returning all zero’s. In fboTest2.vert, I’m expecting val0’s alpha to be 1.2.
I don’t get any errors and I’m not sure what could be wrong or what to fix. Am I even close to getting the code right?
Does anyone know of any examples online? I found RTT examples but I couldn’t figure out how to apply it to my situation.
Help or advice would be greatly appreciated. Thanks.
miko
// initialization
{
GLchar *vertShaderSource1, *fragShaderSource1, *vertShaderSource2;
readShaderSource( "shaders/fboTest1.vert", &vertShaderSource1 );
readShaderSource( "shaders/fboTest1.frag", &fragShaderSource1 );
readShaderSource( "shaders/fboTest2.vert", &vertShaderSource2 );
GLuint shadersList1[1] = {0};
GLuint shadersList2[2] = {0};
// Shaders for 1st pass
GLuint shadersList1[2] = {0};
installShader( vertShaderSource1, GL_VERTEX_SHADER, &shadersList1[0] );
installShader( fragShaderSource1, GL_FRAGMENT_SHADER, &shadersList1[1] );
g_progObject = glCreateProgram();
attachAndLinkShaders( g_progObject, shadersList1, 2 );
// Shaders for 2nd pass
GLuint shadersList2[1] = {0};
installShader( vertShaderSource2, GL_VERTEX_SHADER, &shadersList2[0] );
g_progObject2 = glCreateProgram();
attachAndLinkShaders( g_progObject2, shadersList2, 1 );
// Texture for FBO.
glUseProgram( g_progObject );
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &g_textureId );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, g_textureId );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA16F_ARB, 16, 16, 0, GL_ALPHA, GL_FLOAT, 0 );
glBindTexture( GL_TEXTURE_2D, 0 );
// Create frame buffer object.
glGenFramebuffersEXT( 1, &g_fboId );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_fboId );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, g_textureId, 0 );
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
assert( status == GL_FRAMEBUFFER_COMPLETE_EXT );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
// Set texture variable for 2nd pass.
glUseProgram( g_progObject2 );
glUniform1i( getUniformVariable(g_progObject2, "DataSet"), 0);
}
// render function
{
int windowWidth=800, windowHeight=600;
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0, windowWidth, 0, windowHeight );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glViewport( 0, 0, windowWidth, windowHeight );
// --- 1st pass ---
glUseProgram( g_progObject );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, g_fboId );
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_POINTS);
for( float y=0; y<16; y++ ){
for( float x=0; x<16; x++ ){
glVertex3f( x, y, 0 );
}
}
glEnd();
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
// --- 2nd pass ---
glUseProgram( g_progObject2 );
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_POINTS);
glVertex3f(0, 0, 0);
glEnd();
glFlush();
glutSwapBuffers();
}
// --- fboTest1.vert ---
varying float someVal;
void main(void){
// Do some calculation.
someVal = gl_Vertex.x + 1.2;
gl_Position = ftransform();
}
// --- fboTest1.frag ---
varying float someVal;
void main(void){
gl_FragColor = vec4( 0.0, 0.0, 0.0, someVal );
}
// --- fboTest2.vert ---
uniform sampler2D DataSet;
void main(void){
vec4 val0 = texelFetch2D( DataSet, ivec2(0, 0), 0 );
gl_Position = ftransform() + val0;
}