【raviramamoorthi-Computer Graphics】OpenGL Shading: Fragment Shader——2

(代码来自作业)

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 animation 
  glTranslatef(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函数是OpenGLGLUT工具包中用于实现双缓冲技术的一个重要函数。该函数的功能是交换两个缓冲区指针
通常, 我们所看到的窗体、文字、图像,从根本上来说都是“画”出来的。比如,制作一个简单的五子棋, 我们可能先要绘制棋盘,然后绘制棋子,我们可能还要绘制一些提示信息。虽然这些绘制操作有一定的先后顺序,通常情况下,操作系统的这些绘制速度非常的快,使人眼误认为这些绘制操作是同时完成的。
但当我们进行复杂的绘图操作时,画面便可能有明显的闪烁。解决这个问题的关键在于使绘制的东西同时出现在屏幕上。所谓双缓冲技术, 是指使用两个缓冲区: 前台缓冲和后台缓冲。前台缓冲即我们看到的屏幕,后台缓冲则在内存当中,对我们来说是不可见的。每次的所有绘图操作都在后台缓冲中进行, 当绘制完成时, 把绘制的最终结果复制到屏幕上, 这样, 我们看到所有GDI元素同时出现在屏幕上,从而解决了频繁刷新导致的画面闪烁问题。
在OpenGL中实现双缓冲技术的一种简单方法:
1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);。这里将我们惯用的GLUT_SINGLE替换为GLUT_DOUBLE,意为要使用双缓冲而非单缓冲。
2. 调用glutDisplayFunc(display)注册回调函数时, 在回调函数中所有绘制操作完成后调用glutSwapBuffers()交换两个缓冲区指针。
3. 调用glutIdleFunc注册一个空闲时绘制操作函数, 注册的这个函数再调用display函数。

  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") ;       


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值