gpt4 book ai didi

opengl - Pygobject GTK3 中 Gtk.GLArea 的使用

转载 作者:行者123 更新时间:2023-12-02 03:43:34 26 4
gpt4 key购买 nike

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 setup not supported

(python.exe:120048): Gdk-WARNING **: Compile failure in fragmentshader:

ERROR: 0:5: 'gl_FragColor' : undeclared identifier

ERROR: 0:5: 'texture2D' : no matching overloaded function found (usingimplicit conversion)

对此的任何输入都会有用。我的希望是能够使用 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 命令时遇到一些问题,但可能来 self 安装的 python 包装器。我仍在寻找相当于 pygame 或 glut 的 init 的小部件,并设置投影函数来设置视口(viewport)。如果有人有想法,我很想听听。以下代码运行时没有错误:

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()

最佳答案

使用 Windows 的一体式安装程序时,我注意到有一个 OpenGL 扩展至 GTK+ 的选项。现在它按预期工作了。这是一些工作代码:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from OpenGL.GL import *
from OpenGL.GL import shaders
import numpy as np

FRAGMENT_SOURCE ='''
#version 330
in vec4 inputColor;
out vec4 outputColor;
void main(){
outputColor = vec4(1.0,0.0,0.0,1.0);//constant red. I know it's a poor shader
};'''

VERTEX_SOURCE = '''
#version 330
in vec4 position;
void main(){
gl_Position = position;
}'''

class MyGLArea(Gtk.GLArea):
def __init__(self):
Gtk.GLArea.__init__(self)
self.connect("realize", self.on_realize)
self.connect("render", self.on_render)

def on_realize(self, area):
ctx = self.get_context()
print("realized", ctx)

def on_render(self, area, ctx):
ctx.make_current()
glClearColor(0, 0, 0, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
VERTEX_SHADER_PROG = shaders.compileShader(VERTEX_SOURCE, GL_VERTEX_SHADER)
FRAGMENT_SHADER_PROG = shaders.compileShader(FRAGMENT_SOURCE, GL_FRAGMENT_SHADER)
self.shader_prog = shaders.compileProgram(VERTEX_SHADER_PROG, FRAGMENT_SHADER_PROG)
self.create_object()

def create_object(self):
# Create a new VAO (Vertex Array Object) and bind it
vertex_array_object = glGenVertexArrays(1)
glBindVertexArray(vertex_array_object)
# Generate buffers to hold our vertices
vertex_buffer = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
# Get the position of the 'position' in parameter of our shader and bind it.
position = glGetAttribLocation(self.shader_prog, 'position')
glEnableVertexAttribArray(position)
# Describe the position data layout in the buffer
glVertexAttribPointer(position, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0))
# Send the data over to the buffer
vertices = np.array([-0.6, -0.6, 0.0,
0.0, 0.6, 0.0,
0.6, -0.6, 0.0,
0.7, -0.1, 0.0,
0.8, 0.1, 0.0,
0.9, -0.1, 0.0
], dtype=np.float32)
glBufferData(GL_ARRAY_BUFFER, 96, vertices, GL_STATIC_DRAW)
# Unbind the VAO first (Important)
glBindVertexArray(0)
# Unbind other stuff
glDisableVertexAttribArray(position)




glBindBuffer(GL_ARRAY_BUFFER, 0)
self.display(vertex_array_object)

def display(self, vert):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(self.shader_prog)
glBindVertexArray(vert)
glDrawArrays(GL_TRIANGLES, 0, 3)
glDrawArrays(GL_TRIANGLES, 4, 3)
glBindVertexArray(0)
glUseProgram(0)

class RootWidget(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title='GL Example')
self.set_default_size(800, 500)
gl_area = MyGLArea()
gl_area.set_has_depth_buffer(False)
gl_area.set_has_stencil_buffer(False)
self.add(gl_area)

win = RootWidget()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

Triangle Install Options

关于opengl - Pygobject GTK3 中 Gtk.GLArea 的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47565884/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com