当前位置:首页 > 经验 >

opengl使用手册(opengl学习教程)

来源:原点资讯(www.yd166.com)时间:2022-10-25 10:40:20作者:YD166手机阅读>>

  • 视点变换:相当于设置视点的位置和方向

  • 模型变换:包括平移、旋转、缩放等三种类型

  • 裁剪变换:根据视景体定义的六个面(和附加裁剪面)对三维空间裁剪

  • 视口变换:将视景体内投影的物体显示在二维的视口平面上


安装 PyOpenGL

如果想当然地使用 pip 如下所示安装,可能会有一些麻烦。

pip install pyopengl

当我这样安装之后,运行 OpenGL 代码,得到了这样的错误信息:

FunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling

原来,pip 默认安装的是32位版本的PyOpenGL,而我的操作系统是64位的。建议点击这里下载适合自己的版本,直接安装.whl文件。我是这样安装的:

pip install PyOpenGL-3.1.3b2-cp37-cp37m-win_amd64.whl

OpenGL 库及函数简介

我第一次接触 OpenGL 的 GL / GLU / GLUT 的时候,一下就被这些长得像孪生兄弟的库名字给整懵圈了,要不是内心强大,也许就跟 OpenGL 说再见了。时间久了才发现,OpenGL 的库及函数命名规则非常合理,便于查找、记忆:

OpenGL函数的命名格式如下:

<库前缀><根命令><可选的参数个数><可选的参数类型>

常见的库前缀有 gl、glu、glut、aux、wgl、glx、agl 等。库前缀表示该函数属于 OpenGL 哪一个开发库。从函数名后面中还可以看出需要多少个参数以及参数的类型。I 代表 int 型,f 代表 float 型,d 代表 double 型,u 代表无符号整型。例如 glColor3f 表示了该函数属于gl库,参数是三个浮点数。

OpenGL 函数库相关的 API 有核心库(gl)、实用库(glu)、实用工具库(glut)、辅助库(aux)、窗口库(glx、agl、wgl)和扩展函数库等。gl是核心,glu是对gl的部分封装。glut是为跨平台的OpenGL程序的工具包,比aux功能强大。glx、agl、wgl 是针对不同窗口系统的函数。扩展函数库是硬件厂商为实现硬件更新利用OpenGL的扩展机制开发的函数。本文仅对常用的四个库做简单介绍。

一、OpenGL 核心库 GL

核心库包含有115个函数,函数名的前缀为gl。这部分函数用于常规的、核心的图形处理。此函数由gl.dll来负责解释执行。由于许多函数可以接收不同数以下几类。据类型的参数,因此派生出来的函数原形多达300多个。核心库中的函数主要可以分为以下几类函数:

  • 绘制基本几何图元的函数:

    glBegain、glEnd、glNormal*、glVertex*

  • 矩阵操作、几何变换和投影变换的函数:

    如矩阵入栈函数glPushMatrix,矩阵出栈函数glPopMatrix,装载矩阵函数glLoadMatrix,矩阵相乘函数glMultMatrix,当前矩阵函数glMatrixMode和矩阵标准化函数glLoadIdentity,几何变换函数glTranslate*、glRotate*和glScale*,投影变换函数glOrtho、glFrustum和视口变换函数glViewport

  • 颜色、光照和材质的函数:

    如设置颜色模式函数glColor*、glIndex*,设置光照效果的函数glLight* 、glLightModel*和设置材质效果函数glMaterial

  • 显示列表函数:

    主要有创建、结束、生成、删除和调用显示列表的函数glNewList、glEndList、glGenLists、glCallList和glDeleteLists

  • 纹理映射函数:

    主要有一维纹理函数glTexImage1D、二维纹理函数glTexImage2D、设置纹理参数、纹理环境和纹理坐标的函数glTexParameter*、glTexEnv*和glTetCoord*

  • 特殊效果函数:

    融合函数glBlendFunc、反走样函数glHint和雾化效果glFog*

  • 光栅化、象素操作函数:

    如象素位置glRasterPos*、线型宽度glLineWidth、多边形绘制模式glPolygonMode,读取象素glReadPixel、复制象素glCopyPixel

  • 选择与反馈函数:

    主要有渲染模式glRenderMode、选择缓冲区glSelectBuffer和反馈缓冲区glFeedbackBuffer

  • 曲线与曲面的绘制函数:

    生成曲线或曲面的函数glMap*、glMapGrid*,求值器的函数glEvalCoord* glEvalMesh*

  • 状态设置与查询函数:

    glGet*、glEnable、glGetError

二、OpenGL 实用库 GLU

包含有43个函数,函数名的前缀为glu。OpenGL提供了强大的但是为数不多的绘图命令,所有较复杂的绘图都必须从点、线、面开始。Glu 为了减轻繁重的编程工作,封装了OpenGL函数,Glu函数通过调用核心库的函数,为开发者提供相对简单的用法,实现一些较为复杂的操作。此函数由glu.dll来负责解释执行。OpenGL中的核心库和实用库可以在所有的OpenGL平台上运行。主要包括了以下几种:

  • 辅助纹理贴图函数:

    gluScaleImage 、gluBuild1Dmipmaps、gluBuild2Dmipmaps

  • 坐标转换和投影变换函数:

    定义投影方式函数gluPerspective、gluOrtho2D 、gluLookAt,拾取投影视景体函数gluPickMatrix,投影矩阵计算gluProject和gluUnProject

  • 多边形镶嵌工具:

    gluNewTess、gluDeleteTess、gluTessCallback、gluBeginPolygon、gluTessVertex、gluNextContour、gluEndPolygon

  • 二次曲面绘制工具:

    主要有绘制球面、锥面、柱面、圆环面gluNewQuadric、gluSphere、gluCylinder、gluDisk、gluPartialDisk、gluDeleteQuadric

  • 非均匀有理B样条绘制工具:

    主要用来定义和绘制Nurbs曲线和曲面,包括gluNewNurbsRenderer、gluNurbsCurve、gluBeginSurface、gluEndSurface、gluBeginCurve、gluNurbsProperty

  • 错误反馈工具:

    获取出错信息的字符串gluErrorString

三、OpenGL 工具库 GLUT

包含大约30多个函数,函数名前缀为glut。glut是不依赖于窗口平台的OpenGL工具包,由Mark KLilgrad在SGI编写(现在在Nvidia),目的是隐藏不同窗口平台API的复杂度。函数以glut开头,它们作为aux库功能更强的替代品,提供更为复杂的绘制功能,此函数由glut.dll来负责解释执行。

由于glut中的窗口管理函数是不依赖于运行环境的,因此OpenGL中的工具库可以在X-Window、Windows NT、OS/2等系统下运行,特别适合于开发不需要复杂界面的OpenGL示例程序。对于有经验的程序员来说,一般先用glut理顺3D图形代码,然后再集成为完整的应用程序。这部分函数主要包括:

  • 窗口操作函数:

    窗口初始化、窗口大小、窗口位置函数等 glutInit、glutInitDisplayMode、glutInitWindowSize、glutInitWindowPosition

  • 回调函数:

    响应刷新消息、键盘消息、鼠标消息、定时器函数 GlutDisplayFunc、glutPostRedisplay、glutReshapeFunc、glutTimerFunc、glutKeyboardFunc、glutMouseFunc

  • 创建复杂的三维物体:

    这些和aux库的函数功能相同。

  • 菜单函数:

    创建添加菜单的函数 GlutCreateMenu、glutSetMenu、glutAddMenuEntry、glutAddSubMenu 和 glutAttachMenu

  • 程序运行函数:

    glutMainLoop

四、Windows 专用库 WGL

针对Windows平台的扩展,包含有16个函数,函数名前缀为wgl。这部分函数主要用于连接OpenGL和Windows ,以弥补OpenGL在文本方面的不足。Windows专用库只能用于Windows环境中。这类函数主要包括以下几类:

  • 绘图上下文相关函数:

    wglCreateContext、wglDeleteContext、wglGetCurrentContent、wglGetCurrentDC、wglDeleteContent

  • 文字和文本处理函数:

    wglUseFontBitmaps、wglUseFontOutlines

  • 覆盖层、地层和主平面层处理函数:

    wglCopyContext、wglCreateLayerPlane、wglDescribeLayerPlane、wglReakizeLayerPlatte

  • 其他函数:

    wglShareLists、wglGetProcAddress

开始 OpenGL 的奇幻之旅

一、OpenGL 基本图形的绘制

  • 设置颜色

设置颜色的函数有几十个,都是以 glColor 开头,后面跟着参数个数和参数类型。参数可以是 0 到 255 之间的无符号整数,也可以是 0 到 1 之间的浮点数。三个参数分别表示 RGB 分量,第四个参数表示透明度(其实叫不透明度更恰当)。以下最常用的两个设置颜色的方法:

glColor3f(1.0,0.0,0.0) # 设置当前颜色为红色

glColor4f(0.0,1.0,1.0,1.0) # 设置当前颜色为青色,不透明度

glColor3ub(0, 0, 255) # 设置当前颜色为蓝色

glColor 也支持将三个或四个参数以向量方式传递,例如:

glColor3fv([0.0,1.0,0.0]) # 设置当前颜色为绿色

特别提示:OpenGL 是使用状态机模式,颜色是一个状态变量,设置颜色就是改变这个状态变量并一直生效,直到再次调用设置颜色的函数。除了颜色,OpenGL 还有很多的状态变量或模式。在任何时间,都可以查询每个状态变量的当前值,还可以用 glPushAttrib 或 glPushClientAttrib 把状态变量的集合保存起来,必要的时候,再用 glPopAttrib 或 glPopClientAttrib 恢复状态变量。

  • 设置顶点

顶点(vertex)是 OpengGL 中非常重要的概念,描述线段、多边形都离不开顶点。和设置颜色类似,设置顶点的函数也有几十个,都是以 glVertex 开头,后面跟着参数个数和参数类型,同样也支持将多个以向量方式传递。两个参数的话,分别表示 xy 坐标,三个参数则分别表示 xyz 坐标。如有第四个参数,则表示该点的齐次坐标 w;否则,默认 w=1。至于什么是齐次坐标,显然超出了初中数学的范畴,在此不做探讨。

glVertex2f(1.0,0.5) # xoy平面上的点,z=0

glVertex3f(0.5,1.0,0.0) # 三维空间中的点

  • 绘制基本图形

仅仅设置颜色和顶点,并不能画出来什么。我们可以在任何时候改变颜色,但所有的顶点设置,都必须包含在 glBegin 和 glEnd 之间,而 glBegin 的参数则指定了将这些顶点画成什么。以下是 glBegin 可能的参数选项:

opengl使用手册,opengl学习教程(5)

二、第一个 OpenGL 程序

通常,我们使用工具库(GLUT)创建 OpenGL 应用程序。为啥不用 GL 或者 GLU 库呢?画画之前总得先有一块画布吧,不能直接拿起画笔就开画。前文说过,工具库主要提供窗口相关的函数,有了窗口,就相当于有了画布,而核心库和实用库,就好比各式各样的画笔、颜料。使用工具库(GLUT)创建 OpenGL 应用程序只需要四步(当然,前提是你需要先准备好绘图函数,并给它取一个合适的名字):

  • 初始化glut库

  • 创建glut窗口

  • 注册绘图的回调函数

  • 进入glut主循环

OK,铺垫了这么多之后,我们终于开始第一个 OpenGL 应用程序了:绘制三维空间的世界坐标系,在坐标原点的后方(z轴的负半区)画一个三角形。代码如下:

# -*- coding: utf-8 -*-

# -------------------------------------------

# quidam_01.py 三维空间的世界坐标系和三角形

# -------------------------------------------

from OpenGL.GL import *

from OpenGL.GLUT import *

def draw:

# ---------------------------------------------------------------

glBegin(GL_LINES) # 开始绘制线段(世界坐标系)

# 以红色绘制x轴

glColor4f(1.0, 0.0, 0.0, 1.0) # 设置当前颜色为红色不透明

glVertex3f(-0.8, 0.0, 0.0) # 设置x轴顶点(x轴负方向)

glVertex3f(0.8, 0.0, 0.0) # 设置x轴顶点(x轴正方向)

# 以绿色绘制y轴

glColor4f(0.0, 1.0, 0.0, 1.0) # 设置当前颜色为绿色不透明

glVertex3f(0.0, -0.8, 0.0) # 设置y轴顶点(y轴负方向)

glVertex3f(0.0, 0.8, 0.0) # 设置y轴顶点(y轴正方向)

# 以蓝色绘制z轴

glColor4f(0.0, 0.0, 1.0, 1.0) # 设置当前颜色为蓝色不透明

glVertex3f(0.0, 0.0, -0.8) # 设置z轴顶点(z轴负方向)

glVertex3f(0.0, 0.0, 0.8) # 设置z轴顶点(z轴正方向)

glEnd # 结束绘制线段

# ---------------------------------------------------------------

glBegin(GL_TRIANGLES) # 开始绘制三角形(z轴负半区)

glColor4f(1.0, 0.0, 0.0, 1.0) # 设置当前颜色为红色不透明

glVertex3f(-0.5, -0.366, -0.5) # 设置三角形顶点

glColor4f(0.0, 1.0, 0.0, 1.0) # 设置当前颜色为绿色不透明

glVertex3f(0.5, -0.366, -0.5) # 设置三角形顶点

glColor4f(0.0, 0.0, 1.0, 1.0) # 设置当前颜色为蓝色不透明

glVertex3f(0.0, 0.5, -0.5) # 设置三角形顶点

glEnd

# 结束绘制三角形

# ---------------------------------------------------------------

glFlush # 清空缓冲区,将指令送往硬件立即执行

if __name__ == "__main__":

glutInit # 1. 初始化glut库

glutCreateWindow('Quidam Of OpenGL') # 2. 创建glut窗口

glutDisplayFunc(draw) # 3. 注册回调函数draw

glutMainLoop # 4. 进入glut主循环

运行代码,我这里显示结果如下面左图所示。如果尝试运行这段代码出错的话,我猜应该是 PyOpenGL 安装出现了问题,建议返回到前面重读 PyOpenGL 的安装。

opengl使用手册,opengl学习教程(6)

短暂的激动之后,你可能会尝试画一些其他的线段,变换颜色或者透明度,甚至绘制多边形。很快你会发现,我们的第一个程序有很多问题,比如:

  1. 窗口的标题不能使用中文,否则会显示乱码

  2. 窗口的初始大小和位置无法改变

  3. 改变窗口的宽高比,三角形宽高比也会改变(如上面右图所示)

  4. 三角形不应该遮挡坐标轴

  5. 改变颜色的透明度无效

  6. 不能缩放旋转

没关系,除了第1个问题我不知道怎么解决(貌似无解),其他问题都不是事儿。和我们的代码相比,一个真正实用的 OpenGL 程序,还有许多工作要做:

  • 设置初始显示模式

  • 初始化画布

  • 绘图函数里面需要增加:清除屏幕及深度缓存、投影设置、模型试图设置

  • 绑定鼠标键盘的事件函数

三、设置初始显示模式

初始化 glut 库的时候,我们一般都要用 glutInitDisplayMode 来设置初始的显示模式,它的参数可以是下表中参数的组合。

opengl使用手册,opengl学习教程(7)

使用双缓存窗口,可以避免重绘时产生抖动的感觉。我一般选择 GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH 作为参数来设置初始的显示模式。

四、初始化画布

开始绘图之前,需要对画布做一些初始化工作,这些工作只需要做一次。比如:

glClearColor(0.0, 0.0, 0.0, 1.0) # 设置画布背景色。注意:这里必须是4个参数

glEnable(GL_DEPTH_TEST) # 开启深度测试,实现遮挡关系

glDepthFunc(GL_LEQUAL) # 设置深度测试函数(GL_LEQUAL只是选项之一)

如有必要,还可以开启失真校正(反走样)、开启表面剔除等。

五、清除屏幕及深度缓存

每次重绘之前,需要先清除屏幕及深度缓存。这项操作一般放在绘图函数的开头。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

六、设置投影

投影设置也是每次重绘都需要的步骤之一。glOrtho 用来设置平行投影,glFrustum 用来设置透视投影。这两个函数的参数相同,都是视景体的 left / right / bottom / top / near / far 六个面。

视景体的 left / right / bottom / top 四个面围成的矩形,就是视口。near 就是投影面,其值是投影面距离视点的距离,far 是视景体的后截面,其值是后截面距离视点的距离。far 和 near 的差值,就是视景体的深度。视点和视景体的相对位置关系是固定的,视点移动时,视景体也随之移动。

我个人认为,视景体是 OpengGL 最重要、最核心的概念,它和视口、视点、投影面、缩放、漫游等概念密切关联。只有正确理解了视景体,才能正确设置它的六个参数,才能呈现出我们期望的效果。

为了在窗口宽高比改变时,绘制的对象仍然保持固定的宽高比,一般在做投影变换时,需要根据窗口的宽高比适当调整视景体的 left / right 或者 bottom / top 参数。

假设 view 是视景体,width 和 height 是窗口的宽度和高度,在投影变换之前,需要先声明是对投影矩阵的操作,并将投影矩阵单位化:

glMatrixMode(GL_PROJECTION)

glLoadIdentity

if width > height:

k = width / height

glFrustum(view [0]*k, view [1]*k, view [2], view [3], view [4], view [5])

else:

k = height / width

glFrustum(view [0], view [1], view [2]*k, view [3]*k, view [4], view [5])

七、设置视点

视点是和视景体关联的概念。设置视点需要考虑眼睛在哪儿、看哪儿、头顶朝哪儿,分别对应着eye、lookat 和 eye_up 三个向量。

gluLookAt(

eye[0], eye[1], eye[2],

look_at[0], look_at[1], look_at[2],

eye_up[0], eye_up[1], eye_up[2]

)

八、设置视口

视口也是和视景体关联的概念,相对简单一点。

glViewport(0, 0, width, height)

九、设置模型视图

模型平移、旋转、缩放等几何变换,需要切换到模型矩阵:

glMatrixMode(GL_MODELVIEW)

glLoadIdentity

glScale(1.0, 1.0, 1.0)

十、捕捉鼠标事件、键盘事件和窗口事件

GLUT 库提供了几个函数帮我们捕捉鼠标事件、键盘事件和窗口事件:

  • glutMouseFunc

    该函数捕捉鼠标点击和滚轮操作,返回4个参数给被绑定的事件函数:键(左键/右键/中键/滚轮上/滚轮下)、状态(1/0)、x坐标、y坐标

  • glutMotionFunc

    该函数捕捉有一个鼠标键被按下时的鼠标移动给被绑定的事件函数,返回2个参数:x坐标、y坐标

  • glutPassiveMotionFunc

    该函数捕捉鼠标移动,返回2个参数给被绑定的事件函数:x坐标、y坐标

  • glutEntryFunc

    该函数捕捉鼠标离开或进入窗口区域,返回1个参数给被绑定的事件函数:GLUT_LEFT 或者 GLUT_ENTERED

    glutKeyboardFunc(keydown)

    该函数捕捉键盘按键被按下,返回3个参数给被绑定的事件函数:被按下的键,x坐标、y坐标

  • glutReshapeFunc

    该函数捕捉窗口被改变大小,返回2个参数给被绑定的事件函数:窗口宽度、窗口高度

如果我们需要捕捉这些事件,只需要定义事件函数,注册相应的函数就行:

def reshape(width, height):

pass

def mouseclick(button, state, x, y):

pass

def mousemotion(x, y):

pass

def keydown(key, x, y):

pass

glutReshapeFunc(reshape) # 注册响应窗口改变的函数reshape

glutMouseFunc(mouseclick) # 注册响应鼠标点击的函数mouseclick

glutMotionFunc(mousemotion) # 注册响应鼠标拖拽的函数mousemotion

glutKeyboardFunc(keydown) # 注册键盘输入的函数keydown

十一、综合应用

是时候把我们上面讲的这些东西完整的演示一下了。下面的代码还是画了世界坐标系,并在原点前后各画了一个三角形。鼠标可以拖拽视点绕参考点旋转(二者距离保持不变),滚轮可以缩放模型。

敲击退格键或回车键可以让视点远离或接近参考点。敲击 x/y/z 可以减小参考点对应的坐标值,敲击 X/Y/Z 可以增大参考点对应的坐标值。敲击空格键可以切换投影模式。

opengl使用手册,opengl学习教程(8)

栏目热文

2022年达飞兑付能完成吗(达飞云贷不还5年了)

2022年达飞兑付能完成吗(达飞云贷不还5年了)

拿着结清证明都没用,因为助贷平台和资金方没有协商一致,导致借款人被再次催收、上逾期名单,甚至被起诉。这样的事情就发生在达...

2022-10-25 10:30:25查看全文 >>

达飞金融被法律承认吗(达飞云贷还用还吗)

达飞金融被法律承认吗(达飞云贷还用还吗)

达飞云贷此前就问题颇多,如今一份立案通知在多个群中传播开来,警方似乎已经开始对达飞云贷展开立案调查。撰文 | 昂格出品 ...

2022-10-25 10:19:43查看全文 >>

人死了为什么要盖住脸(人死后为什么要穿寿衣)

人死了为什么要盖住脸(人死后为什么要穿寿衣)

大家都知道,我国有很多约定俗成的习俗。有些习俗被视为封建陋习,有的则不然,比如丧葬就有很多习俗。中国丧葬死于始于原始社会...

2022-10-25 10:05:19查看全文 >>

一路走好天堂安息语句(一路走好图片)

一路走好天堂安息语句(一路走好图片)

生者幸福是对逝去亲人最好的安慰,为了老人家的希望你一定要努力让自己快乐起来!今天小编带来愿逝者安息的唯美句子,一起来看看...

2022-10-25 09:52:42查看全文 >>

opengl入门学习(opengl学习可以掌握哪些技术)

opengl入门学习(opengl学习可以掌握哪些技术)

作者:灵魂奏响曲博客:https://www.jianshu.com/p/21f4d6ee6863这是在Android中...

2022-10-25 10:22:35查看全文 >>

opengl使用说明书(opengl学习教程)

opengl使用说明书(opengl学习教程)

OpenGL是业界使用最广泛的2D和3D图形API,将成千上万的应用程序带到各种计算机平台上。它与窗口系统和操作系统无关...

2022-10-25 10:22:29查看全文 >>

opengl工具(opengl学习网站)

opengl工具(opengl学习网站)

GL StudioGL Studio是美国DiSTI公司的旗舰产品,它是一个独立平台的快速原型工具,用来创建实时的、照片...

2022-10-25 10:26:32查看全文 >>

opengl图解(opengl三个基本操作)

opengl图解(opengl三个基本操作)

在喜欢玩游戏的程序员眼里,OpenGL的魅力是极大的。这个用于渲染2D、3D矢量图形的API,在众多应用程序编程接口中,...

2022-10-25 10:06:33查看全文 >>

opengl自学看什么(opengl适合什么人学)

opengl自学看什么(opengl适合什么人学)

图形编程是计算机科学中最具挑战性的主题之一,并因此而闻名。当今,图形编程是基于着色器的——也就是说,有些程序是用诸如C ...

2022-10-25 10:27:15查看全文 >>

文档排行