Como desenhar com objetos Vertex Array e glDrawElements no PyOpenGL
Eu tenho o seguinte código que deve simplesmente desenhar um triângulo verde na tela. Ele está usando os Objetos Vertex Array e buffers de índice para desenhar e tem o som mais simples que eu poderia fazer.
No começo eu não estava usando buffers de índice e estava simplesmente fazendo a chamada draw comglDrawArrays
que funcionou bem, mas quando eu mudei para usarglDrawElements
então nada é atraído para a tela (é totalmente preto).
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()
Se eu simplesmente comentar oglDrawElements
e descomente oglDrawArrays
linha então funciona corretamente então pelo menos o VBO de vértice está sendo inserido corretamente.
O que eu estou fazendo errado aqui? Toda a documentação do OpenGL que consegui encontrar sugere que estou fazendo isso corretamente, então obviamente estou entendendo mal algo sobre o próprio OpenGL ou o wrapper PyOpenGL.
EDITAR
Alterar a configuração do VAO para usar a função OpenGL mais direta, em vez do wrapper VBO, como:
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)
Não faz diferença.glDrawArrays
ainda funciona eglDrawElements
ainda não faz.