From ffd9ec653d4c97fbd66bfe96f73205eca246dbc4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Aug 2017 00:24:45 +0530 Subject: [PATCH] Allow programs to be used with multiple vertex array objects --- kitty/borders.py | 5 +++-- kitty/char_grid.py | 8 ++++++-- kitty/shaders.py | 43 ++++++++++++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/kitty/borders.py b/kitty/borders.py index 0e72f4a5f..73ee9b29f 100644 --- a/kitty/borders.py +++ b/kitty/borders.py @@ -50,10 +50,10 @@ void main() { 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): - self.send_vertex_data('rect', data) + self.send_vertex_data(self.vao_id, 'rect', data) def set_colors(self, color_buf): glUniform3fv(self.uniform_location('colors'), 3, addressof(color_buf)) @@ -145,6 +145,7 @@ class Borders: if not self.can_render: return with program: + program.bind_vertex_array(program.vao_id) if self.is_dirty: program.send_data(self.rects) program.set_colors(self.color_buf) diff --git a/kitty/char_grid.py b/kitty/char_grid.py index 89318f864..ef546cd19 100644 --- a/kitty/char_grid.py +++ b/kitty/char_grid.py @@ -37,8 +37,10 @@ def load_shader_programs(): vert, frag = load_shaders('cell') vert = vert.replace('STRIDE', str(DATA_CELL_SIZE)) cell = ShaderProgram(vert, frag) - cursor = load_shaders('cursor') - return cell, ShaderProgram(*cursor) + cursor = ShaderProgram(*load_shaders('cursor')) + cell.vao_id = cell.add_vertex_arrays() + cursor.vao_id = cursor.add_vertex_arrays() + return cell, cursor 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('sprite_map'), sprites.buffer_sampler_num) 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) @@ -395,5 +398,6 @@ class CharGrid: glUniform4f(ul('color'), col[0] / 255.0, col[1] / 255.0, col[2] / 255.0, alpha) glUniform2f(ul('xpos'), left, right) 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) glDisable(GL_BLEND) diff --git a/kitty/shaders.py b/kitty/shaders.py index e6c1eb8fa..337471ac9 100644 --- a/kitty/shaders.py +++ b/kitty/shaders.py @@ -20,13 +20,14 @@ from .fast_data_types import ( copy_image_sub_data, glActiveTexture, glAttachShader, glBindBuffer, glBindTexture, glBindVertexArray, glCompileShader, glCopyImageSubData, glCreateProgram, glCreateShader, glDeleteBuffer, glDeleteProgram, - glDeleteShader, glDeleteTexture, glEnableVertexAttribArray, glGenBuffers, - glGenTextures, glGenVertexArrays, glGetAttribLocation, glGetBufferSubData, - glGetIntegerv, glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog, - glGetShaderiv, glGetUniformLocation, glLinkProgram, glPixelStorei, - glShaderSource, glTexBuffer, glTexParameteri, glTexStorage3D, - glTexSubImage3D, glUseProgram, glVertexAttribDivisor, - glVertexAttribPointer, replace_or_create_buffer + glDeleteShader, glDeleteTexture, glDeleteVertexArray, + glEnableVertexAttribArray, glGenBuffers, glGenTextures, glGenVertexArrays, + glGetAttribLocation, glGetBufferSubData, glGetIntegerv, + glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog, glGetShaderiv, + glGetUniformLocation, glLinkProgram, glPixelStorei, glShaderSource, + glTexBuffer, glTexParameteri, glTexStorage3D, glTexSubImage3D, + glUseProgram, glVertexAttribDivisor, glVertexAttribPointer, + replace_or_create_buffer ) from .fonts.render import render_cell from .utils import safe_print @@ -266,27 +267,40 @@ class ShaderProgram: raise ValueError('Error linking shader program: \n%s' % info.decode('utf-8')) glDeleteShader(vs_id) glDeleteShader(frag_id) - self.vao_id = glGenVertexArrays(1) - self.buffers = {} + self.vertex_arrays = {} 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) 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: - 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) aid = self.attribute_location(x.name) glEnableVertexAttribArray(aid) glVertexAttribPointer(aid, x.size, x.dtype, x.normalized, x.stride, x.offset) if x.divisor > 0: glVertexAttribDivisor(aid, x.divisor) - buffer_manager.unbind(buf_id) + if arrays: + buffer_manager.unbind(buf_id) glBindVertexArray(0) + return vao_id - def send_vertex_data(self, name, data, usage=GL_STATIC_DRAW): - bufid = self.buffers[name] + def bind_vertex_array(self, vao_id): + 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) def __hash__(self) -> int: @@ -325,7 +339,6 @@ class ShaderProgram: def __enter__(self): glUseProgram(self.program_id) - glBindVertexArray(self.vao_id) def __exit__(self, *args): glUseProgram(0)