PDA

View Full Version : Bind Texture to a sphere?



mailmessb
08-14-2009, 03:07 PM
Hi,
Am developing a basic application in opengl, involving sphere creation and texturing.

I have texture load mechanism and with aid of bindtexture i can map it to aquare, triangle, rectangle ...

But texturing a sphere is where am strucked!

I tried nehe productions tutorial 23 too. but it wasn't clear for me in the view of texturing a sphere.

Is there a basic api available which can be used with gluSphere() call to bind a texture??
Please help me with the code.

Thanks in advance

Regards
ssb

MaxH
08-14-2009, 03:22 PM
I wrote a short demo which loads a texture and maps it onto a sphere. Maybe it will help you. The source code and associated image files are at:

MaxH - Load & Map Texture To A Sphere Demo (http://www.mfwweb.com/OpenGL/Loading_Textures/)

This is a short, Glut-based, OpenGL, demo which produces the image below. See the source code to learn how to interact with the scene.

http://www.mfwweb.com/OpenGL/Loading_Textures/MaxH_Textures.jpg

mailmessb
08-14-2009, 11:15 PM
Thanks Max.
The code was simple to get through it

A small correction in building the application
This ERROR
"error C2381: 'exit' : redefinition; __declspec(noreturn) differs"
occured

To avoid this error, include glut.h after stdlib.h

Thanks again Max
ssb

marshats
08-14-2009, 11:15 PM
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 (http://http://openil.sourceforge.net/about.php) 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\n",TexID_Logo,TexID_wmap,TexID_Frac);

if (TexID_Logo) ilDeleteImages(1, &amp;TexID_Logo);
if (TexID_wmap) ilDeleteImages(1, &amp;TexID_wmap);
if (TexID_Frac) ilDeleteImages(1, &amp;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\n", 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\n", 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, &amp;ImageName);
ilBindImage(ImageName);
ilLoadImage(szFileName);
*pImageData = ilGetData();
printf("%s %d %d %d\n",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 (&amp;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", &amp;logo);
TexID_wmap = LoadImageDevIL ((char*)"wmap.bmp", &amp;wmap);
TexID_Frac = LoadImageDevIL ((char*)"Frac.bmp", &amp;frac);
atexit(cleanup_images);

earth = gluNewQuadric();

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

glutMainLoop ();

return 1;
}

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

mailmessb
08-14-2009, 11:58 PM
max, i tried the code with a new solution file in windows.
The texture that got mapped to my sphere, came reversed.

However in the code, there is nothing specified about INVERSE operation or parameter.

To get u a clear picture of the output,
The geographical position of north america to south america is,
Top left to right bottom.
North America on Top and Left Side &amp;
South America on Bottom and Right Side.

But in my output,
North America is on Top Right and
South America is on Bottom Left

Some where i went wrong or something i missed??
ssb

marshats
08-15-2009, 08:22 AM
The code works as you would expect on linux. I confirmed

Top left to right bottom.
North America on Top and Left Side &amp;
South America on Bottom and Right Side

Is the OpenGL logo also mirrored? I did a little searching and there is a issue with windows and the way it uses the origin. I have edited the cross-platform code to fix this type of problem. See the "LoadImageDevIL()" and notice the iluMirror call specific to windows only.



//************************************************** ****************************
//********************* OpenGL - Bitmap Loading Demo ***********************
//********************* MaxH - May 18, 2009 ***********************
//********************* Updated -June 3, 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\n",TexID_Logo,TexID_wmap,TexID_Frac);

if (TexID_Logo) ilDeleteImages(1, &amp;TexID_Logo);
if (TexID_wmap) ilDeleteImages(1, &amp;TexID_wmap);
if (TexID_Frac) ilDeleteImages(1, &amp;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(0);
break;

default : printf (" Keyboard %c == %d\n", 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\n", 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, &amp;ImageName);
ilBindImage(ImageName);
ilLoadImage(szFileName);
# ifdef WIN32
iluMirror(); // windows issue being fixed in devIL, temp workaround here
# endif
*pImageData = ilGetData();
printf("%s %d %d %d\n",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 (&amp;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", &amp;logo);
TexID_wmap = LoadImageDevIL ((char*)"wmap.bmp", &amp;wmap);
TexID_Frac = LoadImageDevIL ((char*)"Frac.bmp", &amp;frac);
atexit(cleanup_images);

earth = gluNewQuadric();

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

glutMainLoop ();

return 1;
}

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

mailmessb
08-15-2009, 10:19 AM
will check out that call..
thanks for the help

ssb

MaxH
08-15-2009, 12:54 PM
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 -- You are correct that my image loading demo is Windows specific. Your generalization using DevIL is very helpful. Just knowing about DevIL alone is helpful. Thanks for that. BTW - the link to DevIL in your post is a bit messed up. I'm sure people can figure out how to fix it, or find it using Google. I've posted your version of my code at the same location my version is posted. I elaborated on the comments, including showing the link to DevIL and the Linux command line. So the Linux-DevIL-General version of the code is called 'Linux_Version.cpp'. My original version is called 'Windows_Version.cpp'. This all can be found at -

OpenGL Image Load, Display, Texturing Demos (http://www.mfwweb.com/OpenGL/Loading_Textures/)

Link to the DevIL Image Loading library -

DevIL Image Loading Library (http://openil.sourceforge.net/about.php)

marshats
08-17-2009, 08:04 PM
Thanks MaxH for posting the cross platform code and correcting the link to the devIL library.

I have made a final version of the Linux_Source.cpp code that is the "correct" way to deal with image orientation on loading and saving with devIL. Hope this helps clear up the "problem" seen in win32 :p



//************************************************** ****************************
//********************* OpenGL - Bitmap Loading Demo ***********************
//********************* MaxH - May 18, 2009 ***********************
//********************* Updated -June 3, 2009 ***********************
//************************************************** ****************************
//********************* Modified Cross Platform ***********************
//********************* marshats - August 17, 2009 ***********************
//************************************************** ****************************

// This generalized version of the code was posted by 'marshats' on OpenGL
// Beginners Forum. It is supposed to run on Mac and Linux platforms as well
// as Windows. My original version runs only on Windows platforms because I
// use Windows-specific image loading utilities. This version uses the DevIL
// library to load images. DevIL handles many different image types including
// bmp, png, jpg, tga ...

// According to marshats, the command to compile and link this code on a
// Linux box is -
// g++ Linux_Version.cpp -I/usr/include/GL -lGL -lglut -lIL

// For info on DevIL Library see: http://openil.sourceforge.net/about.php


# 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


GLfloat xrot = 0, yrot = 0, erot = 0, frot = 0;

GLUquadric *earth = 0;

struct TextureHandle {
ILubyte *p; /* pointer to image data loaded into memory */
ILuint id; /* unique DevIL id of image */
ILint w; /* image width */
ILint h; /* image height */
};
TextureHandle wmap, logo, frac;

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//--------------------------- cleanup_images -------------------------------

// Clear out the memory used by loading image files.

void cleanup_images(void) {
printf("cleanup image memory:{");

if (logo.id) {
printf(" %d",logo.id);
ilDeleteImages(1, &amp;logo.id);
}
if (wmap.id) {
printf(" %d",wmap.id);
ilDeleteImages(1, &amp;wmap.id);
}
if (frac.id) {
printf(" %d",frac.id);
ilDeleteImages(1, &amp;frac.id);
}

printf(" }\n");
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//------------------------- cleanup_Quadrics -------------------------------

// Clear out the memory created by gluNewQuadric() calls.

void cleanup_Quadrics(void) {
printf("cleanup gluQuadric memory:{");

if (earth) {
printf(" %p",earth);
gluDeleteQuadric(earth);
}

printf(" }\n");
}


//---+----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.
// Use <Escape> key to exit.

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(0);
break;

default : printf (" Keyboard %c == %d\n", 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\n", key, key);
}

glutPostRedisplay();
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//-------------------------------- Triad -----------------------------------

void Triad (char xlab, char ylab, char zlab, float siz, float color[3])
{
static const float XUP[3] = {1,0,0},
YUP[3] = {0,1,0},
ZUP[3] = {0,0,1},
ORG[3] = {0,0,0};

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, frac.w, frac.h, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, frac.p);
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)
{
static const 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};

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, wmap.w, wmap.h, 0, GL_BGR_EXT,
GL_UNSIGNED_BYTE, wmap.p);

gluSphere (earth, 1.0, 36, 72);
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//----------------------------- Render_Scene -------------------------------

void Render_Scene (void)
{
static GLfloat yelo[3] = {1,1,0};

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 (logo.w, logo.h, GL_BGR_EXT, GL_UNSIGNED_BYTE, logo.p);


// 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 ------------------------------

// use devIL, cross platform image loading library(openil.sourceforge.net/about.php)

ILuint LoadImageDevIL (char *szFileName, struct TextureHandle *T)
{
//When IL_ORIGIN_SET enabled, the origin is specified at an absolute
//position, and all images loaded or saved adhere to this set origin.
ilEnable(IL_ORIGIN_SET);
//sets the origin to be IL_ORIGIN_LOWER_LEFT when loading all images, so
//that any image with a different origin will be flipped to have the set
//origin.
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

//Now load the image file
ILuint ImageNameID;
ilGenImages(1, &amp;ImageNameID);
ilBindImage(ImageNameID);
if (!ilLoadImage(szFileName)) return 0; // failure

T->id = ImageNameID;
T->p = ilGetData();
T->w = ilGetInteger(IL_IMAGE_WIDTH);
T->h = ilGetInteger(IL_IMAGE_HEIGHT);

printf("%s %d %d %d\n",szFileName,T->id,T->w,T->h);
return 1; // success
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//--------------------------------- main -----------------------------------

int main (int argc, char **argv)
{
static const GLfloat lite_pos[4] = {5.0, 5.0, 5.0, 0.0};

glutInit (&amp;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();
assert( LoadImageDevIL ((char*)"Logo.bmp", &amp;logo) );
assert( LoadImageDevIL ((char*)"wmap.bmp", &amp;wmap) );
assert( LoadImageDevIL ((char*)"Frac.bmp", &amp;frac) );
atexit(cleanup_images);

earth = gluNewQuadric();
atexit(cleanup_Quadrics);

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

glutMainLoop ();

return 1;
}

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

MaxH
08-18-2009, 04:07 PM
Thanks MaxH for posting the cross platform code and correcting the link to the devIL library.

I have made a final version of the Linux_Source.cpp code that is the "correct" way to deal with image orientation on loading and saving with devIL. Hope this helps clear up the "problem" seen in win32 :p
I just updated the files on my site with the latest versions (Aug 18 '09) of Linux_Source.cpp and Windows_Source.cpp.
Thanks for your help marshats. They are at:

OpenGL Image & Texture Loading Demo (http://www.mfwweb.com/OpenGL/Loading_Textures/)

marshats
11-22-2009, 10:42 AM
Based on another Post267363 (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&amp;Number=267363#Post2673 63) I realized that the previously posted code was ineffiecient in sending texture data from the CPU memory to the GPU with each iteration. If it used glBindtexture() the texture could be uploaded to the GPU and hence stop the need for CPU-to-GPU data transfers with each loop iteration. Here's the code for those interested :)


//************************************************** ****************************
//********************* OpenGL - Bitmap Loading Demo ***********************
//********************* MaxH - May 18, 2009 ***********************
//********************* Updated -June 3, 2009 ***********************
//************************************************** ****************************
//********************* Modified Cross Platform ***********************
//********************* marshats - November 22, 2009 ***********************
//************************************************** ****************************

// This generalized version of the code was posted by 'marshats' on OpenGL
// Beginners Forum. It is supposed to run on Mac and Linux platforms as well
// as Windows. My original version runs only on Windows platforms because I
// use Windows-specific image loading utilities. This version uses the DevIL
// library to load images. DevIL handles many different image types including
// bmp, png, jpg, tga ...

// According to marshats, the command to compile and link this code on a
// Linux box is -
// g++ Linux_Version.cpp -I/usr/include/GL -lGL -lglut -lIL

// For info on DevIL Library see: http://openil.sourceforge.net/about.php


# 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


GLfloat xrot = 0, yrot = 0, erot = 0, frot = 0;

GLUquadric *earth = 0;

struct TextureHandle {
ILubyte *p; /* pointer to image data loaded into CPU memory */
ILuint id; /* unique DevIL id of image */
ILint w; /* image width */
ILint h; /* image height */
GLuint genID; /* handle to GPU memory ID, from glGenTextures() */
};
TextureHandle wmap, logo, frac;

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//--------------------------- cleanup_images -------------------------------

// Clear out the memory used by loading image files.

void cleanup_images(void) {
printf("cleanup image memory:{");

if (logo.id) {
printf(" %d",logo.id);
ilDeleteImages(1, &amp;logo.id);
glDeleteTextures( 1, &amp;logo.genID);
}
if (wmap.id) {
printf(" %d",wmap.id);
ilDeleteImages(1, &amp;wmap.id);
glDeleteTextures( 1, &amp;wmap.genID);
}
if (frac.id) {
printf(" %d",frac.id);
ilDeleteImages(1, &amp;frac.id);
glDeleteTextures( 1, &amp;frac.genID);
}

printf(" }\n");
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//------------------------- cleanup_Quadrics -------------------------------

// Clear out the memory created by gluNewQuadric() calls.

void cleanup_Quadrics(void) {
printf("cleanup gluQuadric memory:{");

if (earth) {
printf(" %p",earth);
gluDeleteQuadric(earth);
}

printf(" }\n");
}


//---+----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.
// Use <Escape> key to exit.

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(0);
break;

default : printf (" Keyboard %c == %d\n", 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\n", key, key);
}

glutPostRedisplay();
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//-------------------------------- Triad -----------------------------------

void Triad (char xlab, char ylab, char zlab, float siz, float color[3])
{
static const float XUP[3] = {1,0,0},
YUP[3] = {0,1,0},
ZUP[3] = {0,0,1},
ORG[3] = {0,0,0};

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);

glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, frac.genID);

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)
{
static const 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};

glEnable (GL_LIGHTING );

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

glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, wmap.genID);

gluSphere (earth, 1.0, 36, 72);
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//----------------------------- Render_Scene -------------------------------

void Render_Scene (void)
{
static GLfloat yelo[3] = {1,1,0};

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


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

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (0, 1, 0, 1);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

glDisable (GL_DEPTH_TEST);

glEnable (GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, logo.genID);

glTranslatef(0.01,0.83,-1.);
glScalef(0.25,0.3,1.0);
glBegin (GL_QUADS);
glTexCoord2s (0, 0); glVertex2f (0,0);
glTexCoord2s (1, 0); glVertex2f (1,0);
glTexCoord2s (1, 1); glVertex2f (1,0.5); // original logo has height half of width
glTexCoord2s (0, 1); glVertex2f (0,0.5); // keeps original aspect ratio
glEnd ();

// 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 ------------------------------

// use devIL, cross platform image loading library(openil.sourceforge.net/about.php)

ILuint LoadImageDevIL (const char *szFileName, struct TextureHandle *T)
{
//When IL_ORIGIN_SET enabled, the origin is specified at an absolute
//position, and all images loaded or saved adhere to this set origin.
ilEnable(IL_ORIGIN_SET);
//sets the origin to be IL_ORIGIN_LOWER_LEFT when loading all images, so
//that any image with a different origin will be flipped to have the set
//origin.
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

//Now load the image file
ILuint ImageNameID;
ilGenImages(1, &amp;ImageNameID);
ilBindImage(ImageNameID);
if (!ilLoadImage(szFileName)) return 0; // failure

T->id = ImageNameID;
T->p = ilGetData();
T->w = ilGetInteger(IL_IMAGE_WIDTH);
T->h = ilGetInteger(IL_IMAGE_HEIGHT);

// openGL specific part now
// download image data to GPU memory to improve perfromance
glGenTextures(1, &amp;T->genID);
glBindTexture(GL_TEXTURE_2D, T->genID);
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, T->w, T->h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, T->p);

printf("%s %d %d %d\n",szFileName,T->id,T->w,T->h);
return 1; // success
}

//---+----3----+----2----+----1----+---<>---+----1----+----2----+----3----+----4
//--------------------------------- main -----------------------------------

int main (int argc, char **argv)
{
static const GLfloat lite_pos[4] = {5.0, 5.0, 5.0, 0.0};

glutInit (&amp;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();
assert( LoadImageDevIL ("Logo.bmp", &amp;logo) );
assert( LoadImageDevIL ("wmap.bmp", &amp;wmap) );
assert( LoadImageDevIL ("Frac.bmp", &amp;frac) );
atexit(cleanup_images);

// set geometry
earth = gluNewQuadric();
atexit(cleanup_Quadrics);
gluQuadricTexture (earth, GL_TRUE);

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

glutMainLoop ();

return 1;
}

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

beginnertom
03-04-2010, 10:35 PM
thank a lot i fount you discussion.