参考:http://pyopengl.sourceforge.net
pip install PyOpenGL PyOpenGL_accelerate
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()
运行结果,绘制出一个彩色三角形:
使用工具库(GLUT)创建 OpenGL 应用程序只需要四步:
(1)初始化glut库:glutInit()
(2)创建glut窗口:glutCreateWindow('Quidam Of OpenGL')
(3)注册绘图的回调函数: glutDisplayFunc(draw)
(4)进入glut主循环: glutMainLoop()
除了基本组成以外还可以:
(5)设置窗口初始显示模式:初始化 glut 库的时候,一般要用 glutInitDisplayMode() 来设置初始的显示模式。例如:
glutInitDisplayMode( GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
(6)初始化画布
glClearColor(0.0, 0.0, 0.0, 1.0) # 设置画布背景色。注意:这里必须是4个参数 glEnable(GL_DEPTH_TEST) # 开启深度测试,实现遮挡关系 glDepthFunc(GL_LEQUAL) # 设置深度测试函数
关于draw()函数的基本组成:
(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()命令设置当前操作矩阵为单位矩阵
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 三个向量.
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)设置视口
视口的大小和尺寸是在窗口坐标系中进行度量的, 默认状 态下其坐标原点位于窗口的左下角,其尺寸与窗口的大小 相同。
#glViewport(GLint x, Glint y, Glsizei width, Glsizei height) glViewport(0, 0, width, height)
(5)设置模型变换
模型平移、旋转、缩放等几何变换,需要切换到模型矩阵:
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)
同时使用视图变换和模型变换,需要先调用视图变换函数,后调用模型变换函数,以保证模型变换首先对物体起作用。
多种变换组合调用顺序 ,写函数的时候要注意顺序,否则可能不起作用
具体代码分析
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()
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
长按识别二维码并关注微信
更方便到期提醒、手机管理