Sign in to follow this  
xerodsm

Cubemap Textures

Recommended Posts

xerodsm    142
I've tried searching numerous times but unfortunately I haven't had any luck. I'm trying to create a simple ray-tracer using GLSL and so far I have been able to create dynamic cubemaps for certain objects and store them as textures. My question is, how do I take my GL_TEXTURE_2D texture and set it to one of the cubemap textures, like GL_TEXTURE_CUBE_MAP_POSITIVE_X. All the cubemap examples I've seen use "glTexImage2D" but I don't have the pixel data because it's already loaded into a texture. If anyone knows how to get the pixel data from a texture I could use that too. Any other suggestions are welcome. I use: glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, size, size, 0); to create the cubemap textures, six of them. Thanks in advance.

Share this post


Link to post
Share on other sites
Kalidor    1087
Quote:
Original post by xerodsm
I've tried searching numerous times but unfortunately I haven't had any luck. I'm trying to create a simple ray-tracer using GLSL and so far I have been able to create dynamic cubemaps for certain objects and store them as textures. My question is, how do I take my GL_TEXTURE_2D texture and set it to one of the cubemap textures, like GL_TEXTURE_CUBE_MAP_POSITIVE_X. All the cubemap examples I've seen use "glTexImage2D" but I don't have the pixel data because it's already loaded into a texture. If anyone knows how to get the pixel data from a texture I could use that too. Any other suggestions are welcome.

I use:
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, size, size, 0);

to create the cubemap textures, six of them.

Thanks in advance.
You could use the GL_ARB_pixel_buffer_object (PBO) extension to transfer the texel data from one texture into another without needing to copy it to system RAM first, but why not just create the textures as the sides of the cubemap face to begin with? Look at the valid values of target for glCopyTexImage2D.

Share this post


Link to post
Share on other sites
ma_hty    100
You can actually use FBO extension to render 3D model directly onto a cubemap face. You don't have to do any copy at all.

Share this post


Link to post
Share on other sites
xerodsm    142
I realize all this but say I have two objects that both use cubemaps. In order to generate the cubemaps I have to render from the objects perspectives in the + and - x,y and z axes. To do that I have to clear the screen and if I do that I lose all the rendered data. What I want to do is render to a texture, save the textures in the objects class so when I'm ready to render the objects I have all the cubemap information in textures that I can just copy over. Otherwise if I just render straight to the cubemap then I will only have information about one object's cubemap saved at any given time.

Share this post


Link to post
Share on other sites
Kalidor    1087
Quote:
Original post by xerodsm
...
Otherwise if I just render straight to the cubemap then I will only have information about one object's cubemap saved at any given time.
I don't see why you would have that problem. You can use an FBO to render directly to the sides of one cubemap, and then render directly to the sides of the second cubemap; there's no reason you can't keep the first cubemap intact while you render to the second one.

Some light reading.

Share this post


Link to post
Share on other sites
xerodsm    142
Maybe I'm misinterpreting something, but here's how it works now and here's why I want to do it by holding the textures...

So lets say I have two sphere objects that need to have cubemaps:

sphere 1
- generate cubemap (to do this I have to clear the buffer)
- attach cubemap to texture
- draw sphere with appropriate cubemap

sphere 2
- generate cubemap (since I still have to clear the buffer I just cleared everything I drew with sphere1)
- attach cubemap to texture
- draw sphere with appropriate cubemap

Now the only thing I see is sphere two because I just cleared the buffer when I was trying to draw my cubemap for sphere two.

If I create all the cubemaps and hold them in textures then all I have to do is somehow set the cubemap texture data equal to the texture data that I already have. Otherwise how do I generate my cubemaps without clearing the screen and not being able to see anything I drew before generating the map?

Share this post


Link to post
Share on other sites
swiftcoder    18432
Quote:
Original post by xerodsm
sphere 1
- generate cubemap (to do this I have to clear the buffer)
- attach cubemap to texture
- draw sphere with appropriate cubemap

sphere 2
- generate cubemap (since I still have to clear the buffer I just cleared everything I drew with sphere1)
- attach cubemap to texture
- draw sphere with appropriate cubemap

How about thinking outside the box and changing the order?
- generate sphere1 cubemap (six passes, bind each to a cubemap face)
- generate sphere2 cubemap (same again)

- draw sphere1
- draw sphere2

Share this post


Link to post
Share on other sites
xerodsm    142
As far as I know you can't do that because once you bind the second cube values to the cubemap then the first cubemap's values are gone... right? So the second one would have the same maps as the first one.

Share this post


Link to post
Share on other sites
xerodsm    142
I actually do have it in that order right now and it works in terms of creating the right textures for each cubemap, just the overwriting is the problem I'm running into.

Share this post


Link to post
Share on other sites
rozz666    896
Quote:
Original post by xerodsm
I actually do have it in that order right now and it works in terms of creating the right textures for each cubemap, just the overwriting is the problem I'm running into.


You are using glBindTexture etc., aren't you?

Share this post


Link to post
Share on other sites
ma_hty    100
I'm sorry xerodsm.

I just don't see why you need two cubemap and why it is not possible to render two objects onto the same cubemap. It is not necessary for you to clear the screen every you draw the objects, instead, you just need to clear the screen once per frame.

By the way, can you tell us more about your application? What exactly it does with cubemap? (mirror reflection?)

Share this post


Link to post
Share on other sites
dpadam450    2357
"As far as I know you can't do that because once you bind the second cube values to the cubemap then the first cubemap's values are gone... right? So the second one would have the same maps as the first one."

So I'm lost, you have a sphere. You draw facing from the spheres center:
the right axis. glCopyTexImage2D(the color buffer)
//you dont have to clear the color buffer btw
the -right axis. glCopyTexImage2D(the color buffer)

...after you do all 6 axis for this sphere, you know have 6 images. Load them into the cube map like usual. You know with GL_CUBEMAP_X+AXIS or whatever it is.

Then you can setup cube mapping and draw this sphere with the cube map texture bound to it.

"My question is, how do I take my GL_TEXTURE_2D texture and set it to one of the cubemap textures, like GL_TEXTURE_CUBE_MAP_POSITIVE_X. All the cubemap examples I've seen use "glTexImage2D" but I don't have the pixel data because it's already loaded into a texture."

So again, when you first create this texture, it has to be of type GL_TEXTURE_CUBE_MAP. Then openGL is expecting you to provide 6 2d textures for this cube map. Like I stated, you will snap these pictures at run time and update the cube map with glTexImage2D. You will never use GL_TEXTURE_2D if your dealing with a cube map.

Share this post


Link to post
Share on other sites
Kalidor    1087
Quote:
Original post by xerodsm
As far as I know you can't do that because once you bind the second cube values to the cubemap then the first cubemap's values are gone... right? So the second one would have the same maps as the first one.
Why would that happen? You should have two completely independent cubemap texture objects, one for each sphere. When generating the first sphere's cubemap you will either copy into or render directly into the first cubemap texture object's faces. When generating the second sphere's cubemap you will copy/render directly into the second cubemap texture object's faces. There's no reason to create 6 separate 2D texture objects for each sphere and then copy them into a single cubemap texture object's faces when you need to use it.

Using the "copy into cubemap texture object's faces" option above, you will be rendering to the main backbuffer and then calling glCopyTexImage2D to copy the backbuffer into the corresponding cubemap face, then repeat for each face. When you clear the backbuffer, you won't erase the texture data you already copied into the cubemap texture.

But, you can avoid the extra copy by using the FBO extension (spec linked above in my earlier post) to render directly into the cubemaps' faces. See this and this for some easier to digest information on using FBOs to render into textures. It doesn't cover rendering into cubemap faces, but it is almost exactly the same (again, see the previously linked specs for more information).

Share this post


Link to post
Share on other sites
xerodsm    142
Ok, well I think I understand what I was missing before...

I didn't realize that when you use the line: glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_tex); you can bind any number of different texture locations to the cubemap and then just set the + and -, x,y and z cubemaps. Well, I thought adding that to my code would help but now when I try to render everything looks black.

Below is my code to generate the cubemap. Does anyone see anything wrong? If I take out the "glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_tex);" line then it will render but all the cubemaps for each different sphere look the same.



void CFrameBuffer::renderCubemap(CObject *obj, UINT size) // Renders To A Texture
{
glViewport(0,0,size,size);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90,1,0.4f,1000000.0f);//gluPerspective(45,width/height,2,100000);
glMatrixMode(GL_MODELVIEW);

glBindTexture(GL_TEXTURE_CUBE_MAP, obj->cubemap_tex);

for(int i = 0; i < 6; i++)
{
glPushMatrix();

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set The Clear Color To Medium Blue
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And Depth Buffer

glLoadIdentity();

if(i == 0)
{
glRotatef(90,0,0,1);
glRotatef(90,0,1,0);
}
else if(i == 1)
{
glRotatef(-90,0,0,1);
glRotatef(-90,0,1,0);
}
else if(i == 2)
{
glRotatef(0,0,1,0);
}
else if(i == 3)
{
glRotatef(180,0,1,0);
glRotatef(180,0,0,1);
}
else if(i == 4)
{
glRotatef(-90,1,0,0);
}
else if(i == 5)
{
glRotatef(180,0,0,1);
glRotatef(90,1,0,0);
}


glTranslatef(-obj->position.x,-obj->position.y,-obj->position.z);

CCamera::instance()->setTemporaryPosition( obj->position );

CObjectHandler::instance()->renderWithout(obj);

glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA, 0, 0, size, size, 0);

glPopMatrix();
}

//glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
CCamera::instance()->restorePosition();

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glViewport(0 , 0,getWidth() ,getHeight());

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,1,0.4f,1000000.0f);//gluPerspective(45,width/height,2,100000);
glMatrixMode(GL_MODELVIEW);
}

Share this post


Link to post
Share on other sites
Kalidor    1087
Quote:
Original post by xerodsm
Ok, well I think I understand what I was missing before...

I didn't realize that when you use the line: glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_tex); you can bind any number of different texture locations to the cubemap and then just set the + and -, x,y and z cubemaps. Well, I thought adding that to my code would help but now when I try to render everything looks black.

Below is my code to generate the cubemap. Does anyone see anything wrong? If I take out the "glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_tex);" line then it will render but all the cubemaps for each different sphere look the same.


*** Source Snippet Removed ***
The reason they all look the same when you don't bind a specific cubemap is because you will change (overwrite) the default cubemap texture's image data when you generate the cubemap's of each sphere, then you will use be using the default cubemap texture when rendering each time.

The code you posted looks "okay," are you checking for OpenGL errors? Can you show where you generate those cubemap_tex ids for each sphere?

Also it seems like you don't quite understand OpenGL's texture objects. I recommend reading Chapter 9 of the Red Book for some good information. Some of it is a little out-dated by now though (ie: the "high performance working set" of textures and checking if they're resident or prioritizing them).

Share this post


Link to post
Share on other sites
xerodsm    142
I use this:

glGenTextures(1, &cubemap_tex);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_tex);

For every sphere. I understand how textures work, I just didn't really understand how cubemap texturing works.

Share this post


Link to post
Share on other sites
dpadam450    2357
Ok so you have no idea what cube mapping is?...........Sorry but you make no sense. You claim to not understand it, but you also claim to be able to make run-time dynamic cubemaps.

"I just didn't really understand how cubemap texturing works."
"so far I have been able to create dynamic cubemaps for certain objects and store them as textures"

Share this post


Link to post
Share on other sites
xerodsm    142
Thank you for that very informative post.

There's a big difference between getting something to work and understanding exactly how it works. I'm a trial and error coder.

Share this post


Link to post
Share on other sites
V-man    813
developer.nvidia.com has a lot of documentation. There was one called cubemap.pdf and it explains everything you need to know relating to cubemaps for GL.

Trial and error sucks. You will waste a lot of time and probably you won't learn something fully.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this