当前位置:文档之家› 图形学场景设计

图形学场景设计

图形学场景设计计算机图形学课程设计报告题目自然场景设计院(系、部)专业班级学号姓名成绩1 设计目的与要求1.1设计题目自然场景设计1.2 设计目的以小组合作的方式绘制一个自然场景,给绘制的实体添加纹理光照效果,进一步巩固所学知识,提高团队合作能力1.3 设计要求(1)采用真实感图形学技术设计一个自然场景(2)模拟出水、云、山体等至少三种景物(3)实现场景的漫游(4)对设计出的图像进行光照处理(5)将图片的纹理贴附到物体表面2 总体设计2.1 功能简介创建一个900*600的Windows窗口,在窗口中显示冰箱、电灯、茶壶三个实体,根据电灯位置在地面上绘制个实体的投影;为茶壶添加纹理;利用键盘的方向键控制冰箱旋转,实现场景漫游2.2 功能模块图主初始化实体绘键盘操作函数电灯冰箱茶壶2.3 软件各模块功能介绍2.3.1冰箱和茶壶的绘制由四边形拼接出冰箱,通过平移旋转函数放置到指定位置,同时实现茶壶的绘制,在茶壶上添加纹理效果,通过平移旋转变换放置到冰箱上面2.3.2顶灯的绘制绘制出一个带灯罩的电灯,并且将光源放置在灯泡的位置2.3.3 设置光照设置光照的各种参数,为场景添加光照效果,让实体具有立体效果2.3.4 纹理图片生成用数组存储一幅自己设计的纹理图片,方便实体添加纹理效果时的调用2.3.5 影子生成根据需求为场景中的实体添加阴影效果,使得场景效果更加逼真2.3.6 法向量设置为场景设置法向量,确保实体在不同的角度都能被看到3 详细设计及关键代码3.1 光照模块详细设计3.1.1 光照设置功能设置光照的各种参数,为场景添加光照效果,让实体具有立体效果3.1.2 光照设置设计1>设置光照的初值包括:环境光照强度、漫反射光照强度、镜面反射光照强度、光源位置2>在实体绘制函数中开启光照效果3.1.3 具体代码实现GLfloat ambientLight[] = { 0.3f, 0.3f, 1.3f, 1.0f };GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat lightPos[] = { 346.0f, 400.0f, -20.0f, 0.0f };GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };void light(void)//光照函数{GLfloat points[3][3] = { { -30.0f, -149.0f, -400.0f },{ -30.0f, -149.0f, -420.0f },{ 40.0f, -149.0f, -420.0f } };glEnable(GL_DEPTH_TEST);glMatrixMode(GL_PROJECTION);glFrontFace(GL_CCW); // Counter clock-wise polygons face outglEnable(GL_CULL_FACE);glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambientLight);glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuseLight);glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,75);glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);glLightfv(GL_LIGHT0,GL_SPECULAR,specular);glLightfv(GL_LIGHT0,GL_POSITION,lightPos);glEnable(GL_LIGHT0);glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);glMaterialfv(GL_FRONT, GL_SPECULAR, specref);glMateriali(GL_FRONT, GL_SHININESS, 128);glClearColor(0.4f, 0.3f, 0.6f, 1.0f);glDepthFunc(GL_LESS);glEnable(GL_AUTO_NORMAL);glEnable(GL_NORMALIZE);glFrontFace(GL_CW);}3.1.4 光照设置限制条件光源位置设置必须在预先设置好的空间中3.2 纹理模块设置3.2.1 纹理设置模块功能用数组存储一幅自己设计的纹理图片,通过设置对应坐标在指定的实体上添加纹理效果3.2.2 纹理添加模块设计1>.利用三维数组存储纹理图片中每个点的颜色值,在给实体添加纹理时调用纹理图片生成函数,将三维数组中存储的纹理图案添加到实体上2>.从文件中读取一张图片,按照需要将纹理图片添加到对应的实体上3.2.3 纹理添加模块数据结构描述1>. 所用数据结构为一个三维数组,用于存储纹理图片的每点颜色值2>.文件存储纹理图片3.2.4 纹理添加模块具体实现代码1>.纹理图片自己绘制void Get_Mandeldrot_image(void)//生成纹理图片{double min_a,max_a,min_b,max_b,step_a,step_b,a,b;int n=64,x,y,k,t; //n=180 for a Julia setfloat scale=255.0/n,width=300,height=400;for (x=0; x<width; x++){//b=min_b;for ( y=0; y<height; y++){ k=(x/80+2)%2;t=(y/50+2)%2;if(t==0&&k==0){Mandelbrot_image[x][y][0]=255;Mandelbrot_image[x][y][1]=255;Mandelbrot_image[x][y][2]=0;}else{Mandelbrot_image[x][y][0]=255;Mandelbrot_image[x][y][1]=0;Mandelbrot_image[x][y][2]=255;}}}}给实体添加纹理glPushAttrib(GL_ALL_ATTRIB_BITS);glGenTextures(1, &Texture);glBindTexture(GL_TEXTURE_2D, Texture);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);Get_Mandeldrot_image();glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 300, 400, 0, GL_RGB, GL_UNSIGNED_BYTE, Mandelbrot_image);glEnable(GL_TEXTURE_2D);glMatrixMode(GL_TEXTURE);glMatrixMode(GL_MODELVIEW);glColor3f(1.0,1.0,0.00);//glRotatef(90, 1.0f, 0.0f, 0.0f);glTranslated(0.0f,118.0f, -40.0f);glutSolidTeapot(15);//绘制茶壶glPopAttrib();2>.纹理图片由文件读入AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图图象{FILE *File=NULL; // 文件句柄if (!Filename){return NULL;}File=fopen(Filename,"abc");if (File){fclose(File);return auxDIBImageLoadA(Filename);}return NULL; }int LoadGLTextures(){int Status=FALSE;AUX_RGBImageRec *TextureImage[1];memset(TextureImage,0,sizeof(void *)*1);if (TextureImage[0]=LoadBMP("menu.bmp")){Status=TRUE;glGenTextures(1, &texture[0]);glBindTexture(GL_TEXTURE_2D, texture[0]);// 生成纹理glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线形滤波}if (TextureImage[0]) {if (TextureImage[0]->data){free(TextureImage[0]->data); }free(TextureImage[0]);}return Status; // 返回 Status}3.2.5 纹理添加模块限制条件纹理图片添加时应注意比例3.3 法向量设置模块3.3.1 法向量设置模块功能为场景设置法向量,确保实体在不同的角度都能被看到3.3.2 法向量设置模块设计首先用两个点算出一个向量,用同样的方法计算出另外一个向量,对求的的两个向量做笛卡尔积求出平面的法向量3.3.2 法向量设置模块数据结构利用数组存储每个点的坐标值3.3.4 法向量设置模块具体实现代码void calcNormal(float v[3][3], float out[3]){float v1[3], v2[3];static const int x = 0;static const int y = 1;static const int z = 2;// Calculate two vectors from the three pointsv1[x] = v[0][x] - v[1][x];v1[y] = v[0][y] - v[1][y];v1[z] = v[0][z] - v[1][z];v2[x] = v[1][x] - v[2][x];v2[y] = v[1][y] - v[2][y];v2[z] = v[1][z] - v[2][z];// Take the cross product of the two vectors to get // the normal vector which will be stored in outout[x] = v1[y] * v2[z] - v1[z] * v2[y];out[y] = v1[z] * v2[x] - v1[x] * v2[z];out[z] = v1[x] * v2[y] - v1[y] * v2[x];// Normalize the vector (shorten length to one)ReduceToUnit(out);}3.4 影子生成模块详细设计3.4.1 影子生成模块功能根据需求为场景中的实体添加阴影效果,使得场景效果更加逼真3.4.2 影子生成模块设计将所需要添加阴影效果的实体与投影面做求交运算,得到一个边界,将这个区域填充为黑色实现阴影效果3.4.3 影子生成模块具体实现代码void DrawJet(BOOL bShadow){float normal[3]; // Storeage for calculated surface normal// Nose Cone /////////////////////////////// Set material color, note we only have to set to black// for the shadow onceif (!bShadow)glColor3ub(0, 255, 200);Else设置填充颜色为黑色glColor3ub(0, 0, 0);实体各点坐标}3.5 顶灯绘制模块3.5.1 顶灯绘制模块功能绘制出一个带灯罩的电灯,并且将光源放置在灯泡的位置3.5.2 顶灯绘制模块设计1>.灯泡的绘制调用OpenGL库函数glutSolidSphere()绘制一个球并为其添加颜色2>.灯罩绘制和电线绘制调用OpenGl库函数glBegin(GL_QUADS)绘制一个独立填充四边形为其设置颜色,通过平移变换放置到合适位置,电线绘制与灯罩绘制方法类似3.5.3 顶灯绘制模块具体实现代码void draw_lamp()//绘制电灯{glColor3f(.0f,.0f,.0f);glBegin(GL_QUADS);//电线glVertex3f(345,500,-200);glVertex3f(347,500,-200);glVertex3f(347,380,-200);glVertex3f(345,380,-200);glEnd();glColor3f(.0f,1.0f,.0f);//灯罩//glBegin(GL_TRIANGLES);glBegin(GL_QUADS);glVertex3f(347,380,-200);glVertex3f(367,360,-200);glVertex3f(325,360,-200);glVertex3f(345,380,-200);glEnd();glColor3f(2.0f,2.0f,.0f);//灯泡glTranslated(346.0f, 362.0f, -200.0f);glScalef(0.4,0.4,0.4);glutSolidSphere(25.0f, 10, 10);}3.5.4 顶灯绘制模块限制条件绘制实体时应该注意绘制的先后顺序,最先绘制的实体将遮挡后面绘制的实体3.6 冰箱和茶壶绘制模块3.6.1 冰箱茶壶绘制模块功能由四边形拼接出冰箱,通过平移旋转函数放置到指定位置,同时实现茶壶的绘制,在茶壶上添加纹理效果,通过平移旋转变换放置到冰箱上面3.6.2 冰箱茶壶绘制模块设计1>.冰箱绘制调用OpenGL库函数glBegin(GL_QUADS)根据设计要求绘制独立填充四边形,由多个四边形组合成冰箱2>.茶壶绘制调用OpenGL库函数glutSolidTeapot( );绘制一个茶壶,通过平移旋转变换放置到指定位置3.6.3 冰箱茶壶绘制模块具体实现代码绘制冰箱void draw_refrigerator()//绘制冰箱{glPushMatrix();glColor3f( 0.0f,1.0f,0.0f);glTranslated(210.0f, 230.0f, -40.0f);glScalef(0.6,0.6,0.6);glRotatef(yRot, 0.0f, 1.0f, 0.0f);glutSolidTeapot(12);//绘制茶壶glPopMatrix();glPushMatrix();glColor3f(.0f,.0f,.0f);glBegin(GL_LINES);glVertex3f(210.0f, 230.0f, -40.0f); glVertex3f(165,200,-50);glVertex3f(210.0f, 230.0f, -40.0f); glVertex3f(215,200,-50);glVertex3f(210.0f, 230.0f, -40.0f); glVertex3f(190,210,-90);glVertex3f(210.0f, 230.0f, -40.0f); glVertex3f(240,210,-90);glEnd();glColor3f(.0f,.0f,.0f);glBegin(GL_QUADS);glVertex3f(165,100,-50);glVertex3f(165,102,-50);glVertex3f(215,102,-50);glVertex3f(215,100,-50);glEnd();glColor3f(.0f,.0f,.0f);glBegin(GL_QUADS);glVertex3f(165,130,-50); glVertex3f(165,132,-50); glVertex3f(215,132,-50); glVertex3f(215,130,-50); glEnd();glColor3f(2.0f,2.0f,2.0f); glBegin(GL_QUADS);glVertex3f(185,180,-50); glVertex3f(190,180,-50); glVertex3f(190,165,-50); glVertex3f(185,165,-50); glEnd();glColor3f( 0.5f,0.5f,1.0f); glBegin(GL_QUADS);glVertex3f(165,30,-50); glVertex3f(165,200,-50); glVertex3f(215,200,-50); glVertex3f(215,30,-50); glEnd();glColor3f( 1.0f,1.0f,1.0f); glBegin(GL_QUADS);glVertex3f(165,200,-50); glVertex3f(190,210,-50); glVertex3f(240,210,-50); glVertex3f(215,200,-50);glEnd();glBegin(GL_QUADS);glVertex3f(240,210,-50);glVertex3f(240,50,-50);glVertex3f(215,30,-50);glVertex3f(215,200,-50);glEnd(); glPopMatrix();}3.6.4 冰箱茶壶绘制模块限制条件绘制四边形时四个顶点的先后顺序需要根据法向量的方向设置3.7 场景顶视图壁画 电视 窗户 太阳 床头柜冰箱 球 桌子灯4 程序生成界面图形5 参考文献[1] 杨钦,徐永安,翟红英. 计算机图形学[M].北京:清华大学出版社,2005,03(1):70-173。

相关主题