问题:这个简单的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_()
答案:代码中有两个错误。
正如Brett Hale所指出的,glBindAttribLocation
的来电必须在self._shaderProgram.link()
之前。
numpy.ndarray
应替换为numpy.array
。
如果您解决了这两个问题,那么代码将按预期工作。
答案 0 :(得分:2)
来自the man page for glBindAttribLocation
:
程序对象之后发生的任何属性绑定 链接在下次程序对象出现之前不会生效 联的。
首先关联属性索引,然后链接程序。
或者,使用_POSITION
为_COLOR
,glGetAttribLocation
等分配值。
如@KillianDS所述,您可以在着色器中指定索引(位置),前提是您具有GL 3.3或更高版本。这是OS X的挫败感,只有保证 GL 3.2。
可能还值得指出核心配置文件中不支持GL_QUADS
,因此可能需要解决这个问题,例如,使用2个三角形。
答案 1 :(得分:1)
我宁愿发表评论,但它很长。希望这可以帮助你:
由于您在顶点着色器中使用了attribute
关键字(兼容性关键字),您能否澄清一下您使用的OpenGL和GLSL版本?我没有在代码中看到任何引用该版本的内容;我想念它吗?这可能有助于理解问题所在。
如果有可用的话,layout
格式肯定会简化。 此外,您的着色器要求指定 1.10不需要(虽然仍然支持,但OP正在使用/打算使用。#version
(至少在latest spec中,但我认为它适用于所有版本。)
答案 2 :(得分:0)
我不熟悉Python下的Qt,但我很确定你需要使用glUseProgram
将着色器程序设置为活动状态。