CubeMap

I’m trying to follow the wiki instructions on creating a textured sphere. I’m trying to create the Earth.

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

It suggests using a cubemap, pointing to http://www.opengl.org/wiki/Common_Mistakes#Creating_a_Cubemap_Texture

However, it doesn’t give any example or link to a texture. It seems that this needs to be a specific 6 sided image. How do I create one from a normal image?

Here is the type of image that I have…
http://www.oera.net/How2/PlanetTexs/EarthMap_2500x1250.jpg

Solution A:
Don’t use cubemap, you can simply map your texture on the sphere

Solution B:
Use a program to project your map into a cross cubemap then
Use Ati Cubemap Generator to generate cubemap mipmaps.
To project your texture you can use Bixorama (commercial) or pano2VR (commercial), or PanoTools/Hugin or you can setup a 6 camera rendering with your favorite 3d program.
Here you can find Ati cubemap generator
http://developer.amd.com/gpu/cubemapgen/Pages/default.aspx

Solution C: (not suggested)
Convert your texture into a cubemap at loading time, this will take a lot of math an probably you will get a lower quality result.

Yes, Solution A is best, given the texture you have. Something like cylindrical or spherical projection will work.

These projections have problems at the poles, but as your texture is completely white around each pole (probably for this exact reason), the artifacts will not be visible.

You don’t. You need to get a cubemap of the earth.
If you don’t have one, then there is no point of converting a 2D image to a cubemap.

Have you solved your problem yet?

I have followed the advice listed here and went with the 2D image. Thanks

If anyone does want to pursue the cubemap, I think I found a file that would work with that… but haven’t tested it.
http://celestia.h-schmidt.net/earth-vt/

//******************************************************************************
//********************* OpenGL - Bitmap Loading Demo ***********************
//********************* MaxH - May 18, 2009 ***********************
//********************* Updated - Aug 18, 2009 ***********************
//******************************************************************************

#include <glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// $$$$$$$$$$$$ Beginning of bitmap header file by Michael Sweet. $$$$$$$$$$

#ifndef BITMAP_H

define BITMAP_H

ifdef WIN32

include <windows.h>

include <wingdi.h>

endif

ifdef __cplusplus

extern “C” {

endif

ifndef WIN32

typedef struct /**** BMP file header structure ***/
{
unsigned short bfType; /
Magic number for file /
unsigned int bfSize; /
Size of file /
unsigned short bfReserved1; /
Reserved /
unsigned short bfReserved2; /
/
unsigned int bfOffBits; /
Offset to bitmap data */
} BITMAPFILEHEADER;

define BF_TYPE 0x4D42 /* “MB” */

typedef struct /**** BMP file info structure ***/
{
unsigned int biSize; /
Size of info header /
int biWidth; /
Width of image /
int biHeight; /
Height of image /
unsigned short biPlanes; /
Number of color planes /
unsigned short biBitCount; /
Number of bits per pixel /
unsigned int biCompression; /
Type of compression to use /
unsigned int biSizeImage; /
Size of image data /
int biXPelsPerMeter; /
X pixels per meter /
int biYPelsPerMeter; /
Y pixels per meter /
unsigned int biClrUsed; /
Number of colors used /
unsigned int biClrImportant; /
Number of important colors */
} BITMAPINFOHEADER;

define BI_RGB 0 /* No compression - straight BGR data */

define BI_RLE8 1 /* 8-bit run-length compression */

define BI_RLE4 2 /* 4-bit run-length compression */

define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */

typedef struct /**** Colormap entry structure ***/
{
unsigned char rgbBlue; /
Blue value /
unsigned char rgbGreen; /
Green value /
unsigned char rgbRed; /
Red value /
unsigned char rgbReserved; /
Reserved */
} RGBQUAD;

typedef struct /**** Bitmap information structure ***/
{
BITMAPINFOHEADER bmiHeader; /
Image header /
RGBQUAD bmiColors[256]; /
Image colormap */
} BITMAPINFO;

endif /* !WIN32 */

extern GLubyte *LoadDIBitmap (const char *filename, BITMAPINFO **info);
extern int SaveDIBitmap (const char *filename, BITMAPINFO *info,
GLubyte *bits);

ifdef __cplusplus

}

endif /* __cplusplus */

#endif /* !BITMAP_H */

// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ End of Bitmap include file $$$$$$$$$$$$
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

float XUP[3] = {1,0,0}, XUN[3] = {-1, 0, 0},
YUP[3] = {0,1,0}, YUN[3] = { 0,-1, 0},
ZUP[3] = {0,0,1}, ZUN[3] = { 0, 0,-1},
ORG[3] = {0,0,0}, COR[3] = { 1, 0, 1};

GLfloat yelo[3] = {1,1,0}, xrot = 0, yrot = 0, erot = 0, frot = 0,
lite_pos[4] = {5.0, 5.0, 5.0, 0.0};

GLfloat potamb[3] = {0.8,0.8,0.8},
potdfs[3] = {0.9,0.9,0.9},
potspc[3] = {1.0,1.0,1.0};

GLUquadric *earth;

BYTE *wmap, *logo, *frac;

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//------------------------------- Animate ----------------------------------

// Animate rotation of earth and counter-rotation of floor.

void Animate (void)
{
erot += 0.4;
frot -= 0.3;

glutPostRedisplay();

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//------------------------------- Keyboard ---------------------------------

// Use ‘r’ key to reset viewing rotations to zero.
// Use ‘a’ key to toggle earth and floor animation.

void Keyboard (unsigned char key, int q, int s)
{
static int c = 0;

switch (key)  {

   case 'a': if (++c%2) glutIdleFunc (Animate);
	 else       glutIdleFunc (  NULL );
   break;

   case 'r': xrot = 0; yrot = 0; erot = 0; frot = 0;
   break;

   default : printf ("   Keyboard %c == %d

", key, key);
}

glutPostRedisplay();

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//----------------------------- Change_View --------------------------------

void Change_View (int key, int q, int s)
{
switch (key) {

   case GLUT_KEY_DOWN  :  xrot += 2.0;  break;
   case GLUT_KEY_UP    :  xrot -= 2.0;  break;

   case GLUT_KEY_RIGHT :  yrot += 2.0;  break;
   case GLUT_KEY_LEFT  :  yrot -= 2.0;  break;

   default: printf ("   Special key %c == %d

", key, key);
}

glutPostRedisplay();

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//-------------------------------- Triad -----------------------------------

void Triad (char xlab, char ylab, char zlab, float siz, float color[3])
{
glLineWidth (2.0);
glColor3fv (color);
glDisable (GL_LIGHTING);
glDisable (GL_TEXTURE_2D);

glPushMatrix ();

   glScalef (siz, siz, siz);

   glBegin (GL_LINES);
      glVertex3fv (ORG); glVertex3fv (XUP);
      glVertex3fv (ORG); glVertex3fv (YUP);
      glVertex3fv (ORG); glVertex3fv (ZUP);
   glEnd ();

   glRasterPos3f (1.1, 0.0, 0.0);
   glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, xlab);

   glRasterPos3f (0.0, 1.1, 0.0);
   glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, ylab);

   glRasterPos3f (0.0, 0.0, 1.1);
   glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, zlab);

glPopMatrix ();

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//------------------------------ Draw_FLoor --------------------------------

void Draw_Floor (void)
{
glDisable (GL_LIGHTING );
glColor3f (1.0, 1.0, 1.0);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D (GL_TEXTURE_2D, 0, 3, 512, 512, 0, GL_BGR_EXT,
	                               GL_UNSIGNED_BYTE, frac);
glEnable (GL_TEXTURE_2D);

glBegin (GL_QUADS);
   glTexCoord2s (0, 0);  glVertex3d (-2,-2,-1);
   glTexCoord2s (1, 0);  glVertex3d ( 2,-2,-1);
   glTexCoord2s (1, 1);  glVertex3d ( 2, 2,-1);
   glTexCoord2s (0, 1);  glVertex3d (-2, 2,-1);
glEnd ();

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//------------------------------ Draw_Earth --------------------------------

void Draw_Earth (void)
{
glEnable (GL_LIGHTING );
glEnable (GL_TEXTURE_2D);

glMaterialfv (GL_FRONT, GL_AMBIENT  , potamb);
glMaterialfv (GL_FRONT, GL_DIFFUSE  , potdfs);
glMaterialfv (GL_FRONT, GL_SPECULAR , potspc);
glMateriali  (GL_FRONT, GL_SHININESS, 50);

gluQuadricTexture (earth, GL_TRUE);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D (GL_TEXTURE_2D, 0, 3, 512, 256, 0, GL_BGR_EXT,
	                              GL_UNSIGNED_BYTE, wmap);
gluSphere (earth, 1.0, 36, 72);

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//----------------------------- Render_Scene -------------------------------

void Render_Scene (void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Put OpenGL logo in upper left corner of window.

glMatrixMode   (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D     (-300, 300, -200, 200);
glMatrixMode   (GL_MODELVIEW);
glLoadIdentity ();

glDisable (GL_DEPTH_TEST);
glDisable (GL_TEXTURE_2D);

glRasterPos2d (-295, 110);
glDrawPixels  (256, 128, GL_BGR_EXT, GL_UNSIGNED_BYTE, logo);


// Set up perspective view of earth floating above a floor.

glEnable (GL_DEPTH_TEST);

glMatrixMode   (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, 1.33, 1, 10);

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0, 0, -4);      // Move objects away from camera.

glRotatef (xrot, 1,0,0);      // Tip  objects in scene with up/down keys.
glRotatef (yrot, 0,1,0);      // Turn objects in scene with rt/left keys.
glRotatef ( -90, 1,0,0);

glPushMatrix ();
   glRotatef (erot, 0,0,1);
   Draw_Earth ();
   glRotatef (-90, 0,0,1);               // Put 'X' axis thru 0 degs lon.
   Triad ('x', 'y', 'z', 1.5, yelo);
glPopMatrix ();

glPushMatrix ();
   glRotatef (frot, 0,0,1);
   Draw_Floor ();
glPopMatrix ();

glutSwapBuffers();

}

//—±—3----±—2----±—1----±–><—±—1----±—2----±—3----±—4
//----------------------------- Load_BMP_Img -------------------------------

int Load_BMP_Img (char *szFileName, BYTE **pBitmapData)
{
HANDLE hFileHandle;
BITMAPINFO *pBitmapInfo = NULL;

unsigned long lInfoSize = 0, lBitSize = 0;
int nTextureWidth, nTextureHeight;

static short VERBOSE = TRUE, first = TRUE;

hFileHandle = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
	               OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

if (hFileHandle == INVALID_HANDLE_VALUE)  return FALSE;

BITMAPFILEHEADER  bitmapHeader;
DWORD dwBytes;

ReadFile (hFileHandle, &bitmapHeader, sizeof(BITMAPFILEHEADER), 
                       &dwBytes, NULL);

if (dwBytes != sizeof(BITMAPFILEHEADER))  return FALSE;

if (bitmapHeader.bfType != 'MB')  return FALSE;

lInfoSize   = bitmapHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
pBitmapInfo = (BITMAPINFO *) new BYTE[lInfoSize];

ReadFile (hFileHandle, pBitmapInfo, lInfoSize, &dwBytes, NULL);

if (dwBytes != lInfoSize)  return FALSE;

nTextureWidth  = pBitmapInfo-&gt;bmiHeader.biWidth;
nTextureHeight = pBitmapInfo-&gt;bmiHeader.biHeight;
lBitSize       = pBitmapInfo-&gt;bmiHeader.biSizeImage;

if (VERBOSE)  {
   if (first)  {
  first = FALSE;
  printf ("

“);
}
printf (” Image ‘%s’ is: %d by %d pixels
", szFileName,
nTextureWidth, nTextureHeight);
}

if (lBitSize == 0)  lBitSize = (nTextureWidth *
                    pBitmapInfo-&gt;bmiHeader.biBitCount + 7) / 8 *
		            abs(nTextureHeight);

*pBitmapData = new BYTE[lBitSize];

ReadFile (hFileHandle, *pBitmapData, lBitSize, &dwBytes, NULL);

if (lBitSize != dwBytes)
{
   if (*pBitmapData) delete [] (BYTE *) *pBitmapData;
   *pBitmapData = NULL;
   return FALSE;
}

CloseHandle (hFileHandle);

return TRUE;

}

//—±—3----±—2----±—1----±–<>—±—1----±—2----±—3----±—4
//--------------------------------- main -----------------------------------

int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitWindowSize (800, 600);
glutInitWindowPosition (300, 300);
glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE);

glutCreateWindow ("Image Loading - MaxH - August, 2009");
glutDisplayFunc  (Render_Scene);
glutSpecialFunc  (Change_View );
glutKeyboardFunc (  Keyboard  );

Load_BMP_Img ("logo.bmp", &logo);
Load_BMP_Img ("wmap.bmp", &wmap);
Load_BMP_Img ("frac.bmp", &frac);

earth = gluNewQuadric();

glEnable  (GL_LIGHT0);
glLightfv (GL_LIGHT0, GL_POSITION, lite_pos);

glutMainLoop  ();

return 1;

}

//------------------------------------------------------------------------------