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:
这两个三角形会使用当前的颜色进行填充。
多边形的环绕
按照顶点指定的顺序和方向组合称为环绕。上图的两个多边形是顺时针环绕的。我们可以通过改变顶点的顺序,从而改变环绕方向。我们把v4和v5的顺序调换过来,则这个三角形的环绕方向为逆时针了。
OpenGL默认是逆时针环绕方向为正方向,即逆时针环绕的三角形为正面。上图左边的三角形,显示的是正面,而右边的显示的是反面。我们也可以通过函数glFrontFace(GL_CW);来告诉OpenGL顺时针环绕的多边形是正面。环绕方向是多边形一个非常有用的性质,可以用于消除不必要的面。
三角形带
我们可以绘制多个三角形连起来形成多个面或者多边形。使用GL_TRIANGLE_STRIP图元,可以绘制一串相连的多边形,来节省大量的时间。
由上图可以看到,多边形的边的绘制顺序并不是完全按照我们指定的顶点顺序的。而是按照OpenGL指定的顺序逆时针方向绘制的。
使用三角形带而不是分别指定每个三角形的顶点的优势有两个:
- 用前面三个顶点指定一个三角形后,只需再指定一个顶点就能画出第二个三角形。要绘制大量的三角形时,这种方法可以节省大量的代码以及数据存储空间
- 运算性能的提高和带宽的节省。更少的顶点,从内存传输的显卡的时间更快,以及参与变换的顶点更少。
三角形扇
除了三角形带之外,我们还可以通过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超级宝典笔记——画三角形(转)的更多相关文章
- OpenGL超级宝典笔记----框架搭建
自从工作后,总是或多或少的会接触到客户端3d图形渲染,正好自己对于3d图形的渲染也很感兴趣,所以最近打算从学习OpenGL的图形API出发,进而了解3d图形的渲染技术.到网上查了一些资料,OpenGL ...
- OpenGL超级宝典笔记----渲染管线
在OpenGL中任何事物都在3D空间中,但是屏幕和窗口是一个2D像素阵列,所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的 ...
- 【转】OpenGL超级宝典笔记——纹理映射Mipmap
原文地址 http://my.oschina.net/sweetdark/blog/177812 , 感谢作者,若非法转载请联系本人. 目录[-] Mipmapping Mipmap过滤 构建Mip层 ...
- OpenGL超级宝典笔记——贝塞尔曲线和曲面(转)
http://my.oschina.net/sweetdark/blog/183721 参数方程表现形式 在中学的时候,我们都学习过直线的参数方程:y = kx + b;其中k表示斜率,b表示截距(即 ...
- OpenGL超级宝典笔记——遮挡查询 [转]
目录[-] 遮挡查询之前 包围体 遮挡查询 在一个场景中,如果有有些物体被其他物体遮住了不可见.那么我们就不需要绘制它.在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率.遮挡查询就是 ...
- 【转载】OpenGL超级宝典笔记——GLSL语言基础
变量 GLSL的变量命名方式与C语言类似.变量的名称可以使用字母,数字以及下划线,但变量名不能以数字开头,还有变量名不能以gl_作为前缀,这个是GLSL保留的前缀,用于GLSL的内部变量.当然还有一些 ...
- OpenGL超级宝典笔记——深度纹理和阴影 【转】
目录[-] 光源视角 新型的纹理 深度纹理的大小 首先绘制阴影 然后是光照 投影阴影贴图 阴影比较 之前我们介绍过简单的把物体压平到投影平面来制造阴影.但这种阴影方式有其局限性(如投影平面须是平面). ...
- win8+VS2012搭建OpenGL超级宝典的环境
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/booirror/article/details/36957799 自从公司搬到腾讯附近,每天上班都迟 ...
- OpenGL超级宝典visual studio 2013开发环境配置,GLTools
做三维重建需要用到OpenGL,开始看<OpenGL超级宝典>,新手第一步配置环境就折腾了一天,记录下环境的配置过程. <超级宝典>中的例子使用了GLEW,freeglut以及 ...
随机推荐
- Java NIO系列教程(六) Selector
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...
- xml Schema include
first.xsd <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs=&q ...
- KMP算法理解(转)
(作者matrix67) KMP算法是拿来处理字符串匹配的.换句话说,给你两个字符串,你需要回答,B串是否是A串的子串(A串是否包含B串).比如,字符串A="I'm matrix67&quo ...
- 比較C struct 與 C# unsafe struct内存分佈
昨晚在群裏無意間看到一個朋友有一個需求.他是在C裏面將兩個結構體(HeadStruct,BodyStruct)的内存數據直接通過socket send發給C#寫的服務端來處理.當然他之前所使用的需求基 ...
- MFC函数—SetRegistryKey
前言:在用mfc框架编写应用的时候,如果注意,你会发现在App应用类的InitInstance()函数中,初始化时总有一个 SetRegistryKey("String"); 这 ...
- EF访问数据库报“ExecuteReader 要求已打开且可用的 Connection。连接的当前状态为已关闭。”错误
我发生这个问题的原因是因为我用EF访问数据库时用的用到了两用方式,如下图 第一种方式访问时不会出现此错误,出现错误的是第二种方式,下图是dal层代码 其中红框中的代码是出现错误之后改正的代码,也就是说 ...
- vscode 自动提示Threejs
转自:https://blog.csdn.net/github_39125824/article/details/82633993 1.首先,你要安装Node.js 2.在vscode的 查看-> ...
- ThreadLocal的用法
阿里巴巴 java 开发手册中推荐的 ThreadLocal 的用法: public class DateUtil { public static final ThreadLocal<DateF ...
- RestfulAPI超简单入门
简单入门 REST -- REpresentational State Transfer,英语的直译就是"表现层状态转移" 是目前最流行的 API 设计规范,用于 Web 数据接口 ...
- 纯HTML和CSS实现JD轮播图
博主使用了纯HTML和CSS实现了JD的轮播图,没有加动态效果,主要是使用了定位的知识. ,如图为两个侧边箭头图片(其实实际中应该使用CSS3的图标字体,这里没有使用). <!DOCTYPE ...