OpenGL基本配置方式
参考:http://pyopengl.sourceforge.net
pip 安装 PyOpenGL
1
|
pip install PyOpenGL PyOpenGL_accelerate |
测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * def init(): glClearColor( 1 , 1 , 1 , 1 ) gluOrtho2D( - 1 , 1 , - 1 , 1 ) def triangle(): glClear(GL_COLOR_BUFFER_BIT) glColor3f( 1 , 0 , 0 ) glBegin(GL_TRIANGLES) glColor3f( 1 , 0 , 0 ) glVertex2f( - 1 , - 1 ) glColor3f( 0 , 1 , 0 ) glVertex2f( 1 , - 1 ) glColor3f( 0 , 0 , 1 ) glVertex2f( 0 , 1 ) glEnd() glFlush() def main(): glutInit(sys.argv) glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB) glutInitWindowSize( 800 , 600 ) glutInitWindowPosition( 50 , 50 ) glutCreateWindow( "Triangle" ) glutDisplayFunc(triangle) init() glutMainLoop() if __name__ = = '__main__' : main() |
运行结果,绘制出一个彩色三角形:
Python+OpenGL库理解及代码应用
1.读取off文件
使用工具库(GLUT)创建 OpenGL 应用程序只需要四步:
(1)初始化glut库:glutInit()
(2)创建glut窗口:glutCreateWindow('Quidam Of OpenGL')
(3)注册绘图的回调函数: glutDisplayFunc(draw)
(4)进入glut主循环: glutMainLoop()
除了基本组成以外还可以:
(5)设置窗口初始显示模式:初始化 glut 库的时候,一般要用 glutInitDisplayMode() 来设置初始的显示模式。例如:
1
|
glutInitDisplayMode( GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH) |
(6)初始化画布
1
2
3
|
glClearColor( 0.0 , 0.0 , 0.0 , 1.0 ) # 设置画布背景色。注意:这里必须是4个参数 glEnable(GL_DEPTH_TEST) # 开启深度测试,实现遮挡关系 glDepthFunc(GL_LEQUAL) # 设置深度测试函数 |
关于draw()函数的基本组成:
(1)清除屏幕及深度缓存
1
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) |
(2)设置投影
投影设置也是每次重绘都需要的步骤之一。glOrtho() 用来设置平行投影,glFrustum() 用来设置透视投影。这两个函数的参数相同,都是视景体的 left / right / bottom / top / near / far 六个面。视景体的 left / right / bottom / top 四个面围成的矩形,就是视口。near 就是投影面,其值是投影面距离视点的距离,far 是视景体的后截面,其值是后截面距离视点的距离。far 和 near 的差值,就是视景体的深度。视点和视景体的相对位置关系是固定的,视点移动时,视景体也随之移动。假设 view 是视景体,width 和 height 是窗口的宽度和高度,在投影变换之前,需要先声明是对投影矩阵的操作,并将投影矩阵单位化:
glMatrixMode(GL_PROJECTION) ,含义为选定矩阵为模型-观察变换 矩阵
OpenGL中的变换命令都是对当前矩阵(当前矩阵为以后图形变换所要使用的矩阵)进行操作,因此在选定可修#改矩阵后,应首先用glLoadIdentity()命令设置当前操作矩阵为单位矩阵
1
2
3
4
5
6
7
8
|
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 ]) |
(3)设置视点
视点是和视景体关联的概念。设置视点需要考虑眼睛在哪儿、看哪儿、头顶朝哪儿,分别对应着eye, lookat 和 eye_up 三个向量.
1
2
3
4
5
6
7
8
|
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 ] ) |
(4)设置视口
视口的大小和尺寸是在窗口坐标系中进行度量的, 默认状 态下其坐标原点位于窗口的左下角,其尺寸与窗口的大小 相同。
1
2
|
#glViewport(GLint x, Glint y, Glsizei width, Glsizei height) glViewport( 0 , 0 , width, height) |
(5)设置模型变换
模型平移、旋转、缩放等几何变换,需要切换到模型矩阵:
1
2
3
4
5
6
7
8
9
10
|
glMatrixMode(GL_MODELVIEW) glLoadIdentity() #平移操作函数 glTanslate(x,y,z) #平移,(x,y,z,1)乘以 N(4x4矩阵)进行矩阵变换 glMultMatrixf(N) #旋转函数,绕矢量v=(x,y,z)T逆时针方向旋转angle指定的角度。 glRotate(angle,x,y,z) #缩放函数 glScale( 1.0 , 1.0 , 1.0 ) |
同时使用视图变换和模型变换,需要先调用视图变换函数,后调用模型变换函数,以保证模型变换首先对物体起作用。
多种变换组合调用顺序 ,写函数的时候要注意顺序,否则可能不起作用
具体代码分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import numpy as np def readOFF(): file_path = '../off/m1.off' f = open (file_path, 'r' , encoding = 'utf-8' ) lines = f.readlines() m = [] n = [] #把off文件中数据按行读取出来,存储到列表中,由于边数事先看了为0,所以没遍历边,如果边不为0,记得遍历,并在后文加上边的绘制 for line in lines: m.append(line.split()) for i in range ( len (m)): #跳过第一行的OFF if m[i][ 0 ] = = 'OFF' : continue #记录定点数,面片数和边数 elif i = = 1 : v_cout = int (m[i][ 0 ]) f_count = int (m[i][ 1 ]) e_count = int (m[i][ 2 ]) continue #把字符型数据转化为数值型数据 else : for j in range ( len (m[i])): m[i][j] = float (m[i][j]) n.append(m[i]) return v_cout, f_count, e_count, n #绘画模型 def draw(): global angle #读取OFF文件包含的顶点,面片,边和off文件存储数据信息 v_cout, f_count, e_count, n = readOFF() # 设置渲染背景 glClearColor( 0.0 , 0.0 , 0.0 , 0.0 ) #清除缓存 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) # 设置投影(透视投影) glMatrixMode(GL_PROJECTION) glLoadIdentity() # 投影变换 gluPerspective( 100 , 1 , 0.5 , 100 ) angle + = 0.05 while angle > 360 : angle - = 360 glMatrixMode(GL_MODELVIEW) glLoadIdentity() # 视口变换 glViewport( 100 , 100 , 500 , 500 ) #设置观察变换 #设置视点 gluLookAt( - 5 , 5 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , ) #设置模型变换 #平移 glTranslate( 1 , 1 , 0 ) #旋转 glRotatef(angle, - 5 , 5 , 0 ) # 缩放 glScalef( 5 , 5 , 5 ) for i in range (f_count): #获取顶点个数,和顶点信息 cout , a, b, c = n[v_cout + i] cout, a, b, c = int (cout) , int (a) , int (b) , int (c) #得到顶点位置 a1, a2, a3 = n[a] b1, b2, b3 = n[b] c1, c2, c3 = n[c] #绘制多面体 glBegin(GL_POLYGON) glVertex3f(a1, a2, a3) glVertex3f(b1, b2, b3) glVertex3f(c1, c2, c3) glEnd(); # 刷新缓存 glFlush() #关闭窗口 def close(key,x,y): if key = = b '\x1b' : glutDestroyWindow(win_id) if __name__ = = "__main__" : angle = 0 # 初始化glut窗口 glutInit() # 设置窗口显示模式:RGBA四通道|单缓存|深度 glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE | GLUT_DEPTH) # 初始化窗口大小 glutInitWindowSize( 1000 , 800 ) # 创建窗口 win_id = glutCreateWindow( "CUBE" ) # 设置渲染函数 glutDisplayFunc(draw) # 设置窗口空闲时函数 glutIdleFunc(draw) # 开启深度测试 glEnable(GL_DEPTH_TEST) # 开启窗口主循环 glutMainLoop() |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/linian71/article/details/79074193