📄 main.cpp
字号:
#define WIN32_LEAN_AND_MEAN // trim the excess fat from Windows
/*******************************************************************
* Program: Chapter 9 Multitexturing Example 1
* Author: Kevin Hawkins
* Description:
********************************************************************/
////// 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 "glext.h" // header file for OpenGL extensions
////// 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 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 *smileTex;
texture_t *checkerTex;
bool multiPass = false;
////// Multitexturing Info
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
int maxTextureUnits = 0;
// InitMultiTex
// desc: sets up OpenGL for multitexturing support
bool InitMultiTex()
{
char *extensionStr; // list of available extensions
extensionStr = (char*)glGetString(GL_EXTENSIONS);
if (extensionStr == NULL)
return false;
if (strstr(extensionStr, "GL_ARB_multitexture"))
{
// retrieve the maximum number of texture units allowed
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
// retrieve addresses of multitexturing functions
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");
return true;
}
else
return false;
}
// 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 smile texture data
smileTex = LoadTextureFile("smile.bmp");
if (smileTex == NULL)
return false;
// load the checker texture data
checkerTex = LoadTextureFile("chess.bmp");
if (checkerTex == NULL)
return false;
// setup the smile texture as a mipmap with bilinear filtering
glBindTexture(GL_TEXTURE_2D, smileTex->texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // use bilinear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, smileTex->width, smileTex->height, GL_RGB, GL_UNSIGNED_BYTE, smileTex->data);
// generate the water texture as a mipmap
glBindTexture(GL_TEXTURE_2D, checkerTex->texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // use bilinear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // repeat texture
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, checkerTex->width, checkerTex->height, GL_RGB, GL_UNSIGNED_BYTE, checkerTex->data);
return true;
}
void CleanUp()
{
free(smileTex);
free(checkerTex);
}
// 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_DEPTH_TEST); // hidden surface removal
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
InitMultiTex();
LoadAllTextures();
}
// DrawCube
// desc: draws a cube at the specified location in
// the current coordinate space
void DrawCube(float xPos, float yPos, float zPos)
{
glPushMatrix();
glTranslatef(xPos, yPos, zPos);
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f); // top face
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f); // front face
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(1.0f, 0.0f, 0.0f); // right face
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f); // left face
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0f, -1.0f, 0.0f); // bottom face
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(0.5f, -0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, -1.0f); // back face
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f(0.5f, -0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glEnd();
glPopMatrix();
}
// DrawTexturedCube()
// desc: draws a textured cube, assuming the current
// texture has already been defined
void DrawTexturedCube(float xPos, float yPos, float zPos)
{
glPushMatrix();
glTranslatef(xPos, yPos, zPos);
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f); // top face
glTexCoord2f(1.0f, 0.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, -0.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f); // front face
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0.5f, 0.5f, 0.5f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glEnd();
glBegin(GL_QUADS);
glNormal3f(1.0f, 0.0f, 0.0f); // right face
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -