I’ve been asking about my problems with render_to_vertex_array in another thread of this forum, but since my implementation has changed considerably (and so did the problem), I thought I should reformulate the question.
I’m doing the following:
- Render a quad with a texture containing the geometry to an offscreen color buffer using a fbo (from the EXT_framebuffer_object extension).
- Read back the content of the color buffer to a buffer object on the graphics card (from the EXT_pixel_buffer_object extension) calling glReadPixels (see code below).
- Bind this buffer and use it as source for rendering a vertex array (probably better called a vbo in this case since the geometry is already allocated on the graphics card).
The problem is that when I bind the buffer and try to render the vertex array with glDrawElements, the application crashes with the error “Access violation reading location 0x00000000”.
I’m using the ForceWare 76.41 driver for my GeForce 6600 GT, obviously on Windows.
Here is some code to clarify what I’m actually doing:
(I’ve updated the code to change the unbind and bind the buffers more explicitly)
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
GLuint *fboTexIDs;
GLuint *fboIDs;
GLuint *vboIDs;
void initialize()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glClearColor( 1.0, 1.0, 1.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
// initialize compile and link the shader program/-s
initializeGLSL();
// allocate space for the target (floating point) texture to be rendered to
fboTexIDs = new GLuint[1];
glGenTextures( 1, fboTexIDs );
glBindTexture( GL_TEXTURE_2D, fboTexIDs[i] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F_ARB, textureSize, textureSize, 0, GL_RGB, GL_FLOAT, 0 );
// Create and bind the framebuffer and add the (target) textures (fbo)
fboIDs = new GLuint[1];
glGenFramebuffersEXT( 1, fboIDs );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboIDs[0] );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexIDs[0], 0 );
// Create the texture containing the geometry
glEnable( GL_TEXTURE_2D );
textureIDs = new GLuint[1];
glGenTextures( 1, textureIDs );
glBindTexture( GL_TEXTURE_2D, textureIDs[0] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
// Upload the content of the texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F_ARB, textureSize, textureSize,
0, GL_RGB, GL_FLOAT, (float *)textureData );
glBindTexture( GL_TEXTURE_2D, 0 );
glDisable( GL_TEXTURE_2D );
// Generate the VBO for rendering the FBO content as vertex array
vboIDs = new GLuint[1];
glGenBuffers( 1, vboIDs );
glBindBuffer( GL_PIXEL_PACK_BUFFER_EXT, vboIDs[0] );
glBufferData( GL_PIXEL_PACK_BUFFER_EXT, textureSize*textureSize*3*sizeof(float), NULL, GL_STATIC_COPY );
glBindBuffer( GL_PIXEL_PACK_BUFFER_EXT, 0 );
}
void render()
{
int viewport[4];
// FIRST PASS
if( firstPass ) {
firstPass = false;
// save the viewport so that it can be restored later
glGetIntegerv( GL_VIEWPORT, viewport );
glViewport( 0, 0, textureSize, textureSize ); // set viewport to size of texture
// draw to texture
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0, textureSize, 0, textureSize );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboIDs[0] );
GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT };
glDrawBuffersARB(1,buffers); // enable attachment for drawing
firstPassSM->useProgram(); // enable the shader program
// render 2D textured quad
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, textureIDs[0] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0, 0.0); glVertex2f( 0.0, 0.0 );
glTexCoord2f( 1.0, 0.0); glVertex2f( textureSize, 0.0 );
glTexCoord2f( 1.0, 1.0); glVertex2f( textureSize, textureSize );
glTexCoord2f( 0.0, 1.0); glVertex2f( 0.0, textureSize );
glEnd();
glBindTexture( GL_TEXTURE_2D, 0 );
glDisable( GL_TEXTURE_2D );
firstPassSM->useNoProgram(); // disable the shader program
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
// reset the viewport
glViewport( viewport[0], viewport[1], viewport[2], viewport[3] );
// bind the vertex array source to be BUFFER_OFFSET(0)
glBindBuffer( GL_PIXEL_PACK_BUFFER_EXT, vboIDs[0] );
glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
glReadPixels( 0, 0, textureSize, textureSize, GL_RGB32F_ARB, GL_FLOAT, BUFFER_OFFSET(0) );
glBindBuffer( GL_PIXEL_PACK_BUFFER_EXT, 0 );
// Change the binding point of the buffer object to the vertex array binding point
glBindBuffer( GL_ARRAY_BUFFER, vboIDs[0] );
glEnableClientState( GL_VERTEX_ARRAY );
glInterleavedArrays( GL_V3F, 0, BUFFER_OFFSET(0) );
glDisableClientState( GL_VERTEX_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
}
// SECOND PASS
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glBindBuffer( GL_PIXEL_PACK_BUFFER_EXT, 0 );
// Render vertex array
glBindBuffer( GL_ARRAY_BUFFER, vboIDs[0] );
glEnableClientState( GL_VERTEX_ARRAY );
// Render triangle strips with indexed vertices
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
glTranslated( 0.0, 0.0, -1.0 );
glColor3d( 0.7, 0.7, 0.8 );
for( int stripNr = 0; stripNr < isoSurface->getNumOfStrips(); stripNr++ ) {
glDrawElements( GL_TRIANGLE_STRIP, getStripNumOfVerts(stripNr),
GL_UNSIGNED_INT, getStripIndices(stripNr) );
}
glDisableClientState( GL_VERTEX_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
}
I know it’s a bit long to be posted, but I didn’t know how to leave out some part and still make it understandable :rolleyes:
I’m quite sure the FBO is working fine, because I’ve tried to use its content as a texture and render it on screen and it looks just as it should… but the last part is still unsuccessful.
Can anyone tell me what I’m doing wrong? Could this be a problem of the beta driver or am I missing the point?
Thanks in advance for any help and for reading this long post