zoukankan      html  css  js  c++  java
  • OpenGL超级宝典笔记——画三角形(转)

    http://my.oschina.net/sweetdark/blog/161002

    学习了画线的知识,我们可以使用GL_LINE_LOOP来画闭合的多边形。但是使用这种方式画出来的只有线框,多边形没有填充颜色。OpenGL支持绘制实心的多边形,并使用当前的颜色进行填充。

    三角形

    简单的三角形,需要指定三个顶点。

       1: glBegin(GL_TRIANGLES);
       2:     glVertex2f(0.0f, 0.0f);            // V0
       3:     glVertex2f(25.0f, 25.0f);          // V1
       4:     glVertex2f(50.0f, 0.0f);           // V2
       5:     glVertex2f(-50.0f, 0.0f);          // V3
       6:     glVertex2f(-75.0f, 50.0f);         // V4
       7:     glVertex2f(-25.0f, 0.0f);          // V5
       8: glEnd();
       9: 

    这两个三角形会使用当前的颜色进行填充。

    image

    多边形的环绕

    按照顶点指定的顺序和方向组合称为环绕。上图的两个多边形是顺时针环绕的。我们可以通过改变顶点的顺序,从而改变环绕方向。我们把v4和v5的顺序调换过来,则这个三角形的环绕方向为逆时针了。

    image

    OpenGL默认是逆时针环绕方向为正方向,即逆时针环绕的三角形为正面。上图左边的三角形,显示的是正面,而右边的显示的是反面。我们也可以通过函数glFrontFace(GL_CW);来告诉OpenGL顺时针环绕的多边形是正面。环绕方向是多边形一个非常有用的性质,可以用于消除不必要的面。

    三角形带

    我们可以绘制多个三角形连起来形成多个面或者多边形。使用GL_TRIANGLE_STRIP图元,可以绘制一串相连的多边形,来节省大量的时间。

    image

    由上图可以看到,多边形的边的绘制顺序并不是完全按照我们指定的顶点顺序的。而是按照OpenGL指定的顺序逆时针方向绘制的。

    使用三角形带而不是分别指定每个三角形的顶点的优势有两个:

    1. 用前面三个顶点指定一个三角形后,只需再指定一个顶点就能画出第二个三角形。要绘制大量的三角形时,这种方法可以节省大量的代码以及数据存储空间
    2. 运算性能的提高和带宽的节省。更少的顶点,从内存传输的显卡的时间更快,以及参与变换的顶点更少。

    三角形扇

    除了三角形带之外,我们还可以通过GL_TRIANGLE_FAN图元,创建一组围绕一个中心点的三角形扇。通过制定5个顶点我们就可以绘制3个三角形来形成三角形扇。用3个顶点指定一个三角形后,后续的顶点Vn与原点V0以及前面的一个顶点Vn-1形成一个三角形。

    image

    创建实心物体


       1: static void RenderScene()
       2: {
       3:   //清除颜色缓冲区和深度缓冲区
       4:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       5: 
       6:     GLfloat x, y, z, angle;
       7:   //用于颜色判断
       8:   bool color;
       9:     glColor3f(1.0f, 1.0f, 0.0f);
      10:   //是否开启深度缓冲
      11:   if (bDepth)
      12:   {
      13:     glEnable(GL_DEPTH_TEST);
      14:   }
      15:   else
      16:   {
      17:     glDisable(GL_DEPTH_TEST);
      18:   }
      19:   //是否开启隐藏面消除
      20:   if (bCull)
      21:   {
      22:     glEnable(GL_CULL_FACE);
      23:   }
      24:   else
      25:   {
      26:     glDisable(GL_CULL_FACE);
      27:   }
      28:   //开启线框模式 
      29:   if (bOutLine)
      30:   {
      31:     glPolygonMode(GL_BACK, GL_LINE) ;
      32:   }
      33:   else
      34:   {
      35:     glPolygonMode(GL_BACK, GL_FILL);
      36:   }
      37:
      38: 
      39:   glPushMatrix();
      40:   glRotatef(xRot, 1.0f, 0.0f, 0.0f);
      41:   glRotatef(yRot, 0.0f, 1.0f, 0.0f);
      42:   //画椎体
      43:   glBegin(GL_TRIANGLE_FAN);
      44:     glVertex3f(0.0f, 0.0f, 70.0f);
      45: 
      46:     for (angle = 0.0f; angle <= (2 * GL_PI); angle += (GL_PI  / 8))
      47:     {
      48:           x = 50.0f * sin(angle);
      49:           y = 50.0f * cos(angle);
      50:           color = !color;
      51:
      52:       glVertex3f(x, y, 0.0f);
      53:           if(color)
      54:               glColor3f(1.0f, 0.0f, 0.0f);
      55:           else
      56:               glColor3f(0.0f, 1.0f, 1.0f);
      57:     }
      58:   glEnd();
      59:   //画椎体的底面
      60:     glBegin(GL_TRIANGLE_FAN);
      61:       glVertex2f(0.0f, 0.0f);
      62: 
      63:       for (angle = 0.0f; angle <= (2 * GL_PI); angle += (GL_PI  / 8))
      64:       {
      65:           x = 50.0f * sin(angle);
      66:           y = 50.0f * cos(angle);
      67:           color = !color;
      68:
      69:           glVertex2f(x, y);
      70: 
      71:           if(color)
      72:               glColor3f(1.0f, 0.0f, 0.0f);
      73:           else
      74:               glColor3f(0.0f, 1.0f, 1.0f);
      75:       }
      76:     glEnd();
      77: 
      78:   glPopMatrix();
      79:     glutSwapBuffers();
      80: }
      81: 
      82: static void SetupRC()
      83: {
      84:     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      85:   //设置环绕方向
      86:     glEnable(GL_CW);
      87:   //设置填充模式
      88:     glShadeModel(GL_FLAT);
      89:   //设置要消除的隐藏面,这里设置为反面
      90:   glCullFace(GL_BACK);
      91: }

    image

    使用红青相间的方式来绘制一个锥体。

    设置多边形的颜色

    多边形的填充模式有两种一种是单调着色GL_FLAT,一种平滑着色GL_SMOOTH。

    通过glShadeMode(GL_FLAT);和glShadeMode(GL_SMOOTH);来设置。单调着色以三角形的最后一个顶点的颜色来填充三角形。平滑着色则是用三个顶点的颜色值进行内插值运算,来填充三角形的颜色。

    平滑着色效果如下:

    image

    隐藏面消除

    如果没有使用深度缓冲区,来进行深度测试。上面的椎体如何旋转(通过方向键可以旋转),都是把底面显示了出来。因为底面我们是在后面画的,最后一个绘制的物体出现在之前绘制的物体的前面。如果开启了深度测试来解决问题。

    深度测试:当一个像素被绘制时,它将被设置一个值(z值),以表示它和观测者的距离。以后当这个位置要绘制新像素时,新像素的z值就会和旧像素的z值进行比较。如果新像素z值更高,则更靠近观察者,则应该被绘制,反之被忽略。

    启用深度测试只须调用glEnable(GL_DEPTH_TEST);每次场景被渲染之前,应该清楚深度缓冲区,与清楚颜色缓冲区类似。

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    在程序用使用右键点击,弹出菜单,深度测试来切换深度测试。在绘制3D实体时,深度测试往往是必须的。

    image

    剔除

    虽然启用深度测试,可以消除隐藏面。但很多时候,我们清楚那些面是不需要绘制,应该被剔除的。例如:多边形的背面不应该被显示。如果我们告知OpenGL这个图形面不需要被绘制,就不会把这个图形发送给OpenGL驱动程序和硬件,可以提高性能。

    启用剔除面的功能。

    //指定顺时针环绕的面为正面

    glFrontFace(GL_CW);

    //开启剔除面,剔除背面。

    glEnable(GL_CULL_FACE);

    image

    image

    锥体的底面面向锥体内部的是正面。要改变底面的正面,可以再绘制底面时设置glFrontFace(GL_CCW);

    多边形模式

    多边形我们可以指定它的模式,要填充还是只画线框或者只画顶点。

    通过glPolygonMode(GL_BACK, GL_LINE) ;设置多边形的背面只画线。

    通过glPolygonMode(GL_BACK, GL_FILL) ;设置多边形的背面为实体。

    通过glPolygonMode(GL_BACK, GL_POINT) ;设置多边形的背面只画点。

    image

    源代码:https://github.com/sweetdark/openglex/tree/master/triangle

  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/aminxu/p/4704191.html
Copyright © 2011-2022 走看看