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

回答:コードには2つのバグがあります。

  1. ブレット・ヘイルが指摘したように、への呼びかけはglBindAttribLocation前に来なければなりません。self._shaderProgram.link()

  2. numpy.ndarrayに置き換える必要がありますnumpy.array

これらの2つの問題を修正すると、コードは期待どおりに機能します。

4

3 に答える 3

2

のマニュアルページからglBindAttribLocation

プログラムオブジェクトがリンクされた後に発生する属性バインディングは、次にプログラムオブジェクトがリンクされるまで有効になりません。

最初に属性インデックスを関連付けてから、プログラムリンクします。

_POSITIONまたは、を使用して、_COLORなどに値を割り当てますglGetAttribLocation


@KillianDSで言及されているように、GL 3.3以降を使用している場合は、シェーダーでインデックス(場所)を指定できます。これは、GL3.2のみを保証するOSXのフラストレーションの原因です。


コアプロファイルでサポートされていないことも指摘する価値があるかもしれない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 に答える