【问题标题】:How do I get PyOpenGL to work with a wxPython context, based on this C++ Modern OpenGL tutorial?基于此 C++ Modern OpenGL 教程,如何让 PyOpenGL 与 wxPython 上下文一起工作?
【发布时间】:2017-02-05 15:34:44
【问题描述】:

我一直在关注this tutorial,使用着色器和现代 OpenGL 功能(例如顶点数组对象和顶点缓冲区对象)绘制一个简单的三角形。教程代码是用 C++ 编写的,但我认为无论您使用哪种绑定,OpenGL 都是相同的,因此很容易转置为 Python。主要区别是我使用 wxPython glCanvas 上下文来创建一个窗口来绘制。这是我到目前为止所拥有的:

import wx
from wx import glcanvas
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GL.ARB.shader_objects import *
from OpenGL.GL.ARB.fragment_shader import *
from OpenGL.GL.ARB.vertex_shader import *
import numpy as np

vertexSource = """
#version 130
in vec2 position;
void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
}
"""
fragmentSource = """
#version 130
out vec4 outColor;
void main()
{
    outColor = vec4(1.0, 1.0, 1.0, 1.0);
}
"""

class OpenGLCanvas(glcanvas.GLCanvas):
    def __init__(self, parent):
        glcanvas.GLCanvas.__init__(self, parent, -1, size=(640, 480))
        self.init = False
        self.context = glcanvas.GLContext(self) 

    self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
    self.Bind(wx.EVT_PAINT, self.OnPaint)

def OnEraseBackground(self, event):
    pass # Do nothing, to avoid flashing on MSW.

def OnPaint(self, event):
    dc = wx.PaintDC(self)
    self.SetCurrent(self.context)
    if not self.init:
        self.InitGL()
        self.init = True
    self.OnDraw()

def InitGL(self):

    # Vertex Input
    ## Vertex Array Objects
    vao = glGenVertexArrays(1)
    glBindVertexArray(vao)

    ## Vertex Buffer Object
    vbo = glGenBuffers(1) # Generate 1 buffer

    vertices = np.array([0.0,  0.5, 0.5, -0.5, -0.5, -0.5], dtype=np.float32)

    ## Upload data to GPU
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)

    # Compile shaders and combining them into a program
    ## Create and compile the vertex shader
    vertexShader = glCreateShader(GL_VERTEX_SHADER)
    glShaderSource(vertexShader, vertexSource)
    glCompileShader(vertexShader)

    ## Create and compile the fragment shader
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
    glShaderSource(fragmentShader, fragmentSource)
    glCompileShader(fragmentShader)

    ## Link the vertex and fragment shader into a shader program
    shaderProgram = glCreateProgram()
    glAttachShader(shaderProgram, vertexShader)
    glAttachShader(shaderProgram, fragmentShader)
    glBindFragDataLocation(shaderProgram, 0, "outColor")
    glLinkProgram(shaderProgram)
    glUseProgram(shaderProgram)

    # Making the link between vertex data and attributes
    posAttrib = glGetAttribLocation(shaderProgram, "position")
    glEnableVertexAttribArray(posAttrib)
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0)

def OnDraw(self):
    # Set clear color
    glClearColor(0.0, 0.0, 0.0, 1.0)
#Clear the screen to black
    glClear(GL_COLOR_BUFFER_BIT)

    # draw six faces of a cube
    glDrawArrays(GL_TRIANGLES, 0, 3)

    self.SwapBuffers()

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Hello World", size=(640,480))
        canvas = OpenGLCanvas(self)

app = wx.App()
frame = Frame()
frame.Show()
app.MainLoop()

当我运行代码时,没有 python 错误或 OpenGL 错误,并且着色器似乎可以正确编译。但是,它只是绘制了一个黑色窗口,没有三角形。我不认为这是 wxPython 的 glcanvas.GLContext 的问题,因为在使用已弃用的 glBegin() 和 glEnd() 命令之前,我已经成功地使用它来绘制三角形。

顺便说一句,someone has converted the same tutorial to use Python and a pyglet context,它工作得很好,但是我想在我的 GUI 中使用 wxPython。以前有人用过这个吗?

【问题讨论】:

    标签: python python-2.7 wxpython opengl-3 pyopengl


    【解决方案1】:

    如果你仍然有这个问题,我认为问题出在下面这行和 PyOpenGL 的工作方式上。我发现只需进行以下修复即可使您的演示正常工作。

    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, None)
    

    显然 0 != 绑定中没有!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 2023-02-02
      相关资源
      最近更新 更多