Dynamic cubemap + FBO

I’m having problems with dynamic cubemaps, they seem to be toatlly wrong, and I can’t understand why.

FBO Init code:

glGenTextures(1, &dyn_cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, dyn_cubemap);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, mta);
	
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB8, dyn_cm_size, dyn_cm_size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB8, dyn_cm_size, dyn_cm_size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB8, dyn_cm_size, dyn_cm_size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB8, dyn_cm_size, dyn_cm_size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB8, dyn_cm_size, dyn_cm_size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB8, dyn_cm_size, dyn_cm_size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
	
glGenFramebuffers(1, &fb_dcm);
glGenRenderbuffers(1, &rb_dcm);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb_dcm);
glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, dyn_cm_size, dyn_cm_size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb_dcm);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

Render to CM code:

glUseProgramObject(Relief.handle);
	glUniform1i(glGetUniformLocation(Relief.handle, "base"), 0);
	glUniform1i(glGetUniformLocation(Relief.handle, "normal"), 1);
	glUniform4fv(glGetUniformLocation(Relief.handle, "l_pos[0]"), 4, lp[0]);
	glUniform4f(glGetUniformLocation(Relief.handle, "e_pos"), ep[0], ep[1], ep[2], ep[3]);

	glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb_dcm);
	glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb_dcm);
	glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, dyn_cubemap, 0);
	glViewport(0, 0, dyn_cm_size, dyn_cm_size);
	glClear(GL_DEPTH_BUFFER_BIT);
	SetProjection90();
	gluLookAt(0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floor"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floorbm"));
	objs[0].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("iron"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("ironbm"));
	objs[1].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stone"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stonebm"));
	objs[2].Render();

	glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, dyn_cubemap, 0);
	glViewport(0, 0, dyn_cm_size, dyn_cm_size);
	glClear(GL_DEPTH_BUFFER_BIT);
	SetProjection90();
	gluLookAt(0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floor"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floorbm"));
	objs[0].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("iron"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("ironbm"));
	objs[1].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stone"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stonebm"));
	objs[2].Render();

	glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, dyn_cubemap, 0);
	glViewport(0, 0, dyn_cm_size, dyn_cm_size);
	glClear(GL_DEPTH_BUFFER_BIT);
	SetProjection90();
	gluLookAt(0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floor"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floorbm"));
	objs[0].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("iron"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("ironbm"));
	objs[1].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stone"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stonebm"));
	objs[2].Render();

	glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, dyn_cubemap, 0);
	glViewport(0, 0, dyn_cm_size, dyn_cm_size);
	glClear(GL_DEPTH_BUFFER_BIT);
	SetProjection90();
	gluLookAt(0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floor"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floorbm"));
	objs[0].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("iron"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("ironbm"));
	objs[1].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stone"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stonebm"));
	objs[2].Render();

	glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, dyn_cubemap, 0);
	glViewport(0, 0, dyn_cm_size, dyn_cm_size);
	glClear(GL_DEPTH_BUFFER_BIT);
	SetProjection90();
	gluLookAt(0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floor"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floorbm"));
	objs[0].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("iron"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("ironbm"));
	objs[1].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stone"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stonebm"));
	objs[2].Render();

	glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, dyn_cubemap, 0);
	glViewport(0, 0, dyn_cm_size, dyn_cm_size);
	glClear(GL_DEPTH_BUFFER_BIT);
	SetProjection90();
	gluLookAt(0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floor"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("floorbm"));
	objs[0].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("iron"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("ironbm"));
	objs[1].Render();
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stone"));
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, Textures.GetID("stonebm"));
	objs[2].Render();

	glUseProgramObject(0);

	glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
	glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
void SetProjection90()
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90.f, 1.0, .1f, 500.f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

Checking routine:

	glUseProgramObject(0);
	
	//////////////////////////////////////////////////
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, dyn_cubemap);
	glEnable(GL_TEXTURE_CUBE_MAP);
	glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); 
	glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); 
	glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);
	wireframe?glPolygonMode(GL_FRONT_AND_BACK, GL_LINE):glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glColor4f(1.0,1.0,1.0,1.0);
	objs[3].Render();
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
	
	//////////////////////////////////////////////////
	if(ang>0.5){
	const int cs = dyn_cm_size;
	unsigned char cf[cs][cs][3];
	BITMAPFILEHEADER bfh;
	BITMAPINFOHEADER bih;
	bih.biSize			= sizeof(BITMAPINFOHEADER);
	bih.biPlanes        = 1;
	bih.biBitCount      = 24;
	bih.biCompression   = BI_RGB;
	bih.biSizeImage     = cs*cs*3;
	bih.biXPelsPerMeter = 0;
	bih.biYPelsPerMeter = 0;
	bih.biClrUsed       = 0;
	bih.biClrImportant  = 0;
	bih.biWidth         = cs;
	bih.biHeight        = cs;
	bfh.bfSize       = sizeof(BITMAPFILEHEADER);
	bfh.bfType       = 0x4D42;
	bfh.bfReserved1  = 0;
	bfh.bfReserved2  = 0;
	bfh.bfOffBits    = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
	
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_BGR, GL_UNSIGNED_BYTE, cf);
	fstream file;
	file.open("outpx.bmp", ios::out|ios::binary);
	if(file.is_open())
	{
		file.write((char*)&bfh,sizeof(BITMAPFILEHEADER));
		file.write((char*)&bih,sizeof(BITMAPINFOHEADER));
		file.write((const char*)cf,sizeof(unsigned char)*3*cs*cs);
		file.close();
	}
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+1, 0, GL_BGR, GL_UNSIGNED_BYTE, cf);
	file.open("outnx.bmp", ios::out|ios::binary);
	if(file.is_open())
	{
		file.write((char*)&bfh,sizeof(BITMAPFILEHEADER));
		file.write((char*)&bih,sizeof(BITMAPINFOHEADER));
		file.write((const char*)cf,sizeof(unsigned char)*3*cs*cs);
		file.close();
	}
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+2, 0, GL_BGR, GL_UNSIGNED_BYTE, cf);
	file.open("outpy.bmp", ios::out|ios::binary);
	if(file.is_open())
	{
		file.write((char*)&bfh,sizeof(BITMAPFILEHEADER));
		file.write((char*)&bih,sizeof(BITMAPINFOHEADER));
		file.write((const char*)cf,sizeof(unsigned char)*3*cs*cs);
		file.close();
	}
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+3, 0, GL_BGR, GL_UNSIGNED_BYTE, cf);
	file.open("outny.bmp", ios::out|ios::binary);
	if(file.is_open())
	{
		file.write((char*)&bfh,sizeof(BITMAPFILEHEADER));
		file.write((char*)&bih,sizeof(BITMAPINFOHEADER));
		file.write((const char*)cf,sizeof(unsigned char)*3*cs*cs);
		file.close();
	}
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+4, 0, GL_BGR, GL_UNSIGNED_BYTE, cf);
	file.open("outpz.bmp", ios::out|ios::binary);
	if(file.is_open())
	{
		file.write((char*)&bfh,sizeof(BITMAPFILEHEADER));
		file.write((char*)&bih,sizeof(BITMAPINFOHEADER));
		file.write((const char*)cf,sizeof(unsigned char)*3*cs*cs);
		file.close();
	}
	glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+5, 0, GL_BGR, GL_UNSIGNED_BYTE, cf);
	file.open("outnz.bmp", ios::out|ios::binary);
	if(file.is_open())
	{
		file.write((char*)&bfh,sizeof(BITMAPFILEHEADER));
		file.write((char*)&bih,sizeof(BITMAPINFOHEADER));
		file.write((const char*)cf,sizeof(unsigned char)*3*cs*cs);
		file.close();
	}}
	glDisable(GL_TEXTURE_CUBE_MAP);
	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
	/////////////////////////////////////////////////////

Result is very strange, like transformations don’t apply and all faces are rendered as one. When I move away from sphere, it seems that faces dissapear in black.
GetTexImage returns black quads all the time, even if I read back cubemap after n’th frame, when i see some sort of reflections on sphere - obj[3]

After setting your perspective, try calling this routine instead of gluLookAt before further rendering:

void applyCubeFaceMatrix(int face, float x, float y, float z)
{

  switch(face)
  {
    case 0: glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
            glRotatef(180.0f, 0.0f, 0.0f, 1.0f); break;
    case 1: glRotatef( 90.0f, 0.0f, 1.0f, 0.0f);
            glRotatef(180.0f, 0.0f, 0.0f, 1.0f); break;
    case 2: glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); break;
    case 3: glRotatef( 90.0f, 1.0f, 0.0f, 0.0f); break;
    case 4: glRotatef(180.0f, 1.0f, 0.0f, 0.0f); break;
    case 5: glRotatef(180.0f, 0.0f, 0.0f, 1.0f); break;
  }

  glTranslatef(-x, -y, -z);
}

Where x, y and z are the world coordinates of your dynamic cubemap center.

Finally got some time to try your solution, and it works, thanks. Now if only someone could explain me why gluLookAt refuses to work…

Simple, take a look at the implementation of gluLookAt and you’ll see that often your view and position tuples cancel each other out :wink: