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

📄 main.c

📁 游戏编程精粹2第四章源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	else
	{
		drawSkyboxCubeEnvironment();
	}

	/*
	Display the HUD, if so inclined
	*/
	if(hudMode)
	{
		hudBegin();
		glColor3f(1,0,0);

		hudY = 16;
		
		if(skyboxMode == kSkyboxMode2d)
		{
			hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Render Mode - 2d Texture");
		}
		else
		{
			hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Render Mode - Cubic Environment Map");
			hudY+=16;
			switch(objectType)
			{
			case kTorus :
				hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Object Type - Torus");
				break;
			case kSphere :
				hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Object Type - Sphere");
				break;
			case kTeapot :
				hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Object Type - Teapot");
				break;
			case kCube :
				hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Object Type - Cube");
				break;
			case kNoObject :
				hudDisplayString(0,hudY,GLUT_BITMAP_HELVETICA_12,"Object Type - None");
				break;
			};
		}
		
		glColor3f(1,1,1);
		hudEnd();
	}

	glutSwapBuffers();
	glutPostRedisplay();
}

/*
Timer function rotates shiny object
*/
void
onTimer(int value)
{
	if(rotateObject)
	{
		objectAngle=(objectAngle+1)%360;
	}
	glutTimerFunc(10, onTimer, 0);
}


/*
Mouse move functions used to implement "free look" camera
*/
void
onMouseMoveButtonDown(int x,int y)
{
	cameraTheta += (float)(x-mouseDownX);
	cameraPhi += (float)(y-mouseDownY);

	cameraPhi = max(-90,min(cameraPhi,90));

	mouseDownX = x;
	mouseDownY = y;
}


void
onMouseDown(int b,int s,int x,int y)
{
	if (s == GLUT_DOWN)
	{
		mouseDownX = x;
		mouseDownY = y;
		glutMotionFunc(onMouseMoveButtonDown);
	}
	else
	{
		glutMotionFunc(0);
	}
}

/*
Handle cursor keys
*/
void
onSpecialKey(int key,int x,int y)
{
	switch(key)
	{
	case GLUT_KEY_RIGHT:
		cameraTheta = cameraTheta+5;
		while (cameraTheta > 360) cameraTheta -= 360;
		break;
	case GLUT_KEY_LEFT:
		cameraTheta = cameraTheta-5;
		while (cameraTheta < 0) cameraTheta += 360;
		break;
    case GLUT_KEY_UP:
		cameraPhi = cameraPhi+5;
		if (cameraPhi > 90) cameraPhi = 90;
		break;
	case GLUT_KEY_DOWN:
		cameraPhi = cameraPhi-5;
		if (cameraPhi < -90) cameraPhi = -90;
		break;
	};
}

/*
Handle typed characters
*/
void
onKey(unsigned char key,int x,int y)
{
	switch(key)
	{
	case 'M':
	case 'm':
		if(cubeMapAvailable)
		{
			skyboxMode = (skyboxMode==kSkyboxMode2d) ? kSkyboxModeCubeEnvironment : kSkyboxMode2d;
		}
		break;

	case 'r':
	case 'R':
		rotateObject = !rotateObject;
		break;
	
	case 'o':
	case 'O':
		objectType = (objectType+1)%kObjectTypeCount;
		break;

	case 'h':
	case 'H':
		hudMode = !hudMode;
		break;
	};
}


/*
Loads a Windows BMP file onto the given texture target
*/
GLboolean
loadImage(GLenum target,const char *fileName)
{
	int i,topRow,bottomRow;
	AUX_RGBImageRec *image = auxDIBImageLoad(fileName);
	if(image!=0)
	{
		/*
		BMP files are upside down, so flip pixels
		*/
		topRow = 0;
		bottomRow = 3*image->sizeX*(image->sizeY-1);
		while (topRow < bottomRow)
		{
			for (i=0;i<3*image->sizeX;i++)
			{
				SWAP_BYTES(image->data[bottomRow+i],image->data[topRow+i]);
			}
			bottomRow -= 3*image->sizeX;
			topRow += 3*image->sizeX;
		}	

		glTexImage2D(target,0,3,image->sizeX,image->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,image->data);

		free(image->data);
		free(image);

		return GL_TRUE;
	}
	else
	{
		printf("Could not load texture file %s\n",fileName);
		return GL_FALSE;
	}
}

/*
Set up skybox rendering
*/
GLboolean
initSkybox(void)
{
	int i;
	GLint clampMode;
	GLboolean succeeded = GL_TRUE;
	char *imageFiles[] = {"image1.bmp","image2.bmp","image3.bmp","image4.bmp","image5.bmp","image6.bmp"};
	
	/*
	Allocate texture objects
	*/
	glGenTextures(6,textureObjects2d);
	glGenTextures(1,&textureObjectCubeMap);

	/*
	Let OpenGL normalize normals
	*/
	glEnable(GL_NORMALIZE);

	/*
	Use GL_CLAMP_TO_EDGE if we can
	*/
	if (glutExtensionSupported("GL_EXT_texture_edge_clamp"))
	{
		clampMode = GL_CLAMP_TO_EDGE;
	}
	else
	{
		clampMode = GL_CLAMP;
	}

	/*
	Generate 2d textures
	*/
	for (i=0;i<6;i++)
	{
		glBindTexture(GL_TEXTURE_2D,textureObjects2d[i]);
		glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,clampMode);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,clampMode);
		succeeded = succeeded && loadImage(GL_TEXTURE_2D,imageFiles[i]);
	}

	
	/*
	Generate cube map, if supported
	*/
	if(glutExtensionSupported("GL_ARB_texture_cube_map"))
	{
		cubeMapAvailable = 1;
		glBindTexture(GL_TEXTURE_CUBE_MAP_ARB,textureObjectCubeMap);

		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

		succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,imageFiles[0]);
		succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,imageFiles[1]);
		
		succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,imageFiles[2]);
		succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,imageFiles[3]);
		
		succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,imageFiles[4]);
		succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,imageFiles[5]);
		
	}
	else
	{
		cubeMapAvailable = 0;
	}
	return succeeded;

}

/*
Shutdown code 
*/
void
shutdownSkybox(void)
{
	/*
	Deallocate texture objects
	*/
	glDeleteTextures(6,textureObjects2d);
	glDeleteTextures(1,&textureObjectCubeMap);
}


/*
hudBegin()/hudEnd() modeled after glBegin()/glEnd()
*/
void
hudBegin(void)
{
	GLfloat w,h;

	/*
	No world transform in HUD mode
	*/
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	

	/*
	Switch to orthographic projection
	*/
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	
	w = (GLfloat)glutGet(GLUT_WINDOW_WIDTH);
	h = (GLfloat)glutGet(GLUT_WINDOW_HEIGHT);
	glOrtho(0,w,0,h,-1.0,1.0);

	/*
	Save current attributes and disable texturing
	*/
	glPushAttrib(GL_ALL_ATTRIB_BITS);
	glDisable(GL_TEXTURE_2D);

	if(cubeMapAvailable)
	{
		glDisable(GL_TEXTURE_CUBE_MAP_ARB);
	}
}

void
hudEnd(void)
{
	/*
	Pop attributes and matrices
	*/
	glPopAttrib();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
}

/*
HUD text display code
Between hudBegin() and hudEnd(), call hudDisplayString() to display text at x,y with 0,0 at the upper left-hand corner
*/
void 
hudDisplayString(int x,int y,void *font,const char *str)
{
	int i,l=strlen(str);
	GLint h = glutGet(GLUT_WINDOW_HEIGHT);

	glRasterPos2i(x,h-y);

	for(i=0;i<l;i++)
		glutBitmapCharacter(font,str[i]);
}


int
main(int argc, char **argv)
{
	
	/*
	Initialize GLUT Window
	*/
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutCreateWindow("Game Gems II Skybox Demo");
	
	/*
	Setup GLUT callbacks
	*/
	glutDisplayFunc(onDisplay);
	glutMouseFunc(onMouseDown);
	glutSpecialFunc(onSpecialKey);
	glutKeyboardFunc(onKey);
	glutTimerFunc(10, onTimer, 0);

	/*
	Initialize
	*/
	if(!initSkybox())
	{
		shutdownSkybox();
		return 0;
	}
	
	/*
	Print Instructions
	*/
	printf("Game Gems II Skybox Demo\n");
	printf("Keys:\n");
	printf("Arrow Keys - move camera\n");
	if(cubeMapAvailable)
	{
		printf("M - toggle render mode (2d texture/cube environment)\n");
		printf("R - toggle object rotation in cube environment mode (on/off)\n");
		printf("O - cycle object type in cube environment mode\n");
	}
	else
	{
		printf("Cubic Environment Mapping Not Available!\n");
	}
	printf("H - toggle hud mode (on/off)\n");
	printf("Click and drag mouse for free-look camera\n");
	
	/*
	Run, Lola, Run
	*/
	glutMainLoop();
	
	/*
	Deinitialize
	*/
	shutdownSkybox();
	return 0;             
}

⌨️ 快捷键说明

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