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, &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_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, &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();
}
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 :)
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.