简单的OpenGL/GLSL程序可以

2024-06-08 19:59:21 发布

您现在位置:Python中文网/ 问答频道 /正文

问题:这个简单的OpenGL/GLSL程序出了什么问题? 它应该产生一个具有红绿渐变色的四边形。 但我只看到一个黑色的窗口,没有错误信息。在

import numpy
from OpenGL.GL import *
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtOpenGL import *

_vertexShaderSource = (
    'attribute vec2 a_position;'
    'attribute vec3 a_color;'
    'varying vec3 v_color;'
    ''
    'void main()'
    '{'
    '   gl_Position = vec4(a_position, 0.0, 1.0);'
    '   v_color = a_color;'
    '}'
)

_fragmentShaderSource = (
    'varying vec3 v_color;'
    ''
    'void main()'
    '{'
    '    gl_FragColor = vec4(v_color, 1.0);'
    '}'
)

_POSITION = 0
_COLOR = 1

class HelloWidget(QGLWidget):

    def __init__(self):
        QGLWidget.__init__(self)

    def initializeGL(self):
        self._shaderProgram = QGLShaderProgram(self.context())
        self._shaderProgram.addShaderFromSourceCode(QGLShader.Vertex, _vertexShaderSource)
        self._shaderProgram.addShaderFromSourceCode(QGLShader.Fragment, _fragmentShaderSource)
        self._shaderProgram.link()
        self._shaderProgram.bind()

        glBindAttribLocation(self._shaderProgram.programId(), _POSITION, 'a_position')
        glBindAttribLocation(self._shaderProgram.programId(), _COLOR, 'a_color')

    def paintGL(self):
        glViewport(0, 0, self.width(), self.height())
        glClear(GL_COLOR_BUFFER_BIT)

        position = numpy.ndarray([-0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5], numpy.float32)
        glVertexAttribPointer(_POSITION, 2, GL_FLOAT, False, 0, position)
        glEnableVertexAttribArray(_POSITION)

        color = numpy.ndarray([1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0], numpy.float32)
        glVertexAttribPointer(_COLOR, 3, GL_FLOAT, False, 0, color)
        glEnableVertexAttribArray(_COLOR)

        glDrawArrays(GL_QUADS, 0, 4)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = HelloWidget()
    w.show()
    app.exec_()

答案:代码中有两个错误。在

  1. 正如Brett Hale所指出的,对glBindAttribLocation的调用必须在self._shaderProgram.link()之前。

  2. numpy.ndarray应替换为numpy.array

如果您修复了这两个问题,那么代码将按预期工作。在


Tags: fromimportselfnumpymaindefpositioncolor
3条回答

我本想发表评论的,但时间太长了。希望这能帮助您:

由于您在顶点着色器中使用了attribute关键字(兼容性关键字),您能澄清一下您使用的OpenGL和GLSL的版本吗?我在代码中没有看到任何与版本相关的内容;我错过了吗?这可能有助于理解问题所在。在

{cd2}如果你可以简化格式化的话。另外,着色器要求指定#version(至少在latest spec中,但我认为它适用于所有版本)。对于1.10(尽管仍然受支持)不是必需的,而OP正在使用/打算使用它。在

我不熟悉Python下的Qt,但我确信您需要使用glUseProgram将着色器程序设置为活动的。在

来自the man page for ^{}:

Any attribute binding that occurs after the program object has been linked will not take effect until the next time the program object is linked.

首先关联属性索引,然后链接程序。在

或者,使用glGetAttribLocation_POSITION_COLOR等赋值。在


正如@KillianDS所提到的,如果您有gl3.3或更高版本,您可以在着色器中指定索引(位置)。这是OSX的一个挫败之源,OSX只能保证GL3.2。在


还需要指出的是,GL_QUADS在核心配置文件中不受支持,因此可能需要解决这个问题,例如使用2个三角形。在

相关问题 更多 >