www.pudn.com > Opengl.rar > colorcube.cpp


#include 		// Header File For Windows 
#include 			// Header File For Standard Input/Output 
#include 			// Header File For The OpenGL32 Library 
#include 			// Header File For The GLu32 Library 
#include  
#include 		// Header File For The Glaux Library 
#include  
 
GLfloat	xrot=0.0f;				// X Rotation 
GLfloat	yrot=0.0f;				// Y Rotation 
GLfloat	z=0.0f;			// Depth Into The Screen 
 
GLfloat LightAmbient[]=		{ 0.5f, 0.5f, 0.5f, 1.0f }; 
GLfloat LightDiffuse[]=		{ 1.0f, 1.0f, 1.0f, 1.0f }; 
GLfloat LightPosition1[]=	{ 0.0f, 0.0f, 2.0f, 1.0f }; 
GLfloat LightPosition2[]={ 100.0f, 100.0f, 100.0f, 1.0f }; 
GLfloat LightSpecular[] = { 1.0, 1.0, 1.0, 1.0 }; 
GLfloat LightShininess[]={100.0}; 
GLfloat tempS=0.4; 
GLfloat light1_ambient[]= { tempS, tempS, tempS, 1.0 }; 
GLfloat light1_diffuse[]= { tempS, tempS, tempS, 1.0 }; 
GLfloat light1_specular[] = { tempS, tempS, tempS, 1.0 }; 
GLfloat light1_position[] = { 0, 0.0, 20.0, 0.0 }; 
 
GLfloat spot_direction[]={ 1.0,1.0,-1.0}; 
 
 
GLuint	texture[6];			// Storage For 3 Textures 
char* filenames[6]={"Data/temp7.bmp","Data/temp2.bmp","Data/temp3.bmp","Data/temp4.bmp","Data/temp5.bmp","Data/temp6.bmp"}; 
 
static GLfloat theta[]={0.0,0.0,0.0}; 
static GLint axis=2; 
static GLdouble viewer[]={0.0,0.0,5.0}; 
int InitGL(GLvoid); 
int DrawGLScene(GLvoid); 
int LoadGLTextures(); 
void display(void) 
{ 
	//光照 
	glLightfv(GL_LIGHT0,GL_POSITION,LightPosition2); 
 
	glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); 
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); 
	glLightfv(GL_LIGHT1, GL_SPECULAR,light1_specular); 
	glLightfv(GL_LIGHT1, GL_POSITION,light1_position); 
  
	glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 30.0); 
	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION,spot_direction); 
  
 
	glEnable(GL_LIGHTING); 
	glEnable(GL_LIGHT0); 
	glEnable(GL_LIGHT1); 
	glDepthFunc(GL_LESS); 
 
	//通知OpenGL用当前设置的背景颜色清除颜色缓存,同时清除深度排序缓存 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
 
	//告诉opengl后续的矩阵运算将施加到模型视图矩阵堆栈中,opengl的模型坐标系和世界坐标系是重合的 
    //通过乘以一些列变换矩阵,他可以对场景中的物体做一系列平移、放缩、旋转操作 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
 
    /* 
	void gluLookAt(GLdouble eyex, GLdouble eyey, 
                  GLdouble eyez, GLdouble centerx, 
                  GLdouble centery, GLdouble centerz, GLdouble upx, 
                  GLdouble upy, GLdouble upz ); 
    参数: 
	eyex, eyey, eyez : 眼睛点处的x, y和z 坐标 
    centerx, centery, centerz: 被看的场景中心的X, y, 和 z 坐标 
    upx, upy, upz: 指定的上向量的x, y, 和 z 分量	 
	*/ 
	//GLdouble: x, y, and z coordinates of the eye point 
	gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);//设置uvn坐标系 
	//画立方体 
	DrawGLScene(); 
 
	glPushMatrix(); 
	glRotatef(theta[0],1.0,0.0,0.0);//绕x轴旋转 
	glRotatef(theta[1],0.0,1.0,0.0);//绕y轴旋转 
	glRotatef(theta[2],0.0,0.0,1.0);//绕z轴旋转 
	//glDisable(GL_TEXTURE_2D); 
	glShadeModel(GL_SMOOTH); 
	glColor4f(0.0f, 0.0f, 1.0f, 0.4f);//画透明茶壶 
	glEnable (GL_BLEND); 
	glDisable(GL_DEPTH_TEST); 
	//glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
	//glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);  
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);	 
	glutSolidTeapot(3.0); 
	glPopMatrix(); 
 
	glFlush();//强制执行绘制命令,Opengl的命令是批处理的并非来一条执行一条。 
 
	//在双缓冲模式下,交换视图窗口画布的前后两个缓存, 
	//前缓存是当前显示在屏幕上的内容,后缓存是刚画出的图元 
	glutSwapBuffers(); 
} 
 
void mouse(int btn,int state,int x,int y) 
{ 
	//用鼠标进行旋转 
	if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)//鼠标左键按下 
		axis=0; 
	if(btn==GLUT_MIDDLE_BUTTON&&state==GLUT_DOWN)//鼠标中键按下 
		axis=1; 
	if(btn==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)//鼠标右键按下 
		axis=2; 
	theta[axis]+=2.0;  //角度 
	if(theta[axis]>360.0) 
		theta[axis]-=360.0; 
	glutPostRedisplay();//强制glut更新当前当前窗口中的内容 
} 
 
void keys(unsigned char key,int x,int y) 
{ 
	//改变视点的位置 
	if(key=='x') 
		viewer[0]-=1.0; 
	if(key=='X') 
		viewer[0]+=1.0; 
	if(key=='y') 
		viewer[1]-=1.0; 
	if(key=='Y') 
		viewer[1]+=1.0; 
	if(key=='z') 
		viewer[2]-=1.0; 
	if(key=='Z') 
		viewer[2]+=1.0; 
 
 
	if (key=='-') 
	{ 
		z-=1.0f; 
	} 
	if (key=='+') 
	{ 
		z+=1.0f; 
	} 
	if (key=='8') 
	{ 
		xrot-=10.0f; 
	} 
	if (key=='2') 
	{ 
		xrot+=10.0f; 
	} 
	if (key=='6') 
	{ 
		yrot+=10.0f; 
	} 
	if (key=='4') 
	{ 
		yrot-=10.0f; 
	} 
 
	glutPostRedisplay();//强制glut更新当前当前窗口中的内容 
} 
 
void myReshape(int w,int h) 
{ 
	GLfloat nRange=2.0f; 
	//防止被0除 
    if(h==0) 
	  h=1; 
 
	//设置屏幕视口大小,视口是OpenGL最终在屏幕上绘制图元的一个屏幕矩形区域,它被一个框架窗口所包围。 
	glViewport(0,0,w,h); 
 
	//告诉opengl后续的矩阵运算将施加到投影变换矩阵堆栈中 
    //将三维实体最终画到屏幕上需要通过向屏幕投影变为二维实体 
    //这可以通过两种投影变换实现:一个是透视投影变换,一个是平行投影变换 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity();//初始化投影变换矩阵为单位矩阵 
 
	//glOrtho函数指定投影变换为平行投影变换, 
    //其视景体是一个长方体,位于视景体外的物体都将不出现在屏幕上 
    //其六个参数指定了长方体的六个面,他将创建一个平行投影变换矩阵 
    //他将与前面初始化的投影变换矩阵相乘实现平行投影变换 
 
	//要建立透视投影矩阵将调用glFrustum函数,他建立一个四棱台视景体 
    //更多的是用gluPerspective来创建透视投影,它将自动建立四棱台视景体 
	if(w<=h) 
		//glFrustum(-2.0,2.0,-2.0*(GLfloat)h/(GLfloat)w,2.0*(GLfloat)h/(GLfloat)w,1.0,20.0); 
		glFrustum(-nRange,nRange,-nRange*(GLfloat)h/(GLfloat)w,nRange*(GLfloat)h/(GLfloat)w,1.0,nRange*10.0f);		 
	else 
		//glFrustum(-2.0,2.0,-2.0*(GLfloat)w/(GLfloat)h,2.0*(GLfloat)w/(GLfloat)h,1.0,20.0); 
		glFrustum(-nRange,nRange,-nRange*(GLfloat)w/(GLfloat)h,nRange*(GLfloat)w/(GLfloat)h,1.0,nRange*10.0f);		 
	 
/* 
	GLfloat fAspect; 
	fAspect = (GLfloat)w/(GLfloat)h;//视口的宽高比 
	gluPerspective(120.0f, fAspect, 1.0, 500.0);//参数为:水平视野角度,视口宽高比,进裁剪平面,远裁剪平面 
*/ 
	//告诉opengl后续的矩阵运算将施加到模型视图矩阵堆栈中,opengl的模型坐标系和世界坐标系是重合的 
    //通过乘以一些列变换矩阵,他可以对场景中的物体做一系列平移、放缩、旋转操作 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
 
} 
 
 
 
/* 
 *载入图像函数 
 *返回指向图像文件的指针,发生错误返回NULL 
*/ 
AUX_RGBImageRec *LoadBMP(char *Filename) 
{ 
	FILE *File=NULL;									//文件指针 
 
	if (!Filename)										//防止文件名为空 
	{ 
		return NULL;									//如果文件名为空,返回NULL 
	} 
 
	File=fopen(Filename,"r");							//以只读方式打开文件 
 
	if (File)											//如果文件打开成功 
	{ 
		fclose(File);									//关闭文件流 
		return auxDIBImageLoad(Filename);				//载入图像文件并返回指向图像文件的指针 
	} 
 
	return NULL;										//如果加载失败,返回NULL 
} 
/* 
 *绑定BMP贴图函数 
*/ 
int LoadGLTextures() 
{ 
	int Status=FALSE;									//状态变量 
 
	AUX_RGBImageRec *TextureImage[6];					//为纹理贴图创建存储空间 
 
	memset(TextureImage,0,sizeof(void *)*1);           	//设置指针为空 
 
	glGenTextures(6, &texture[0]);					//创建纹理 
	//载入BMP图像,并设置纹理 
	for(int i=0;i<6;i++) 
	{ 
		if (TextureImage[i]=LoadBMP(filenames[i]))//通过LoadBMP函数载入图像 
		{ 
			Status=true; 
			//设置纹理 
			glBindTexture(GL_TEXTURE_2D, texture[i]); 
			/* 
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
			*/ 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 
			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data); 
		} 
	} 
	//释放图像资源 
	for(i=0;i<6;i++) 
	{ 
		if (TextureImage[i])								//如果纹理存在 
		{ 
			if (TextureImage[i]->data)						//如果纹理图像存在 
			{ 
				free(TextureImage[i]->data);				//释放纹理图像占用的空间 
			} 
 
			free(TextureImage[i]);							//释放图像结构 
		} 
	} 
	return Status;										//返回状态值 
} 
int InitGL(GLvoid)										// 
{ 
	if (!LoadGLTextures())								// Jump To Texture Loading Routine 
	{ 
		return FALSE;									// If Texture Didn't Load Return FALSE 
	} 
 
	glEnable(GL_TEXTURE_2D);							// Enable Texture Mapping 
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading 
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background 
	glClearDepth(1.0f);									// Depth Buffer Setup 
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing 
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations 
	 
 
	glColor4f(1.0f, 1.0f, 1.0f, 1.0);					// Full Brightness.  50% Alpha 
	glBlendFunc(GL_SRC_ALPHA,GL_ZERO);					// Set The Blending Function For Translucency 
 
	return TRUE;										// Initialization Went OK 
} 
 
int DrawGLScene(GLvoid)									// 
{ 
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer 
	 
	glPushMatrix(); 
	InitGL();	 
	glLoadIdentity();									// Reset The View 
	gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);//设置uvn坐标系 
	glTranslatef(0.0f,0.0f,z); 
	glRotatef(xrot,1.0f,0.0f,0.0f); 
	glRotatef(yrot,0.0f,1.0f,0.0f); 
	// Front Face 
	glBindTexture(GL_TEXTURE_2D, texture[0]); 
	glBegin(GL_QUADS); 
	glNormal3f( 0.0f, 0.0f, 1.0f); 
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); 
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 
	glEnd(); 
	// Back Face 
	glBindTexture(GL_TEXTURE_2D, texture[1]); 
	glBegin(GL_QUADS); 
	glNormal3f( 0.0f, 0.0f,-1.0f); 
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); 
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); 
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 
	glEnd(); 
	// Top Face 
	glBindTexture(GL_TEXTURE_2D, texture[2]); 
	glBegin(GL_QUADS); 
	glNormal3f( 0.0f, 1.0f, 0.0f); 
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); 
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); 
	glEnd(); 
	// Bottom Face 
	glBindTexture(GL_TEXTURE_2D, texture[3]); 
	glBegin(GL_QUADS); 
	glNormal3f( 0.0f,-1.0f, 0.0f); 
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); 
	glEnd(); 
	// Right face 
	glBindTexture(GL_TEXTURE_2D, texture[4]); 
	glBegin(GL_QUADS); 
	glNormal3f( 1.0f, 0.0f, 0.0f); 
	glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 
	glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f); 
	glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 
	glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 
	glEnd(); 
	// Left Face 
	glBindTexture(GL_TEXTURE_2D, texture[5]); 
	glBegin(GL_QUADS); 
	glNormal3f(-1.0f, 0.0f, 0.0f); 
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f); 
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f); 
	glEnd(); 
 
	glPopMatrix(); 
	return TRUE; 
} 
/**************************************************************/ 
 
int main(int argc,char **argv) 
{ 
	char* output="请尝试如下操作:\n旋转Teapot:鼠标左键、中键、右键;\n改变视点的位置:x,X,y,Y,z,Z;\n旋转Cube:4、6、2、8;\n沿z轴平移:+、-\n"; 
	printf("%s\n",output); 
	glutInit(&argc,argv);//初始化GLUT库 
 
	//初始化OpenGL窗口的GLUT库的显示模式, 
    //GLUT_DOUBLE是使用图形双缓冲,GLUT_RGB指定颜色使用RGB三个分量表示, 
	//GLUT_DEPTH指定32bit的深度缓存,深度缓存用来对图形按其到观察者的距离的远近排序,远的先画,近的后画 
	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); 
	glutInitWindowPosition(150, 100);  //设置窗口起始位置 
	//设置显示窗口的初始宽度和高度的象素数 
	glutInitWindowSize(600,600); 
	//创建显示窗口 
	glutCreateWindow("colorcube");	 
	//设置窗口的重绘回调函数,当窗口改变大小(包括第一次显示)、被遮挡后又重新出现时都需要重绘 
	glutReshapeFunc(myReshape); 
	//为当前窗口设置显示图形的回调函数 
	//you should put all the routines you need to redraw the scene in the display callback function. 
	glutDisplayFunc(display); 
	//设置鼠标事件的回调函数以处理鼠标消息 
	glutMouseFunc(mouse); 
	//设置键盘上的ASCII键点击事件的回调函数以处理ASCII键点击消息 
	glutKeyboardFunc(keys); 
	//开启z轴方向上的深度测试机制 
	glEnable(GL_DEPTH_TEST); 
	//开始程序主循环 
	glutMainLoop(); 
	return 0; 
}