Another wglShareLists question ...

Hi all,

I want to render-to-vertex-array using pbo and vbo in a p-buffer. Here’s some code:

void test()
{
//	pbuffer->Activate();
	static bool done(false);
	if (!done) {
		BuildMesh();
		done = true;
	}
        int vp[4];
        glGetIntegerv(GL_VIEWPORT, vp);
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(-1, 1, -1, 1, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glEnable(texType);
	glBindTexture(texType, hNodeTex[0]);
	glBegin(GL_QUADS);
		glColor3f(1.0f, 1.0f, 1.0f);
		glTexCoord2f(0, 0); glVertex3f(-1, -1, 0);
		glTexCoord2f(1, 0); glVertex3f( 1, -1, 0);
		glTexCoord2f(1, 1); glVertex3f( 1,  1, 0);
		glTexCoord2f(0, 1); glVertex3f(-1,  1, 0);
	glEnd();
	glDisable(texType);
	GLfloat pixels[width*height*4];
	glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, pixels);
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glViewport(vp[0], vp[1], vp[2], vp[3]);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(4, GL_FLOAT, 0, pixels);
//	pbuffer->Deactivate();
	glDrawArrays(GL_QUADS, 0, width*height);
}

Activate and deactivate the p-buffer it doesn’t work. The p-buffer and normal window have different formats and sizes, but wglShareLists returns true (called at pbuffer creation). Activate and Deactivate just call wglMakeCurrent with the appropriate hdc and hglrc. Main window’s hdc and hglrc are stored at creation in the pbuffer object. Can these change over time? I thought they were constant once allocated. What else am I missing? Everything else, like window parameters etc are the same. Are vertex arrays (and vbo) shared via wglShareLists? I would’ve imagined so. Any hints?

Thanks in advance.

The vertex array objects should be shared, assuming the share-lists operation worked.

However, other state, such as glEnable(), glEnableClientState(), glActiveTexture(), glBindTexture(), glVertexPointer(), etc is NOT shared between the contexts. Thus, you have to make sure that your state mirroring functions can re-apply all the state you care about when switching to a new context.

Thanks jwatte. You got me thinking, so I messed around a bit and got it to work - render from texture to vertex array in a p-buffer - awesome! Wouldn’t have figured it out without you. Here’s the messy sample code for anyone interested:

void test()
{
	pbuffer->Activate();
	static bool done(false);
	if (!done) {
		BuildMesh();
		glGenBuffers(1, hVbo);
		done = true;
	}
	glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, hVbo);
	glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, width*height*4, NULL, GL_DYNAMIC_DRAW);
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1, 1, -1, 1, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glEnable(texType);
	glBindTexture(texType, hNodeTex[0]);
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex3f(-1, -1, 0);
		glTexCoord2f(1, 0); glVertex3f( 1, -1, 0);
		glTexCoord2f(1, 1); glVertex3f( 1,  1, 0);
		glTexCoord2f(0, 1); glVertex3f(-1,  1, 0);
	glEnd();
	glDisable(texType);
	glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, (char *)NULL + 0);
	pbuffer->Deactivate();
	glBindBufferARB(GL_ARRAY_BUFFER, hVbo);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(4, GL_FLOAT, 0, (char *)NULL + 0);
	glDrawArrays(GL_QUADS, 0, width*height);
}

No performance figures or anything, but this will be pretty useful for me. ReadPixels reads into a buffer object which is shared between a floating-point p-buffer and the regular RGBA framebuffer. BindBufferARB, EnableClientState and VertexPointer use the shared buffer object to render with DrawArrays. Nice. Until render_target comes along …