Earlier we introduced running turtle in Tkinter. This section introduces running OpenGL components in Tkinter.
Among the support modules of HP_tk2, we have this module HP_tko. Using the HP_tko module, you can put the Tkinter component of OpenGL in the Tkinter window to realize 3D animation.
The demo code is given below.
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()
The following is the result of the operation.
The OpenglFrame component is an OpenGL drawing area placed in the Tkinter window. OpenGL drawing commands are executed in this drawing area to implement 3D animation.
The source code of opengl_demo is given below.
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()
The reason for the slower graphics display is that we use tkinter's after method to render every 5 seconds.
def _render_loop(self):
self.render_scene()
...
self.parent.after(5, self._render_loop)
In actual use, multi-threading and looping are used to achieve high-speed graphics rendering.
Of course, you can also insert textures to achieve complex animations.