Allow programs to be used with multiple vertex array objects
This commit is contained in:
parent
ee3c3e4cb4
commit
ffd9ec653d
@ -50,10 +50,10 @@ void main() {
|
|||||||
final_color = vec4(color, 1);
|
final_color = vec4(color, 1);
|
||||||
}
|
}
|
||||||
''')
|
''')
|
||||||
self.add_vertex_arrays(self.vertex_array('rect'))
|
self.vao_id = self.add_vertex_arrays(self.vertex_array('rect'))
|
||||||
|
|
||||||
def send_data(self, data):
|
def send_data(self, data):
|
||||||
self.send_vertex_data('rect', data)
|
self.send_vertex_data(self.vao_id, 'rect', data)
|
||||||
|
|
||||||
def set_colors(self, color_buf):
|
def set_colors(self, color_buf):
|
||||||
glUniform3fv(self.uniform_location('colors'), 3, addressof(color_buf))
|
glUniform3fv(self.uniform_location('colors'), 3, addressof(color_buf))
|
||||||
@ -145,6 +145,7 @@ class Borders:
|
|||||||
if not self.can_render:
|
if not self.can_render:
|
||||||
return
|
return
|
||||||
with program:
|
with program:
|
||||||
|
program.bind_vertex_array(program.vao_id)
|
||||||
if self.is_dirty:
|
if self.is_dirty:
|
||||||
program.send_data(self.rects)
|
program.send_data(self.rects)
|
||||||
program.set_colors(self.color_buf)
|
program.set_colors(self.color_buf)
|
||||||
|
|||||||
@ -37,8 +37,10 @@ def load_shader_programs():
|
|||||||
vert, frag = load_shaders('cell')
|
vert, frag = load_shaders('cell')
|
||||||
vert = vert.replace('STRIDE', str(DATA_CELL_SIZE))
|
vert = vert.replace('STRIDE', str(DATA_CELL_SIZE))
|
||||||
cell = ShaderProgram(vert, frag)
|
cell = ShaderProgram(vert, frag)
|
||||||
cursor = load_shaders('cursor')
|
cursor = ShaderProgram(*load_shaders('cursor'))
|
||||||
return cell, ShaderProgram(*cursor)
|
cell.vao_id = cell.add_vertex_arrays()
|
||||||
|
cursor.vao_id = cursor.add_vertex_arrays()
|
||||||
|
return cell, cursor
|
||||||
|
|
||||||
|
|
||||||
class Selection: # {{{
|
class Selection: # {{{
|
||||||
@ -119,6 +121,7 @@ def render_cells(buffer_id, sg, cell_program, sprites, invert_colors=False):
|
|||||||
glUniform1i(ul('sprites'), sprites.sampler_num)
|
glUniform1i(ul('sprites'), sprites.sampler_num)
|
||||||
glUniform1i(ul('sprite_map'), sprites.buffer_sampler_num)
|
glUniform1i(ul('sprite_map'), sprites.buffer_sampler_num)
|
||||||
glUniform2f(ul('sprite_layout'), *(sprites.layout))
|
glUniform2f(ul('sprite_layout'), *(sprites.layout))
|
||||||
|
cell_program.bind_vertex_array(cell_program.vao_id)
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, sg.xnum * sg.ynum)
|
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, sg.xnum * sg.ynum)
|
||||||
|
|
||||||
|
|
||||||
@ -395,5 +398,6 @@ class CharGrid:
|
|||||||
glUniform4f(ul('color'), col[0] / 255.0, col[1] / 255.0, col[2] / 255.0, alpha)
|
glUniform4f(ul('color'), col[0] / 255.0, col[1] / 255.0, col[2] / 255.0, alpha)
|
||||||
glUniform2f(ul('xpos'), left, right)
|
glUniform2f(ul('xpos'), left, right)
|
||||||
glUniform2f(ul('ypos'), top, bottom)
|
glUniform2f(ul('ypos'), top, bottom)
|
||||||
|
cursor_program.bind_vertex_array(cursor_program.vao_id)
|
||||||
glDrawArrays(GL_TRIANGLE_FAN if is_focused else GL_LINE_LOOP, 0, 4)
|
glDrawArrays(GL_TRIANGLE_FAN if is_focused else GL_LINE_LOOP, 0, 4)
|
||||||
glDisable(GL_BLEND)
|
glDisable(GL_BLEND)
|
||||||
|
|||||||
@ -20,13 +20,14 @@ from .fast_data_types import (
|
|||||||
copy_image_sub_data, glActiveTexture, glAttachShader, glBindBuffer,
|
copy_image_sub_data, glActiveTexture, glAttachShader, glBindBuffer,
|
||||||
glBindTexture, glBindVertexArray, glCompileShader, glCopyImageSubData,
|
glBindTexture, glBindVertexArray, glCompileShader, glCopyImageSubData,
|
||||||
glCreateProgram, glCreateShader, glDeleteBuffer, glDeleteProgram,
|
glCreateProgram, glCreateShader, glDeleteBuffer, glDeleteProgram,
|
||||||
glDeleteShader, glDeleteTexture, glEnableVertexAttribArray, glGenBuffers,
|
glDeleteShader, glDeleteTexture, glDeleteVertexArray,
|
||||||
glGenTextures, glGenVertexArrays, glGetAttribLocation, glGetBufferSubData,
|
glEnableVertexAttribArray, glGenBuffers, glGenTextures, glGenVertexArrays,
|
||||||
glGetIntegerv, glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog,
|
glGetAttribLocation, glGetBufferSubData, glGetIntegerv,
|
||||||
glGetShaderiv, glGetUniformLocation, glLinkProgram, glPixelStorei,
|
glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog, glGetShaderiv,
|
||||||
glShaderSource, glTexBuffer, glTexParameteri, glTexStorage3D,
|
glGetUniformLocation, glLinkProgram, glPixelStorei, glShaderSource,
|
||||||
glTexSubImage3D, glUseProgram, glVertexAttribDivisor,
|
glTexBuffer, glTexParameteri, glTexStorage3D, glTexSubImage3D,
|
||||||
glVertexAttribPointer, replace_or_create_buffer
|
glUseProgram, glVertexAttribDivisor, glVertexAttribPointer,
|
||||||
|
replace_or_create_buffer
|
||||||
)
|
)
|
||||||
from .fonts.render import render_cell
|
from .fonts.render import render_cell
|
||||||
from .utils import safe_print
|
from .utils import safe_print
|
||||||
@ -266,27 +267,40 @@ class ShaderProgram:
|
|||||||
raise ValueError('Error linking shader program: \n%s' % info.decode('utf-8'))
|
raise ValueError('Error linking shader program: \n%s' % info.decode('utf-8'))
|
||||||
glDeleteShader(vs_id)
|
glDeleteShader(vs_id)
|
||||||
glDeleteShader(frag_id)
|
glDeleteShader(frag_id)
|
||||||
self.vao_id = glGenVertexArrays(1)
|
self.vertex_arrays = {}
|
||||||
self.buffers = {}
|
|
||||||
|
|
||||||
def vertex_array(self, name, size=3, dtype=GL_FLOAT, normalized=False, stride=0, offset=0, divisor=0):
|
def vertex_array(self, name, size=3, dtype=GL_FLOAT, normalized=False, stride=0, offset=0, divisor=0):
|
||||||
return VertexArray(name, size, dtype, normalized, stride, offset, divisor)
|
return VertexArray(name, size, dtype, normalized, stride, offset, divisor)
|
||||||
|
|
||||||
def add_vertex_arrays(self, *arrays):
|
def add_vertex_arrays(self, *arrays):
|
||||||
glBindVertexArray(self.vao_id)
|
vao_id = glGenVertexArrays(1)
|
||||||
|
self.vertex_arrays[vao_id] = buffers = {}
|
||||||
|
glBindVertexArray(vao_id)
|
||||||
for x in arrays:
|
for x in arrays:
|
||||||
self.buffers[x.name] = buf_id = buffer_manager.create(for_use=GL_ARRAY_BUFFER)
|
buffers[x.name] = buf_id = buffer_manager.create(for_use=GL_ARRAY_BUFFER)
|
||||||
buffer_manager.bind(buf_id)
|
buffer_manager.bind(buf_id)
|
||||||
aid = self.attribute_location(x.name)
|
aid = self.attribute_location(x.name)
|
||||||
glEnableVertexAttribArray(aid)
|
glEnableVertexAttribArray(aid)
|
||||||
glVertexAttribPointer(aid, x.size, x.dtype, x.normalized, x.stride, x.offset)
|
glVertexAttribPointer(aid, x.size, x.dtype, x.normalized, x.stride, x.offset)
|
||||||
if x.divisor > 0:
|
if x.divisor > 0:
|
||||||
glVertexAttribDivisor(aid, x.divisor)
|
glVertexAttribDivisor(aid, x.divisor)
|
||||||
buffer_manager.unbind(buf_id)
|
if arrays:
|
||||||
|
buffer_manager.unbind(buf_id)
|
||||||
glBindVertexArray(0)
|
glBindVertexArray(0)
|
||||||
|
return vao_id
|
||||||
|
|
||||||
def send_vertex_data(self, name, data, usage=GL_STATIC_DRAW):
|
def bind_vertex_array(self, vao_id):
|
||||||
bufid = self.buffers[name]
|
glBindVertexArray(vao_id)
|
||||||
|
|
||||||
|
def remove_vertex_array(self, vao_id):
|
||||||
|
buffers = self.vertex_arrays.pop(vao_id, None)
|
||||||
|
if buffers is not None:
|
||||||
|
glDeleteVertexArray(vao_id)
|
||||||
|
for buf_id in buffers.values():
|
||||||
|
buffer_manager.delete(buf_id)
|
||||||
|
|
||||||
|
def send_vertex_data(self, vao_id, name, data, usage=GL_STATIC_DRAW):
|
||||||
|
bufid = self.vertex_arrays[vao_id][name]
|
||||||
buffer_manager.set_data(bufid, data, usage=usage)
|
buffer_manager.set_data(bufid, data, usage=usage)
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
@ -325,7 +339,6 @@ class ShaderProgram:
|
|||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
glUseProgram(self.program_id)
|
glUseProgram(self.program_id)
|
||||||
glBindVertexArray(self.vao_id)
|
|
||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
glUseProgram(0)
|
glUseProgram(0)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user