0

问题:这个简单的 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必须先调用 to 。self._shaderProgram.link()

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

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

4

3 回答 3

2

手册页glBindAttribLocation

在程序对象被链接之后发生的任何属性绑定直到下次程序对象被链接时才会生效。

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

_POSITION或者,使用 为、_COLOR等赋值glGetAttribLocation


正如@KillianDS 所提到的,您可以在着色器中指定索引(位置),前提是您拥有 GL 3.3 或更高版本。这是 OS X 上令人沮丧的根源,它只保证GL 3.2。


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

于 2012-12-01T13:07:39.013 回答
1

我宁愿发表评论,但它很长。希望这可以帮助您:

由于您attribute在顶点着色器中使用了关键字(兼容性关键字),您能否说明您使用的是哪个版本的 OpenGL 和 GLSL?我在您的代码中看不到任何与版本相关的内容;我错过了吗?了解问题所在可能会有所帮助。

如果您有可用的格式,layout格式肯定会简化事情。此外,您的着色器需要#version指定它(至少在最新规范中,尽管我认为它适用于所有版本)。OP 正在使用/打算使用的 1.10(尽管仍受支持)不是必需的。

于 2012-12-01T17:54:23.747 回答
0

我不熟悉 Python 下的 Qt,但我很确定您需要使用glUseProgram.

于 2012-12-01T11:51:40.480 回答