(代码来自作业)
void display(void)
{// clear all pixels
.glClear(GLbitfield mask);
功能;用预先设置的值清除缓冲区。
参数说明;mask指定 被刷新的缓冲区,可以是GL_COLOR_BUFFER_BIT. GL_DEPTH_BUFFER_BIT ,GL_ACCUM_BUFFER_BIT, GL_STENCIL_BUFFER_BIT
GL_COLOR_BUFFER_BIT.表示颜色缓冲区
GL_DEPTH_BUFFER_BIT ,表示深度缓冲区
GL_ACCUM_BUFFER_BIT,表示累积缓冲区
GL_STENCIL_BUFFER_BIT表示模板缓冲区
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
// draw white polygon (square) of unit length centered at the origin
// Note that vertices must generally go counterclockwise
// Change from the first program, in that I just made it white.
// The old OpenGL code of using glBegin... glEnd no longer appears.
// The new version uses vertex buffer objects from init.
// Does the order of drawing matter? What happens if I draw the ground
// after the pillars? I will show this in class
glUniform系列的基本就是赋值语句= =
glUniform1i(islight,0) ; // 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
// Now draw several cubes with different transforms, colors
// I continue to use the deprecated push-pop and matrix mode
// Since it is convenient (or you have to write your own stack).
glMatrixMode(GL_MODELVIEW) ;
// 1st pillar
glPushMatrix()就是将此时栈顶的矩阵复制一个,然后压进去。
glPushMatrix() ;
这是一个变换矩阵,会自动放到栈顶,并且左乘栈顶(即之前压进来的这个复制矩阵,其实是GL_MODELVIEW)
glTranslatef(-0.4,-0.4,0.0) ;
当变换完成之后,就可以画上东西了。这个函数是在另一个cpp文件里定义的。
drawcolor(CUBE, 0) ;
完成之后,将栈顶的综合变换矩阵弹出,就回复原来的栈顶了GL_MODELVIEW
glPopMatrix() ;// 2nd pillar
glPushMatrix() ;
glTranslatef(0.4,-0.4,0.0) ;
drawcolor(CUBE, 1) ;
glPopMatrix() ;
// 3rd pillar
glPushMatrix() ;
glTranslatef(0.4,0.4,0.0) ;
drawcolor(CUBE, 2) ;
glPopMatrix() ;
// 4th pillar
glPushMatrix() ;
glTranslatef(-0.4,0.4,0.0) ;
drawcolor(CUBE, 3) ;
glPopMatrix() ;
// Draw the glut teapot
// This is using deprecated old-style OpenGL certainly
/* New for Demo 3; add lighting effects */
{
注意第四个分量都是1!
const GLfloat one[] = {1, 1, 1, 1};
const GLfloat medium[] = {0.8, 0.8, 0.8, 1};const GLfloat small[] = {0.2, 0.2, 0.2, 1};
const GLfloat high[] = {100} ;
const GLfloat zero[] = {0.0, 0.0, 0.0, 1.0} ;
const GLfloat light_specular[] = {1, 0.5, 0, 1};
const GLfloat light_specular1[] = {0, 0.5, 1, 1};
const GLfloat light_direction[] = {0.5, 0, 0, 0}; // Dir light 0 in w
const GLfloat light_position1[] = {0, -0.5, 0, 1};
GLfloat light0[4], light1[4] ;
// Set Light and Material properties for the teapot
// Lights are transformed by current modelview matrix.
// The shader can't do this globally.
// So we need to do so manually.
void transformvec (const GLfloat input[4], GLfloat output[4]) {
GLfloat modelview[16] ; // in column major order
glGetFloatv(GL_MODELVIEW_MATRIX, modelview) ;
for (int i = 0 ; i < 4 ; i++) {
output[i] = 0 ;
for (int j = 0 ; j < 4 ; j++)
output[i] += modelview[4*j+i] * input[j] ;
}
}
这是自己定义的函数,函数里头,将light_direction和modelview的矩阵乘起来。因为shader不能在全局视角下完成这个。
transformvec(light_direction, light0) ;
transformvec(light_position1, light1) ;glUniform3fv(light0dirn, 1, light0) ;
glUniform4fv(light0color, 1, light_specular) ;
glUniform4fv(light1posn, 1, light1) ;
glUniform4fv(light1color, 1, light_specular1) ;
// glUniform4fv(light1color, 1, zero) ;
glUniform4fv(ambient,1,small) ;
glUniform4fv(diffuse,1,medium) ;
glUniform4fv(specular,1,one) ;
glUniform1fv(shininess,1,high) ;
// Enable and Disable everything around the teapot
// Generally, we would also need to define normals etc.
// But glut already does this for us
if (DEMO > 4)
glUniform1i(islight,lighting) ; // turn on lighting only for teapot.
}
// ** NEW ** Put a teapot in the middle that animates
glColor3f(0.0,1.0,1.0) ; // Deprecated command to set the color
此时矩阵仍然是Modelview
glPushMatrix() ;
// I now transform by the teapot translation for animationglTranslatef(teapotloc, 0.0, 0.0) ;
// The following two transforms set up and center the teapot
// Remember that transforms right-multiply the stack
因此是先rotate然后再做两次translate
glTranslatef(0.0,0.0,0.1) ;
glRotatef(90.0,1.0,0.0,0.0) ;
可以理解为,将场景转了一下然后把壶放上来。。因此看起来就是茶壶转了
glutSolidTeapot(0.15) ;glUniform1i(islight,0) ; // turn off lighting
glPopMatrix() ;
// Does order of drawing matter?
// What happens if I draw the ground after the pillars?
// I will show this in class.
// drawobject(FLOOR) ;
// don't wait!
// start processing buffered OpenGL routines
glutSwapBuffers() ;
强制刷新缓冲。
glFlush ();}
补充:在init里面有一段代码,是实现之前说的Mapping的。
vertexshader = initshaders(GL_VERTEX_SHADER, "shaders/light.vert") ;
fragmentshader = initshaders(GL_FRAGMENT_SHADER, "shaders/light.frag") ;
shaderprogram = initprogram(vertexshader, fragmentshader) ;
// * NEW * Set up the shader parameter mappings properly for lighting.
islight = glGetUniformLocation(shaderprogram,"islight") ;
light0dirn = glGetUniformLocation(shaderprogram,"light0dirn") ;
light0color = glGetUniformLocation(shaderprogram,"light0color") ;
light1posn = glGetUniformLocation(shaderprogram,"light1posn") ;
light1color = glGetUniformLocation(shaderprogram,"light1color") ;
ambient = glGetUniformLocation(shaderprogram,"ambient") ;
diffuse = glGetUniformLocation(shaderprogram,"diffuse") ;
specular = glGetUniformLocation(shaderprogram,"specular") ;
shininess = glGetUniformLocation(shaderprogram,"shininess") ;