//******************************************************************************
//********************* 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->bmiHeader.biWidth;
nTextureHeight = pBitmapInfo->bmiHeader.biHeight;
lBitSize = pBitmapInfo->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->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;
}
//------------------------------------------------------------------------------