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

📄 main.c

📁 游戏编程精粹2第四章源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) Jason Shankel, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Jason Shankel, 2001"
 */
/*
Game Gems II Skybox Demo
by
Jason Shankel
*/

#include <GL/glut.h>
#include <GL/glaux.h>
#include "GL/glext.h"
#include <stdio.h>
#include <stdlib.h>

/*
Camera controls
*/
static GLfloat cameraTheta=0,cameraPhi=0;
static GLint mouseX=0,mouseY=0,mouseDownX=0,mouseDownY=0;

/*
Skybox rendering mode
*/
#define kSkyboxMode2d 0
#define kSkyboxModeCubeEnvironment 1
static int skyboxMode = kSkyboxMode2d; 
static int cubeMapAvailable = 0;
static int hudMode = 1;

/*
Texture objects
*/
static GLuint textureObjectCubeMap;
static GLuint textureObjects2d[6];

/*
Shiny object parameters
*/
static int rotateObject = 1;
static GLint objectAngle=0;
#define kTorus 0
#define kSphere 1
#define kTeapot 2
#define kCube 3
#define kNoObject 4
#define kObjectTypeCount 5
static int objectType = kTorus;


/*
Rendering functions
*/
static void drawSkybox2d(void);
static void drawSkyboxCubeEnvironment(void);
static void hudEnd(void);
static void hudBegin(void);
static void hudDisplayString(int x,int y,void *font,const char *str);

/*
Init/Shutdown 
*/
static GLboolean initSkybox(void);
static void shutdownSkybox(void);

/*
Image loading
SWAP_BYTES is used to flip inverted *.bmp files
*/
GLboolean loadImage(GLenum target,const char *fileName);
#define SWAP_BYTES(b1,b2) (b1)=(b1)^(b2);(b2)=(b1)^(b2);(b1)=(b1)^(b2);


/*
GLUT callbacks
*/
static void onTimer(int value);
static void onDisplay(void);
static void onMouseMoveButtonDown(int x,int y);
static void onMouseDown(int b,int s,int x,int y);
static void onSpecialKey(int key,int x,int y);
static void onKey(unsigned char key,int x,int y);


/*
Draw skybox using cube environment mapping.  The skybox cube is drawn as two triangle fans, centered around opposite corners of the cube
*/
void 
drawSkyboxCubeEnvironment(void)
{
	/*
	Setup cube environment mapping
	*/
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_TEXTURE_CUBE_MAP_ARB);
	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB,textureObjectCubeMap);
	
	/*
	Disable the depth buffer when rendering the skybox
	*/
	glDisable(GL_DEPTH_TEST);
	glDepthMask(0);
	
	/*
	Draw a fan around 10,10,10
	*/
	glBegin(GL_TRIANGLE_FAN);
	
	glTexCoord3f(1,1,1);
	glVertex3f(10,10,10);
	
	glTexCoord3f(1,1,-1);
	glVertex3f(10,10,-10);
	
	glTexCoord3f(-1,1,-1);
	glVertex3f(-10,10,-10);
	
	glTexCoord3f(-1,1,1);
	glVertex3f(-10,10,10);
	
	glTexCoord3f(-1,-1,1);
	glVertex3f(-10,-10,10);
	
	glTexCoord3f(1,-1,1);
	glVertex3f(10,-10,10);

	glTexCoord3f(1,-1,-1);
	glVertex3f(10,-10,-10);
	
	glTexCoord3f(1,1,-1);
	glVertex3f(10,10,-10);
	
	glEnd();

	/*
	Draw a fan around -10,-10,-10
	*/
	glBegin(GL_TRIANGLE_FAN);

	glTexCoord3f(-1,-1,-1);
	glVertex3f(-10,-10,-10);

	glTexCoord3f(-1,-1,1);
	glVertex3f(-10,-10,10);

	glTexCoord3f(1,-1,1);
	glVertex3f(10,-10,10);

	glTexCoord3f(1,-1,-1);
	glVertex3f(10,-10,-10);
	
	glTexCoord3f(1,1,-1);
	glVertex3f(10,10,-10);
	
	glTexCoord3f(-1,1,-1);
	glVertex3f(-10,10,-10);
	
	glTexCoord3f(-1,1,1);
	glVertex3f(-10,10,10);
	
	glTexCoord3f(-1,-1,1);
	glVertex3f(-10,-10,10);
	
	glEnd();
	
	/*
	Reactivate depth buffer
	*/
	glEnable(GL_DEPTH_TEST);
	glDepthMask(1);

	/*
	Now draw shiny object
	*/

	/*
	Set up reflection mapping coordinate generation
	*/
	glTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_ARB);
	glTexGenf(GL_T,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_ARB);
	glTexGenf(GL_R,GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP_ARB);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);

	/*
	Set up object matrix
	*/
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glTranslatef(0,0,-8);
	glRotatef(cameraPhi,1,0,0);
	glRotatef(cameraTheta,0,1,0);
	
	/*
	Rotating about two axes with different angles gives a nice tumbling effect
	*/
	glRotatef((GLfloat)objectAngle,1,0,0);
	glRotatef((GLfloat)2*objectAngle,0,1,0);

	/*
	Rotate texture matrix to match camera matrix
	*/
	glMatrixMode(GL_TEXTURE);
	glPushMatrix();
	glLoadIdentity();
	glRotatef(-cameraTheta,0,1,0);
	glRotatef(-cameraPhi,1,0,0);

	/*
	Some glut objects require matrix-mode to be set to GL_MODELVIEW
	*/
	glMatrixMode(GL_MODELVIEW);

	/*
	Draw Object
	*/
	if(objectType != kNoObject)
	{
		switch(objectType)
		{
			case kTorus:
				glutSolidTorus(1,2,16,16);
				break;

			case kSphere:
				glutSolidSphere(3,16,16);
				break;

			case kTeapot:
				glutSolidTeapot(3);
				break;

			case kCube:
				glutSolidCube(3);
				break;
		};
	}

	/*
	Restore texture and modelview matrices
	*/
	glMatrixMode(GL_TEXTURE);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();


	/*
	Disable reflection mapping
	*/
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
	
}

/*
Draw skybox using six faces and six 2d textures
*/
void
drawSkybox2d(void)
{
	/*
	Enable 2d texture mapping
	*/
	glDisable(GL_TEXTURE_CUBE_MAP_ARB);
	glEnable(GL_TEXTURE_2D);
	
	/*
	Disable the depth buffer when rendering the skybox
	*/
	glDisable(GL_DEPTH_TEST);
	glDepthMask(0);


	/*
	Rear Face
	*/
	glBindTexture(GL_TEXTURE_2D,textureObjects2d[0]);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(1,0);
	glVertex3f(10,10,10);
	glTexCoord2f(1,1);
	glVertex3f(10,-10,10);
	glTexCoord2f(0,1);
	glVertex3f(-10,-10,10);
	glTexCoord2f(0,0);
	glVertex3f(-10,10,10);
	glEnd();
	
	/*
	Front Face
	*/
	glBindTexture(GL_TEXTURE_2D,textureObjects2d[1]);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(1,0);
	glVertex3f(-10,10,-10);
	glTexCoord2f(1,1);
	glVertex3f(-10,-10,-10);
	glTexCoord2f(0,1);
	glVertex3f(10,-10,-10);
	glTexCoord2f(0,0);
	glVertex3f(10,10,-10);
	glEnd();

	/*
	Right Face
	*/
	glBindTexture(GL_TEXTURE_2D,textureObjects2d[2]);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(1,0);
	glVertex3f(10,10,-10);
	glTexCoord2f(1,1);
	glVertex3f(10,-10,-10);
	glTexCoord2f(0,1);
	glVertex3f(10,-10,10);
	glTexCoord2f(0,0);
	glVertex3f(10,10,10);
	glEnd();

	/*
	Left Face
	*/
	glBindTexture(GL_TEXTURE_2D,textureObjects2d[3]);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(1,0);
	glVertex3f(-10,10,10);
	glTexCoord2f(1,1);
	glVertex3f(-10,-10,10);
	glTexCoord2f(0,1);
	glVertex3f(-10,-10,-10);
	glTexCoord2f(0,0);
	glVertex3f(-10,10,-10);
	glEnd();
	
	/*
	Top Face
	*/
	glBindTexture(GL_TEXTURE_2D,textureObjects2d[4]);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(0,1);
	glVertex3f(-10,10,10);
	glTexCoord2f(0,0);
	glVertex3f(-10,10,-10);
	glTexCoord2f(1,0);
	glVertex3f(10,10,-10);
	glTexCoord2f(1,1);
	glVertex3f(10,10,10);
	glEnd();

	/*
	Bottom Face
	*/
	glBindTexture(GL_TEXTURE_2D,textureObjects2d[5]);
	glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(0,1);
	glVertex3f(-10,-10,-10);
	glTexCoord2f(0,0);
	glVertex3f(-10,-10,10);
	glTexCoord2f(1,0);
	glVertex3f(10,-10,10);
	glTexCoord2f(1,1);
	glVertex3f(10,-10,-10);
	glEnd();

	/*
	Reactive depth buffer
	*/
	glEnable(GL_DEPTH_TEST);
	glDepthMask(1);
}




/*
Main Display Function
*/
void
onDisplay(void)
{
	int hudY;
	
	/*
	Set projection matrix for 100 degree FOV
	*/
	GLfloat w = (GLfloat)glutGet(GLUT_WINDOW_WIDTH),h = (GLfloat)glutGet(GLUT_WINDOW_HEIGHT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(100.0,w/h,1,100);
	
	/*
	Set modelview matrix for camera 
	*/
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glRotatef(cameraPhi,1,0,0);
	glRotatef(cameraTheta,0,1,0);
	

	/*
	No need to clear the color buffer, the skybox fills the whole screen
	Shiny objects in cube environment mode use depth buffer, so we do need to clear that one
	*/
	glClear(GL_DEPTH_BUFFER_BIT);
	
	
	/*
	Draw skybox
	*/
	if(skyboxMode == kSkyboxMode2d)
	{
		drawSkybox2d();

⌨️ 快捷键说明

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