在前面两篇相关文章
Win32 OpenGL 编程(1)Win32下OpenGL编程必须步骤
Win32 OpenGL编程(2) 寻找缺失OpenGL
中我们已经建立了个较为全面Win32 OpenGL编程环境及个简单框架并且实际上掌握了OpenGL在Windows下和Win32窗口交互思路方法在此基础上总算是可以正式进行些OpenGL相关知识学习前面那些也就算是热身本文目是将OpenGL中基本图元(点线多边形)绘制大概讲解遍最后可以组合使用这些技术用OpenGL完成较为复杂2D图形
2、 基本图元相关概念
首先讲讲相关概念在OpenGL中即使是复杂图形实际上也是由些非常基本图元组成即点直线多边形多边形中用较多又是 3角形和矩形在数学中两点确定条直线 3点确定个 3角形和个面同个面上 4个点确定个 4边形在OpenGL中也大致利用此方式来确定直线和多边形也就是说当你想画个直线或者个多边形时候只需要告诉OpenGL能确定此直线或者多边形点即可用参考2中描述是:“在OpenGL中所有几何物体最终都描述成组有序顶点”有此基本概念后就可以看下面例子了
3、 OpenGLHello World举例分析
这里Hello World指是个利用OpenGL完成矩形绘制相对于在系列文章1中Win32 OpenGL编程框架简化了很多东西只剩下最最基本OpenGL元素但也是个完善OpenGL举例了此举例显示是个白色矩形运行效果如附图1完整代码见我博客代码2009-10-12\SimpleRectangle工程具体下载及查看思路方法见本文最后介绍说明
此举例OpenGL相关主要就是两部分
//OpenGL化开始
void SceneInit( w, h)
{
}
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.5, -0.5, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(-0.5, 0.5, 0.0);
glEnd;
glFlush;
}
我们下面从OpenGL角度来分析此作为HelloWorld级我简化了很多东西首先OpenGL化省略了用都是OpenGL默认值具体有哪些后面步步说以下是按步骤介绍说明每个OpenGL
1. glClear
OpenGL参考手册:
glClear takes a single argument that is the bitwise OR of several values indicating which buffer is to be cleared.
GL_COLOR_BUFFER_BIT Indicates the buffers currently enabled for color writing.
作用是清除颜色缓冲区类似于我们使用块新申请内存时先用mem/ZeroMemory去清零下用这样Clear操作为我们需要使用颜色缓冲区(Color Buffer)清零下假如没有这样操作以前留在显存/内存(不确定)中值会影响我们操作并且这样问题往往是非常难以调试和发现这点大家可以尝试下
2. glBeginglEnd
OpenGL参考手册:
glBegin, glEnd - delimit the vertices of a primitive or a group of like primitives
OpenGL代码主体部分是:
glBegin(GL_QUADS);
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.5, -0.5, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(-0.5, 0.5, 0.0);
glEnd;
glBegin和glEnd很明显是对标志着组OpenGL操作开始和结束并且在参数中告诉了OpenGL下面操作是针对什么图形进行此例中GL_QUADS是表示 4边形事实上还有很多其他参数来表示各类图形在OpenGL Programming Guide此页中Figure 2-7 : Geometric Primitive Types 图形象介绍说明了各个参数作用
3. glVertex*
glVertex3f就是在 基本图元相关概念 节提到OpenGL中确定顶点简而言的上面4句glVertex3f确定了矩形4个顶点(注意顺序)然后OpenGL就会自动根据glBegin指定参数去完成相关绘制任务了此例中GL_QUADS是表示 4边形所以最后效果是个矩形实际其他参数读者可以自己尝试下
4. OpenGL默认坐标系
我们再看下glVertex*指定顶点代码:
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.5, -0.5, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(-0.5, 0.5, 0.0);
为什么上述就指定了个矩形 4个顶点呢?需要介绍说明是在OpenGL中默认坐标体系和Windows中常用区别Windows中常用坐标体系(仅2D)是用户区左上角为坐标原点即(0.0,0.0)点右为坐标轴X轴正方向下为Y轴正方向OpenGL中坐标轴(3D)默认以客户区中心点为坐标原点(0.0,0.0,0.0)右为坐标轴X轴正方向上为Y轴正方向垂直指出屏幕方向为Z轴正方向长度定义是将客户区范围为按单位长度定义即整个客户区恰好是(-1,-1)(左下)到(1,1)(右上)附图2是个上述举例附上OpenGL平面坐标系图也可以作为OpenGL默认坐标系参考图
5. OpenGL命名
这里顺面介绍下OpenGL命名规范标准C语言天生弱点及丰富数据类型在OpenGL中凡是牵涉到和参数数量和数据类型相关般命名方式都是xxxx[n][t]
xxxx表示意义[t]用于表示此对应类型般用单个字母表示参数类型s表示16位整数(OpenGL中将这个类型定义为GL)i表示32位整数(OpenGL中将这个类型定义为GL和GLsizei)f表示32位浮点数(OpenGL中将这个类型定义为GLfloat)d表示64位浮点数(OpenGL中将这个类型定义为GLdouble)此例中使用是32位浮点数所以是f这是C语言没有重载机制天生弱点导致扭曲应对方案(用C就不需要这么麻烦了)
然后是数字同样原因在C语言中个同样意义不能同时有区别个数参数所以OpenGL用个数字来表示参数个数此例中是3表示以3个参数(即点X,Y,Z坐标)来表示顶点(事实上还有glVertex2*glVertex4*)
比如此例中用如下代码效果是样:
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glVertex2f(0.5, 0.5) ;
glVertex2f(-0.5, 0.5);
在glVertex2f中Z轴默认为0.
这里我依照参考2使用方法以*作为通配符来表示组*既可以表示代表参数数量数字也可以表示代表类型字母
6. glFlush
OpenGL参考手册:
glFlush - force execution of GL commands in finite time
说白了就是强制执行已经指定OpenGL命令和fflush命名类似作用也类似
7. 小结
以上5个OpenGL就构成了个基本OpenGL(不包括模板中使用那些)由glClear清空颜色缓冲区获得干净环境由glBegin指定开始组顶点操作开始并确认绘制图形由glVertex*指定顶点由glEnd表示操作结束由glFlush强制开始绘图运行效果如附图1
4、 基本图元
事实上上节已经包含了所有知识各个图元在OpenGL中绘制方式区别仅仅在于glBegin参数区别而已这里将基本图元简单介绍下
1. 点
点是最常用图元的了而且所有图像都可以看做是由点构成事实上屏幕也就是由个个像素点构成了图像:)
画点方式是使用GL_POINTS为参数glBegin那么每个glVertex*指定顶点就会绘制成个单独点点默认大小为1个像素可以通过glPoSize来改变点大小在点比较大并且没有开启抗锯齿时是按照个正方形来绘制比如上例中仅仅将GL_QUADS换成GL_POINTS将是绘制上述矩形4个顶点为了截图效果显著glPoSize将点大小改为20如下代码:
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glPoSize(20);
glBegin(GL_POINTS);
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.5, -0.5, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(-0.5, 0.5, 0.0);
glEnd;
glFlush;
}
效果如附图3所示
光是点也可以做很多有趣应用Windows屏保模拟星空即是其事实上在原来学习简单图形编程时我用多种语言尝试了用点做些有意思东西见简单图形编程学习系列:
简单图形编程学习(2)---点 (Qt实现)
简单图形编程学习(2)---点 (Windows GDI实现)
简单图形编程学习(2)---点 (small basic实现)
其中点和文字结合形成那个星空文字效果我是印象深刻我直将其作为“简单编程技术+创意”也能很强大例子
2. 直线
直线也是很基础东西了但是OpenGL中直线和数学概念上有些区别不知道外国那些专家在命名时为啥乱了其实OpenGL中直线和数学中线段概念致有两个端点确认长度事实上在OpenGL绘制中指定也就是线段两个端点用GL_LINESglBegin时表示绘制是直线默认情况下宽度为个像素同样OpenGL也提供了glLineWidth用以改变直线宽度比如上例中仅仅将GL_QUADS换成GL_LINES将是两条平行直线并用glLineWidth将直线宽度改为5如下代码:
//这里进行所有绘图工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glLineWidth(5);
glBegin(GL_LINES);
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.5, -0.5, 0.0);
glVertex3f(0.5, 0.5, 0.0);
glVertex3f(-0.5, 0.5, 0.0);
glEnd;
glFlush;
}
运行效果如附图4所示
直线应用也是非常广泛还记得Windows屏保中变幻线吗?千变万变无论多么绚烂效果其实也仅仅是条条变化线段而已
3. 多边形
其实可以将多边形看成是从点到线到面种扩展这里面自然也是有范围那么就成了多边形了在绘制图形中用最多是 3角形 3角形肯定在同个面上这样可以简化很多计算处理GL_TRIANGLESglBegin表示开始绘制 3角形然后还有GL_QUADS表示 4边形(上例中使用方法)GL_POLYGON表示多边形(必须是凸)
4. 小结
其实除了上面讲到那些参数还有些额外参数比如GL_LINE_STRIP,GL_TRIANGLES_STRIP等表示绘制时候绘制些列连续图形这些参数用文字解释起来不够形象还是推荐参考OpenGL Programming Guide此页中Figure 2-7 : Geometric Primitive Types 图此图形象展示了各个参数时对点解释方式和顺序在此图下面还有个表整理总结了下各个参数作用
在个glBegin和glEnd对中可以连续制定多个顶点甚至超出你指定图形数目比如绘制 3角形时可以指定6个点那么此时将会绘制两个 3角形而不是个这样而当指定45个点时用GL_TRIANGLES参数时将会丢弃用GL_TRIANGLE_STRIP参数时将会连续绘制两个 3角形具体解释思路方法也是要看glBegin参数建议还是参考上述图片
5、 最后介绍说明
本文中所有代码(如果有话)都能用Mercurial在Google Code中下载
文章以博文发表日期分目录存放下载地址见:
http://code.google.com/p/jtianling/source/checkout?repo=blog-sample-code
或者直接使用Mercurial克隆下列库:
http://blog-sample-code.jtianling.googlecode.com/hg/
Mercurial使用思路方法见分布式新代版本控制系统Mercurial介绍及简要入门
6、 附图1. 图1 SimpleRectangle
图片看不清楚?请点击这里查看原图(大图)
图2 SimpleRectangle with coordinate
图片看不清楚?请点击这里查看原图(大图)
图3 SimplePos
图片看不清楚?请点击这里查看原图(大图)
图4 SimpleLines
图片看不清楚?请点击这里查看原图(大图)
最新评论