场景漫游

来源:互联网 发布:淘宝卖家客服几点上班 编辑:程序博客网 时间:2024/05/01 21:37

实验三:场景漫游

win8.1+VS2013+GLUT


#include <math.h>#include <glut.h>#include <stdio.h> #include<iostream>  #include <Windows.h>  // Include GLM#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include<vector>using namespace std;#define BMP_Header_Length 54/////设计目标///////////纹理贴图(内侧)√//设置光源//层次建模建立三维模型(桌椅)√//扫面建模(花瓶)//几何变换(放在桌子上)//交互控制及观察√//简单光照明(添加屋顶灯光)//阴影计算//光线跟踪算法,全局光照明//场景漫游√//地球仪(底座、支撑杆、地球)//读取dragon.odj/////////////////////GLfloat EyeX = 5.0;GLfloat EyeY = 0.0;GLfloat EyeZ = 0.0;GLfloat RdegreeX = 0.0;GLfloat RdegreeZ = 0.0;float PI = 3.14159f;static int du=90,oldmy=-1,oldmx=-1; //du是视点绕y轴的角度,opengl里默认y轴是上方向   //场景漫游变量// 追踪观察点的方向static GLfloat s_eye[] = { 17.0,-3.0,0.0 };static GLfloat s_at[] = { 0.0, -3.0,0.0 };static GLfloat s_angle = -180.0;//如果初始角度设置为0则初始面向X轴正方向,设置//为-90面向Z轴负方向,符合默认情况下的设计习惯。float rad;float speed = 0.5;//漫游速度//灯光位置GLfloat position_light[] = {10,2,22};//x,y,z//贴图变量GLint room_ground;//地面GLint room_wall;//墙GLint room_up;//房顶GLint desk;//桌子GLint chair;//椅子GLint map;//地图GLint vase;//花瓶GLint dizuo;//地球仪底座GLint w,h,total_bytes; GLbyte *pixels = 0; GLint last_texture_ID;GLuint texture_ID = 0;//带贴图的正方体void MyCube(float size ,GLint tex){glTranslatef(0.0,0.0,0.0);//整体平移桌子glScalef(size/2, size/2, size/2);//glColor4f(1.0,1.0,1.0,1.0);glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, tex);glPushMatrix();//-zglBegin(GL_POLYGON);              glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, -1.0 );glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, -1.0 );glEnd();//zglBegin(GL_POLYGON);              glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 );glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0, 1.0 );glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, 1.0 );glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0, 1.0 );glEnd();//-yglBegin(GL_POLYGON);              glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0, -1.0, -1.0 );glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0, -1.0,  1.0 );glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, -1.0,  1.0 );glEnd();//yglBegin(GL_POLYGON);              glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0,  1.0, -1.0 );glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0,  1.0, -1.0 );glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0,  1.0 );glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );glEnd();//-xglBegin(GL_POLYGON);              glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0,  1.0, -1.0 );glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0,  1.0,  1.0 );glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, -1.0,  1.0 );glEnd();//xglBegin(GL_POLYGON);              glTexCoord2f( 0.0, 0.0 ); glVertex3f(  1.0, -1.0,-1.0 );glTexCoord2f( 1.0, 0.0 ); glVertex3f(  1.0,  1.0,-1.0 );glTexCoord2f( 1.0, 1.0 ); glVertex3f(  1.0,  1.0, 1.0 );glTexCoord2f( 0.0, 1.0 ); glVertex3f(  1.0, -1.0, 1.0 );glEnd();glPopMatrix();glDisable(GL_TEXTURE_2D);}//贴图练习void DrawMf(void){float xishu=1;//贴图数量比例glRotatef(90.0, 1.0, 0.0, 0.0);glTranslatef(4.0,0.0,0.0 );glColor4f(0,0,0,1.0);glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, room_ground);glPushMatrix();glBegin(GL_POLYGON);              glTexCoord2f( 0, 0.0 ); glVertex3f(  -10.0,10.0, -10.0 );glTexCoord2f( xishu*1.0, 0.0 ); glVertex3f(  10.0,10.0, -10.0 );glTexCoord2f( xishu*1.0, xishu*1.0 ); glVertex3f(  10.0,10.0, 10.0 );glTexCoord2f( 0, xishu*1.0 ); glVertex3f(  -10.0,10.0, 10.0 );glEnd();glPopMatrix();glDisable(GL_TEXTURE_2D);}//屋顶灯void DrawLight(void){glPushMatrix(); glTranslatef(0,0,30); glScalef(8, 8, 0.8); glutSolidCube(1.0);//测试灯光用的立方体glPopMatrix();}//房间void DrawRoom(void){//地面glPushMatrix();glTranslatef(0.0,0.0,-3.0);//整体平移glScalef(80,80,0.2);MyCube(1.0,room_ground);glPopMatrix();//墙//1右glPushMatrix();glTranslatef(40.0,0.0,14.0);//整体平移glScalef(0.2,80,35);MyCube(1.0,room_wall);glPopMatrix();//2左glPushMatrix();glTranslatef(-40.0,0.0,14.0);//整体平移glScalef(0.2,80,35);MyCube(1.0,room_wall);glPopMatrix();/*//3前glPushMatrix();glTranslatef(0.0,-40,14.0);//整体平移glScalef(80,0.2,35);MyCube(1.0,room_wall);glPopMatrix();*///4后glPushMatrix();glTranslatef(0.0,40,14.0);//整体平移glScalef(80,0.2,35);MyCube(1.0,room_wall);glPopMatrix();//房顶glPushMatrix();glTranslatef(0.0,0.0,30.0);//整体平移glScalef(80,80,0.2);MyCube(1.0,room_up);glPopMatrix();}//椅子void DrawChair(void){//glRotatef(90.0, 0.0, 0.0, 1.0);//glScalef(0.8, 0.8, 0.8);//glTranslatef(-6.0,0.0,-3.0);//整体平移glPushMatrix();//腿//glColor4f(1,1,1,1.0);//1glPushMatrix();glTranslatef(-1.5,-1.5,1.5);glScalef(0.2, 0.2, 6);MyCube(1.0,chair);glPopMatrix();//2glPushMatrix();glTranslatef(-1.5,1.5,1.5);glScalef(0.2, 0.2, 6);MyCube(1.0,chair);glPopMatrix();//3glPushMatrix();glTranslatef(1.5,1.5,0);glScalef(0.2, 0.2, 3);MyCube(1.0,chair);glPopMatrix();//4glPushMatrix();glTranslatef(1.5,-1.5,0);glScalef(0.2, 0.2, 3);MyCube(1.0,chair);glPopMatrix();//椅子面glPushMatrix();//glColor4f(0.6,1.0,0.0,1.0);glTranslatef(0.0,0.0,1.5);glScalef(3.4, 3.4, 0.2);MyCube(1.0,chair);glPopMatrix();//椅子靠背glPushMatrix();glTranslatef(-1.5,0.0,3.7);glScalef(0.1, 3.4, 1.5);MyCube(1.0,chair);glPopMatrix();glPopMatrix();}//桌子void DrawDesk(void){glPushMatrix();//桌子腿glTranslatef(0.0,0.0,-3.0);//glColor4f(0.914,0.467,0.192,1.0);//桌子腿的颜色//1glPushMatrix();glTranslatef(3.0,3.0,0.0);glPushMatrix();/*参数1(1.0F)是圆柱体的底面半径,参数2(1.0F)是圆柱体的饿顶面半径,参数3(3.0F)是圆柱体的高度。参数4(32)是纬线(环绕Z轴有多少细分),参数5(32)是经线(沿着Z轴有多少细分)*/gluCylinder(gluNewQuadric(),0.5,0.2,3.0,20,20);glPopMatrix();glPopMatrix();//2glPushMatrix();glTranslatef(-3.0,3.0,0.0);glPushMatrix();gluCylinder(gluNewQuadric(),0.5,0.2,3.0,20,20);glPopMatrix();glPopMatrix();//3glPushMatrix();glTranslatef(-3.0,-3.0,0.0);glPushMatrix();gluCylinder(gluNewQuadric(),0.5,0.2,3.0,20,20);glPopMatrix();glPopMatrix();//4glPushMatrix();glTranslatef(3.0,-3.0,0.0);glPushMatrix();gluCylinder(gluNewQuadric(),0.5,0.2,3.0,20,20);glPopMatrix();glPopMatrix();//桌子面glTranslatef(0.0,0.0,3.0);//glColor4f(0.0,1.0,0.8,1.0);glPushMatrix();glScalef (8.0, 8.0, 0.2);MyCube(1.0,desk);glPopMatrix();glPopMatrix();}//画花瓶//用四边形带画花瓶的一层,该层上底面圆心坐标为(x,y,z),上底面圆的半径为radius_up,下底面圆的半径为radius_down,M表示圆周的被分成多少份,yy_down代表下圆面y值void DrawVase_one(GLfloat xx, GLfloat yy_up, GLfloat zz, GLfloat radius_up, GLfloat radius_down, GLfloat M, GLfloat yy_down, GLfloat tt,GLfloat VaseN,GLint tex){float step_z = 2*PI/M;//角度步长float x[4],y[4],z[4];float angle_z = 0.0;//角度glEnable(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, tex);glBegin(GL_QUADS); for(float i=0; i<M; i++){angle_z = i * step_z;x[0] = radius_up * sin(angle_z);y[0] = yy_up;z[0] = radius_up * cos(angle_z);x[1] = radius_up * sin(angle_z + step_z);y[1] = yy_up;z[1] = radius_up * cos(angle_z + step_z);x[2] = radius_down * sin(angle_z + step_z);y[2] = yy_down;z[2] = radius_down * cos(angle_z + step_z);x[3] = radius_down * sin(angle_z);y[3] = yy_down;z[3] = radius_down * cos(angle_z);glTexCoord2f( i/M, 1-tt/VaseN );glVertex3f(xx+x[0], yy_up+y[0],zz+z[0]);glTexCoord2f( (i+1)/M, 1-tt/VaseN );     glVertex3f(xx+x[1], yy_up+y[1],zz+z[1]);glTexCoord2f( (i+1)/M, 1-(tt+1)/VaseN );glVertex3f(xx+x[2], yy_up+y[2],zz+z[2]);glTexCoord2f( i/M, 1-(tt+1)/VaseN );glVertex3f(xx+x[3], yy_up+y[3],zz+z[3]); }glEnd();glDisable(GL_TEXTURE_2D);}//花瓶void DrawVase(void){float Hight=3;//花瓶高度float VaseY_0;int VaseN=30;//花瓶竖直方向细分数float hh;//Y方向步长float radius_down;float radius_up;VaseY_0=Hight/2;hh=Hight/VaseN;radius_down=VaseY_0;glPushMatrix();glTranslatef(8.0,0,5.5);glRotatef(90, 1.0, 0.0, 0.0);//glColor4f(1,1,1,1.0);glScalef(0.7, 0.8, 0.7);for(int tt=0;tt < VaseN;tt++){radius_up=radius_down;radius_down=VaseY_0-hh*(tt+1);DrawVase_one(0,radius_up,0,0.7*sinf(2*PI*(1-hh*tt/Hight))+1.1,0.7*sinf(2*PI*(1-hh*(tt+1)/Hight))+1.1,200,radius_down-hh,tt,VaseN,vase);}glPopMatrix();}//地球仪void DrawMap(void){float Hight=3;//球体高度float VaseY_0;int VaseN=30;//球体竖直方向细分数float hh;//Y方向步长float radius_down;float radius_up;VaseY_0=Hight/2;hh=Hight/VaseN;radius_down=VaseY_0;glPushMatrix();glRotatef(90.0, 1.0, 0.0, 0.0);glTranslatef(4.0,0.8,-3.0);glScalef(0.5, 0.5, 0.5);//画球体glPushMatrix();//glColor4f(1,1,1,1.0);glScalef(1, 1, 1);glRotatef(45.0, 0.0, 1.0, 0.0);glTranslatef(0.0,9.0,0.0);for(int tt=0;tt < VaseN;tt++){radius_up=radius_down;radius_down=VaseY_0-hh*(tt+1);DrawVase_one(0,radius_up,0,sqrtf(pow(Hight,2)-pow((2*Hight*(1-hh*tt/Hight)-Hight),2)),sqrtf(pow(Hight,2)-pow((2*Hight*(1-hh*(tt+1)/Hight)-Hight),2)),200,radius_down-hh,tt,VaseN,map);}glPopMatrix();//底座glPushMatrix();glScalef(1.2, 0.8, 1.2);glRotatef(0.0, 0.0, 1.0, 0.0);glTranslatef(-0.0,5.0,-0.0);//glColor4f(1,1,1,1.0);DrawVase_one(0,1,0,0,2,200,0,1,1,dizuo);glPopMatrix();//轴glPushMatrix();glScalef(1, 1, 1);glRotatef(0.0, 0.0, 1.0, 0.0);glTranslatef(-0.0,0.0,0.0);//glColor4f(1,1,1,1.0);DrawVase_one(0,5,0,0.1,0.1,100,0,1,1,dizuo);glPopMatrix();glPopMatrix();}//导入OBJ文件函数vector<glm::vec3> vertices;  vector<glm::vec2> uvs;  vector<glm::vec3> normals;  int nodesSize;bool loadOBJ(        const char * path,        std::vector<glm::vec3> & out_vertices,        std::vector<glm::vec2> & out_uvs,        std::vector<glm::vec3> & out_normals){        printf("Loading OBJ file %s...\n", path);        std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;        std::vector<glm::vec3> temp_vertices;        std::vector<glm::vec2> temp_uvs;        std::vector<glm::vec3> temp_normals;        FILE * file = fopen(path, "r");        if( file == NULL ){                printf("Impossible to open the file ! Are you in the right path ? See Tutorial 1 for details\n");                return false;        }        while( 1 ){                char lineHeader[128];                // read the first word of the line                int res = fscanf(file, "%s", lineHeader);                if (res == EOF)                        break; // EOF = End Of File. Quit the loop.                // else : parse lineHeader                if ( strcmp( lineHeader, "v" ) == 0 ){                    //cout<<"Get v"<<endl;                        glm::vec3 vertex;                        fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z );                        temp_vertices.push_back(vertex);                }else if ( strcmp( lineHeader, "vt" ) == 0 ){                    //cout<<"Get vt"<<endl;                        glm::vec2 uv;                        fscanf(file, "%f %f\n", &uv.x, &uv.y );                        uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders.                        temp_uvs.push_back(uv);                }else if ( strcmp( lineHeader, "vn" ) == 0 ){                    //cout<<"Get vn"<<endl;                        glm::vec3 normal;                        fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z );                        temp_normals.push_back(normal);                }else if ( strcmp( lineHeader, "f" ) == 0 ){                    //cout<<"Get f"<<endl;                        std::string vertex1, vertex2, vertex3;                        unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];                        int matches = fscanf(file, "%d//%d %d//%d %d//%d\n", &vertexIndex[0], &normalIndex[0], &vertexIndex[1], &normalIndex[1], &vertexIndex[2], &normalIndex[2]);                          if (matches != 6){                                  printf("File can't be read by our simple parser :-( Try exporting with other options\n");                                  return false;                          }                          vertexIndices.push_back(vertexIndex[0]);                          vertexIndices.push_back(vertexIndex[1]);                          vertexIndices.push_back(vertexIndex[2]);                          normalIndices.push_back(normalIndex[0]);                          normalIndices.push_back(normalIndex[1]);                          normalIndices.push_back(normalIndex[2]);                  }else{                        // Probably a comment, eat up the rest of the line                        char stupidBuffer[1000];                        fgets(stupidBuffer, 1000, file);                }        }        // For each vertex of each triangle        for( unsigned int i=0; i<vertexIndices.size(); i++ ){                // Get the indices of its attributes                unsigned int vertexIndex = vertexIndices[i];                unsigned int normalIndex = normalIndices[i];                // Get the attributes thanks to the index                glm::vec3 vertex = temp_vertices[ vertexIndex-1 ];                glm::vec3 normal = temp_normals[ normalIndex-1 ];                // Put the attributes in buffers                out_vertices.push_back(vertex);                out_normals .push_back(normal);        }        return true;}//画龙void DrawDragon(void){ glPushMatrix();  glTranslatef(4,-3,4);  glRotated(0,0,0,1);  glRotated(90,1,0,0);  glScalef(2.0,2.0,2.0);  int i;glBegin(GL_TRIANGLES);  for(i = 0; i<nodesSize; i++)  {  glNormal3f(normals[i].x, normals[i].y, normals[i].z);  glVertex3f( vertices[i].x, vertices[i].y, vertices[i].z);  }  glEnd();  glPopMatrix();}//实现场景漫游void WalkMan(void){rad = float(PI*s_angle / 180.0f);                    //计算SIN和COS函数中需要的参数。// 观察点s_at[0] = float(s_eye[0] + 100 * cos(rad));s_at[2] = float(s_eye[2] + 100 * sin(rad));s_at[1] = s_eye[1];//观察点可以设置的更远一些,如果设置的更小可能导致不能看到较远的物体,也是通过sin和cos函数实现//向前进方向去设置观察点。// 设置观察点glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(s_eye[0], s_eye[1], s_eye[2],s_at[0], s_at[1], s_at[2],0.0, 1.0, 0.0);}//阴影void pointSourceShadow( double lx, double ly, double lz,     double a, double b, double c, double d, GLfloat M[16]) {     double new_d = d + (a * lx + b * ly + c * lz);     M[0] = 1;            M[4] = 0;            M[8] = 0;             M[12] = 0;     M[1] = 0;            M[5] = 1;            M[9] = 0;             M[13] = 0;     M[2] = 0;            M[6] = 0;            M[10] = 1; M[14] = 0;     M[3]= -a/new_d;  M[7]= -b/new_d;  M[11]= -c/new_d;  M[15] = 0;}void myDisplay(void){GLfloat position0[]={position_light[0],position_light[1],position_light[2],0};//光源位置,最后一位  0:光源类型为方向光glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix();WalkMan();//通过改变摄像机的位置来实现场景漫游//绘制立方体glColor4f(1.0,1.0,1.0,1.0);glRotatef(RdegreeZ, 0.0, 1.0, 0.0);glRotatef(RdegreeX, 1.0, 0.0, 0.0);glColor4f(1.0,1.0,1.0,1.0);glRotatef(-90.0, 1.0, 0.0, 0.0);glTranslatef(-5.0,0.0,-5.0);//整体平移桌子DrawDesk();//桌子glColor4f(1.0,1.0,1.0,1.0);glRotatef(90.0, 0.0, 0.0, 1.0);glScalef(0.8, 0.8, 0.8);glTranslatef(-6.0,0.0,-3.0);//整体平移DrawChair();//椅子glColor4f(1.0,1.0,1.0,1.0);DrawRoom();//房间glColor4f(1.0,1.0,1.0,1.0);DrawMap();//地球仪glColor4f(1,0,0,1.0);DrawDragon();//画龙glColor4f(1.0,1.0,1.0,1.0);DrawVase();//花瓶glColor4f(1.0,1.0,1.0,1.0);DrawLight();//屋顶灯glPushMatrix(); glTranslatef(position_light[0],position_light[1],position_light[2]); glRotated(0,0,0,0); glutSolidCube(1.0);//测试灯光用的立方体glPopMatrix();//阴影GLfloat M[16];double light_x = position_light[0], light_y = position_light[1],light_z = position_light[2];glPushMatrix();glPushMatrix();glDisable( GL_LIGHTING);glDisable(GL_LIGHT0); glColor4f( 0.2, 0.2, 0.2, 0.3);//glMatrixMode(GL_MODELVIEW);//glLoadIdentity();glTranslatef( light_x, light_y, light_z);pointSourceShadow( light_x, light_y, light_z, 0, 0, 1, -3.2, M);            glMultMatrixf( M);glTranslatef( -light_x, -light_y, -light_z);DrawMap();//地球仪DrawVase();//花瓶DrawDragon();//画龙glPopMatrix();//glPushMatrix();//glDisable( GL_LIGHTING);//glDisable(GL_LIGHT0); //glColor4f( 0, 0, 0, 1);////glMatrixMode(GL_MODELVIEW);////glLoadIdentity();//glTranslatef( light_x, light_y, light_z);//pointSourceShadow( light_x, light_y, light_z, 0, 0, 1, 2.5, M);            //glMultMatrixf( M);//glTranslatef( -light_x, -light_y, -light_z);//glPushMatrix();//DrawDesk();//桌子//glPopMatrix();//DrawChair();//椅子//glPopMatrix();glPopMatrix();glEnable(GL_LIGHTING); //启用光源glEnable(GL_LIGHT0);   //使用指定灯光glLightfv(GL_LIGHT0,GL_POSITION,position0);//设置光源位置printf("x=%f \t",position_light[0]); printf("y=%f \t",position_light[1]); printf("z=%f \n",position_light[2]);//输出灯光位置glPopMatrix();glutSwapBuffers();//双缓存刷新}//贴图GLint load_texture(const char *file_name){FILE* pFile = fopen(file_name, "rb"); //读取图片if( pFile == 0 ) {return 0;}fseek(pFile, 0x0012, SEEK_SET);//移动到0x0012位置fread(&w, 4, 1, pFile);//读取宽度fread(&h, 4, 1, pFile);//读取高度fseek(pFile, BMP_Header_Length, SEEK_SET);//跳过BMP头部的54个字节,这些字节我们不用GLuint line_bytes = w * 3;//BMP里一个像素3字节 while( line_bytes % 4 != 0 ) {++line_bytes;}//补齐成4的倍数total_bytes = line_bytes * h;pixels = (GLbyte*)malloc(total_bytes);//分配内存if( pixels == 0 ) {fclose(pFile); return 0; }if( fread(pixels, total_bytes, 1, pFile) <= 0 ) { free(pixels); fclose(pFile); return 0; }glGenTextures(1, &texture_ID);//创建新纹理并标记if( texture_ID == 0 ) { free(pixels); fclose(pFile); return 0; }glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_ID);glBindTexture(GL_TEXTURE_2D, texture_ID);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, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);GLfloat blend[] = {1.0,1.0,1.0,1.0};glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, blend);//最后一个参数必须为GL_BLEND才能实现光照和纹理融合glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);glBindTexture(GL_TEXTURE_2D, last_texture_ID);free(pixels);//释放内存return texture_ID;}//鼠标事件void Mouse(int button, int state, int x, int y) //处理鼠标点击  {      if(state==GLUT_DOWN){ //第一次鼠标按下时,记录鼠标在窗口中的初始坐标          oldmx=x,oldmy=y;  printf("%s \n", "this is mouse");}}  //鼠标移动事件void onMouseMove(int x,int y) //处理鼠标拖动  {  s_angle += (x-oldmx);      oldmx=x,oldmy=y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备  glutPostRedisplay();}  //键盘控制void keyboard(unsigned char key, int x, int y){switch (key){case'q'://printf("%s \n", "this is Q");position_light[0]-=1;//如果按上方向键,沿着转换角度后的方向前进,speed为每次前进的步长,通过sin和cos函数实现沿着现//有角度方向前进。glutPostRedisplay();break;case'w'://printf("%s \n", "this is W");position_light[0]+=1;//如果按上方向键,沿着转换角度后的方向前进,speed为每次前进的步长,通过sin和cos函数实现沿着现//有角度方向前进。glutPostRedisplay();break;case's'://printf("%s \n", "this is S");position_light[1]+=1;//如果按上方向键,沿着转换角度后的方向前进,speed为每次前进的步长,通过sin和cos函数实现沿着现//有角度方向前进。glutPostRedisplay();break;case'a'://printf("%s \n", "this is A");position_light[1]-=1;glutPostRedisplay();break;case'd':printf("%s \n", "this is D");glutPostRedisplay();break;case'z'://printf("%s \n", "this is Z");position_light[2]-=1;glutPostRedisplay();break;case'x'://printf("%s \n", "this is X");position_light[2]+=1;glutPostRedisplay();break;default:break;}}//键盘方向键控制void mySpecial(int key, int x, int y){switch (key){case GLUT_KEY_UP://printf("%s \n", "this is up");//RdegreeX += 5.0;s_eye[2] += (float)sin(rad) * speed;s_eye[0] += (float)cos(rad) * speed;//如果按上方向键,沿着转换角度后的方向前进,speed为每次前进的步长,通过sin和cos函数实现沿着现//有角度方向前进。glutPostRedisplay();break;case GLUT_KEY_DOWN://printf("%s \n", "this is down");//RdegreeX -= 5.0;s_eye[2] -= (float)sin(rad) * speed;s_eye[0] -= (float)cos(rad) * speed;//如果按下方向键,沿着转换角度后的方向后退,speed为每次前进的步长,通过sin和cos函数实现沿着现//有角度方向前进。glutPostRedisplay();break;case GLUT_KEY_LEFT://printf("%s \n", "this is left");//RdegreeZ += 5.0;s_angle -= 2.0;                        //每按一次左键,旋转2度。glutPostRedisplay();break;case GLUT_KEY_RIGHT://printf("%s \n", "this is right");//RdegreeZ -= 5.0;s_angle += 2.0;                       //每按一次右键,旋转2度。glutPostRedisplay();break;}}//初始化函数void init(){//更改清屏颜色glClearColor(0.0, 0.0, 0.0, 0.0);//黑色glClearDepth(1.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(75,1,0.1,1000);//视景体(摄像机)参数:60度+长宽比=1+近点=1+远点=100glMatrixMode(GL_MODELVIEW);glLoadIdentity();WalkMan();glEnable(GL_DEPTH_TEST);//隐藏面消除//贴图图片room_ground = load_texture("地板.bmp"); room_wall= load_texture("墙.bmp"); room_up=load_texture("屋顶.bmp"); desk= load_texture("木纹_桌子.bmp"); chair= load_texture("木纹_椅子.bmp"); map= load_texture("地图.bmp"); vase= load_texture("花瓶.bmp"); dizuo=load_texture("底座.bmp"); //材质GLfloat diffuseMaterial[]={0.5,0.5,0.5,1.0};GLfloat mat_specular[]={1.0,1.0,1.0,1.0};glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuseMaterial);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialf(GL_FRONT,GL_SHININESS,25.0);glEnable(GL_COLOR_MATERIAL);//启动颜色追踪//灯光glShadeModel(GL_SMOOTH);//GL_SMOOTH:光滑明暗处理//glEnable(GL_BLEND);//启用颜色混合//设置普通灯光照0位置及参数GLfloat position0[]={position_light[0],position_light[1],position_light[2],1};/*光源位置,最后一位  0:方向光(线光源)  1:无方向(点光源)position的第四个分量如果是0,那么光源就是directional的,postion值实际是一个向量;否则这个光源就是postional,position就是他的位置。光源的位置和方向都会受ModelView Matrix的影响。*/GLfloat light0s[]={1,1,1,1};//RGBA下的镜面光GLfloat light0d[]={1,1,1,1};//RGBA下的漫反射光GLfloat light0a[]={1,1,1,1};//RGBA下的环境光GLfloat light_Model_Ambient[]={0.2,0.2,0.2,1.0};glLightModelfv( GL_LIGHT_MODEL_AMBIENT , light_Model_Ambient ); //设置全局环境光的方法glLightfv(GL_LIGHT0,GL_POSITION,position0);//设置光源位置glLightfv(GL_LIGHT0,GL_SPECULAR,light0s);glLightfv(GL_LIGHT0,GL_DIFFUSE,light0d);glLightfv(GL_LIGHT0,GL_AMBIENT,light0a);//聚光灯参数设置//glLightf( GL_LIGHT0,GL_SPOT_CUTOFF , 45.0 );//灯锥张角//GLfloat spot_direction[]={ 0.0 , 0.0 , -1.0 };//聚光灯朝向//glLightfv( GL_LIGHT0 , GL_SPOT_DIRECTION , spot_direction );//glLightf( GL_LIGHT0 , GL_SPOT_EXPONENT , 0 );//设置聚光指数 聚光指数控制光的集中程度,光锥中心的光强最大,越靠边的光强越小。缺省时为0,即均匀照射。glEnable(GL_LIGHTING); //启用光源glEnable(GL_LIGHT0);   //使用指定灯光//glDisable(GL_LIGHTING); //关闭光源}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);glutInitWindowPosition(300, 50);glutInitWindowSize(600, 600);glutCreateWindow("hp_CG_03_三维场景");init();glutDisplayFunc(&myDisplay);glutKeyboardFunc(keyboard);glutMouseFunc(Mouse);  glutMotionFunc(onMouseMove);  glutSpecialFunc(mySpecial);//导入OBJ文件bool res = loadOBJ("dragon.obj", vertices, uvs, normals);      cout<<vertices.size()<<endl;  nodesSize = vertices.size();glutMainLoop();return 0;}

0 0
原创粉丝点击