我正在使用PyOpenGL绘制一个简单的三角形。但是,我只得到一个空屏幕。我认为问题是我没有正确地将数据传递给glBufferData。我试着按照this stackoverflow question中的答案,但没有结果。着色器编译和工作正常,因为使用glBegin()和glVertex()工作。但是,使用glDrawElements或glDrawArrays绘图不起作用。这是我的代码(我在OpenGL窗口中使用pygame):
import numpy as np
import pygame as pg
from pygame.locals import *
from array import array
SCREEN_SIZE = (800, 600)
from OpenGL.GL import *
from OpenGL.GLU import *
def resize(width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/height, .1, 1000.)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def create_shader(shader_type,source):
shader = glCreateShader(shader_type)
glShaderSource(shader,source)
glCompileShader(shader)
print(glGetShaderiv(shader, GL_COMPILE_STATUS, None))
return shader
pg.init()
screen = pg.display.set_mode(SCREEN_SIZE, HWSURFACE|OPENGL|DOUBLEBUF)
resize(*SCREEN_SIZE)
#creating and compiling fragment shader
fragment = create_shader(GL_FRAGMENT_SHADER,"""
#version 130
out vec4 finalColor;
void main()
{
finalColor = vec4(.0,0.0,1.0,1.0);
}
""")
#creating and compiling vertex shader
vertex = create_shader(GL_VERTEX_SHADER,"""
#version 130
in vec3 pos;
void main()
{
gl_Position=gl_ProjectionMatrix*gl_ModelViewMatrix *vec4(pos,1.0);
}
""")
#create and link program
program = glCreateProgram()
glAttachShader(program, fragment)
glAttachShader(program, vertex)
glLinkProgram(program)
#get location of the position variable in vertex shader
posAttrib = glGetAttribLocation(program, "pos")
vbo=glGenBuffers(1)
ebo=glGenBuffers(1)
vao=glGenVertexArrays(1)
#specify the integer and float types to use in the glGenBuffer function
dtypei=np.dtype('<u4')
dtypef=np.dtype('<f4')
glBindVertexArray(vao)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, np.array([0,1,2],dtype=dtypei), GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
vert=[-1.5, -0.5, -4.0, -0.5, -0.5, -4.0, -0.5, 0.5, -4.0]
nparray = np.array(vert,dtype=dtypef)
glBufferData(GL_ARRAY_BUFFER, nparray, GL_STATIC_DRAW)
#can also try using the array library
#ar = array("f",vert)
#glBufferData(GL_ARRAY_BUFFER, ar.tostring(), GL_STATIC_DRAW)
#specify how the variable pos gets data from the buffer data
glEnableVertexAttribArray(posAttrib)
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 3*4,0)
while 1:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0, 1.0, 1.0, 0.0)
glUseProgram(program)
glBindVertexArray(vao)
#this draw function produces NOTHING
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0)
#can also try using glDrawArrays
#glDrawArrays(GL_TRIANGLES, 0, 3)
#this drawing produces a triangle
#glBegin(GL_TRIANGLES)
#glColor3f( 0,1,0 )
#glVertex3f( -1.5, -0.5, -4.0 )
#glColor3f( 0,1,1 )
#glVertex3f( -0.5, -0.5, -4.0 )
#glColor3f( 1,1,0 )
#glVertex3f( -0.5, 0.5, -4.0 )
#glEnd()
pg.display.flip()
pg.time.delay(10)
您可以取消注释glBegin()... glEnd()部分,您将看到将绘制一个蓝色三角形,因此着色器工作正常。
我试图改变变量dtypei和dtypef(分别对应于传递给glGenBuffers的numpy数组的int类型的float类型),没有运气。可以尝试的不同类型是
dtypei=np.dtype('<i4')
dtypei=np.dtype('>i4')
dtypei=np.dtype('=i4')
dtypei=np.int32
dtypei=np.dtype('<u4')
dtypei=np.dtype('>u4')
dtypei=np.dtype('=u4')
dtypei=np.uint32
dtypef=np.dtype('>f4')
dtypef=np.dtype('<f4')
dtypef=np.dtype('=f4')
dtypef=np.float32
对应于具有不同字节顺序的整数/浮点数(uint32,int32和float32可能是多余的)。见documentation。我也尝试使用数组库中的数组对象,这也是在其他stackoverflow帖子中提出的,也没有任何结果
我真的迷失在这里。
答案 0 :(得分:3)
问题不是numpy数据类型对象,而是调用glVertexAttribPointer
和glDrawElements
:
glVertexAttribPointer
的第6个参数的数据类型必须为ctypes.c_void_p
这意味着您必须使用ctypes.cast
:
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 3*4, ctypes.cast(0, ctypes.c_void_p))
或None
:
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, False, 3*4, None)
的第4个参数也是如此
无论
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, ctypes.cast(0, ctypes.c_void_p))
或
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, None)