CS184.1X 计算机图形学导论 第8讲 学习笔记
L8V1:OPENGL 2:几何
1.基本的几何设置
1 const int numobjects = 2;//物体对象的数量 2 const int numperobj = 3; 3 const int ncolors = 4; 4 GLunit buffers[numperobj*numobjects+ncolors];//缓存 5 GLunit objects[numobjects]; 6 GLenum PrimType[numobjects]; 7 GLsizei NumElems[numobjects]; 8 9 10 #define BUFFER_OFFSET(bytes) ((GLubyte *) NULL + (bytes)) 11 #define NumberOf(array) (sizeof(array)/sizeof(array[0])) 12 enum {Vertices, Colors, Elements}; 13 enum {FLOOR, CUBE};
2.长方体的几何
1 const GLfloat wd = 0.1; 2 const GLfloat ht = 0.5; 3 const GLfloat _cubecol[4][3] = { 4 {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 1.0, 0.0} }; 5 const GLfloat cubeverts[8][3] = { 6 {-wd, -wd, 0.0}, {-wd, wd, 0.0}, {wd, wd, 0.0}, {wd, -wd, 0.0}, 7 {-wd, -wd, ht}, {wd, -wd, ht}, {wd, wd, ht}, {-wd, wd, ht} }; 8 GLfloat cubecol[8][3]; 9 const GLubyte cubeinds[6][4] = { 10 {0, 1, 2, 3},//BOTTOM 11 {4, 5, 6, 7},//TOP 12 {0, 4, 7, 1},//LEFT 13 {0, 3, 5, 4},//FRONT 14 {3, 2, 6, 5},//RIGHT 15 {1, 7, 6, 2},//BACK 16 };
3.长方体的初始化(颜色除外)
1 void initobjectnocol(GLunit object, GLfloat * vert, GLint sizevert, GLubytes * inds, GLint sizeinds, GLenum type){ 2 int offset = object * numperobj ; 3 glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ; 4 glBufferData(GL_ARRAY_BUFFER, sizevert, vert,GL_STATIC_DRAW); 5 glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ; 6 glEnableClientState(GL_VERTEX_ARRAY) ; 7 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,buffers[Elements+offset]) ; 8 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeind, inds, GL_STATIC_DRAW); 9 PrimType[object] = type ; 10 NumElems[object] = sizeind ; 11 }
4.颜色设置
1 // Simple function to init a bunch of color buffers for the cube 2 void initcolorscube (void) { 3 int base = numobjects * numperobj ; 4 for (int i = 0 ; i < ncolors ; i++) { 5 for (int j = 0 ; j < 8 ; j++) 6 for (int k = 0 ; k < 3 ; k++) 7 cubecol[j][k] = _cubecol[i][k] ; 8 glBindBuffer(GL_ARRAY_BUFFER, buffers[base+i]) ; 9 glBufferData(GL_ARRAY_BUFFER, sizeof(cubecol), cubecol ,GL_STATIC_DRAW); 10 glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ; 11 glEnableClientState(GL_COLOR_ARRAY) ; } 12 } 13 14 //in init 15 initobjectnocol(CUBE, (GLfloat *) cubeverts, sizeof(cubeverts), (GLubyte *) cubeinds, sizeof(cubeinds), GL_QUADS);
5.绘制
1 // And a function to draw with them, similar to drawobject but with color 2 void drawcolor(GLuint object, GLuint color) { 3 int offset = object * numperobj ; 4 int base = numobjects * numperobj ; 5 glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]) ; 6 glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ; 7 glEnableClientState(GL_VERTEX_ARRAY) ; 8 glBindBuffer(GL_ARRAY_BUFFER, buffers[base+color]) ; // Set color 9 glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)) ; 10 glEnableClientState(GL_COLOR_ARRAY) ; 11 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ; 12 glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNEND_BYTE, BUFFER_OFFET(0)); 13 }
L8V2:OPENGL 2:矩阵堆栈
1.OpenGL顶点变换流程概要
2. 绘制顺序会影响物体前后关系;
L8V3:OPENGL 2:Z 缓冲
1.引入的目的:解决消除隐藏体的问题
2.双缓冲
1)思想:把全部场景或全部几何绘制在一个后面的缓存中,它不显示在屏幕上,当绘制完后,直接交换两个缓存,这样,整个屏幕将被同时刷新,不用等待一个物体绘制完后再画另一个物体。
2)代码:
1 glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 2 3 ... 4 5 glutSwapBuffers() ; 6 glFlush();
3)打开深度检测:对于每一个像素点,存储离摄像头最近的Z值
1 //in display() 2 gluInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); 3 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4 5 //in init() 6 glEnable (GL_DEPTH_TEST); 7 glDepthFunc (GL_LESS);
L8V4:OPENGL 2:动画
1.茶壶绘制
1 void display(){ 2 3 ... 4 5 // ** NEW ** Put a teapot in the middle that animates 6 glColor3f(0.0,1.0,1.0) ; // Deprecated command to set the color 7 glPushMatrix() ; 8 // I now transform by the teapot translation for animation 9 glTranslatef(teapotloc, 0.0, 0.0) ; 10 11 // The following two transforms set up and center the teapot 12 // Remember that transforms right-multiply the stack 13 14 glTranslatef(0.0,0.0,0.1) ; 15 glRotatef(rotamount, 0.0, 0.0, 1.0); 16 glRotatef(90.0,1.0,0.0,0.0) ; 17 glutSolidTeapot(0.15) ; 18 glUniform1i(islight,0) ; // turn off lighting 19 glPopMatrix() ; 20 21 }
2.动画触发器
1 void animation(void) { 2 teapotloc = teapotloc + 0.0025 ; 3 rotamount = rotamount + 0.25; 4 if (teapotloc > 0.5) teapotloc = -0.5 ; 5 if (rotamount > 360.0) rotamount = 0.0; 6 glutPostRedisplay() ; 7 } 8 9 void keyboard (unsigned char key, int x, int y) 10 { 11 switch (key) { 12 ... 13 case 'p': // ** NEW ** to pause/restart animation 14 animate = !animate ; 15 if (animate) glutIdleFunc(animation) ; 16 else glutIdleFunc(NULL) ; 17 break ; 18 ... 19 } 20 }
L8V5:OPENGL 2:纹理
1.全局基本变量的设置:
GLubyte woodtexture[256][256][3] ; // ** NEW ** texture (from grsites.com) GLuint texNames[1] ; // ** NEW ** texture buffer GLuint istex ; // ** NEW ** blend parameter for texturing GLuint islight ; // ** NEW ** for lighting GLint texturing = 1 ; // ** NEW ** to turn on/off texturing GLint lighting = 1 ; // ** NEW ** to turn on/off lighting //in display() glUniform1i(islight,false) ; // Turn off lighting (except on teapot, later) glUniform1i(istex,texturing) ; drawtexture(FLOOR,texNames[0]) ; // Texturing floor // drawobject(FLOOR) ; glUniform1i(istex,0) ; // Other items aren't textured
2.触发器
case 's': // ** NEW ** to turn on/off shading (always smooth) ; lighting = !lighting ; glutPostRedisplay() ; break ;
4.纹理读取(ppm文件)
1 void inittexture (const char * filename, GLuint program) { 2 int i,j,k ; 3 FILE * fp ; 4 GLint err ; 5 assert(fp = fopen(filename,"rb")) ; 6 fscanf(fp,"%*s %*d %*d %*d%*c") ; 7 for (i = 0 ; i < 256 ; i++) 8 for (j = 0 ; j < 256 ; j++) 9 for (k = 0 ; k < 3 ; k++) 10 fscanf(fp,"%c",&(woodtexture[i][j][k])) ; 11 fclose(fp) ; 12 ... 13 }
5.设置纹理坐标
// Set up Texture Coordinates glGenTextures(1, texNames) ; glBindBuffer(GL_ARRAY_BUFFER, buffers[numobjects*numperobj+ncolors]) ; glBufferData(GL_ARRAY_BUFFER, sizeof (floortex), floortex,GL_STATIC_DRAW); glActiveTexture(GL_TEXTURE0) ; glEnable(GL_TEXTURE_2D) ; glTexCoordPointer(2,GL_FLOAT,0,BUFFER_OFFSET(0)) ; glEnableClientState(GL_TEXTURE_COORD_ARRAY) ; glBindTexture (GL_TEXTURE_2D, texNames[0]) ; glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, woodtexture) ; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ; glTexParameterf(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) ;