python - basic openGL, buffers de vértices y pyglet
(2)
glDrawArrays(GL_POINTS, 0, 1)
instruye a dibujar 1 punto, en tu tutorial, 1 es 3:
glDrawArrays(GL_POINTS, 0, 3)
Observe también que la cuarta (w) componente de sus vértices debe ser 1, no 0:
vertexPositions = [0.0, 0.0, 0.0, 1.0,
0.25, 0.0, 0.0, 1.0,
1.75, 1.75, 0.0, 1.0]
Alternativamente, puedes eliminar el componente w,
vertexPositions = [0.0, 0.0, 0.0,
0.25, 0.0, 0.0,
1.75, 1.75, 0.0]
y cambie la siguiente llamada a:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
Otra cosa, no soy un experto en pyglet, pero es posible que glBufferData, al igual que su contraparte C, tome un tamaño en bytes, no en elementos. Cada flotador tiene 4 bytes, podrías intentar:
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
Editar: rotoglup encontró los problemas en mi código, agregando los sombreadores que había eliminado completaron la solución. Ver mi respuesta a continuación para el código correcto (con sombreadores).
Hola a todos !
Estoy tratando de aprender algunos conceptos básicos de OpenGL moderno de este tutorial .
Sin embargo, me gustaría hacerlo con python / pyglet en lugar de C ++. Sé que pyglet puede abstraer gran parte del bajo nivel de OpenGL; Sin embargo, quiero entender algunos de los conceptos básicos antes de seguir ocultándolos detrás de capas de abstracción.
Mi problema es extremadamente simple: el siguiente código solo dibuja un punto único en lugar de los 3 que estoy esperando. Mi código es, hasta donde puedo decir, idéntico al C ++ en el tutorial, excepto por la eliminación de vértices y sombreadores de fragmentos (hecho a través de gletools en python), que parece no afectar mi problema.
Simplificar las cosas en un solo punto muestra un comportamiento que no entiendo (la primera coordenada parece ser la única que afecta a algo), lo que me lleva de vuelta a mi creencia de que simplemente no he podido entender algo muy básico sobre pyglet, OpenGL, o incluso 3D en general: p
Aquí está el código relevante:
import pyglet
from pyglet.gl import *
window = pyglet.window.Window()
positionBufferObject = GLuint()
vao = GLuint()
vertexPositions = [0.0, 0.0, 0.0,
0.25, 0.0, 0.0,
1.75, 1.75, 0.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)
@window.event
def on_draw():
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glDrawArrays(GL_POINTS, 0, 3)
glDisableVertexAttribArray(0)
glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glClearColor(0.0, 0.0, 0.0, 0.0)
pyglet.app.run()
¡Finalmente lo entendí bien!
Parece que me estaba engañando el hecho de que jugar con vértices, glDrawArrays y glVertexAttribPointer a veces resultaba en un solo punto que se mostraba. Esto parece ser un accidente: con las correcciones proporcionadas por la respuesta de rotoglup, nada se dibuja. Este es el comportamiento "correcto" para el código en mi pregunta original.
Un inventario de mis errores en caso de que ayude a alguien:
estableciendo la coordenada w en 0, en lugar de 1, falta por completo las explicaciones para la transformación de espacio de clip en el tutorial.
dando a glBufferData el tamaño del búfer en vértices cuando espera bytes.
- eliminando el vértice y fragmenta los sombreadores (para simplificar el código mientras se buscan los dos problemas anteriores). Esto aseguró que nada se renderizaría ... excepto el único punto (con errores) que a veces obtengo.
Para el registro, el siguiente código muestra un solo triángulo, con sombreadores de paso, en lo que espero estar actualizado y corrija OpenGL. Los requisitos son pyglet y gletools.
import pyglet
from pyglet.gl import *
from gletools import ShaderProgram, FragmentShader, VertexShader
window = pyglet.window.Window()
positionBufferObject = GLuint()
vertexPositions = [0.75, 0.75, 0.0, 1.0,
0.75, -0.75, 0.0, 1.0,
-0.75, -0.75, 0.0, 1.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)
program = ShaderProgram(
FragmentShader(''''''
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}''''''),
VertexShader(''''''
#version 330
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}'''''')
)
@window.event
def on_draw():
with program:
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
glDrawArrays(GL_TRIANGLES, 0, 3)
glDisableVertexAttribArray(0)
glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
pyglet.app.run()