PDA

View Full Version : texturing a cube to make a skybox



Manojo
12-08-2007, 06:04 PM
Hello,

I have six images and I would like to use them to make a skybox in a cube that I am calling from a display list.
Right now, only the 6th face is textured on all faces .

Here's the code that initialises texturing :


void generateTextures(){
int i = 0;
//load an image to an SDL surface (i.e. a buffer)
texture[0] = IMG_Load("skybox_images/neg_z.bmp");
texture[1] = IMG_Load("skybox_images/neg_x.bmp");
texture[2] = IMG_Load("skybox_images/pos_z.bmp");
texture[3] = IMG_Load("skybox_images/pos_x.bmp");
texture[4] = IMG_Load("skybox_images/pos_y.bmp");
texture[5] = IMG_Load("skybox_images/neg_y.bmp");

/* if(texture == NULL)
{
printf("bad image\n");
exit(1);
}*/

//create an OpenGL texture object
glGenTextures(6, textureObjSkyBox);

for(i = 0; i < 6; i++){
//select the texture object you need
glBindTexture(GL_TEXTURE_2D, textureObjSkyBox[i]);
//define the parameters of that texture object
//how the texture should wrap in s direction
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//how the texture should wrap in t direction
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//how the texture lookup should be interpolated when the face is smaller than the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//how the texture lookup should be interpolated when the face is bigger than the texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//send the texture image to the graphic card
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture[i]->w, texture[i]->h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[i]-> pixels);
//clean the SDL surface
SDL_FreeSurface(texture[i]);
}
}


After doing this, I have a display list in my cube where I want to texture each face.

How would I go about it ?

Thanks,
Manojo

plasmonster
12-08-2007, 10:45 PM
You need to use the GL_TEXTURE_CUBE_MAP texture target with glBindTexture and the glTexParameter* procs, then use
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i for the glTexImage2D calls.

sqrt[-1]
12-08-2007, 11:13 PM
I don't think he wants a cube map - just a cube skybox with six faces. (yes you can do it with a cube map - but much simpler to use 2D textures)

Basically want you want to do is:

Loop for all faces
Set texture
Draw Cube face

Manojo
12-09-2007, 03:48 AM
Thanks for the reply, swrt[-1] is right, I just need a cube skybox with 6 faces.

The thing is that I have manually defined all the faces in a display list, but precising every vertex. Therefore, the looping part is not necessary I think.

In my display list, for each face this is what I do :

-set the normal
- bind texture
- draw the cube face by precising the vertices.

The problem is only one texture is applied, and it is applied to all six faces :



static void generateSkyBox(unsigned int* aListId, float size, unsigned int * theTexture){
/*generating a display list for the skybox*/
*aListId = glGenLists(1);
glNewList(*aListId, GL_COMPILE);
glEnable(GL_TEXTURE_2D);
//draw a face (with one texel per face)
glColor3f(1.0, 1.0, 1.0);
//front face
glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, -1.0);
glBindTexture(GL_TEXTURE_2D, theTexture[2]);
glTexCoord2f(0.0, 0.0); glVertex3f(-size, size, size);
glTexCoord2f(1.0, 0.0); glVertex3f( size, size, size);
glTexCoord2f(1.0, 1.0); glVertex3f( size, -size, size);
glTexCoord2f(0.0, 1.0); glVertex3f(-size, -size, size);

//right face

glNormal3f(-1.0, 0.0, 0.0);
glBindTexture(GL_TEXTURE_2D, theTexture[3]);
glTexCoord2f(0.0, 0.0); glVertex3f( size, size, size);
glTexCoord2f(1.0, 0.0); glVertex3f( size, size, -size);
glTexCoord2f(1.0, 1.0); glVertex3f( size, -size, -size);
glTexCoord2f(0.0, 1.0); glVertex3f( size, -size, size);

//back face

glNormal3f(0.0, 0.0, 1.0);
glBindTexture(GL_TEXTURE_2D, theTexture[0]);
glTexCoord2f(0.0, 0.0); glVertex3f( size, size, -size);
glTexCoord2f(1.0, 0.0); glVertex3f(-size, size, -size);
glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, -size);
glTexCoord2f(0.0, 1.0); glVertex3f( size, -size, -size);

//left face

glNormal3f(1.0, 0.0, 0.0);
glBindTexture(GL_TEXTURE_2D, theTexture[1]);
glTexCoord2f(0.0, 0.0); glVertex3f(-size, size, -size);
glTexCoord2f(1.0, 0.0); glVertex3f(-size, size, size);
glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, size);
glTexCoord2f(0.0, 1.0); glVertex3f(-size, -size, -size);

//top face

glNormal3f(0.0, -1.0, 0.0);
glBindTexture(GL_TEXTURE_2D, theTexture[4]);
glTexCoord2f(0.0, 0.0); glVertex3f(-size, size, -size);
glTexCoord2f(1.0, 0.0); glVertex3f( size, size, -size);
glTexCoord2f(1.0, 1.0); glVertex3f( size, size, size);
glTexCoord2f(0.0, 1.0); glVertex3f(-size, size, size);

//bottom face

glNormal3f(0.0, 1.0, 0.0);
glBindTexture(GL_TEXTURE_2D, theTexture[5]);
glTexCoord2f(0.0, 0.0); glVertex3f( size, -size, size);
glTexCoord2f(1.0, 0.0); glVertex3f( size, -size, -size);
glTexCoord2f(1.0, 1.0); glVertex3f(-size, -size, -size);
glTexCoord2f(0.0, 1.0); glVertex3f(-size, -size, size);
glEnd();
glEndList ();
};
};


Am I missing something ?

ZbuffeR
12-09-2007, 05:51 AM
it should work, provided that theTexture and textureObjSkyBox hold the same data.

sqrt[-1]
12-09-2007, 05:57 AM
From here: http://www.opengl.org/sdk/docs/man/xhtml/glBindTexture.xml

"GL_INVALID_OPERATION is generated if glBindTexture is executed
between the execution of glBegin and the corresponding
execution of glEnd."

Try code like this instead - although I really don't think you need display lists to do this stuff..

Also - trying using GLIntercept when developing to catch errors like this: http://www.opengl.org/sdk/tools/GLIntercept/ I suggest the "AuthorStd" profile for development.




glNewList(*aListId, GL_COMPILE);
glEnable(GL_TEXTURE_2D);
glColor3f(1.0, 1.0, 1.0);

glBindTexture(GL_TEXTURE_2D, theTexture[2]);

glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-size, size, size);
glTexCoord2f(1.0, 0.0); glVertex3f( size, size, size);
glTexCoord2f(1.0, 1.0); glVertex3f( size, -size, size);
glTexCoord2f(0.0, 1.0); glVertex3f(-size, -size, size);
glEnd();

glBindTexture(GL_TEXTURE_2D, theTexture[3]);

glBegin(GL_QUADS);
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f( size, size, size);
glTexCoord2f(1.0, 0.0); glVertex3f( size, size, -size);
glTexCoord2f(1.0, 1.0); glVertex3f( size, -size, -size);
glTexCoord2f(0.0, 1.0); glVertex3f( size, -size, size);
glEnd();

etc...

Manojo
12-09-2007, 06:27 AM
Wow thanks a lot complex number :-) Indeed, I didn't know about this GL_INVALID_OPERATION. thanks for the tip on catching the errors.. will allow me not to waste time on searching for useless stuff

Have a nice day (or night ?)

Manojo