高级计算机图形学 讲授 : 董兰芳研究方向 : 科学计算可视化图形 图像处理模式识别 Telephone:0551-3603484 Email:lfdong@ustc.edu.cn Homepage: http://staff.ustc.edu.cn/~lfdong 中国科学技术大学视觉计算与可视化实验室 1
第四章几何对象和变换 (3)( 4.5 OpenGL 中的标架 4.6 建模一个彩色立方体 4.7 OpenGL 中几何变换 4.8 虚拟跟踪球 2
4.5 OpenGL 中的标架 对象坐标系或建模坐标系 世界坐标系 照相机坐标系 裁剪坐标系 规范化的设备坐标系 窗口坐标系或者屏幕坐标系 3
4.5 OpenGL 中的标架 4
4.5 OpenGL 中的标架 世界坐标系下的表示到照相机坐标系下的表示的变换矩阵 : 5
第四章几何对象和变换 (3)( 4.5 OpenGL 中的标架 4.6 建模一个彩色立方体 4.7 OpenGL 中几何变换 4.8 虚拟跟踪球 6
4.6.1 建模立方体的面 void polygon(int a, int b, int c, int d) GLfloat vertices[][3] = { glbegin(gl_polygon); {{-1.0,-1.0,-1.0}, glcolor3fv(colors[a]); {1.0,-1.0,-1.0},{1.0,1.0,-1.0}, glnormal3fv(normals[a]); {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0}, glvertex3fv(vertices[a]); {1.0,-1.0,1.0}, {1.0,1.0,1.0}, glcolor3fv(colors[b]); {-1.0,1.0,1.0}}; glnormal3fv(normals[b]); glvertex3fv(vertices[b]); GLfloat colors[][3] = glcolor3fv(colors[c]); {{0.0,0.0,0.0},{1.0,0.0,0.0}, glnormal3fv(normals[c]); {1.0,1.0,0.0}, {0.0,1.0,0.0}, glvertex3fv(vertices[c]); {0.0,0.0,1.0},{1.0,0.0,1.0}, glcolor3fv(colors[d]); 1.0,1.0,1.0}, {0.0,1.0,1.0}}; glnormal3fv(normals[d]); glvertex3fv(vertices[d]); glend();} 7
4.6.2 向内和向外的面 8
4.6.3 对象表示的数据结构 9
4.6.4 彩色立方体 void polygon(int a, int b, int c, int d) GLfloat vertices[][3] = {{-1.0,-1.0,-1.0}, { glbegin(gl_polygon); glcolor3fv(colors[a]); {1.0,-1.0,-1.0},{1.0,1.0,-1.0}, glnormal3fv(normals[a]); void colorcube(void) {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0}, glvertex3fv(vertices[a]); { polygon(0,3,2,1); {1.0,-1.0,1.0}, {1.0,1.0,1.0}, glcolor3fv(colors[b]); polygon(2,3,7,6); {-1.0,1.0,1.0}}; glnormal3fv(normals[b]); polygon(0,4,7,3); glvertex3fv(vertices[b]); polygon(1,2,6,5); glcolor3fv(colors[c]); GLfloat colors[][3] = polygon(4,5,6,7); glnormal3fv(normals[c]); {{0.0,0.0,0.0},{1.0,0.0,0.0}, polygon(0,1,5,4); glvertex3fv(vertices[c]); {1.0,1.0,0.0}, {0.0,1.0,0.0}, } glcolor3fv(colors[d]); {0.0,0.0,1.0},{1.0,0.0,1.0}, glnormal3fv(normals[d]); 1.0,1.0,1.0}, {0.0,1.0,1.0}}; glvertex3fv(vertices[d]); glend();} 10
4.6.5 双线性插值 11
4.6.6 顶点数组 GLfloat vertices[][3] = {{-1.0,-1.0,-1.0}, {1.0,-1.0,-1.0},{1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0}, {1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}}; GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0}, {1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0},{1.0,0.0,1.0}, 1.0,1.0,1.0}, {0.0,1.0,1.0}}; GLubyte cubeindices[]={ 0,3,2,1, 2,3,7,6, 0,4,7,3, 1,2,6,5, 4,5,6,7, 0,1,5,4}; glvertexpointer(3,gl_float, 0, vertices); glcolorpointer(3,gl_float, 0, colors); gldrawelements(gl_quads,24, GL_UNSIGNED_BYTE, cubeindices); 12
第四章几何对象和变换 (3)( 4.5 OpenGL 中的标架 4.6 建模一个彩色立方体 4.7 OpenGL 中几何变换 4.8 虚拟跟踪球 13
4.7 OpenGL 中的几何变换 当前变换矩阵 CTM: 14
4.7 OpenGL 中的几何变换 OpenGL 的矩阵操作指定一个 4*4 的建模观察矩阵为当前矩阵 OpenGL 中的 4 种矩阵模式 : 建模观察模式, 允许保存 32 个矩阵投影模式纹理模式颜色模式 OpenGl 按照列优先次序存储矩阵元素 15
4.7 OpenGL 中的几何变换 旋转 平移和缩放 : glrotatef(angle,vx,vy,vz); gltranslatef(dx,dy,dz); glscalef(sx,sy,sz); glloadmatrixf(pointer_to_matrix); glloadidentity(); 16
4.7 OpenGL 中的几何变换 在 OpenGL 中实现具有任意不动点的旋转 : glmatrixmode(gl_modelview); glloadidentity(); gltranslatef(4.0,5.0,6.0); glrotatef(45.0,1.0,2.0,3.0); gltranslatef(-4.0,-5.0,-6.0); 17
4.7 OpenGL 中的几何变换 变换的顺序 : C<-I C<-CT(4.0,5.0,6.0) C<-CR(45.0,1.0,2.0,3.0) C<-CT(-4.0,-5.0,-6.0) C=T(4.0,5.0,6.0)R(45.0,1.0,2.0,3.0) T(-4.0,-5.0,-6.0) 18
4.7 OpenGL 中的几何变换 glulookat(eyex, eyey, eyez, /* 视点 */ atx, aty, atz, /* 参考点 */ upx, upy, upz); /* 观察正向 */ 19
4.7 OpenGL 中的几何变换 例 : glcolor3f (0.0, 0.0, 1.0); glrecti (50, 100, 200, 150); // Display blue rectangle. glcolor3f (1.0, 0.0, 0.0); gltranslatef (-200.0, -50.0, 0.0); // Set translation parameters. glrecti (50, 100, 200, 150); // Display red, translated rectangle. glloadidentity ( ); // Reset current matrix to identity. glrotatef (90.0, 0.0, 0.0, 1.0); // Set 90-deg. rotation about z axis. glrecti (50, 100, 200, 150); // Display red, rotated rectangle. glloadidentity ( ); // Reset current matrix to identity. glscalef (-0.5, 1.0, 1.0); // Set scale-reflection parameters. glrecti (50, 100, 200, 150); // Display red, transformed rectangle. 20
4.7 OpenGL 中的几何变换 例 : glmatrixmode (GL_MODELVIEW); glcolor3f (0.0, 0.0, 1.0); // Set current color to blue. glrecti (50, 100, 200, 150); // Display blue rectangle. glpushmatrix ( ); // Make copy of identity (top) matrix. glcolor3f (1.0, 0.0, 0.0); // Set current color to red. gltranslatef (-200.0, -50.0, 0.0); // Set translation parameters. glrecti (50, 100, 200, 150); // Display red, translated rectangle. glpopmatrix ( ); // Throw away the translation matrix. glpushmatrix ( ); // Make copy of identity (top) matrix. glrotatef (90.0, 0.0, 0.0, 1.0); // Set 90-deg. rotation about z axis. glrecti (50, 100, 200, 150); // Display red, rotated rectangle. glpopmatrix ( ); // Throw away the rotation matrix. glscalef (-0.5, 1.0, 1.0); // Set scale-reflection parameters. glrecti (50, 100, 200, 150); // Display red, transformed rectangle. 21
4.7 OpenGL 中的几何变换 立方体的旋转 : glutdisplayfunc(display); glutidlefunc(spincube); glutmousefunc(mouse); void spincube() { theta[axis] += 2.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0; glutpostredisplay(); } void display(void) { glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); glloadidentity(); glulookat(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0); gltranslatef(0.0, 3.0, 0.0); glrotatef(theta[0], 1.0, 0.0, 0.0); glrotatef(theta[1], 0.0, 1.0, 0.0); glrotatef(theta[2], 0.0, 0.0, 1.0); glcolorpointer(3,gl_float, 0, colors); gldrawelements(gl_quads, 24, GL_UNSIGNED_BYTE, cubeindices); glutswapbuffers(); } 22
4.7 OpenGL 中的几何变换 立方体的旋转变换矩阵的加载 进栈和出栈 : glloadmatrixf(myarray) glmultmatrixf(myarray) Glfloat m[4][4]; Glfloat myarray[16]; glpushmatrix(); gltranslatef( ); gltranslatef( ); gltranslatef( ); glpopmatrix(); for(i=0;i<3;i++) for(j=0;j<3;j++) myarray[4*j+i]=m[i][j]; 23
第四章几何对象和变换 (3)( 4.5 OpenGL 中的标架 4.6 建模一个彩色立方体 4.7 OpenGL 中的几何变换 4.8 虚拟跟踪球 24
4.8 虚拟跟踪球 25
4.8 虚拟跟踪球 int float bool bool bool winwidth, winheight; angle = 0.0, axis[3], trans[3]; trackingmouse = false; redrawcontinue = false; trackballmove = false; main(int argc, char **argv) { glutinit(&argc, argv); glutinitdisplaymode(glut_double GLUT_RGB GLUT_DEPTH); glutinitwindowsize(500, 500); glutcreatewindow("colorcube"); glutreshapefunc(myreshape); glutdisplayfunc(display); glutidlefunc(spincube); glutmousefunc(mousebutton); glutmotionfunc(mousemotion); glenable(gl_depth_test); glmatrixmode(gl_projection); glloadidentity(); glortho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); glmatrixmode(gl_modelview); glutmainloop(); } 26
4.8 虚拟跟踪球 void display(void) { glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); /* view transform */ //glpushmatrix(); if (trackballmove) { glrotatef(angle, axis[0], axis[1], axis[2]); } colorcube(); //glpopmatrix(); glutswapbuffers(); } void mousebutton(int button, int state, int x, int y) { if(button==glut_right_button) exit(0); if(button==glut_left_button) switch(state) { case GLUT_DOWN: y=winheight-y; startmotion( x,y); break; case GLUT_UP: stopmotion( x,y); break; } } 27
4.8 虚拟跟踪球 startmotion(int x, int y) { } trackingmouse = true; redrawcontinue = false; startx = x; starty = y; curx = x; cury = y; trackball_ptov(x, y, winwidth, winheight, lastpos); trackballmove=true; stopmotion(int x, int y) { trackingmouse = false; if (startx!= x starty!= y) { redrawcontinue = true; } else { angle = 0.0F; redrawcontinue = false; trackballmove = false; } } 28
4.8 虚拟跟踪球 mousemotion(int x, int y) { float curpos[3], dx, dy, dz; trackball_ptov(x, y, winwidth, winheight, curpos); if(trackingmouse) {dx = curpos[0] - lastpos[0]; dy = curpos[1] - lastpos[1]; dz = curpos[2] - lastpos[2]; if (dx dy dz) { angle = 90.0F * sqrt(dx*dx + dy*dy + dz*dz); axis[0] = lastpos[1]*curpos[2] - lastpos[2]*curpos[1]; axis[1] = lastpos[2]*curpos[0] - lastpos[0]*curpos[2]; axis[2] = lastpos[0]*curpos[1] - lastpos[1]*curpos[0]; lastpos[0] = curpos[0]; lastpos[1] = curpos[1]; lastpos[2] = curpos[2]; }} glutpostredisplay();} 29
4.8 虚拟跟踪球 trackball_ptov(int x, int y, int width, int height, float v[3]) { float d, a; /* project x,y onto a hemi-sphere centered within width, height */ v[0] = (2.0F*x - width) / width; v[1] = (height - 2.0F*y) / height; d = (float) sqrt(v[0]*v[0] + v[1]*v[1]); v[2] = (float) cos((m_pi/2.0f) * ((d < 1.0F)? d : 1.0F)); a = 1.0F / (float) sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] *= a; v[1] *= a; v[2] *= a; } 30
第四章几何对象和变换 (3)( 4.5 OpenGL 中的标架 4.6 建模一个彩色立方体 4.7 OpenGL 中几何变换 4.8 虚拟跟踪球 31