Modify VAO API to allow using multiple buffers

This commit is contained in:
Kovid Goyal 2017-08-23 17:32:46 +05:30
parent b6679ff7b5
commit e0e517d6ec
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 43 additions and 28 deletions

View File

@ -52,7 +52,9 @@ void main() {
final_color = vec4(color, 1); final_color = vec4(color, 1);
} }
''') ''')
self.vao_id = self.add_vertex_arrays(self.vertex_array('rect')) with self.array_object_creator() as add_attribute:
self.vao_id = add_attribute.vao_id
add_attribute('rect')
def send_data(self, data): def send_data(self, data):
self.send_vertex_data(self.vao_id, data, usage=GL_STATIC_DRAW) self.send_vertex_data(self.vao_id, data, usage=GL_STATIC_DRAW)

View File

@ -38,16 +38,17 @@ class CellProgram(ShaderProgram):
def create_sprite_map(self): def create_sprite_map(self):
stride = DATA_CELL_SIZE * sizeof(GLuint) stride = DATA_CELL_SIZE * sizeof(GLuint)
size = DATA_CELL_SIZE // 2 size = DATA_CELL_SIZE // 2
return self.add_vertex_arrays( with self.array_object_creator() as add_attribute:
self.vertex_array('sprite_coords', size=size, dtype=GL_UNSIGNED_INT, stride=stride, divisor=1), add_attribute('sprite_coords', size=size, dtype=GL_UNSIGNED_INT, stride=stride, divisor=1)
self.vertex_array('colors', size=size, dtype=GL_UNSIGNED_INT, stride=stride, offset=stride // 2, divisor=1), add_attribute('colors', size=size, dtype=GL_UNSIGNED_INT, stride=stride, offset=stride // 2, divisor=1)
) return add_attribute.vao_id
def load_shader_programs(): def load_shader_programs():
cell = CellProgram(*load_shaders('cell')) cell = CellProgram(*load_shaders('cell'))
cursor = ShaderProgram(*load_shaders('cursor')) cursor = ShaderProgram(*load_shaders('cursor'))
cursor.vao_id = cursor.add_vertex_arrays() with cursor.array_object_creator() as add_attribute:
cursor.vao_id = add_attribute.vao_id
return cell, cursor return cell, cursor

View File

@ -4,7 +4,6 @@
import os import os
import sys import sys
from collections import namedtuple
from contextlib import contextmanager from contextlib import contextmanager
from ctypes import addressof, sizeof from ctypes import addressof, sizeof
from functools import lru_cache from functools import lru_cache
@ -36,7 +35,6 @@ VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
ITALIC_MASK = 1 << ITALIC ITALIC_MASK = 1 << ITALIC
BOLD_MASK = 1 << BOLD BOLD_MASK = 1 << BOLD
BASE = os.path.dirname(os.path.abspath(__file__)) BASE = os.path.dirname(os.path.abspath(__file__))
VertexArray = namedtuple('VertexArray', 'name size dtype normalized stride offset divisor')
@lru_cache() @lru_cache()
@ -250,21 +248,34 @@ class ShaderProgram: # {{{
glDeleteShader(frag_id) glDeleteShader(frag_id)
self.vertex_arrays = {} self.vertex_arrays = {}
def vertex_array(self, name, size=3, dtype=GL_FLOAT, normalized=False, stride=0, offset=0, divisor=0): @contextmanager
return VertexArray(name, size, dtype, normalized, stride, offset, divisor) def array_object_creator(self):
def add_vertex_arrays(self, *arrays):
vao_id = glGenVertexArrays(1) vao_id = glGenVertexArrays(1)
self.vertex_arrays[vao_id] = buf_id = buffer_manager.create(for_use=GL_ARRAY_BUFFER) self.vertex_arrays[vao_id] = buffers = []
with self.bound_vertex_array(vao_id), buffer_manager.bound_buffer(buf_id): buf_id = None
for x in arrays:
aid = self.attribute_location(x.name) def newbuf():
nonlocal buf_id
buf_id = buffer_manager.create(for_use=GL_ARRAY_BUFFER)
buffers.append(buf_id)
return buf_id
def add_attribute(name, size=3, dtype=GL_FLOAT, normalized=False, stride=0, offset=0, divisor=0):
nonlocal buf_id
aid = self.attribute_location(name)
if aid > -1: if aid > -1:
if buf_id is None:
buf_id = newbuf()
with buffer_manager.bound_buffer(buf_id):
glEnableVertexAttribArray(aid) glEnableVertexAttribArray(aid)
glVertexAttribPointer(aid, x.size, x.dtype, x.normalized, x.stride, x.offset) glVertexAttribPointer(aid, size, dtype, normalized, stride, offset)
if x.divisor > 0: if divisor > 0:
glVertexAttribDivisor(aid, x.divisor) glVertexAttribDivisor(aid, divisor)
return vao_id
add_attribute.newbuf = newbuf
add_attribute.vao_id = vao_id
with self.bound_vertex_array(vao_id):
yield add_attribute
@contextmanager @contextmanager
def bound_vertex_array(self, vao_id): def bound_vertex_array(self, vao_id):
@ -273,17 +284,18 @@ class ShaderProgram: # {{{
glBindVertexArray(0) glBindVertexArray(0)
def remove_vertex_array(self, vao_id): def remove_vertex_array(self, vao_id):
buf_id = self.vertex_arrays.pop(vao_id, None) buffers = self.vertex_arrays.pop(vao_id, None)
if buf_id is not None: if buffers is not None:
glDeleteVertexArray(vao_id) glDeleteVertexArray(vao_id)
for buf_id in buffers:
buffer_manager.delete(buf_id) buffer_manager.delete(buf_id)
def send_vertex_data(self, vao_id, data, usage=GL_STREAM_DRAW): def send_vertex_data(self, vao_id, data, usage=GL_STREAM_DRAW, bufnum=0):
bufid = self.vertex_arrays[vao_id] bufid = self.vertex_arrays[vao_id][bufnum]
buffer_manager.set_data(bufid, data, usage=usage) buffer_manager.set_data(bufid, data, usage=usage)
def get_vertex_data(self, vao_id): def get_vertex_data(self, vao_id, bufnum=0):
bufid = self.vertex_arrays[vao_id] bufid = self.vertex_arrays[vao_id][bufnum]
return buffer_manager.get_data(bufid) return buffer_manager.get_data(bufid)
def __hash__(self) -> int: def __hash__(self) -> int: