PyOpenGL-安装与测试

1,目的

本文只是为了初步了解一下Python的OpenGL使用方法(整合前辈的技术Blog),至于绘图方面的博大精深,我们尚不知一二,有待于作者以后深入学习和实践,不在本文的讲述范围。不过,计算机绘图方面的技术深度和商业使用,是值得深入学习研究的。但是,是否是Python所长,就看以后的技术演化了。

2,安装

  • 执行Linux命令安装
pip install PyOpenGL PyOpenGL_accelerate
  • Windows下,Pycharm安装
    ** PyOpenGL
    ** PyOpenGL_accelerate

3,初级Demo

下面的代码,可以直接执行,详细的函数介绍,请查看:
用PyOpenGL叩开3D的心扉——OpenGL全解析(3)
http://eyehere.net/2011/learn-opengl-3d-by-pyopengl-3/

先上图:
此处输入图片的描述

再看代码:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

def drawFunc():
    glClear(GL_COLOR_BUFFER_BIT)
    # glRotatef(1, 0, 1, 0)
    glutWireTeapot(0.5)
    glFlush()

glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(400, 400)
glutCreateWindow("First")
glutDisplayFunc(drawFunc)
# glutIdleFunc(drawFunc)
glutMainLoop()

最后,代码介绍:

初始化窗口

11~17行基本也是固定的,

glutInit()是用glut来初始化OpenGL的,所有的问题都交给这个函数吧,基本不用管,虽说可以接受参数的,基本无用。

glutInitDisplayMode(MODE)非常重要,这里告诉系统我们需要一个怎样显示模式。至于其参数GLUT_RGBA就是使用(red,
green, blue)的颜色系统。有没有写错?这里有个A啊,不应该是(red, green, blue,
alpha)么?大概是历史原因,GLUT_RGBA和GLUT_RGB是其实是等价的(坑爹啊),要想实现Alpha还得用其他的参数。而GLUT_SINGLE意味着所有的绘图操作都直接在显示的窗口执行,相对的,我们还有一个双缓冲的窗口,对于动画来说非常合适。看看用Python和Pygame写游戏-从入门到精通(3)有些说明。

glutInitWindowSize(400,
400)这个函数很容易理解,设置出现的窗口的大小。实际上还有个glutInitWindowPosition()也很常用,用来设置窗口出现的位置。

glutCreateWindow(“First”),一旦调用了,就出现一个窗口了,参数就是窗口的标题。

glutDisplayFunc(func)是glut非常讨人喜欢的一个功能,它注册了一个函数,用来绘制OpenGL窗口,这个函数里就写着很多OpenGL的绘图操作等命令,也就是我们主要要学习的东西。

glutMainLoop(),主循环,一旦调用了,我们的OpenGL就一直运行下去了。和很多程序中的主循环一样,不停的运行,画出即时的图像,处理输入等。

绘图

看看drawFunc里的几句话,这里是实际绘图的函数。

glClear(GL_COLOR_BUFFER_BIT)是把先前的画面给清除,这基本是定律,每次重绘之前都要把原来的画面擦除,否则叠加起来什么都看不出了。glClear一看就知道是OpenGL原生的命令,而参数就是指明要清除的buffer。大家一定会有疑问,我们清除,不就是清除屏幕上的画面么,为什么还要指定?OpenGL的博大精深这里就体现出来了,buffer不仅仅有我们看到的那个GL_COLOR_BUFFER_BIT,OpenGL中还有其他的buffer类型,我们会在后面的章节讲到。

glutWireTeapot(0.5)是glut提供的绘制犹他茶壶的工具函数,茶壶还是相当复杂的一个几何体,用这个函数一下子就画出来了,不过基本也就演示用用。这里是用的线模型,因为没有说光照和材质,如果glutSolidTeapot()画出来就成纸片儿了。

glFlush()似乎不用多说,画了那么多,自然要刷新一下显示。不过,这里的刷新不仅仅是屏幕上的更新,实际上,它是处理OpenGL的渲染流水线,让所有排队中的命令得到执行。OpenGL的渲染流水线是一个很重要的概念,不过这里暂时还不打算多说明,否则对初学者来说,未免有些麻烦了。但是这并不意味着可以无视这些基础,知道怎么做只能让你优秀,知道为什么这么做才能让你卓越。

小惊喜

现在你可以把注释的两个语句打开了,执行以下看到什么?旋转的茶壶!不得不说帅多了~

glutIdleFunc(Func)又是一个激动人心的函数,可以让OpenGL在闲暇之余,调用一下注册的函数,这是是产生动画的绝好方法。

glRotatef(1, 0, 1,
0)是一个我们以后会详细讲的函数,简单来说四个参数第一个是角度,后三个是一个向量,意义就是绕着这个向量旋转,这里是绕着Y轴旋转1°。这一度一度的累加,最后使得茶壶围绕Y轴不停的旋转。从这里我们也能看出来,我们指定了一个旋转的角度后,重新绘制并不会复位,而是在上一次旋转的结果上继续旋转。这是一个非常重要的概念,OpenGL是一个状态机,一旦你指定了某种状态,知道再指定位置,它会保持那种状态。不仅仅是旋转,包括以后的光照贴图等等,都遵循这样的规律。

好了,我们有了第一个PyOpenGL程序了,虽然离我们详细中的五光十色的立体世界还有些差距,不过毕竟画了点东西出来了(要知道,犹他茶壶在3D技术发展之初,是里程碑一般的作品)。慢慢的,我们会充实自己的知识,绘制出更靓丽的画面。

4,入门Demo

下面的代码可以直接执行,详细的代码请查看:
用PyOpenGL叩开3D的心扉——OpenGL全解析(5)
http://eyehere.net/2013/learn-opengl-3d-by-pyopengl-5/

先上图:
此处输入图片的描述

再看代码:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from numpy import *
import sys

global W, H, R
(W, H, R) = (500, 500, 10.0)


def init():
    glClearColor(1.0, 1.0, 1.0, 1.0)


def drawfunc():
    glClear(GL_COLOR_BUFFER_BIT)
    glColor3f(0.0, 0.0, 0.0)
    glBegin(GL_POINTS)
    for x in arange(-R, R, 0.04):
        print '%.1f%%r' % ((R + x) / (R + R) * 100),
        for y in arange(-R, R, 0.04):
            r = cos(x) + sin(y)
            glColor3f(cos(y * r), cos(x * y * r), sin(x * r))
            glVertex2f(x, y)
    print '100%!!'
    glEnd()
    glFlush()


def reshape(w, h):
    if h <= 0: h = 1;
    glViewport(0, 0, w, h)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    if w <= h:
        gluOrtho2D(-R, R, -R * h / w, R * h / w)
    else:
        gluOrtho2D(-R * w / h, R * w / h, -R, R)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()


def keyboard(key, x, y):
    if key == chr(27) or key == "q":  # Esc is 27
        sys.exit()

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowPosition(20, 20)
    glutInitWindowSize(W, H)
    glutCreateWindow("Artist Drawer")
    glutReshapeFunc(reshape)
    glutDisplayFunc(drawfunc)
    glutKeyboardFunc(keyboard)
    init()
    glutMainLoop()

main()

最后,代码介绍:

glViewport:指定了视口程序显示的范围,也就是OpenGL绘制的范围,这里使用(0, 0, w,
h)便是说明整个窗口,一般情况下总是如此,但是我们也是可以指定小于这个范围的ViewPort的。事实上我隐瞒了很多细节,这个函数必须和下面要讲的gluOrtho2D函数一起用才能出现正确的结果。
gluOrtho2D:这个函数派生于OpenGL的glOrtho,它创建了一个正交的视景体(View
Volume),我们所看到的物体,都处在这个体中,四个参数分别代表了(left, right, bottom,
top),也就是竖直的左右边界和水平的下上边界;而近远则是默认的(-1,
1),glOrtho有六个参数可以设定。这个体越大,我们看到的东西就越小;反之看到的东西就越大。我知道这样很难理解,打个比方就是一个六边形的鱼缸,这个函数定出了一个鱼缸的大小,我们所看的东西呢,都在这个鱼缸里面。
上面说glViewport要和gluOrtho2D一起用才能正确显示是个什么意思呢?gluOrtho2D只管创建一个视体,而glViewport只管绘图的范围,如果视体是个正方体,而窗口是个长方体,直接绘制的结果会是什么呢?很明显,整个视体里的东西都被拉长了,而一般我们viewport都是指明了窗口大小,自然只能修改视体来适应各种不同的比例了。
修改代码,拉伸窗口,查看最终的结果会是怎样的。

glMatrixMode:这个函数非常难以理解,但是又极其重要!这关系到了OpenGL中的“矩阵”的概念。矩阵……你是说黑客帝国么?好像很有趣诶~~
嗯嗯没错,矩阵是个伟大的东西,通过它,3D世界的所有维度都蜷曲到内存中的一维数据里去了。这是一个有点儿抽象的概念但其实也没什么特别的,OpenGL里有如下几种矩阵:

GL_MODELVIEW:模型观察矩阵,表示物体的位置变化和观察点的改变;
GL_PROJECTION:投影矩阵,描述如何将一个物体投影到平面上; GL_TEXTURE:纹理矩阵,描述纹理坐标的动态变化 …
我不想搬出一堆数字和大括号来说明矩阵的基本运算和应用(好吧其实真实原因是我也不会:),也不会告诉你最后的ModelView矩阵是View矩阵与Model矩阵的乘积,更不会告诉你有glRotate和glTranslate之流的函数来改变矩阵!暂时这么理解就好了,矩阵就是我们走路的方向,我们现在朝南走,看到的南边的风景,然后说“向右拐”,现在看到西边的风景了,再说“向后转”,现在看到东边的风景了。就是通过这样可以累积的变换,我们把我们最初的一些数据变成了更复杂的东西表达了出来,转了几圈后也许有点糊涂了,用glLoadIdentity将当前指定的矩阵还原为最初的状态。

5,参考页面

PyOpenGL安装
http://pyopengl.sourceforge.net/
用PyOpenGL叩开3D的心扉——OpenGL全解析(3)
http://eyehere.net/2011/learn-opengl-3d-by-pyopengl-3/
用PyOpenGL叩开3D的心扉——OpenGL全解析(5)
http://eyehere.net/2013/learn-opengl-3d-by-pyopengl-5/

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值