用Tkinter打造GUI开发工具(33)Tkinter中的OpenGL组件

112 篇文章 45 订阅
104 篇文章 107 订阅

前面我们介绍了在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)

实际使用要用多线程,循环方式实现高速图形渲染。

当然也可以插入纹理,实现复杂的动画。
在这里插入图片描述

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荷蒲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值