PDA

View Full Version : Cube Mapping Using OpenGL



someoney
02-17-2010, 12:58 PM
I've been attempting to cube map (this time using opengl).

I generate the textures as:



glGenTextures(7, texture_name); //generate the texture names
GLubyte texture[texture_size][texture_size][4]; //generic array for textures

//top
makeFillTexture(texture, top_rgba);
bindTextures(pos_y_face, texture);

//bottom
makeFillTexture(texture, bottom_rgba);
bindTextures(neg_y_face, texture);

//left
makeStripeTexture(texture, left_rgba, left_alt_rgba);
bindTextures(neg_x_face, texture);

//right
makeStripeTexture(texture, right_rgba, right_alt_rgba);
bindTextures(pos_x_face, texture);

//front
makeCheckerTexture(texture, front_rgba, front_alt_rgba);
bindTextures(pos_z_face, texture);

//back
makeFillTexture(texture, back_rgba);
bindTextures(neg_z_face, texture);

glEnable(GL_TEXTURE_2D);

GLubyte texture2[6][texture_size][texture_size][4];

//environment mapping
glBindTexture(GL_TEXTURE_CUBE_MAP, texture_name[6]);
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_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

//top
makeFillTexture(texture2[0], top_rgba);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2[0]);

//bottom
makeFillTexture(texture2[1], bottom_rgba);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2[1]);

//left
makeStripeTexture(texture2[2], left_rgba, left_alt_rgba);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2[2]);

//right
makeStripeTexture(texture2[3], right_rgba, right_alt_rgba);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2[3]);

//front
makeCheckerTexture(texture2[4], front_rgba, front_alt_rgba);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2[4]);

//back
makeFillTexture(texture2[5], back_rgba);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, texture_size, texture_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2[5]);


And apply it using:



if (sphere_quad_strip == NULL)
makeSphere();

glBindTexture(GL_TEXTURE_CUBE_MAP, texture_name[6]);
glEnable(GL_TEXTURE_CUBE_MAP);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

glBegin(GL_QUAD_STRIP);

for (int i = 0; i < sphere_quad_strip_size; i++)
glVertex3d(sphere_quad_strip[i][0], sphere_quad_strip[i][1], sphere_quad_strip[i][2]);

glEnd();

drawPole(sphere_top_tri_strip);
drawPole(sphere_bottom_tri_strip);

glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_CUBE_MAP);



To summarize: I create the textures, bind them to the faces, assign it to a texture name, and then use automatic texture coord generation to texture my sphere.

However, the resulting texture uses only one side of the texture map.

I probably assigned the textures incorrectly.

Thank you for any help.

strattonbrazil
02-17-2010, 03:08 PM
Have you seen this tutorial? It's the best I've seen on cube mapping.

http://developer.nvidia.com/object/cube_map_ogl_tutorial.html

Your code appears almost identical. The only thing that catches my eye is you don't provide vertex normals (at least not that I can see). And according to the above tutorial:



In practice however, it usually makes more sense to use one of OpenGL's texture coordinate generation modes. Two new texgen modes are added that generate the eye-space reflection vector or normal vector in the (s,t,r) texture coordinates. Reflection map example:

glTexGenfv(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
glTexGenfv(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
glTexGenfv(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

Normal map example:

glTexGenfv(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
glTexGenfv(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
glTexGenfv(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

For these two modes to operate correctly, correct per-vertex normals must be supplied.


That's nVidia's opinion, at least.

Also, if you look at this link you'll see the texture coordinates are actually generated using vertex position AND normal.

http://www.opengl.org/wiki/Mathematics_of_glTexGen

That's my guess. Always thought cube mapping was one of the trickier-to-setup features.

someoney
02-17-2010, 03:30 PM
Thank you for your response. I believe that the normals is definitely one part of the problem. Originially, it was a flat circle, but the inclusion of normals make it actually look like a sphere.

Unfortunately, the sphere is still textured using a single texture.

only a minor change in the code to incorporate normals (since the vertices are of unit length and the sphere is centered at the origin):



if (sphere_quad_strip == NULL)
makeSphere();

glBindTexture(GL_TEXTURE_CUBE_MAP, texture_name[6]);
glEnable(GL_TEXTURE_CUBE_MAP);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

glBegin(GL_QUAD_STRIP);

for (int i = 0; i < sphere_quad_strip_size; i++) {

glNormal3fv(sphere_quad_strip[i]);
glVertex3fv(sphere_quad_strip[i]);

}

glEnd();

drawPole(sphere_top_tri_strip);
drawPole(sphere_bottom_tri_strip);

glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_CUBE_MAP);

strattonbrazil
02-18-2010, 08:59 AM
Can you post a picture?

someoney
02-18-2010, 09:45 AM
Sure.

What I got from implementing cube mapping without using OpenGL cube mapping abilities:

http://img188.imageshack.us/img188/7159/sphere3b.png

I sort of expect opengl to handle cube mapping better than above, but:

http://img188.imageshack.us/img188/9814/sphere1b.png

http://img188.imageshack.us/img188/9577/sphere2b.png

As you can see, only one texture face is used for mapping in OpenGL cube mapping. The reason that there are different textures in the above two was probably due to the fact I allowed my program to switch from one method to the other (my cube mapping to opengl's cube mapping). So if I switched at a certain angles around the sphere, I result in different textures mapped to the opengl cube mapped sphere.

I'm assuming this is because OpenGL is in fact texture mapping the previously assigned texture from when I was showing my implementation of cube mapping. In other words, OpenGL did not switch to the cube map I assigned to texture_name[6].

That's why I believe that I was setting up the cube mapping incorrectly (either the binding or the setting up of the auto texture coord generation).

strattonbrazil
02-21-2010, 04:37 PM
So it's jumping between textures when you move your camera? So if you just rotate around to one side, when you cross a certain point it changes? Like each time a new face becomes more visible?

Try this just to make just your texture setup is correct. Have each texture specified to a fixed point in 3D and pick some different numbers. Without moving the camera around, see if you can swap textures on the screen just by using different texture coordinates. If so, it might be a texture coordinate generation issue.

beginnertom
02-21-2010, 05:53 PM
So it's jumping between textures when you move your camera? So if you just rotate around to one side, when you cross a certain point it changes? Like each time a new face becomes more visible?

Try this just to make just your texture setup is correct. Have each texture specified to a fixed point in 3D and pick some different numbers. Without moving the camera around, see if you can swap textures on the screen just by using different texture coordinates. If so, it might be a texture coordinate generation issue.
thank you.
i had seen your discussion .
from here:
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&amp;Number=272571#Post2725 71 (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&amp;Number=272571#Post2725 71?ubb=showflat&amp;Number=272571#Post272571)
it is really helpful for me
i meand yes my probelm is the texture map. mimmap. two box texture map.

xora_kho
02-21-2010, 08:38 PM
can u guide me to model 3D object using openGL??..thx guys!

someoney
02-24-2010, 11:25 AM
Sorry, I've been away for a while.

The texture doesn't change with the rotation of the camera. Rotating the camera while using OpenGl's implementation of cube mapping results in the same texture. The change of texture is from switching between my cube mapping implementation to OpenGL's.

That is why I believe that OpenGl is simply using the last texture assigned in my implementation to generate coordinates for in OpenGL's.

Thank you for your responses!

James_Bond
04-15-2010, 05:56 AM
Up!

I was wondering, did you manage to make the cube map texture "rotate" with the camera so the reflection map didn't "show" the same face?

James_Bond
04-20-2010, 03:02 AM
I found how to do it.

Jittar
12-19-2010, 12:53 AM
HI friends,

i hve drawn a cube using guads. Now i want to do texture mapping inside the this cube not outside...

how can i do that