?? main.cpp
字號(hào):
//////////////////////////////////////////////////////////////////////////////////////////
// Main.cpp
// Shadow Volumes
// Downloaded from: www.paulsprojects.net
// Created: 4th September 2002
// Updated: 3rd October 2002 - Added EXT_stencil_two_side support
// Added vertex program extrusion
// Improved "zFail required" testing
// 15th November 2002 - Corrected problem on systems not suppotring
// ARB_vertex_program.
//
// Copyright (c) 2006, Paul Baker
// Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
// http://www.paulsprojects.net/NewBSDLicense.txt)
//////////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <GL\gl.h>
#include <GL\glu.h>
#include <GL\glext.h>
#include <GL\wglext.h>
#include "LOG.h"
#include "WINDOW.h"
#include "extensions/EXT_stencil_two_side_extension.h"
#include "extensions/EXT_stencil_wrap_extension.h"
#include "extensions/ARB_vertex_program_extension.h"
#include "ARB_program.h"
#include "FPS_COUNTER.h"
#include "TIMER.h"
#include "Maths/Maths.h"
#include "SHADOW_MODEL.h"
#include "INTERACTOR.h"
#include "main.h"
#include "box.h"
//link to libraries
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "winmm.lib")
//errorLog MUST be kept - it is used by other files
LOG errorLog;
WINDOW window;
FPS_COUNTER fpsCounter;
TIMER timer;
COLOR backgroundColor(0.0f, 0.0f, 0.0f, 0.0f);
INTERACTOR camera;
LIGHT light;
SHADOW_MODEL models[2];
float modelRadii[2];
const int numTori=4;
TORUS torus[numTori];
//Always use zFail?
bool alwaysUseZFail=true;
//2 sided stencil supported?
bool twoSidedStencilSupported=false;
//Using 2 sided stencil?
bool useTwoSidedStencil=false;
//Vertex program volume generation supported?
bool VPVolumesSupported=false;
//Using vertex program volume generation
bool useVPVolumes=false;
GLuint shadowVolumeVP;
GLuint lightingVP;
//sphere
GLUquadricObj * sphere;
//Projection matrix
MATRIX4X4 projectionMatrix;
//Set up variables
bool DemoInit()
{
if(!window.Init("Shadow Volumes", 640, 480, 32, 24, 8, WINDOWED_SCREEN))
return 0; //quit if not created
//Set up extensions
SetUpEXT_stencil_two_side();
SetUpEXT_stencil_wrap();
SetUpARB_vertex_program();
if(EXT_stencil_two_side_supported && EXT_stencil_wrap_supported)
twoSidedStencilSupported=true;
if(ARB_vertex_program_supported)
VPVolumesSupported=true;
camera.Init(VECTOR3D(0.0f, 0.0f, 12.0f), 3.0f, 25.0f);
//Set up models
models[1].GenerateTorus(0.3f, 1.0f);
//Set model radii - could easily calculate these for more complex models
modelRadii[0]=1.05f;
modelRadii[1]=1.3f;
//Set colors
torus[0].color.Set(1.0f, 0.0f, 0.0f, 0.0f); //small red torus
torus[1].color.Set(1.0f, 0.0f, 0.0f, 0.0f); //small red torus
torus[2].color.Set(0.0f, 1.0f, 0.0f, 0.0f); //larger green torus
torus[3].color.Set(0.0f, 1.0f, 0.0f, 0.0f); //larger green torus
//Set up light
light.position.Set(0.0f, 0.0f, 0.0f);
light.color=white/1.5;
sphere=gluNewQuadric();
//reset timer for start
timer.Reset();
return true;
}
//Set up openGL
bool GLInit()
{
//set viewport
int height;
if (window.height==0)
height=1;
else
height=window.height;
glViewport(0, 0, window.width, height); //reset viewport
//set up projection matrix (infinite far plane)
glMatrixMode(GL_PROJECTION); //select projection matrix
projectionMatrix.SetPerspective(45.0f, (GLfloat)window.width/(GLfloat)height, 1.0f, -1.0f);
glLoadMatrixf(projectionMatrix);
//load identity modelview
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//other states
//shading
glShadeModel(GL_SMOOTH);
glClearColor( backgroundColor.r,
backgroundColor.g,
backgroundColor.b,
backgroundColor.a);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
//depth
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
//hints
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_CULL_FACE);
//Enable vertex arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
//Set up color material
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
//load vertex programs
if(ARB_vertex_program_supported)
{
glGenProgramsARB(1, &shadowVolumeVP);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, shadowVolumeVP);
if(!LoadARB_program(GL_VERTEX_PROGRAM_ARB, "shadow volume VP.txt"))
return false;
glGenProgramsARB(1, &lightingVP);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, lightingVP);
if(!LoadARB_program(GL_VERTEX_PROGRAM_ARB, "lighting VP.txt"))
return false;
}
return true;
}
//Perform per frame updates
void UpdateFrame()
{
window.Update();
camera.Update();
//Toggle pause
if(window.isKeyPressed('P'))
timer.Pause();
if(window.isKeyPressed('U'))
timer.Unpause();
//Switch to/from always using zFail
if(window.isKeyPressed('F'))
alwaysUseZFail=true;
if(window.isKeyPressed('G'))
alwaysUseZFail=false;
//Switch to/from using 2 sided stencil
if(window.isKeyPressed('1'))
useTwoSidedStencil=false;
if(window.isKeyPressed('2') && twoSidedStencilSupported)
useTwoSidedStencil=true;
//Switch to/from using vertex program volume generation
if(window.isKeyPressed('V') && VPVolumesSupported)
useVPVolumes=true;
if(window.isKeyPressed('S'))
useVPVolumes=false;
//Update light position
if(window.isKeyPressed(VK_UP) && light.position.y<4.5f)
light.position.y+=0.05f;
if(window.isKeyPressed(VK_DOWN) && light.position.y>-4.5f)
light.position.y-=0.05f;
//Update model positions and angles
for(int i=0; i<numTori; ++i)
{
if(i==0 || i==1)
{
torus[i].position.Set( 2.0f*(float)sin(timer.GetTime()/1000 + M_PI*i),
0.0f,
2.0f*(float)cos(timer.GetTime()/1000 + M_PI*i));
torus[i].angle=(float)timer.GetTime()/15;
}
else
{
torus[i].position.Set( 4.0f*(float)sin(-timer.GetTime()/800 + M_PI*i),
(float)sin(-timer.GetTime()/300 + M_PI*i),
4.0f*(float)cos(-timer.GetTime()/800 + M_PI*i));
//keep the green tori at the same angle to the light
torus[i].angle=(float)timer.GetTime()*180/float(800*M_PI);
}
//Find the object space light positions
MATRIX4X4 inverseModelMatrix;
glPushMatrix();
glLoadIdentity();
glRotatef(-torus[i].angle, 0.0f, 0.0f, 1.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glTranslatef(-torus[i].position.x, -torus[i].position.y, -torus[i].position.z);
glGetFloatv(GL_MODELVIEW_MATRIX, inverseModelMatrix);
glPopMatrix();
//Set the object space light positions
torus[i].objectSpaceLightPosition=inverseModelMatrix*light.position;
}
}
//draw a frame
void RenderFrame()
{
//Clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity(); //reset modelview matrix
//Set view
camera.SetupViewMatrix();
glMultMatrixf(camera.viewMatrix);
//Calculate the viewProjection matrix (world -> clip coords)
MATRIX4X4 viewProjectionMatrix=projectionMatrix*camera.viewMatrix;
MATRIX4X4 inverseViewProjectionMatrix=viewProjectionMatrix.GetInverse();
//Calculate the points in world space which become the corners of the near plane
VECTOR3D corners[4];
corners[0]=inverseViewProjectionMatrix*VECTOR3D( 1.0f, 1.0f,-1.0f);
corners[1]=inverseViewProjectionMatrix*VECTOR3D(-1.0f, 1.0f,-1.0f);
corners[2]=inverseViewProjectionMatrix*VECTOR3D(-1.0f,-1.0f,-1.0f);
corners[3]=inverseViewProjectionMatrix*VECTOR3D( 1.0f,-1.0f,-1.0f);
//Calculate the planes to check the model position against
// /light
// ------------o------------- lightPlanes[5]
// / \
// lPlanes[0]-/ * \ - lightPlanes[1]
// / \
// ---------eeeeeee---------- lightPlanes[4]
// \eye near plane
//Plane normals face "inwards" (towards *). If the occluder is completely behind any plane,
//there is no way its shadow can intersect the near plane, so no need for zfail technique
//and hence no need for caps on volume
PLANE lightPlanes[6];
lightPlanes[0].SetFromPoints(light.position, corners[0], corners[1]);
lightPlanes[1].SetFromPoints(light.position, corners[1], corners[2]);
lightPlanes[2].SetFromPoints(light.position, corners[2], corners[3]);
lightPlanes[3].SetFromPoints(light.position, corners[3], corners[0]);
lightPlanes[4].SetFromPoints(corners[0], corners[2], corners[1]); //near clip plane
lightPlanes[5].SetFromPoints(corners[0], corners[1], corners[2]); //"far clip plane"
lightPlanes[5].CalculateIntercept(light.position);
//Draw ambient
glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_COLOR_MATERIAL);
glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(light.position));
glLightfv(GL_LIGHT1, GL_AMBIENT, light.color/5);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light.color/5);
glLightfv(GL_LIGHT1, GL_SPECULAR, black);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
//Enable vertex program if using VP for volumes
if(useVPVolumes)
{
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, lightingVP);
glEnable(GL_VERTEX_PROGRAM_ARB);
}
//Draw box
glColor3f(0.2f, 0.2f, 1.0f);
DrawBox();
//Draw models
for(int i=0; i<numTori; ++i)
{
glColor4fv(torus[i].color);
glPushMatrix();
glTranslatef(torus[i].position.x, torus[i].position.y, torus[i].position.z);
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
glRotatef(torus[i].angle, 0.0f, 0.0f, 1.0f);
if(i==0 || i==1)
{
glVertexPointer(3, GL_FLOAT, sizeof(SHADOW_MODEL_VERTEX), &models[0].vertices[0].position);
glNormalPointer(GL_FLOAT, sizeof(SHADOW_MODEL_VERTEX), &models[0].vertices[0].normal);
glDrawElements(GL_TRIANGLES, models[0].numIndices, GL_UNSIGNED_INT, models[0].indices);
}
else
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -