Thanks for the link to “MaxH - Load & Map Texture To A Sphere Demo”. I saw it was glut based so I tried it on my linux box – and was disappointed it had some windows specific stuff related to loading the BMP files. To get the code to compile on my linux machine, I replaced that BMP specific stuff with the cross-platform DevIL library with a very simple modification. One benefit is that you can load many more types of files png, jpg, tga, … but that is beside the point.
So for anyone on linux, apple, or a windows box, the modified cross-platform Source.cpp is given below. You will still need the image files from the above link posted by MaxH. Again, the demo was very helpful so hopefully this version will help other OS user who want to try the example.
Note on Linux the compile command is:
g++ Source.cpp -I/usr/include/GL -lGL -lglut -lIL
//******************************************************************************
//********************* OpenGL - Bitmap Loading Demo ***********************
//********************* MaxH - May 18, 2009 ***********************
//********************* Updated -June 3, 2009 ***********************
//**************** Modified Cross Platform -August 14, 2009 *********
//******************************************************************************
# ifdef WIN32
# include <windows.h>
# include <wingdi.h>
# endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glut.h>
#include <IL/ilut.h> //http://openil.sourceforge.net/tuts/tut_step/index.htm
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;
ILubyte *wmap, *logo, *frac;
ILuint TexID_Logo;
ILuint TexID_wmap;
ILuint TexID_Frac;
void cleanup_images(void) {
printf("cleanup image memory: %d %d %d
",TexID_Logo,TexID_wmap,TexID_Frac);
if (TexID_Logo) ilDeleteImages(1, &TexID_Logo);
if (TexID_wmap) ilDeleteImages(1, &TexID_wmap);
if (TexID_Frac) ilDeleteImages(1, &TexID_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;
case 27: exit(true);
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 up/down 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
//----------------------------- LoadImageDevIL -------------------------------
ILuint LoadImageDevIL (char *szFileName, GLubyte **pImageData)
{
ILuint ImageName;
ilGenImages(1, &ImageName);
ilBindImage(ImageName);
ilLoadImage(szFileName);
*pImageData = ilGetData();
printf("%s %d %d %d
",szFileName,ImageName,ilGetInteger(IL_IMAGE_WIDTH),ilGetInteger(IL_IMAGE_HEIGHT));
return ImageName;
}
//---+----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 - May 18, 2009");
glutDisplayFunc (Render_Scene);
glutSpecialFunc (Change_View );
glutKeyboardFunc ( Keyboard );
ilInit();
TexID_Logo = LoadImageDevIL ((char*)"Logo.bmp", &logo);
TexID_wmap = LoadImageDevIL ((char*)"wmap.bmp", &wmap);
TexID_Frac = LoadImageDevIL ((char*)"Frac.bmp", &frac);
atexit(cleanup_images);
earth = gluNewQuadric();
glEnable (GL_LIGHT0);
glLightfv (GL_LIGHT0, GL_POSITION, lite_pos);
glutMainLoop ();
return 1;
}
//------------------------------------------------------------------------------