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

📄 main.cpp

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

/*******************************************************************
*	Program: Chapter 12 OpenGL Buffers Example 3: Stencil Buffers
*	Author: Kevin Hawkins
*	Description: Displays rotating, texture mapped torus that is reflected in the
*		    checker textured floor.
********************************************************************/

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

////// Includes
#include <windows.h>			// standard Windows app include
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl/gl.h>				// standard OpenGL include
#include <gl/glu.h>				// OpenGL utilties
#include <gl/glaux.h>			// OpenGL auxiliary library

////// Types
typedef struct 
{
	int width;					// width of texture
	int height;					// height of texture
	unsigned int texID;			// the texture object id of this texture
	unsigned char *data;		// the texture data
} texture_t;

////// 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 objectAngle = 0.0f;		// object rotation angle
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

////// Texture Information
texture_t *envTex;				// environment map
texture_t *floorTex;			// floor texture

// vertices for the floor
float floorData[4][3] = { { -5.0, 0.0, 5.0 }, { 5.0, 0.0, 5.0 },
							{ 5.0, 0.0, -5.0 }, { -5.0, 0.0, -5.0 } };

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

texture_t *LoadTextureFile(char *filename)
{
	BITMAPINFOHEADER texInfo;
	texture_t *thisTexture;

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

	// load the texture data and check validity
	thisTexture->data = LoadBitmapFile(filename, &texInfo);
	if (thisTexture->data == NULL)
	{
		free(thisTexture);
		return NULL;
	}

	// set width and height info for this texture
	thisTexture->width = texInfo.biWidth;
	thisTexture->height = texInfo.biHeight;

	// generate the texture object for this texture
	glGenTextures(1, &thisTexture->texID);

	return thisTexture;
}

bool LoadAllTextures()
{
	// load the environment map
	envTex = LoadTextureFile("waterenv.bmp");
	if (envTex == NULL)
		return false;

	// load the floor texture
	floorTex = LoadTextureFile("chess.bmp");
	if (floorTex == NULL)
		return false;

	// setup the torus' environment map       
	glBindTexture(GL_TEXTURE_2D, envTex->texID);       
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, envTex->width, envTex->height, GL_RGB, GL_UNSIGNED_BYTE, envTex->data);

	// setup the floor texture
	glBindTexture(GL_TEXTURE_2D, floorTex->texID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, floorTex->width, floorTex->height, GL_RGB, GL_UNSIGNED_BYTE, floorTex->data);

	return true;
}

void CleanUp()
{
	free(envTex);
	free(floorTex);
}

// Initialize
// desc: initializes OpenGL
void Initialize()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// clear to black

	glShadeModel(GL_SMOOTH);					// use smooth shading
	glEnable(GL_CULL_FACE);						// do not calculate inside of poly's
	glFrontFace(GL_CCW);						// counter clock-wise polygons are out
	glEnable(GL_TEXTURE_2D);					// enable 2D texturing

	LoadAllTextures();
}

// DrawFloor()
// desc: draws the floor (one quad)
void DrawFloor()
{
  glBindTexture(GL_TEXTURE_2D, floorTex->texID);
  glBegin(GL_QUADS);
    glTexCoord2f(0.0, 0.0); glVertex3fv(floorData[0]);
    glTexCoord2f(0.0, 4.0); glVertex3fv(floorData[1]);
    glTexCoord2f(4.0, 4.0); glVertex3fv(floorData[2]);
    glTexCoord2f(4.0, 0.0); glVertex3fv(floorData[3]);
  glEnd();
}

// DrawTorus()
// desc: draws the environment mapped torus
void DrawTorus()
{
	glPushMatrix();
		// setup environment mapping
		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
		glEnable(GL_TEXTURE_GEN_S);
		glEnable(GL_TEXTURE_GEN_T);

		// bind the environment texture
		glBindTexture(GL_TEXTURE_2D, envTex->texID);

		// translate and rotate
		glTranslatef(0.0f, 4.0f, 0.0f);
		glRotatef(objectAngle, 1.0f, 1.0f, 0.0f);
		glRotatef(objectAngle, 0.0f, 1.0f, 0.0f);
		glRotatef(objectAngle, 0.0f, 0.0f, 1.0f);

		// draw torus
		auxSolidTorus(1.0f, 2.0f);

		// disable texture coordinate generation
		glDisable(GL_TEXTURE_GEN_T);
		glDisable(GL_TEXTURE_GEN_S);
	glPopMatrix();
}

// Render
// desc: handles drawing of scene
void Render()
{
	objectAngle += 0.2f;					// increase object rotation angle
	radians =  float(PI*(angle-90.0f)/180.0f);

	// calculate the camera's position
	cameraX = lookX + sin(radians)*mouseY;	// multiplying by mouseY makes the
	cameraZ = lookZ + cos(radians)*mouseY;  // camera get closer/farther away with mouseY
	cameraY = lookY + mouseY / 2.0f;

	// point camera at (0,0,0)
	lookX = 0.0f;
	lookY = 2.0f;
	lookZ = 0.0f;

	// clear color, depth, and stencil buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	glLoadIdentity();

	// set the camera position
	gluLookAt(cameraX, cameraY, cameraZ, lookX, lookY, lookZ, 0.0, 1.0, 0.0);

	/// disable depth testing
    glDisable(GL_DEPTH_TEST);

	// disable modification of all color components
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    // enable stencil testing
    glEnable(GL_STENCIL_TEST);

	// setup the stencil buffer for a function reference value
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 1, 1);

    // draw the floor; this will set the floor pixels in the stencil buffer
	// to 1, since we defined 1 as the mask value with the glStencilFunc() command
    DrawFloor();

    // enable modification of all color components
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

	// enable depth testing
    glEnable(GL_DEPTH_TEST);

    // make it so we can only render where the stencil buffer is equal to 1
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

⌨️ 快捷键说明

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