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: 

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

多边形的环绕

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

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

三角形带

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

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

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

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

三角形扇

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

创建实心物体

   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: }

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

设置多边形的颜色

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

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

平滑着色效果如下:

隐藏面消除

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

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

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

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

剔除

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

启用剔除面的功能。

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

glFrontFace(GL_CW);

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

glEnable(GL_CULL_FACE);

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

多边形模式

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

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

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

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

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

OpenGL超级宝典笔记——画三角形(转)的更多相关文章

  1. OpenGL超级宝典笔记----框架搭建

    自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...

  2. OpenGL超级宝典笔记----渲染管线

    在OpenGL中任何事物都在3D空间中,但是屏幕和窗口是一个2D像素阵列,所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的 ...

  3. 【转】OpenGL超级宝典笔记——纹理映射Mipmap

    原文地址 http://my.oschina.net/sweetdark/blog/177812 , 感谢作者,若非法转载请联系本人. 目录[-] Mipmapping Mipmap过滤 构建Mip层 ...

  4. OpenGL超级宝典笔记——贝塞尔曲线和曲面(转)

    http://my.oschina.net/sweetdark/blog/183721 参数方程表现形式 在中学的时候,我们都学习过直线的参数方程:y = kx + b;其中k表示斜率,b表示截距(即 ...

  5. OpenGL超级宝典笔记——遮挡查询 [转]

    目录[-] 遮挡查询之前 包围体 遮挡查询 在一个场景中,如果有有些物体被其他物体遮住了不可见.那么我们就不需要绘制它.在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率.遮挡查询就是 ...

  6. 【转载】OpenGL超级宝典笔记——GLSL语言基础

    变量 GLSL的变量命名方式与C语言类似.变量的名称可以使用字母,数字以及下划线,但变量名不能以数字开头,还有变量名不能以gl_作为前缀,这个是GLSL保留的前缀,用于GLSL的内部变量.当然还有一些 ...

  7. OpenGL超级宝典笔记——深度纹理和阴影 【转】

    目录[-] 光源视角 新型的纹理 深度纹理的大小 首先绘制阴影 然后是光照 投影阴影贴图 阴影比较 之前我们介绍过简单的把物体压平到投影平面来制造阴影.但这种阴影方式有其局限性(如投影平面须是平面). ...

  8. win8+VS2012搭建OpenGL超级宝典的环境

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/booirror/article/details/36957799 自从公司搬到腾讯附近,每天上班都迟 ...

  9. OpenGL超级宝典visual studio 2013开发环境配置,GLTools

    做三维重建需要用到OpenGL,开始看<OpenGL超级宝典>,新手第一步配置环境就折腾了一天,记录下环境的配置过程. <超级宝典>中的例子使用了GLEW,freeglut以及 ...

随机推荐

  1. es6学习笔记7--Set

    Set 基本用法 ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. var s = new Set(); [2, ...

  2. PetaPoco源代码学习--2.TableInfo、ColumnInfo类和Cache类

    当把常用的特性填写到POCO实体类时,执行数据库操作时,需要根据实体类上的特性信息进行相应的操作,PetaPoco中的TableInfo和ColumnInfo类就是用来保存实体类上的特性信息. Tab ...

  3. HTML 初识 HTML【 整体结构 文字 图片 表格 超链接】

    HTML        超文本标记语言,页面内可以包含图片.链接,甚至音乐.程序等非文字元素.       网页的本质就是超级文本标记语言,万维网是建立在超文本基础之上的.TML 通过标记符号来标记要 ...

  4. Java“毒丸”使用示例,实现取消任务

    一.简介 在Java并发编程中,“毒丸”指的是将一个对象放在队列当中,当得到这个对象的时候立即停止执行 下面是一个使用“毒丸”来取消任务的一个示例 如图所示,我们假设一个任务从开始到结束需要经历4个步 ...

  5. ETCD 简介 + 使用

    etcd简介 etcd是一个高可用的分布式键值(key-value)数据库.etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现. etcd是一个服务发现系统,具备以下的特点: 简单: ...

  6. ubuntu 17.10 安装后的应用软件安装

    目录 安装 sogou 拼音 安装markdown编辑器 安装codeblocks 下载工具uGet+aira2 安装QT 安装remarkable(markdown工具) 安装StarUML(UML ...

  7. 自定义MVC框架之工具类-图像处理类

    截止目前已经改造了4个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 图像处理类: 1,图片加水印处理( ...

  8. macbook 外接显示器黑屏,不显示

    我的mac本有点老了,11年底的那款 整了个显示器,刚开始连上没问题,后来开机状态拔了雷电线,再插  或者关机后莫名的原因再启动,显示器黑屏 网上好多方法都不行,自己总结了一个方法 拔掉连接线,关闭m ...

  9. php实现同一时间内一个账户只允许在一个终端登陆

    在账户表的基础上,我新建了一个账户account_session表,用来记录登录账户的account_id和最新一次登录成功用户的session_id,然后首先要修改登录方法:每次登录成功后,要将登录 ...

  10. ngnix https

    server {            listen       80;#端口号        server_name  www.xxxx.net;#本机                charset ...