OpenGL编程轻松入门(一)
(由同事黄燕创作)
 
本文介绍了有关OpenGL的基本知识,主要涉及颜色、绘制几何体、坐标变换、堆栈操作、显示列表、光照和材质、纹理映射、特殊效果、曲面和曲线的绘制、二次几何体绘制、像素操作、如何绘制动画物体及菜单管理。通过对本文及本文中例子的理解消化,你可以较容易地进入OpenGL的世界。相信,再通过一段时间的学习,你将很快成为OpenGL高手。
1.         OpenGL背景简介
OpenGL(Open Graphics Library)是图形硬件的一个软件接口,也是该领域的工业标准。图形程序员利用这些指令可以创建高质量的交互式的三维应用。OpenGL的前身是SGI(Silicon Graphics)公司为其图形工作站开发的IRIS GL。IRIS GL虽然功能强大但是移植性不好,于是SGI公司便在IRIS GL的基础上开发了OpenGL。
OpenGL是一个与硬件无关的软件接口。可以在不同的平台如Windows 95、Windows NT、Unix、Linux、MacOS、OS/2之间进行移植。因此,支持OpenGL的软件具有很好的移植性,可以获得非常广泛的应用。
OpenGL是网络透明的,具有网络功能。即便客户机和服务器是不同类型的计算机OpenGL程序也可以在网络上运行。这一点对于制作大型3D图形、动画非常有用。例如,《玩具总动员》、《泰坦尼克》等电影的电脑特技画面就是通过应用OpenGL的网络功能,使用120多台图形工作站共同工作来完成的。
OpenGL的发展一直处于一种较为迟缓的态势,每次版本的提高新增的技术很少,大多只是对其中部分做出修改和完善。随着DirectX的不断发展和完善,OpenGL的优势逐渐丧失,至今虽然已有3Dlabs提倡开发的2.0版本面世,在其中加入了很多类似于DirectX中可编程单元的设计,但厂商的用户认知程度并不高,未来的OpenGL发展前景迷茫。
但是OpenGL具有许多优势,这些优势可以为硬件及软件研发人员提供很多便利。首先,它是行业标准,得到广泛的技术支持,是唯一的真正开放、稳定、和销售商无关的、多平台的图形标准。第二,可靠性和可移植性。第三,允许新功能的加入。第四,可在从PC机到超级计算机不同级别的机器上运行。第四,容易使用,一般的应用程序几行代码就可以完成,并且无需考虑硬件。第五,具有大量文档,例子可供参考。
注意,在不同的平台如何安装OpenGL,如何设置运行环境会有一些不同。为了力求讲解的形象生动,本文举了十多个例子,这些例子都是在Windows 2000平台,Microsoft Visual C++ 6.0环境下编译运行的。
作者将尽量详尽地解释文中的例子,解释每一行代码在做什么,即便你对OpenGL甚至Visual C++一无所知,你也可以基本上读懂这些例子,并且可以模仿这些例子写一些自己的程序。所以如果你是一个初学者,我想本文会对你有很大帮助,但是如果你已经是一个OpenGL编程高手,这篇文章对你来说就太简单了。
2.         一个简单的例子
先编译运行一个简单的例子,这样我们可以有一个直观的印象。从这个例子我们可以看到OpenGL可以做什么,当然这个例子只做了很简单的一件事——绘制一个彩色的三角形。除此以外,我们还可以看到典型的OpenGL程序结构及openGL的运行顺序。
例1:本例在黑色的背景下绘制一个彩色的三角形。
#include <stdlib.h>
#include <GL/glut.h>
void background(void)
{
glClearColor(0.0,0.0,0.0,0.0);//设置背景颜色为黑色
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);//buffer设置为颜色可写
glBegin(GL_TRIANGLES);//开始画三角形
glShadeModel(GL_SMOOTH);//设置为光滑明暗模式
glColor3f(1.0,0.0,0.0);//设置第一个顶点点为红色
glVertex2f(-1.0,-1.0);//设置第一个顶点的坐标为(-1.0,-1.0)
glColor3f(0.0,1.0,0.0);//设置第二个顶点点为绿色
glVertex2f(0.0,-1.0);//设置第二个顶点的坐标为(0.0,-1.0)
glColor3f(0.0,0.0,1.0);//设置第三个顶点点为蓝色
glVertex2f(-0.5,1.0);//设置第三个顶点的坐标为(-0.5,1.0)
glEnd();//三角形结束
glFlush();//强制OpenGL函数在有限时间内运行
}
void myReshape(GLsizei w,GLsizei h)
{
glViewport(0,0,w,h);//设置视口
glMatrixMode(GL_PROJECTION);//指明当前矩阵为GL_PROJECTION
glLoadIdentity();//将当前矩阵置换为单位阵
if(w <= h)
gluOrtho2D(-1.0,1.5,-1.5,1.5*(GLfloat)h/(GLfloat)w);//定义二维正视投影矩阵
else
gluOrtho2D(-1.0,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5);
glMatrixMode(GL_MODELVIEW);//指明当前矩阵为GL_MODELVIEW
}
int main(int argc,char ** argv)
{
/*初始化*/
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(400,400);
glutInitWindowPosition(200,200);
/*创建窗口*/
glutCreateWindow("Triangle");
/*绘制与显示*/
background();
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);
/*进入GLUT事件处理循环*/
glutMainLoop();
return(0);
}
首先创建工程,其步骤如下:
1)创建一个Win32 Console Application。
2)链接OpenGL libraries。在Visual C++中先单击Project,再单击Settings,再找到Link单击,最后在Object/library modules 的最前面加上OpenGL32.lib GLu32.lib GLaux.lib
3)单击Project Settings中的C/C++标签,将Preprocessor definitions 中的_CONSOLE改为__WINDOWS。最后单击OK。
现在你可以把下面的例子拷贝到工程中去,编译运行。你可以看到一个彩色的三角形。
我们先看看main函数。函数中以glut开头的函数都包含在glut.h中。GLUT库的函数主要执行如处理多窗口绘制、处理回调驱动事件、生成层叠式弹出菜单、绘制位图字体和笔画字体,以及各种窗口管理等任务。
l         glutInit用来初始化GLUT库并同窗口系统对话协商。
l         glutInitDisplayMode用来确定所创建窗口的显示模式。本例中的参数GLUT_SINGLE 指定单缓存窗口,这也是缺省模式,对应的模式为GLUT_DOUBLE 双缓存窗口。参数GLUT_RGB指定颜色RGBA模式,这也是缺省模式,对应的模式为GLUT_INDEX 颜色索引模式窗口。
l         glutInitWindowSize 初始化窗口的大小,第一个参数为窗口的宽度,第二个参数为窗口的高度,以像素为单位。
l         glutInitWindowPosition 设置初始窗口的位置,第一个参数为窗口左上角x的坐标,第二个参数为窗口左上角y的坐标,以像素为单位。屏幕的左上角的坐标为(0,0),横坐标向右逐渐增加,纵坐标向下逐渐增加。
l         glutCreateWindow 创建顶层窗口,窗口的名字为扩号中的参数。
l         background() 这是自己写的函数,设置背景。其实这个函数中的语句可以写在display函数中,但为了使功能块更加清晰,所以把背景这一部分单独提出来。
l         glutReshapeFunc 注册当前窗口的形状变化回调函数。当改变窗口大小时,该窗口的形状改变回调函数将被调用。在此例中就是myReshape指定形状变化函数。
l         glutDisplayFunc 注册当前窗口的显示回调函数。当一个窗口的图像层需要重新绘制时,GLUT将调用该窗口的的显示回调函数。在此例中的mydisplay就是显示回调函数,显示回调函数不带任何参数,它负责整个图像层的绘制。我们的大部分工作将集中在这个函数中。
l         glutMainLoop 进入GLUT事件处理循环。glutMainLoop函数在GLUT程序中最多只能调用一次,它一旦被调用就不再返回,并且调用注册过的回调函数。所以这个函数必须放在注册回调函数的后面,此例中为glutReshapeFunc, glutDisplayFunc。
现在我们对OpenGL程序的典型的程序结构有了一个了解。首先初始化,包括对GLUT库的初始化和对窗口的设置及显示模式的设置。第二,创建窗口。第三,自己创作的核心部分。第四,glutMainLoop 进入GLUT事件处理循环。
下面,我们转到我们的创作核心。
background这个函数很简单,只有一行语句。glClearColor中的四个参数分别是红、绿、蓝和alpha值。这些值定义了窗口的颜色。这些值的范围在[0,1]之间。缺省值均为0。你可以改变这些值,观察背景色彩的变化。
myDisplay画了一个彩色的三角形。
l         glClear 将buffers设置为预先设定的值。参数GL_COLOR_BUFFER_BIT表明现在可以向buffer中写入颜色值。
l         glBegin和glEnd是一一对应的。这两个函数限制了一组或多组图元的顶点定义。在这两个函数中间就是你所绘制的由多个顶点组成的图元。函数的参数表明了所绘制的图元的类型。本例中的GL_TRIANGLES 表明所绘制的图形为三角形。
l         glShadeModel选择平坦或光滑渐变模式。GL_SMOOTH为缺省值,为光滑渐变模式,GL_FLAT为平坦渐变模式。
l         glColor设置当前颜色。后面跟的数字为参数个数。3表明有三个参数,分别为红、绿、蓝,4则多一个参数alpha。紧跟数字后面的字母表示数据类型。本例中的glColor3f表示三个参数,数据类型为GLfloat。
l         glVertex指定顶点。同样函数明中的数字表明参数个数。参数分别为x,y或x、y、z。紧跟数字后面的字母表示数据类型。本例中glVertex2f表明两个参数,数据类型为GLfloat。窗口的中心为原心,坐标为(0,0,0)。横坐标向左为负,向右为正;纵坐标向上为正,向下为负;z坐标向屏幕里为负,屏幕外为正,坐标系符合右手定则。
现在你将main函数中的glutReshapeFunc(myReshape); 注释掉,任意改变三角形顶点的坐标你会发现窗口的最左边,最右边的x值分别为-1和1,而窗口的最上端,最下端的y值分别为1和-1。由此可见glVertex中坐标的值实际上是和窗口的大小成倍数的关系。好了,现在恢复原来的程序。
l         glFlush迫使OpenGL函数在有限时间里运行。glFlush清空所有buffer,使所有发出的命令能在规定的时间内运行。一定不能忘记这一条语句。只有加了这一句,前面的命令才能执行。
myReshape 改变窗口的大小。
l         glViewport(Glint x,Glint y,GLsizei width,GLsizei height)设置视口。视口是一个矩形,x,y为视口左下角的坐标,以像素为单位,缺省值为(0,0)。width和height分别为视口的宽和高。OpenGl  context第一次贴到窗口上时width和height分别设置成窗口的大小。
l         glMatrixMode 指明哪一个矩阵为当前矩阵。本例中GL_PROJECTION指明投影矩阵堆栈为随后的矩阵操作的目标。GL_MODELVIEW指明模型视景矩阵。
l         glLoadIdentity将当前矩阵置换为单位阵。
l         gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)定义二维正视投影矩阵。left,right分别设置左右垂直切平面的坐标,bottom,top分别设置上下垂直切平面的坐标。
现在你可能对这几个参数的意义还不是很清楚。我们现在将myReshape 函数glLoadIdentity();后面所有的语句注释掉。加上gluOrtho2D(-1.5,1.5,-1.5,1.5);改变三角型的坐标及gluOrtho2D中的数值,你就可以清楚的理解gluOrtho2D中数值的含义。
现在,你应该大致了解OpenGL到底是怎么一回事。通过这一节的学习我们知道怎样使用颜色及绘制几何图形及物体的最基本的函数,更多的函数你可以在网上或有关书中查到。下一节我们继续讲一下颜色的使用。

OpenGL编程轻松入门(一)相关推荐

  1. OpenGL编程轻松入门(四)

    1.         曲面和曲线 前面我们讲了如何绘制平面的图形,这一节我们学习如何绘制曲线和曲面. 例10:绘制一个曲面,本程序使用二维求值器绘制一个曲面.本例中也有一些特殊效果的操作. #incl ...

  2. OpenGL编程轻松入门之显示例表

    利用显示列表,我们们可以减少重复的劳动.我们可以从例5中得到体会. 例5:绘制六个彩色的三角形,如图六. #include <windows.h> #include <GL/glut ...

  3. OpenGL编程轻松入门之二次几何体

    这一章我们讲一下二次几何物体的绘制.二次几何物体的绘制有几种不同的方式,在本例中可以看出不同的绘制方式的不同效果,如图十五所示. 例13:本例使用GLU库函数绘制了四个几何物体,分别为圆柱体.球体.圆 ...

  4. OpenGL编程轻松入门之使用颜色

    通过上一节的例子我们已经知道一些简单的使用颜色的方法.这一节我们进一步讲讲颜色的使用. 例2:本例子使用颜色引索模式绘制8个不同颜色的球体,如图二所示.阅读此例时,请主要关注函数palette和Dra ...

  5. opengl编程从入门到精通-hello,window

    窗口 程序中使用的glad.c和glad.h源码: 链接: https://pan.baidu.com/s/1TmtM7O8J4aTnfP6elIgs7g 密码: g5go github源码仓库 op ...

  6. C++ STL编程轻松入门基础

    C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...

  7. C++ STL编程轻松入门【转载】

    1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL "什么是STL?",假如你对STL还知之甚少,那么我想,你一定很想知道这个问题的答案,坦率地讲,要指望用短短数 ...

  8. 新手学堂:C++ STL编程轻松入门

    作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的.STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现.本教程旨在传播和普及STL的基础知识,若能借此机 ...

  9. C++ STL编程轻松入门

    作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的.STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现.本教程旨在传播和普及STL的基础知识,若能借此机 ...

最新文章

  1. ASP.NET MVC2 Web项目中公用类库的问题
  2. 史上最全Java多线程面试60题,含答案大赠送!
  3. centos 下载文件很慢_CentOS镜像下载
  4. ec200t 拨号_移远EC20 R2.0 AT指令拨号流程
  5. recycleview 自动循环滚动_划重点 | 不能不知的滚动轴承知识—轴承分类(续)
  6. 服务器端渲染为什么会比较快,原理是什么?
  7. PHP三级联动视频教程,PHP教程:thinkPHP实现的省市区三级联动功能示例
  8. DIGITS使用步骤
  9. 中国互联网二十四年红黑史
  10. 法国警告Nobelium网络间谍攻击法国组织
  11. 计算机不显示验证码,为什么验证码不显示,验证码显示不出来
  12. 打印机 针式打印机 热敏打印机
  13. linux桌面开发工程师,linux开发工程师是做什么的?linux开发工程师岗位职责工作内容 - 职友集...
  14. 【调剂】2021年齐齐哈尔大学朱磊教授课题组招收通信与信息系统、电子信息相关专业硕士调剂...
  15. Vue.js / Nuxt.js / uni-app - 移动端 H5 网页,在电脑 PC 上打开时居中显示(手机网页在电脑上打开后,简单粗暴防止 “界面样式“ 拉伸变形的解决方案)适用所有web项目
  16. 女孩们,请别到职场卖萌,甘当不专…
  17. tv端h5_最新版H5双端影视APP源码
  18. 在云服务器重装系统后vscode连不上服务器的解决
  19. JDK9-JDK17新特性总结
  20. 10万级半导体无尘车间尘埃粒子检测器

热门文章

  1. [转载]We Recommend a Singular Value Decomposition
  2. python操作SQL
  3. block的用法以及block和delegate的比较(转发)
  4. jquery 选中单选按钮的值
  5. XCTF-高手进阶区:php_rce
  6. mysql根据经纬度搜周边_mysql根据经纬度获取附近的商家
  7. h5网页在移动端(安卓)head里的title为空,默认显示url地址。js代码将head的title设置为空
  8. vue路由切换时内容组件的滚动条回到顶部
  9. 获取extjs 选择后的表头_批量写入审计底稿的表头信息设定页面
  10. vue项目中使用JSX