FBO - cubemap rendering

i’ve got FBO rendering to normal 2d texture okay, but now i wanna set up rendering to cube map.

so where i would have set up for a 2d texture:

target = GL_TEXTURE_2D;

		glEnable(target);
		glBindTexture(target, texture);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
			GL_RGBA, GL_UNSIGNED_BYTE, NULL);

		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_CLAMP_TO_EDGE);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		Device::GetInstance().CheckErrors();

		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
			GL_COLOR_ATTACHMENT0_EXT,
			GL_TEXTURE_2D, texture, 0);

i’ve set up like a cube map:

		target = GL_TEXTURE_CUBE_MAP;

		glEnable(target);
		glBindTexture(target, texture);

		for (int i = 0; i < 6; ++i)
		{
			GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;

			glTexImage2D(target, 0, GL_RGBA8, width, height, 0,
				GL_RGBA, GL_UNSIGNED_BYTE, NULL);

			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_CLAMP_TO_EDGE);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			Device::GetInstance().CheckErrors();

			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
				GL_COLOR_ATTACHMENT0_EXT, target, texture, 0);
		}

but i get “unsupposrted framebuffer format” error.
do i need to something different?

That doesn’t look right, a cubemap is not a 2D texture. The texture target should be one of the faces like GL_TEXTURE_CUBE_MAP_POSITIVE_X.
Otherwise glGetFramebufferAttachmentParameterivEXT wouldn’t make sense with GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT.

This code seems to work OK so far:

glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb_dcm);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb_dcm);
for(int i=0; i<6; i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, dyn_cubemap, 0);
glViewport(0, 0, dyn_cm_size, dyn_cm_size);
glClear(GL_DEPTH_BUFFER_BIT);
SetProjection90();
SetFace(...);
Render();
}
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

and init:

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);
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);
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);

glGenRenderbuffers(1, &rb_dcm);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb_dcm);
glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, dyn_cm_size, dyn_cm_size);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

glGenFramebuffers(1, &fb_dcm);
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb_dcm);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);

Gotta look what is this GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT for… :rolleyes:

That’s for the Guiness Book category “Longest OpenGL enum”. :smiley:
No, it’s to query which cube face is currently attached and used with glGetFramebufferAttachmentParameterivEXT, as I said.

lol, I didn’t noticed glGet part :slight_smile:
And yeap, glGetFramebufferAttachmentParameterivEXT coupled with GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT should do it for the longest GL call :eek:

Do you guys count extensions that noone uses?

void ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN(const uint *rc, const float *tc, const float *c, const float *n, const float *v);

:eek:

http://oss.sgi.com/projects/ogl-sample/registry/SUN/vertex.txt

Hey, that’s not a GLenum. :wink:

Good thing for copy-and-paste. :wink:

-SirKnight

M/\dm/
, so i need to bind and render to each face seperately?

edit:
i tried a similar approach to what you have above, but it’s complaning about invalid format :-/

i hate to post slabs of code but here is what i got:

bool TextureRender::Create(int width, int height, TextureFlags flags)
{
	// http://opengl.org/documentation/extensions/EXT_framebuffer_object.txt

	this->width = width;
	this->height = height;

	Device::GetInstance().CheckErrors();

	glGenFramebuffersEXT(1, &fb);
	glGenTextures(1, &texture);
	glGenRenderbuffersEXT(1, &depth);
	glGenRenderbuffersEXT(1, &stencil);

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	// initialize color texture
	if (flags & CubeMap)
	{
		target = GL_TEXTURE_CUBE_MAP;

		glEnable(target);
		glBindTexture(target, texture);

		for (int i = 0; i < 6; ++i)
		{
			GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;

			glTexImage2D(face, 0, GL_RGBA8, width, height, 0,
				GL_RGBA, GL_UNSIGNED_BYTE, NULL);

			glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
				GL_COLOR_ATTACHMENT0_EXT, face, texture, 0);
		}
	}
	else
	{
		target = GL_TEXTURE_2D;

		glEnable(target);
		glBindTexture(target, texture);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
			GL_RGBA, GL_UNSIGNED_BYTE, NULL);

		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_CLAMP_TO_EDGE);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
			GL_COLOR_ATTACHMENT0_EXT,
			GL_TEXTURE_2D, texture, 0);
	}

	// initialize depth renderbuffer
	if (flags & Depth)
	{
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth);

		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
			GL_DEPTH_COMPONENT24, width, height);

		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
			GL_DEPTH_ATTACHMENT_EXT,
			GL_RENDERBUFFER_EXT, depth);
	}

	// initialize stencil renderbuffer
	if (flags & Stencil)
	{
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil);

		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
			GL_STENCIL_INDEX, width, height);

		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
			GL_STENCIL_ATTACHMENT_EXT,
			GL_RENDERBUFFER_EXT, stencil);
	}

	Device::GetInstance().CheckFramebufferStatus();

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

	Device::GetInstance().CheckFramebufferStatus();

	return true;
}

int TextureRender::Lock()
{
	Texture::RestoreDefault();

	glBindTexture(target, 0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	Device::GetInstance().CheckFramebufferStatus(); //<< "unsupposrted format" error here

	glPushAttrib(GL_VIEWPORT_BIT);

	return (target == GL_TEXTURE_2D) ? 1 : 6;
}

void TextureRender::BindTarget(int index, bool clear)
{
	if (target != GL_TEXTURE_2D)
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+index, texture, 0);
	
	glViewport(0, 0, width, height);
	glClearColor(1, 0, 0, 0);

	if (clear)
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	Device::GetInstance().CheckFramebufferStatus(); //<< "unsupposrted format" error here
}

void TextureRender::UnLock()
{
	glPopAttrib();

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

	Device::GetInstance().CheckFramebufferStatus();
}

Exactly.
You can only render to 2D surfaces and in a cube map that’s each individual face.

okay it actually works, except having some issues with cg which is causing it to fail :slight_smile: