⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 一本关于OPenGL的很好的电子书
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#define WIN32_LEAN_AND_MEAN		// trim the excess fat from Windows

/*******************************************************************
*	Program: Chapter 19 .MD2 Model Example - OOP
*	Author: Kevin Hawkins
*	Description: The OOP version of the .MD2 model loading example.
********************************************************************/

////// Defines
#define BITMAP_ID 0x4D42		// the universal bitmap ID
#define PI	3.14159

////// Includes
#include "md2.h"

////// Global Variables
HDC g_HDC;			// global device context
bool fullScreen = false;		// true = fullscreen; false = windowed
bool keyPressed[256];		// holds true for keys that are pressed	

float angle = 0.0f;			// camera angle 
float radians = 0.0f;		// camera angle in radians

////// Mouse/Camera Variables
int mouseX, mouseY;		// mouse coordinates
float cameraX, cameraY, cameraZ;	// camera coordinates
float lookX, lookY, lookZ;		// camera look-at coordinates

CMD2Model *myModel;		// the character model
CMD2Model *gunModel;		// the gun model
modelState_t modelState;		// global model state
texture_t *groundTexture;		// ground texture


// LoadBitmapFile
// desc: Returns a pointer to the bitmap image of the bitmap specified
//       by filename. Also returns the bitmap header information.
//		 No support for 8-bit bitmaps.
unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
	FILE *filePtr;							// the file pointer
	BITMAPFILEHEADER	bitmapFileHeader;		// bitmap file header
	unsigned char		*bitmapImage;			// bitmap image data
	unsigned int		imageIdx = 0;		// image index counter
	unsigned char		tempRGB;				// swap variable

	// open filename in "read binary" mode
	filePtr = fopen(filename, "rb");
	if (filePtr == NULL)
		return NULL;

	// read the bitmap file header
	fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
	
	// verify that this is a bitmap by checking for the universal bitmap id
	if (bitmapFileHeader.bfType != BITMAP_ID)
	{
		fclose(filePtr);
		return NULL;
	}

	// read the bitmap information header
	fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);

	// move file pointer to beginning of bitmap data
	fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);

	// allocate enough memory for the bitmap image data
	bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);

	// verify memory allocation
	if (!bitmapImage)
	{
		free(bitmapImage);
		fclose(filePtr);
		return NULL;
	}

	// read in the bitmap image data
	fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr);

	// make sure bitmap image data was read
	if (bitmapImage == NULL)
	{
		fclose(filePtr);
		return NULL;
	}

	// swap the R and B values to get RGB since the bitmap color format is in BGR
	for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3)
	{
		tempRGB = bitmapImage[imageIdx];
		bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
		bitmapImage[imageIdx + 2] = tempRGB;
	}

	// close the file and return the bitmap image data
	fclose(filePtr);
	return bitmapImage;
}

// LoadPCXFile()
// desc: loads a PCX file into memory
unsigned char *LoadPCXFile(char *filename, PCXHEADER *pcxHeader)
{
     int idx = 0;                  // counter index
     int c;                             // used to retrieve a char from the file
     int i;                             // counter index
     int numRepeat;      
     FILE *filePtr;                // file handle
     int width;                         // pcx width
     int height;                        // pcx height
     unsigned char *pixelData;     // pcx image data
     unsigned char *paletteData;   // pcx palette data

     // open PCX file
     filePtr = fopen(filename, "rb");
     if (filePtr == NULL)
          return NULL;

     // retrieve first character; should be equal to 10
     c = getc(filePtr);
     if (c != 10)
     {
          fclose(filePtr);
          return NULL;
     }

     // retrieve next character; should be equal to 5
     c = getc(filePtr);
     if (c != 5)
     {
          fclose(filePtr);
          return NULL;
     }

     // reposition file pointer to beginning of file
     rewind(filePtr);

     // read 4 characters of data to skip
     fgetc(filePtr);
     fgetc(filePtr);
     fgetc(filePtr);
     fgetc(filePtr);

     // retrieve leftmost x value of PCX
     pcxHeader->xMin = fgetc(filePtr);       // loword
     pcxHeader->xMin |= fgetc(filePtr) << 8; // hiword

     // retrieve bottom-most y value of PCX
     pcxHeader->yMin = fgetc(filePtr);       // loword
     pcxHeader->yMin |= fgetc(filePtr) << 8; // hiword

     // retrieve rightmost x value of PCX
     pcxHeader->xMax = fgetc(filePtr);       // loword
     pcxHeader->xMax |= fgetc(filePtr) << 8; // hiword

     // retrieve topmost y value of PCX
     pcxHeader->yMax = fgetc(filePtr);       // loword
     pcxHeader->yMax |= fgetc(filePtr) << 8; // hiword

     // calculate the width and height of the PCX
     width = pcxHeader->xMax - pcxHeader->xMin + 1;
     height = pcxHeader->yMax - pcxHeader->yMin + 1;

     // allocate memory for PCX image data
     pixelData = (unsigned char*)malloc(width*height);

     // set file pointer to 128th byte of file, where the PCX image data starts
     fseek(filePtr, 128, SEEK_SET);
     
     // decode the pixel data and store
     while (idx < (width*height))
     {
          c = getc(filePtr);
          if (c > 0xbf)
          {
               numRepeat = 0x3f & c;
               c = getc(filePtr);

               for (i = 0; i < numRepeat; i++)
               {
                    pixelData[idx++] = c;
               }
          }
          else
               pixelData[idx++] = c;

          fflush(stdout);
     }

     // allocate memory for the PCX image palette
     paletteData = (unsigned char*)malloc(768);

     // palette is the last 769 bytes of the PCX file
     fseek(filePtr, -769, SEEK_END);

     // verify palette; first character should be 12
     c = getc(filePtr);
     if (c != 12)
     {
          fclose(filePtr);
          return NULL;
     }

     // read and store all of palette
     for (i = 0; i < 768; i++)
     {
          c = getc(filePtr);
          paletteData[i] = c;
     }

     // close file and store palette in header
     fclose(filePtr);
     pcxHeader->palette = paletteData;

     // return the pixel image data
     return pixelData;
}

// LoadPCXTexture()
// desc: loads a PCX image file as a texture
texture_t *LoadPCXTexture(char *filename)
{
     PCXHEADER texInfo;            // header of texture
     texture_t *thisTexture;       // the texture
     unsigned char *unscaledData;// used to calculate pcx
     int i;                             // index counter
     int j;                             // index counter
     int width;                         // width of texture
     int height;                        // height of texture

     // allocate memory for texture struct
     thisTexture = (texture_t*)malloc(sizeof(texture_t));
     if (thisTexture == NULL)
          return NULL;

     // load the PCX file into the texture struct
     thisTexture->data = LoadPCXFile(filename, &texInfo);
     if (thisTexture->data == NULL)
     {
          free(thisTexture->data);
          return NULL;
     }

     // store the texture information
     thisTexture->palette = texInfo.palette;
     thisTexture->width = texInfo.xMax - texInfo.xMin + 1;
     thisTexture->height = texInfo.yMax - texInfo.yMin + 1;
     thisTexture->textureType = PCX;

     // allocate memory for the unscaled data
     unscaledData = (unsigned char*)malloc(thisTexture->width*thisTexture->height*4);

     // store the unscaled data via the palette
     for (j = 0; j < thisTexture->height; j++) 
     {
          for (i = 0; i < thisTexture->width; i++) 
          {
               unscaledData[4*(j*thisTexture->width+i)+0] = (unsigned char)thisTexture->palette[3*thisTexture->data[j*thisTexture->width+i]+0];
               unscaledData[4*(j*thisTexture->width+i)+1] = (unsigned char)thisTexture->palette[3*thisTexture->data[j*thisTexture->width+i]+1];
               unscaledData[4*(j*thisTexture->width+i)+2] = (unsigned char)thisTexture->palette[3*thisTexture->data[j*thisTexture->width+i]+2];
               unscaledData[4*(j*thisTexture->width+i)+3] = (unsigned char)255;
          }
     }

     // find width and height's nearest greater power of 2
     width = thisTexture->width;
     height = thisTexture->height;

     // find width's
     i = 0;
     while (width)
     {
          width /= 2;
          i++;
     }
     thisTexture->scaledHeight = (long)pow(2, i-1);

     // find height's
     i = 0;
     while (height)
     {
          height /= 2;
          i++;
     }
     thisTexture->scaledWidth = (long)pow(2, i-1);

     // clear the texture data
     if (thisTexture->data != NULL)
     {
          free(thisTexture->data);
          thisTexture->data = NULL;
     }

     // reallocate memory for the texture data
     thisTexture->data = (unsigned char*)malloc(thisTexture->scaledWidth*thisTexture->scaledHeight*4);
     
     // use the GL utility library to scale the texture to the unscaled dimensions
     gluScaleImage (GL_RGBA, thisTexture->width, thisTexture->height, GL_UNSIGNED_BYTE, unscaledData, thisTexture->scaledWidth, thisTexture->scaledHeight, GL_UNSIGNED_BYTE, thisTexture->data);

     return thisTexture;
}

// LoadBMPTexture()
// desc: loads a texture of the BMP format
texture_t *LoadBMPTexture(char *filename)
{
	BITMAPINFOHEADER texInfo;		// BMP header
	texture_t *thisTexture;			// the texture

	// allocate memory for the texture
	thisTexture = (texture_t*)malloc(sizeof(texture_t));
	if (thisTexture == NULL)
		return NULL;

	// store BMP data in texture
	thisTexture->data = LoadBitmapFile(filename, &texInfo);
	if (thisTexture->data == NULL)
	{
		free(thisTexture);
		return NULL;
	}
	
	// store texture information
	thisTexture->width = texInfo.biWidth;
	thisTexture->height = texInfo.biHeight;
	thisTexture->palette = NULL;
	thisTexture->scaledHeight = 0;
	thisTexture->scaledWidth = 0;
	thisTexture->textureType = BMP;

	return thisTexture;
}

// LoadTexture()
// desc: loads a texture given the filename
texture_t *LoadTexture(char *filename)
{
	texture_t *thisTexture;
	char *extStr;

	// get extension from filename
	extStr = strchr(filename, '.');
	extStr++;

	// set the texture type based on extension of filename
	if ((strcmp(extStr, "BMP") == 0) || (strcmp(extStr, "bmp") == 0))
		thisTexture = LoadBMPTexture(filename);
	else if ((strcmp(extStr, "PCX") == 0) || (strcmp(extStr, "pcx") == 0) )
		thisTexture = LoadPCXTexture(filename);
	/*
	else if ((strcmp(extStr, "TGA") == 0) || (strcmp(extStr, "tga") == 0) )
		thisTexture = LoadTGATexture(filename);
		//texType = TGA;
	*/
	return thisTexture;
}

// SetupGround()
// desc: sets up the ground texture
void SetupGround(texture_t *groundTex)
{
     // set the proper parameters for an MD2 texture
     glGenTextures(1, &groundTex->texID);
     glBindTexture(GL_TEXTURE_2D, groundTex->texID);
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
     
     switch (groundTex->textureType)
     {
     case BMP:
          gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, groundTex->width, groundTex->height, 
               GL_RGB, GL_UNSIGNED_BYTE, groundTex->data);
          break;
     case PCX:
          gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, groundTex->width, groundTex->height,
               GL_RGBA, GL_UNSIGNED_BYTE, groundTex->data);
     case TGA:			// no TGA support
          break;
     default:
          break;
	}
}


// DrawGround()
// desc: draws the textured ground
void DrawGround(texture_t *groundTex, float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glBindTexture(GL_TEXTURE_2D, groundTex->texID);
		glTranslatef(xPos, yPos, zPos);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0f, 0.0f);
			glVertex3f(-150.0f, 0.0f, 150.0f);
			glTexCoord2f(5.0f, 0.0f);
			glVertex3f(150.0f, 0.0f, 150.0f);
			glTexCoord2f(5.0f, 5.0f);
			glVertex3f(150.0f, 0.0f, -150.0f);
			glTexCoord2f(0.0f, 5.0f);
			glVertex3f(-150.0f, 0.0f, -150.0f);
		glEnd();
	glPopMatrix();
}


// CalculateNormal()
// desc: given 3 points, calculates the normal to the points
void CalculateNormal( float *p1, float *p2, float *p3 )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -