I'm currently developing a test project to explore OpenGL 3 texturing abilities. I have a simple cube, made of 8 vertices and 36 indices. I want each of the cubes faces to have a different texture, so I devised this texture:


I made it obvious which sections I want visible (I hope...). In Direct3D, I once made a skybox, and I used a cubemap. However, I had to split it into 6 different textures. This is annoying and hard to manage, it would be nice to have just one texture. Is this even possible? I read somewhere that I could do this by duplicating vertices, is that a good idea? Someone else said I could do it in the shader, but that also baffles me...

  • 2
    \$\begingroup\$ A cube texture is a single texture. A texture is not a 2D image; it is a container of multiple images. Those can be mipmaps, cubemap faces and their mipmaps, array layers and their mipmaps, or arrays of cubemap faces and their mipmaps. These are all stored in one texture. \$\endgroup\$ – Nicol Bolas Apr 22 '12 at 6:10
  • 1
    \$\begingroup\$ If '6 different textures' (or 6 different texture images) are 'annoying and hard to manage', then I'd have to say you have issues in your project well beyond what packing things into a single image will fix. I'd worry about the root issue much more than the symptom; being able to handle a cubemap, or bundles of texture images, effectively will be much more useful to you in the long run. \$\endgroup\$ – Steven Stadnicki Apr 22 '12 at 19:56
  • \$\begingroup\$ @StevenStadnicki It's not that I can't manage them, its that I'd rather not. It's easier to have 1 paper with your shopping list than 6 papers each with a different portion of your list; it's easier to have 1 texture than 6 textures. There is less margin for stuff like missing textures to happen, and it keeps things nice an tidy. \$\endgroup\$ – smoth190 Apr 22 '12 at 20:25
  • \$\begingroup\$ @smoth190: What "6 papers" are you talking about? DDS can store all of the cubemap faces in the same file. And once loaded into memory, they're all in the same texture object. So what 6 things are you having a problem with? \$\endgroup\$ – Nicol Bolas Apr 23 '12 at 0:21
  • 1
    \$\begingroup\$ @smoth190: DDS is an image format and nothing more than that. There's no law that says you can't load DDS images into an OpenGL texture. Indeed, this is commonly done; there are even libraries that will do it for you. \$\endgroup\$ – Nicol Bolas Apr 23 '12 at 20:12

If you want to do it with a single texture, the easiest thing to do is UV map your sky cube model to that texture layout. Then, you can use a normal texturing shader.

  • \$\begingroup\$ You won't get the special cubemap hardware features though, such as being able to simply pass a 3D vector and have the hardware figure out the UVs, or bilinear texture filtering across the face boundaries. \$\endgroup\$ – Nathan Reed Apr 22 '12 at 18:11
  • \$\begingroup\$ Of course. It IS the easiest method, though. \$\endgroup\$ – jmegaffin Apr 22 '12 at 18:34
  • \$\begingroup\$ What I'm trying to do isn't create an actual cubemap, but just to make my job easier by having only one texture. A just want a cube with 6 different textures, it is not for a sky or anything. I can't seem to figure out how to wrap that around with only 8 vertices, therefor 8 UV values. \$\endgroup\$ – smoth190 Apr 22 '12 at 18:40
  • \$\begingroup\$ So...use indexing. Just because there are only eight vertex positions doesn't mean there has to be 8 UV positions. \$\endgroup\$ – jmegaffin Apr 22 '12 at 19:54
  • 2
    \$\begingroup\$ The way you usually do this is with a position list, a UV list, and two indices per vertex. I don't know if you can use 2 index buffers explicitly in OpenGL, so you have to build the vertex buffer from that data manually. Just look at how you would load an OBJ model. \$\endgroup\$ – jmegaffin Apr 22 '12 at 23:16

If you want to get a cube map texture starting with that image on disk, then just extend your texture loader to slice up that image into individual cube map faces!

  • \$\begingroup\$ I'm still confused at how I would set up the UV normals. I only have 8 vertices. \$\endgroup\$ – smoth190 Apr 22 '12 at 18:40
  • \$\begingroup\$ If you are using a cube map texture, then that is not a problem — you specify the texture coordinates like normals, in three dimensions, and as Nathan Reed mentioned, the GPU will figure out the necessary 2D positions. If you were trying to use a 2D texture, then you would have to duplicate vertices to get distinct texture coordinates. \$\endgroup\$ – Kevin Reid Apr 22 '12 at 21:12
  • \$\begingroup\$ Hm, I see. Well I don't want to use a cubemap because it isn't needed. However, duplicated vertices can build up if I have a lot of these cubes. Which one is less of a performance hit? \$\endgroup\$ – smoth190 Apr 22 '12 at 23:07
  • \$\begingroup\$ I don't know, sorry. I don't have a lot of experience with OpenGL performance considerations. \$\endgroup\$ – Kevin Reid Apr 22 '12 at 23:21

It is possible to stack the cube faces vertically in a single image, and either split the original bitmap in software, or offset the pointer to the image data when uploading the textures to the GPU. (usually by: bytesPerPixel * width * (height \ 6) * faceIndex).

A custom cube mapping shader is not difficult, selecting the largest component of the view ray as z, calculate texture coordinates using this formula: ray.xy/ray.z * 0.5 + 0.5. To select an image, divide v by 6, and add 1/6 * the face's index. Filtering across the edges might be more of a challenge.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.