使用Gtk.GLArea

时间:2018-07-27 01:16:19

标签: python opengl gtk pygobject

编辑2-已解决 看来这是已修复的已知GDK Win32错误。现在,由于我使用的是最新版本的PyGObject多合一安装程序,因此我只需要弄清楚如何修补或更新。

Bugzilla post

END EDIT 2

我在Win7上使用Pygobject,并且在创建多个顶层窗口时,如果使用GLArea小部件,则gl命令似乎都在我创建的最后一个窗口上绘制。我正在分别编译着色器。我从on_render()方法内部调用gl代码,这应该意味着GLArea的上下文是最新的。我什至尝试调用具有相同结果的make_current()方法。甚至更奇怪的是,最后一个窗口绘制似乎“窃取”了Gtk.Widget的上下文,并且所有Windows窗口小部件都绘制在一个上。这似乎是Windows上gtk的一个错误,但是我没有足够的经验说我没有违反某些gl或gtk规则。我还找到了相关的GTK +帖子,所以我想这可能是一个重复的问题。 GTK3 + OpenGL for windows: multiple GtkGLArea (ie. OpenGL contexts) 那条帖子没有答案。

编辑1

我在linux(Mint 18.1)中尝试了此确切的代码,并且可以正常工作。我还在单个窗口上尝试了多个GLAreas,并且没有问题。我调试了render方法,以查看正在使用的上下文,窗口和眩光对象。它们都符合应有的条件。我试图查看所有上下文是否具有相同的窗口,但事实并非如此。即使上下文的窗口不同并且正确的上下文是“当前”,窗口系统似乎也绘制在同一窗口上。

END EDIT1

查看图片: context issue

context issue with labels

这是我的代码:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject
settings = Gtk.Settings.get_default()
settings.set_property("gtk-application-prefer-dark-theme", True)
from OpenGL.GL import *
from OpenGL.GL import shaders
import numpy as np

class MyGLArea(Gtk.GLArea):
    def __init__(self, window):
        self.window = window # use for to to context and window
        super(MyGLArea, self).__init__()
        self.shader_prog = None
        self.realized = False
        self.vao = None
        self.data_loaded = None
        self.vert_data = None
        self.connect("realize", self.on_realize)
        self.connect("render", self.on_render)

    def compile_shaders(self):
        vert_source = '''
                    #version 410
                    in vec4 vert;
                    in vec4 in_color;
                    out vec4 color;
                    void main () {
                        color = in_color;
                        gl_Position = vert;
                    }
                    '''
        vert_shader = shaders.compileShader(vert_source, GL_VERTEX_SHADER)
        frag_source = '''
                        #version 410

                        in vec4 color;
                        out vec4 fColor;

                        void main () {
                            fColor = color;
                        }'''
        frag_shader = shaders.compileShader(frag_source, GL_FRAGMENT_SHADER)
        self.shader_prog = shaders.compileProgram(vert_shader, frag_shader)

    def on_realize(self, area):
        self.realized = True

    def on_render(self, area, context):
        if not self.shader_prog:
            self.compile_shaders()
        if not self.vao:
            self.vao = glGenVertexArrays(1)
        if not self.data_loaded:
            # make some verts
            self.vert_data = np.array([-0.6, -0.6, 0.0, 1.0,
                                  0.0, 0.6, 0.0, 1.0,
                                  0.6, -0.6, 0.0, 1.0,
                                  -0.6, -0.6, 0.0, 1.0,
                                  ], dtype=np.float32)
            # Generate buffer to hold vertices
            vbo = glGenBuffers(1)
            glBindBuffer(GL_ARRAY_BUFFER, vbo)
            glBufferData(GL_ARRAY_BUFFER, len(self.vert_data) * sizeof(GLfloat), None, GL_STATIC_DRAW)
            glBindVertexArray(self.vao)
            # bind buffer
            glBindBuffer(GL_ARRAY_BUFFER, vbo)
            #stuff buffer
            glBufferSubData(GL_ARRAY_BUFFER,
                            0 * sizeof(GLfloat), #offset
                            len(self.vert_data) * sizeof(GLfloat),
                            self.vert_data)
            vert_ID = glGetAttribLocation(self.shader_prog, 'vert')
            glVertexAttribPointer(vert_ID, 4, GL_FLOAT, 0, 0, ctypes.c_void_p(0))
            glEnableVertexAttribArray(vert_ID)
            glBindBuffer(GL_ARRAY_BUFFER, 0)
            glBindVertexArray(0)
            self.data_loaded = True
        #draw every render
        glBindVertexArray(self.vao)
        color_ID = glGetAttribLocation(self.shader_prog, 'in_color')
        # set color
        if color_ID >= 0:
            glVertexAttrib4f(color_ID, 1.0,0.0,0.0,1.0)
        else:
            print('gl color attrib failure')
        glUseProgram(self.shader_prog)
        glLineWidth(2)
        glDrawArrays(GL_LINE_STRIP, 0, len(self.vert_data)/4)
        glBindVertexArray(0)
        glUseProgram(0)








for x in range(3):
    win = Gtk.Window()
    win.connect("delete-event", Gtk.main_quit)
    box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
    box.pack_start(MyGLArea(win), 1, 1, 0)
    box.pack_start(Gtk.Label('WTF???'), 0, 0, 0)
    win.set_title(str(win))
    win.add(box)
    win.show_all()

Gtk.main()

0 个答案:

没有答案