Я пытаюсь интегрировать совет из https://gamedev.stackexchange.com/questions/10727/fastest-way-to-draw-quads-in-opengl-es и Как рисовать с помощью объектов массива вершин и glDrawElements в PyOpenGL для рендеринга четырехугольников с использованием индексного буфера, реализованного OpenGL.arrays.vbo.VBO
в контексте, предоставляемом GLFW, и с использованием вспомогательного класса. (Я также, по крайней мере сейчас, полагаюсь на ctypes
для необработанных данных, а не на Numpy.)
Я создал следующий минимальный пример (если я смогу это исправить, я смогу исправьте фактический код):
import ctypes
import glfw
from OpenGL.arrays import vbo
from OpenGL.GL import *
from OpenGL.GL import shaders
def setup_window():
glfw.init()
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(256,256,'test',None,None)
glfw.make_context_current(window)
glfw.set_input_mode(window, glfw.STICKY_KEYS, True)
return window
def get_program():
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)
return shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
window = setup_window()
glUseProgram(get_program())
vertices = vbo.VBO(
(ctypes.c_float * 16)(
-1, -1, 0, 0,
-1, 1, 0, 0,
1, 1, 0, 0,
1, -1, 0, 0
)
)
indices = vbo.VBO(
(ctypes.c_float * 6)(
0, 1, 2, 1, 2, 3
),
target=GL_ELEMENT_ARRAY_BUFFER
)
while (
glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS
and not glfw.window_should_close(window)
):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
with vertices, indices:
glVertexAttribPointer(0, 4, GL_FLOAT, False, 0, None)
glEnableVertexAttribArray(0)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, None)
glfw.swap_buffers(window)
glfw.poll_events()
Вызов glDrawElements
завершается неудачно с совершенно бесполезным исключением «недопустимая операция». Когда закомментировано, все остальное вроде работает нормально (кроме, конечно, ничего не прорисовывается).
Что именно здесь не так? Я понял, что использование экземпляров VBO
в качестве менеджеров контекста (блок with
) должно гарантировать, что данные привязаны и, следовательно, должны быть доступны для glDrawElements
для рендеринга.
Я также пробовал следующие, но не действуют:
- с использованием явных
.bind()
вызовов VBO вместо with
блока - с использованием пустых данных
- изменение
size
аргумент в вызове glDrawElements
любого другого номера, который я мог представить, был прав