如何在PyOpenGL中使用顶点数组对象和glDrawElements进行绘制

我有以下代码,应该在屏幕上简单地绘制一个绿色三角形。它使用顶点数组对象和索引缓冲区进行绘制,并且具有我可以制作的最简单的着色器。

最初,我没有使用索引缓冲区,只是简单地进行了绘画调用,glDrawArrays但工作正常,但是当我将其更改为使用时,glDrawElements则屏幕上没有任何内容绘制出来(它完全是黑色的)。

from OpenGL.GL import shaders

from OpenGL.arrays import vbo

from OpenGL.GL import *

from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \

glBindVertexArray

import pygame

import numpy as np

def run():

pygame.init()

screen = pygame.display.set_mode((800,600), pygame.OPENGL)

#Create the Vertex Array Object

vertexArrayObject = GLuint(0)

glGenVertexArrays(1, vertexArrayObject)

glBindVertexArray(vertexArrayObject)

#Create the VBO

vertices = np.array([[0,1,0],[-1,-1,0],[1,-1,0]], dtype='f')

vertexPositions = vbo.VBO(vertices)

#Create the index buffer object

indices = np.array([0,1,2], dtype='uint16')

indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)

indexPositions.bind()

vertexPositions.bind()

glEnableVertexAttribArray(0) # from 'location = 0' in shader

glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)

glBindVertexArray(0)

vertexPositions.unbind()

indexPositions.unbind()

#Now create the shaders

VERTEX_SHADER = shaders.compileShader("""

#version 330

layout(location = 0) in vec4 position;

void main()

{

gl_Position = position;

}

""", GL_VERTEX_SHADER)

FRAGMENT_SHADER = shaders.compileShader("""

#version 330

out vec4 outputColor;

void main()

{

outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);

}

""", GL_FRAGMENT_SHADER)

shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)

#The draw loop

while True:

glUseProgram(shader)

glBindVertexArray(vertexArrayObject)

#glDrawArrays(GL_TRIANGLES, 0, 3) #This line works

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0) #This line does not

glBindVertexArray(0)

glUseProgram(0)

# Show the screen

pygame.display.flip()

run()

如果我只是glDrawElements注释掉该glDrawArrays行并取消注释该行,则它可以正常工作,因此至少可以正确输入顶点VBO。

我在这里做错了什么?我能够找到的所有OpenGL文档都表明我正确地执行了此操作,因此我显然对OpenGL本身或PyOpenGL包装器有误解。

更改VAO设置以使用更直接的OpenGL函数,而不是VBO包装器,例如:

vertices = np.array([[0,1,0],[-1,-1,0],[1,-1,0]], dtype='f')

vertexPositions = glGenBuffers(1)

glBindBuffer(GL_ARRAY_BUFFER, vertexPositions)

glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)

#Create the index buffer object

indices = np.array([0,1,2], dtype='uint16')

indexPositions = glGenBuffers(1)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexPositions)

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexPositions)

glBindBuffer(GL_ARRAY_BUFFER, vertexPositions)

glEnableVertexAttribArray(0) # from 'location = 0' in shader

glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)

glBindVertexArray(0)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

glBindBuffer(GL_ARRAY_BUFFER, 0)

没有区别。glDrawArrays仍然有效,glDrawElements但仍然没有。

回答:

谢谢@NicolBolas。他激励我真正采用此代码并使之生效。而不是理论化:)我删除了vertexArrayObject(它是多余的,因为我们已经有用于顶点和索引的VBO)。因此,您只需在调用glDraw

*之前绑定索引和顶点缓冲区(以及属性)即可。当然,将None(空指针)传递给glDrawElements索引而不是0!非常重要。

from OpenGL.GL import shaders

from OpenGL.arrays import vbo

from OpenGL.GL import *

from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \

glBindVertexArray

import pygame

import numpy as np

def run():

pygame.init()

screen = pygame.display.set_mode((800,600), pygame.OPENGL|pygame.DOUBLEBUF)

#Create the VBO

vertices = np.array([[0,1,0],[-1,-1,0],[1,-1,0]], dtype='f')

vertexPositions = vbo.VBO(vertices)

#Create the index buffer object

indices = np.array([[0,1,2]], dtype=np.int32)

indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)

#Now create the shaders

VERTEX_SHADER = shaders.compileShader("""

#version 330

layout(location = 0) in vec4 position;

void main()

{

gl_Position = position;

}

""", GL_VERTEX_SHADER)

FRAGMENT_SHADER = shaders.compileShader("""

#version 330

out vec4 outputColor;

void main()

{

outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);

}

""", GL_FRAGMENT_SHADER)

shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)

#The draw loop

while True:

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

glUseProgram(shader)

indexPositions.bind()

vertexPositions.bind()

glEnableVertexAttribArray(0);

glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)

#glDrawArrays(GL_TRIANGLES, 0, 3) #This line still works

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, None) #This line does work too!

# Show the screen

pygame.display.flip()

run()

以上是 如何在PyOpenGL中使用顶点数组对象和glDrawElements进行绘制 的全部内容, 来源链接: utcz.com/qa/400733.html

回到顶部