案例 隧道
#include "GLTools.h"
#include "GLShaderManager.h"
#include "GLFrustum.h"
#include "GLBatch.h"
#include "GLFrame.h"
#include "GLMatrixStack.h"
#include "GLGeometryTransform.h"
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
GLShaderManager shaderManager;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrustum viewFrustum;
GLGeometryTransform transformPipeline;
GLBatch floorBatch;
GLBatch ceilingBatch;
GLBatch leftWallBatch;
GLBatch rightWallBatch;
GLfloat viewZ = -65.0f;
#define TEXTURE_BRICK 0
#define TEXTURE_FLOOR 1
#define TEXTURE_CEILING 2
#define TEXTURE_COUNT 3
GLuint textures[TEXTURE_COUNT];
const char *szTextureFiles[TEXTURE_COUNT] = { "brick.tga", "floor.tga", "ceiling.tga" };
void ProcessMenu(int value)
{
GLint iLoop;
for(iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
{
glBindTexture(GL_TEXTURE_2D, textures[iLoop]);
switch(value)
{
case 0:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
break;
case 1:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
break;
case 2:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
break;
case 3:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
break;
case 4:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
break;
case 5:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
break;
case 6:
GLfloat fLargest;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
break;
case 7:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
break;
}
}
glutPostRedisplay();
}
void SetupRC()
{
glClearColor(0.0f, 0.0f, 0.0f,1.0f);
shaderManager.InitializeStockShaders();
GLbyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
GLint iLoop;
glGenTextures(TEXTURE_COUNT, textures);
for(iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
{
glBindTexture(GL_TEXTURE_2D, textures[iLoop]);
pBytes = gltReadTGABits(szTextureFiles[iLoop],&iWidth, &iHeight,
&iComponents, &eFormat);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
glGenerateMipmap(GL_TEXTURE_2D);
free(pBytes);
}
GLfloat z;
floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-10.0f, -10.0f, z);
floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
floorBatch.Vertex3f(10.0f, -10.0f, z);
floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
}
floorBatch.End();
ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
ceilingBatch.Vertex3f(-10.0f, 10.0f, z);
ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
ceilingBatch.Vertex3f(10.0f, 10.0f, z);
}
ceilingBatch.End();
leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
leftWallBatch.Vertex3f(-10.0f, -10.0f, z);
leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
leftWallBatch.Vertex3f(-10.0f, 10.0f, z);
leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);
leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
}
leftWallBatch.End();
rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
rightWallBatch.Vertex3f(10.0f, -10.0f, z);
rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
rightWallBatch.Vertex3f(10.0f, 10.0f, z);
rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
}
rightWallBatch.End();
}
void ShutdownRC(void)
{
glDeleteTextures(TEXTURE_COUNT, textures);
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
viewZ += 0.5f;
if(key == GLUT_KEY_DOWN)
viewZ -= 0.5f;
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
if(h == 0)
h = 1;
glViewport(0, 0, w, h);
GLfloat fAspect = (GLfloat)w/(GLfloat)h;
viewFrustum.SetPerspective(80.0f,fAspect,1.0,120.0);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0.0f, 0.0f, viewZ);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(), 0);
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_FLOOR]);
floorBatch.Draw();
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_CEILING]);
ceilingBatch.Draw();
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BRICK]);
leftWallBatch.Draw();
rightWallBatch.Draw();
modelViewMatrix.PopMatrix();
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Tunnel");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("GL_NEAREST",0);
glutAddMenuEntry("GL_LINEAR",1);
glutAddMenuEntry("GL_NEAREST_MIPMAP_NEAREST",2);
glutAddMenuEntry("GL_NEAREST_MIPMAP_LINEAR", 3);
glutAddMenuEntry("GL_LINEAR_MIPMAP_NEAREST", 4);
glutAddMenuEntry("GL_LINEAR_MIPMAP_LINEAR", 5);
glutAddMenuEntry("Anisotropic Filter", 6);
glutAddMenuEntry("Anisotropic Off", 7);
glutAttachMenu(GLUT_RIGHT_BUTTON);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}
案例 球体世界
#include "GLTools.h"
#include "GLShaderManager.h"
#include "GLFrustum.h"
#include "GLBatch.h"
#include "GLMatrixStack.h"
#include "GLGeometryTransform.h"
#include "StopWatch.h"
#include <math.h>
#include <stdio.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
#define NUM_SPHERES 50
GLFrame spheres[NUM_SPHERES];
GLShaderManager shaderManager;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrustum viewFrustum;
GLGeometryTransform transformPipeline;
GLTriangleBatch torusBatch;
GLBatch floorBatch;
GLTriangleBatch sphereBatch;
GLFrame cameraFrame;
GLuint uiTextures[3];
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
GLbyte *pBits;
int nWidth, nHeight, nComponents;
GLenum eFormat;
pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
if(pBits == NULL)
return false;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, nWidth, nHeight, 0,
eFormat, GL_UNSIGNED_BYTE, pBits);
free(pBits);
if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
minFilter == GL_LINEAR_MIPMAP_NEAREST ||
minFilter == GL_NEAREST_MIPMAP_LINEAR ||
minFilter == GL_NEAREST_MIPMAP_NEAREST)
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
void SetupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
shaderManager.InitializeStockShaders();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
gltMakeSphere(torusBatch, 0.4f, 40, 80);
gltMakeSphere(sphereBatch, 0.1f, 26, 13);
GLfloat texSize = 10.0f;
floorBatch.Begin(GL_TRIANGLE_FAN, 4,1);
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-20.f, -0.41f, 20.0f);
floorBatch.MultiTexCoord2f(0, texSize, 0.0f);
floorBatch.Vertex3f(20.0f, -0.41f, 20.f);
floorBatch.MultiTexCoord2f(0, texSize, texSize);
floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);
floorBatch.MultiTexCoord2f(0, 0.0f, texSize);
floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
floorBatch.End();
for (int i = 0; i < NUM_SPHERES; i++) {
GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
spheres[i].SetOrigin(x, 0.0f, z);
}
glGenTextures(3, uiTextures);
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
LoadTGATexture("marslike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
LoadTGATexture("moonlike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
}
void ShutdownRC(void)
{
glDeleteTextures(3, uiTextures);
}
void ChangeSize(int nWidth, int nHeight)
{
glViewport(0, 0, nWidth, nHeight);
viewFrustum.SetPerspective(35.0f, float(nWidth)/float(nHeight), 1.0f, 100.0f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
modelViewMatrix.LoadIdentity();
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
void drawSomething(GLfloat yRot)
{
static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static GLfloat vLightPos[] = { 0.0f, 3.0f, 0.0f, 1.0f };
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
for(int i = 0; i < NUM_SPHERES; i++) {
modelViewMatrix.PushMatrix();
modelViewMatrix.MultMatrix(spheres[i]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
modelViewMatrix.Translate(0.0f, 0.2f, -2.5f);
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
torusBatch.Draw();
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
void RenderScene(void)
{
static GLfloat vFloorColor[] = { 1.0f, 1.0f, 0.0f, 0.75f};
static CStopWatch rotTimer;
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
modelViewMatrix.PushMatrix();
modelViewMatrix.Scale(1.0f, -1.0f, 1.0f);
modelViewMatrix.Translate(0.0f, 0.8f, 0.0f);
glFrontFace(GL_CW);
drawSomething(yRot);
glFrontFace(GL_CCW);
modelViewMatrix.PopMatrix();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
transformPipeline.GetModelViewProjectionMatrix(),
vFloorColor,
0);
floorBatch.Draw();
glDisable(GL_BLEND);
drawSomething(yRot);
modelViewMatrix.PopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}
void SpeacialKeys(int key,int x,int y)
{
float linear = 0.1f;
float angular = float(m3dDegToRad(5.0f));
if (key == GLUT_KEY_UP) {
cameraFrame.MoveForward(linear);
}
if (key == GLUT_KEY_DOWN) {
cameraFrame.MoveForward(-linear);
}
if (key == GLUT_KEY_LEFT) {
cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);
}
if (key == GLUT_KEY_RIGHT) {
cameraFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);
}
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800,600);
glutCreateWindow("OpenGL SphereWorld");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpeacialKeys);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}