GLUT subwindows, texture problems

Dear all,

I’m trying to figure out why my program can’t simultaneously display two subwindows that have 2D textures bound to them. Whichever subwindow gets created last in the main function (see below) is the one that gets updated correctly, while the other one just remains blank. Switching the order in which I create them, also switches the one that gets updated correctly.

Since they both - individually - can display the correct images, I suspect it must be something I’m doing wrong in terms of texture generation/binding/unbinding.

Anyway, here’s the pseudo source code, stripped of all data generation (if necessary for better understanding of my problem, I have no problem posting more of it):

main function:


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH);
glutInitWindowPosition(200,100);
glutInitWindowSize(2*width1+3*GAP,height1+2*GAP);

// main window    
main_window = glutCreateWindow("Main window");
glutDisplayFunc(displayMain);
glutTimerFunc(1, displayAll, 0);
init();
glewInit();
		
// subwindows
subwindow2 = glutCreateSubWindow (main_window, width1 + 2*GAP, GAP, subwindow2_w,subwindow2_h);
glutDisplayFunc(displaySubwindow2);
init();	

subwindow1 = glutCreateSubWindow (main_window, GAP, GAP, subwindow1_w, subwindow1_h);
glutDisplayFunc(displaySubwindow1);
init();		

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
initGLResourcesSubwindows();
        
glutMainLoop();

glutTimerFunc:


void displayAll(int value){

glutSetWindow(main_window);
glutPostRedisplay();
		
glutSetWindow(subwindow1);
glutPostRedisplay();

glutSetWindow(subwindow2);
glutPostRedisplay();

glutTimerFunc(1,displayAll,0);
		
}

inits:


void init() {
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glLoadIdentity();
}

VBO/PBO setup and 2D texture setup (for now I just want to use two PBO’s, later a VBO will be added in a third subwindow, if possible):


void initGLResourcesSubwindows()
{
// We need two VBO's (one for actual 2D index coordinates and one for z_positions) and one IBO for indices
__glewGenBuffers(1, &z_position_VBO_ID);
__glewBindBuffer(GL_ARRAY_BUFFER, z_position_VBO_ID);
__glewBufferData(GL_ARRAY_BUFFER, z_position_VBO_size, 0, GL_DYNAMIC_DRAW);
    

cudaGraphicsGLRegisterBuffer(&z_position_VBO_resource, z_position_VBO_ID, cudaGraphicsMapFlagsWriteDiscard);
cudaGraphicsGLRegisterBuffer(&mesh_coordinates_VBO_resource, mesh_coordinates_VBO_ID, cudaGraphicsMapFlagsWriteDiscard);

// create vertex and index buffer for mesh
createMeshPositionVBO(&mesh_coordinates_VBO_ID, width, height);
createMeshIndexBuffer(&indexBuffer, width, height);

// ... and another one to store the normals
int outputSize =  width*height*sizeof(float2);
createVBO(&slopeVertexBuffer, outputSize);
checkCudaErrors(cudaGraphicsGLRegisterBuffer(&cuda_slopeVB_resource, slopeVertexBuffer, cudaGraphicsMapFlagsWriteDiscard));
    	
glGenTextures(2, textures);
	// create pixel buffer objects pbo1 and pbo2
	// pbo1
	__glewGenBuffers(1, &pbo1);
	__glewBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo1);
	__glewBufferData(GL_PIXEL_UNPACK_BUFFER, 
		width*height*sizeof(float), 
		NULL, GL_STREAM_DRAW);

	GLint bsize;
	__glewGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER, GL_BUFFER_SIZE, &bsize);
	if ((GLuint)bsize != (width*height*sizeof(float)))
	{
		printf("Buffer object (%d) has incorrect size (%d).
", (unsigned)pbo1, (unsigned)bsize);
		cudaDeviceReset();
		system("PAUSE");
		exit(EXIT_FAILURE);
	}
	else 
	{
		printf("Buffer object (%d) has correct size (%d).
", (unsigned)pbo1, (unsigned)bsize);        
	}
	__glewBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	cudaGraphicsGLRegisterBuffer(&cuda_pbo1_resource, pbo1,
		cudaGraphicsMapFlagsReadOnly);

	glBindTexture(GL_TEXTURE_2D, textures[0]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 640, 480, 0, GL_LUMINANCE, GL_FLOAT, NULL);
	glBindTexture(GL_TEXTURE_2D, 0);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	// pbo2
	__glewGenBuffers(1, &pbo2);
	__glewBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo2);
	__glewBufferData(GL_PIXEL_UNPACK_BUFFER, 
		width*height*sizeof(float), 
		NULL, GL_STREAM_DRAW);

	__glewGetBufferParameteriv(GL_PIXEL_UNPACK_BUFFER, GL_BUFFER_SIZE, &bsize);
	if ((GLuint)bsize != (width*height*sizeof(float)))
	{
		printf("Buffer object (%d) has incorrect size (%d).
", (unsigned)pbo2, (unsigned)bsize);
		cudaDeviceReset();
		system("PAUSE");
		exit(EXIT_FAILURE);
	}
	else 
	{
		printf("Buffer object (%d) has correct size (%d).
", (unsigned)pbo2, (unsigned)bsize);        
	}
	__glewBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	cudaGraphicsGLRegisterBuffer(&cuda_pbo2_resource, pbo2,
		cudaGraphicsMapFlagsReadOnly);
	
    glBindTexture(GL_TEXTURE_2D, textures[1]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 640, 480, 0, GL_LUMINANCE, GL_FLOAT, NULL);
	glBindTexture(GL_TEXTURE_2D, 0);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	
	glutSwapBuffers();
	

}

main display:


void displayMain() {
glutSetWindow(main_window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSwapBuffers();

glutSetWindow(subwindow1);
glutPostRedisplay();

glutSetWindow(subwindow2);
glutPostRedisplay();
}

subwindows display:

void displaySubwindow1(void) 
{   

	glutSetWindow(subwindow1);
	glLoadIdentity();


	// Reserve a memory address in GPU memory and link with OpenGL
	//float *d_result;
	cudaGraphicsMapResources(1, &cuda_pbo1_resource, 0);
	size_t num_bytes;
	cudaGraphicsResourceGetMappedPointer((void**)&d_result, &num_bytes, cuda_pbo1_resource);
	
        //*** d_result is calculated here, and checked for accurateness ***//
	cudaThreadSynchronize();


	cudaGraphicsUnmapResources(1, &cuda_pbo1_resource, 0);

	
	
	glBindTexture(GL_TEXTURE_2D, textures[0]);
	__glewBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo1);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 640, 480, 0, GL_LUMINANCE, GL_FLOAT, NULL);
	
	__glewBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

	glDisable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        glutSetWindow(subwindow1);	

	glBegin(GL_QUADS);
            glTexCoord2f(0,0);
            glVertex2f(-2,-2);
            glTexCoord2f(1,0);
            glVertex2f(2,-2);
            glTexCoord2f(1,1);
            glVertex2f(2,2);
            glTexCoord2f(0,1);
            glVertex2f(-2,2);
	glEnd();

	glBindTexture(GL_TEXTURE_2D, 0);
	

	glutSwapBuffers();

}
void displaySubwindow2(void) 
{   
	identical, except for d_result calculations
}

Many thanks in advance for any pointers,

Sam

Turns out that if I error check, the line:

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 640, 480, 0, GL_LUMINANCE, GL_FLOAT, NULL);
error = glGetError();
cout <<"Error code = " << error << endl;

returns “ERROR 1282: invalid operation” for one of the two glTexImage2D commands, whichever’s subwindow is not positioned last in the main function…

Any thoughts?