PDA

View Full Version : FBO - cubemap rendering



supagu
06-08-2005, 01:32 AM
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?

Relic
06-08-2005, 03:35 AM
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_EX T.

M/\dm/\n
06-08-2005, 04:41 AM
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, &amp;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, &amp;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, &amp;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_EX T for... :rolleyes:

Relic
06-08-2005, 04:50 AM
That's for the Guiness Book category "Longest OpenGL enum". :D
No, it's to query which cube face is currently attached and used with glGetFramebufferAttachmentParameterivEXT, as I said.

M/\dm/\n
06-08-2005, 04:53 AM
lol, I didn't noticed glGet part :)
And yeap, glGetFramebufferAttachmentParameterivEXT coupled with GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EX T should do it for the longest GL call :eek:

Overmind
06-08-2005, 05:55 AM
Do you guys count extensions that noone uses?

void ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3f vSUN(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

Relic
06-08-2005, 07:13 AM
Hey, that's not a GLenum. ;)

SirKnight
06-08-2005, 08:39 AM
Good thing for copy-and-paste. ;)

-SirKnight

supagu
06-09-2005, 02:44 AM
M/\dm/\n, 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, &amp;fb);
glGenTextures(1, &amp;texture);
glGenRenderbuffersEXT(1, &amp;depth);
glGenRenderbuffersEXT(1, &amp;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();
}

Relic
06-09-2005, 02:55 AM
Exactly.
You can only render to 2D surfaces and in a cube map that's each individual face.

supagu
06-10-2005, 12:55 AM
okay it actually works, except having some issues with cg which is causing it to fail :)