前面我们介绍了在Tkinter中运行turtle。这节介绍在Tkinter中运行OpenGL组件。
HP_tk2的支持模块中,我们有这个模块HP_tko。利用HP_tko模块,可以在Tkinter窗口中,放OpenGL的Tkinter组件,来实现三维动画。
下面给出演示代码。
import tkinter as tk #导入Tkinter
from HP_tko import OpenglFrame,opengl_demo
from HP_tko import GL_BLEND, GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_DEPTH_TEST, \
GL_MODELVIEW, GL_ONE_MINUS_SRC_ALPHA, GL_PROJECTION, GL_QUADS, GL_RENDERER, \
GL_SRC_ALPHA, GL_VENDOR, GL_VERSION, \
glBegin, glClear, glBlendFunc, glClearColor, \
glClearDepth, glColor3f, glEnable, glEnd, glGetString, glFlush, \
glLoadIdentity, glMatrixMode, glOrtho, glRotatef, glVertex3f, glViewport
root=tk.Tk()
root.title('Tkinter中的OpenGL演示')
root.geometry('{}x{}+{}+{}'.format(800, 600, 100, 200))
o = opengl_demo(root, width=320, height=200)
o.pack(fill=tk.BOTH, expand=tk.YES)
root.mainloop()
下面是运行的结果。
OpenglFrame组件是在Tkinter窗口中放置的OpenGL绘图区,在这个绘图区执行OpenGL绘图命令来实现三维动画。
下面给出opengl_demo的源代码。
class opengl_demo(OpenglFrame):
rot = 0
def on_resize(self, event, arg=None):
if event:
w = event.width
h = event.height
else:
if arg:
w = arg['w']
h = arg['h']
else:
raise Exception
dx = w/h
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(
-2 * dx,
2 * dx,
-2,
2,
-2,
2
)
def set_ortho_view(self):
glEnable(GL_BLEND)
glEnable(GL_DEPTH_TEST)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glClearColor(0, 0, 0, 0)
glClearDepth(1)
glMatrixMode(GL_PROJECTION)
self.on_resize(None, arg={
'w': self.winfo_width(),
'h': self.winfo_height()
})
print('%s - %s - %s' % (
glGetString(GL_VENDOR),
glGetString(GL_VERSION),
glGetString(GL_RENDERER)
))
def render_scene(self):
self.rot += .5
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glRotatef(self.rot, 1, 1, 0.5)
# Draw a simple cube.
glBegin(GL_QUADS)
glColor3f(0, 1, 0)
glVertex3f(1, 1, -1)
glVertex3f(-1, 1, -1)
glVertex3f(-1, 1, 1)
glVertex3f(1, 1, 1)
glColor3f(1, 0.5, 0)
glVertex3f(1, -1, 1)
glVertex3f(-1, -1, 1)
glVertex3f(-1, -1, -1)
glVertex3f(1, -1, -1)
glColor3f(1, 0, 0)
glVertex3f(1, 1, 1)
glVertex3f(-1, 1, 1)
glVertex3f(-1, -1, 1)
glVertex3f(1, -1, 1)
glColor3f(1, 1, 0)
glVertex3f(1, -1, -1)
glVertex3f(-1, -1, -1)
glVertex3f(-1, 1, -1)
glVertex3f(1, 1, -1)
glColor3f(0, 0, 1)
glVertex3f(-1, 1, 1)
glVertex3f(-1, 1, -1)
glVertex3f(-1, -1, -1)
glVertex3f(-1, -1, 1)
glColor3f(1, 0, 1)
glVertex3f(1, 1, -1)
glVertex3f(1, 1, 1)
glVertex3f(1, -1, 1)
glVertex3f(1, -1, -1)
glEnd()
glFlush()
图形显示比较慢的原因,我们采用了tkinter的after方法,每5秒渲染一次。
def _render_loop(self):
self.render_scene()
...
self.parent.after(5, self._render_loop)
实际使用要用多线程,循环方式实现高速图形渲染。
当然也可以插入纹理,实现复杂的动画。