【发布时间】:2017-11-30 04:28:08
【问题描述】:
使用 Gtk3 的 python 包装器的文档有些有限。我找到了几个常见的小部件示例。我正在尝试使用 Gtk.GLArea 小部件。 API 文档是针对 C 语言的,我没有太多运气来猜测使用这个小部件的等效 python 调用。在示例中,小部件是使用以下 C 代码创建的:
// create a GtkGLArea instance
GtkWidget *gl_area = gtk_gl_area_new ();
g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL);
那么渲染函数里面有OpenGL命令:
static gboolean
render (GtkGLArea *area, GdkGLContext *context)
{
// inside this function it's safe to use GL; the given
// #GdkGLContext has been made current to the drawable
// surface used by the #GtkGLArea and the viewport has
// already been set to be the size of the allocation
// we can start by clearing the buffer
glClearColor (0, 0, 0, 0);
glClear (GL_COLOR_BUFFER_BIT);
// draw your object
draw_an_object ();
// we completed our drawing; the draw commands will be
// flushed at the end of the signal emission chain, and
// the buffers will be drawn on the window
return TRUE;
}
我的问题是你如何在 python 中做同样的事情?
这是我的尝试:
class RootWidget(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title='GL Example')
self.set_default_size(800,500)
gl = Gtk.GLArea()
gl.connect("render", self.gl_render)
self.add(gl)
def gl_render(self, gl):
print(gl)
Gtk.glClearColor(0,0,0,1)
Gtk.glClear(Gtk.GL_COLOR_BUFFER_BIT)
return True
您会注意到我添加了“Gtk”。到 gl 命令。不确定这是否正确,但 python 不知道函数中的 glClearColor 是什么。我对 C 命名空间不是很熟悉,但我也不知道 C 函数如何理解 gl 命令是什么。该程序确实运行,我在控制台中收到以下错误:
不支持FB设置
(python.exe:120048): Gdk-WARNING **: 片段编译失败 着色器:
错误:0:5:'gl_FragColor':未声明的标识符
错误:0:5:'texture2D':找不到匹配的重载函数(使用 隐式转换)
对此的任何意见都会很有用。我希望能够使用 opengl 命令在固定的小部件区域进行绘制。
编辑:
这是我最近的尝试。在on_render() 函数中,我打印上下文,我确实看到上下文属性设置为<gtk.gdk.Win32GLContext object at 0x3f133f0>,并且调试确实表明这是当前上下文。问题是我仍然得到相同的着色器、Frag_Color 和纹理错误,而且我什至没有调用任何 gl 命令。
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from OpenGL.GL import *
from OpenGL.GLU import *
class MyGLArea(Gtk.GLArea):
def __init__(self):
Gtk.GLArea.__init__(self)
self.connect("realize", self.on_realize)
def on_realize(self, area):
ctx = self.get_context()
ctx.make_current()
print("The context is {}".format(self.get_property("context")))
err = self.get_error()
if err:
print(err)
return
class RootWidget(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title='GL Example')
self.set_default_size(800,500)
gl_area = MyGLArea()
self.add(gl_area)
win = RootWidget()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
编辑 2: 好像我只是遇到了 GLArea 小部件的安装问题。看起来很奇怪,因为我使用了 30 多个不同的 Gtk 小部件而没有问题。我有错误只是添加小部件,甚至没有发送命令。我在 Ubuntu python 解释器中运行代码,它在创建小部件时没有任何错误。我对某些 GL 命令有一些问题,但可能来自我安装的 python 包装器。我仍在寻找与 pygame 或 glut 的 init 等效的小部件,并设置投影函数来设置视口。如果有人有想法,我很想听听。以下代码运行时没有错误:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from OpenGL.GL import *
from OpenGL.GLU import *
class MyGLArea(Gtk.GLArea):
def __init__(self):
Gtk.GLArea.__init__(self)
self.connect("realize", self.on_realize)
self.connect("render", self.render)
def on_realize(self, area):
ctx = self.get_context()
ctx.make_current()
err = self.get_error()
if err:
print("The error is {}".format(err))
def render(self, area, ctx):
glClearColor(1,0,0,1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
return True
class RootWidget(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title='GL Example')
self.set_default_size(800,500)
gl_area = MyGLArea()
self.add(gl_area)
win = RootWidget()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
【问题讨论】:
-
python 文档:lazka.github.io/pgi-docs/#Gtk-3.0/classes/GLArea.html。但我同意示例是用 C 语言编写的,这是一个问题。
-
glClearColor 不在 GTK 中,它在 opengl 库中:khronos.org/registry/OpenGL-Refpages/gl4/html/…。该库必须有一些 python 包装器,它似乎被命名为 PyOpenGL:pyopengl.sourceforge.net
-
这里有一个 PyOpenGL 教程,可以帮助您入门:pythonprogramming.net/…
-
@liberforce 谢谢。这清除了 gl 命令的来源。我确实运行了 pygame 教程,它的工作方式与我想在 gtk 中使用它的方式完全相同,只是它不是一个单独的窗口,而是一个小部件。阅读 Gdk.GLContext 的 API 文档,一旦上下文变为“当前”,它将接受 gl 命令。我什至在发送之前收到 gl 错误。