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; }