def initializeGL(self, gls: 'GLShared') -> None: self.gls = gls assert self.gls is not None # Basic solid-color program self.prog = self.gls.shader_cache.get("vert2", "frag1") self.mat_loc = GL.glGetUniformLocation(self.prog.program, "mat") self.col_loc = GL.glGetUniformLocation(self.prog.program, "color") # Build a VBO for rendering square "drag-handles" self.vbo_handles_ar = numpy.ndarray((4, ), dtype=[("vertex", numpy.float32, 2)]) self.vbo_handles_ar["vertex"] = numpy.array(corners) * HANDLE_HALF_SIZE self.vbo_handles = VBO(self.vbo_handles_ar, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) self.vao_handles = VAO() with self.vbo_handles, self.vao_handles: VBOBind(self.prog.program, self.vbo_handles_ar.dtype, "vertex").assign() # Build a VBO/VAO for the perimeter # We don't initialize it here because it is updated every render # 4 verticies for outside perimeter # 6 verticies for each dim self.vbo_per_dim_ar = numpy.zeros(16, dtype=[("vertex", numpy.float32, 2)]) self.vbo_per_dim = VBO(self.vbo_per_dim_ar, GL.GL_DYNAMIC_DRAW, GL.GL_ARRAY_BUFFER) self.vao_per_dim = VAO() with self.vao_per_dim, self.vbo_per_dim: VBOBind(self.prog.program, self.vbo_per_dim_ar.dtype, "vertex").assign()
def _initializeGL(self): self.initialized = True self.__filled_vao = VAO() self.__outline_vao = VAO() with self.__filled_vao, self.parent._sq_vbo: vbobind(self.parent._filled_shader, self.parent._sq_vbo.data.dtype, "vertex").assign() # Use a fake array to get a zero-length VBO for initial binding filled_instance_array = numpy.ndarray( 0, dtype=self.parent._filled_instance_dtype) self.filled_instance_vbo = VBO(filled_instance_array) with self.__filled_vao, self.filled_instance_vbo: vbobind(self.parent._filled_shader, self.parent._filled_instance_dtype, "pos", div=1).assign() vbobind(self.parent._filled_shader, self.parent._filled_instance_dtype, "r", div=1).assign() vbobind(self.parent._filled_shader, self.parent._filled_instance_dtype, "r_inside_frac_sq", div=1).assign() vbobind(self.parent._filled_shader, self.parent._filled_instance_dtype, "color", div=1).assign() with self.__outline_vao, self.parent._outline_vbo: vbobind(self.parent._outline_shader, self.parent._outline_vbo.data.dtype, "vertex").assign() # Build instance for outline rendering # We don't have an inner 'r' for this because we just do two instances per vertex # Use a fake array to get a zero-length VBO for initial binding outline_instance_array = numpy.ndarray( 0, dtype=self.parent._outline_instance_dtype) self.outline_instance_vbo = VBO(outline_instance_array) with self.__outline_vao, self.outline_instance_vbo: vbobind(self.parent._outline_shader, self.parent._outline_instance_dtype, "pos", div=1).assign() vbobind(self.parent._outline_shader, self.parent._outline_instance_dtype, "r", div=1).assign() vbobind(self.parent._outline_shader, self.parent._outline_instance_dtype, "color", div=1).assign()
def initializeGL(self, gls: 'GLShared', width: int, height: int) -> None: self.__width = width self.__height = height # Initialize (but don't fill) the Color LUT self.__texture_colors = Texture(debug_name="Layer Color LUT") with self.__texture_colors.on(GL.GL_TEXTURE_1D): GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST) GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE) GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE) # Compositing shader and geometry self.__composite_shader = gls.shader_cache.get( "layer_composite_vert", "layer_composite_frag", fragment_bindings={"final_color": 0}) ar = self.__get_vbo_data() self.__composite_vao = VAO(debug_name="Compositor Quad VAO") self.__composite_vbo = VBO(ar, GL.GL_STATIC_DRAW) GL.glObjectLabel(GL.GL_BUFFER, int(self.__composite_vbo), -1, "Compositor Quad VBO") with self.__composite_vao: self.__composite_vbo.bind() VBOBind(self.__composite_shader.program, ar.dtype, "vertex").assign() VBOBind(self.__composite_shader.program, ar.dtype, "texpos").assign()
def initializeGL(self): self.vbo = VBO(numpy.ndarray(0, dtype=self.__text_render.buffer_dtype), GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) self.vao = VAO() with self.vao, self.vbo: self.__text_render.b1.assign() self.__text_render.b2.assign()
def initializeGL(self): # Working VBO that will contain glyph data self.vbo = VBO(numpy.ndarray(0, dtype=self.text_render.buffer_dtype), GL.GL_DYNAMIC_DRAW, GL.GL_ARRAY_BUFFER) self.vao = VAO() with self.vao, self.vbo: self.text_render.b1.assign() self.text_render.b2.assign() self.__vbo_needs_update = True
def initializeGL(self, gls, width, height): # Get shader self.__shader = gls.shader_cache.get("basic_fill_vert", "basic_fill_frag") self.__vbo = VBO(numpy.ndarray(0, dtype=self.__vbo_dtype), GL.GL_STATIC_DRAW) self.__vao = VAO() # Create array of lines sufficient to fill screen self.resize(width, height)
def __init__(self, dtype, shader, glhint): self.__dtype = dtype self.vao = VAO() self.batch_vbo = VBO(numpy.array([], dtype=dtype), glhint) with self.vao, self.batch_vbo: vbobind(shader, dtype, "vertex").assign() self.clear()
def __initialize_uniform(self, gls): self.__uniform_shader_vao = VAO() self.__uniform_shader = gls.shader_cache.get( "line_vertex_shader", "frag1", defines={"INPUT_TYPE": "uniform"}) with self.__uniform_shader_vao, self.trace_vbo: vbobind(self.__uniform_shader, self.trace_vbo.dtype, "vertex").assign() vbobind(self.__uniform_shader, self.trace_vbo.dtype, "ptid").assign() self.index_vbo.bind()
def initializeGL(self) -> None: self.__dtype = numpy.dtype([('vertex', numpy.float32, 2)]) self.__shader = self.__view.gls.shader_cache.get( "basic_fill_vert", "basic_fill_frag") self._va_vao = VAO() self._va_batch_vbo = VBO(numpy.array([], dtype=self.__dtype), GL.GL_STREAM_DRAW) GL.glObjectLabel(GL.GL_BUFFER, int(self._va_batch_vbo), -1, "Hairline VA batch VBO") with self._va_vao, self._va_batch_vbo: VBOBind(self.__shader.program, self.__dtype, "vertex").assign()
def initializeGL(self, gls: 'GLShared') -> None: self.gls = gls # zap the cached text on GL reinitialize (VBO handles / etc are likely invalid) self.textCached = {} # basic solid-color shader self.prog = gls.shader_cache.get("vert2", "frag1") # Construct a VBO containing all the points we need for rendering dtype = numpy.dtype([("vertex", numpy.float32, 2)]) points = numpy.ndarray((16, ), dtype=dtype) # keypoint display: edge half-dimension in pixels self.d1 = d1 = 20 # keypoint display: text-area "flag" height in pixels th = 16 # keypoint display: right-edge offset of text flag in pixels tw = 6 points["vertex"] = [ # Lines making up keypoint cross (rendered with GL_LINES) (-d1, -d1), (-d1, d1), (-d1, d1), (d1, d1), (d1, d1), (d1, -d1), (d1, -d1), (-d1, -d1), (0, -d1), (0, d1), (-d1, 0), (d1, 0), # flag (rendered with GL_TRIANGLE_STRIP) (-d1, -d1), (-d1, -d1 - th), (-tw, -d1), (-tw, -d1 - th) ] # Pack it all into a VBO self.handle_vbo = VBO(points, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) # and bind the program for rendering self.handle_vao = VAO() with self.handle_vao, self.handle_vbo: VBOBind(self.prog.program, dtype, "vertex").assign()
def initGL(self, gls: 'GLShared') -> None: self._tex = Texture() # Setup the basic texture parameters with self._tex.on(GL.GL_TEXTURE_2D): GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE) # numpy packs data tightly, whereas the openGL default is 4-byte-aligned # fix line alignment to 1 byte so odd-sized textures load right GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1) # Download the data to the buffer. cv2 stores data in BGR format GL.glTexImage2D( GL.GL_TEXTURE_2D, 0, GL.GL_RGB, self.im.shape[1], self.im.shape[0], 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self.im.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8))) self.prog = gls.shader_cache.get("image_vert", "image_frag") ar = numpy.ndarray( (4, ), dtype=[("vertex", numpy.float32, 2), ("texpos", numpy.float32, 2)]) # type: ignore sca = max(self.im.shape[0], self.im.shape[1]) x = self.im.shape[1] / float(sca) y = self.im.shape[0] / float(sca) ar["vertex"] = [(-x, -y), (-x, y), (x, -y), (x, y)] ar["texpos"] = [(0, 0), (0, 1), (1, 0), (1, 1)] self.b1 = VBOBind(self.prog.program, ar.dtype, "vertex") self.b2 = VBOBind(self.prog.program, ar.dtype, "texpos") self.vbo = VBO(ar, GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) self.mat_loc = GL.glGetUniformLocation(self.prog.program, "mat") self.tex1_loc = GL.glGetUniformLocation(self.prog.program, "tex1") self.vao = VAO() with self.vbo, self.vao: self.b1.assign() self.b2.assign()
def initializeGL(self, gls: 'GLShared') -> None: self.shader = gls.shader_cache.get("vert2", "frag1") self.vao = VAO() self.vbo = VBO(bytes(), usage=GL.GL_STREAM_DRAW) # bind the shader with self.vao, self.vbo: loc = GL.glGetAttribLocation(self.shader.program, "vertex") assert loc != -1 GL.glEnableVertexAttribArray(loc) # TODO - HACK. AttribPointer is dependent on ABI data layout. # Should be common on all sane archs, but this should be fetched on demand GL.glVertexAttribPointer(loc, 2, GL.GL_FLOAT, False, 8, ctypes.c_void_p(0)) GL.glVertexAttribDivisor(loc, 0)
def initializeGL(self) -> None: self.__vao = VAO() # Lookup for vertex positions self.__vert_vbo_dtype = numpy.dtype([("vertex", numpy.float32, 2)]) self.__vert_vbo = VBO(numpy.ndarray(0, dtype=self.__vert_vbo_dtype), GL.GL_DYNAMIC_DRAW) self.__vert_vbo_current = False self.__index_vbo_dtype = numpy.uint32 self.__index_vbo = VBO(numpy.ndarray(0, dtype=self.__index_vbo_dtype), GL.GL_DYNAMIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER) self.__index_vbo_current = False self.__shader = self.__gls.shader_cache.get("vert2", "frag1") with self.__vao, self.__vert_vbo: VBOBind(self.__shader.program, self.__vert_vbo_dtype, "vertex").assign() self.__index_vbo.bind()
def initializeGL(self, glshared: 'GLShared') -> None: self._filled_shader = glshared.shader_cache.get( "via_filled_vertex_shader", "via_filled_fragment_shader") self._outline_shader = glshared.shader_cache.get( "via_outline_vertex_shader", "basic_fill_frag") # Build geometry for filled rendering using the frag shader for circle borders filled_points = [ ((-1, -1), ), ((1, -1), ), ((-1, 1), ), ((1, 1), ), ] ar = numpy.array(filled_points, dtype=[("vertex", numpy.float32, 2)]) self._sq_vbo = VBO(ar, GL.GL_STATIC_DRAW) GL.glObjectLabel(GL.GL_BUFFER, int(self._sq_vbo), -1, "Via SQ VBO") # Build geometry for outline rendering outline_points = [] for i in numpy.linspace(0, math.pi * 2, N_OUTLINE_SEGMENTS, False): outline_points.append(((math.cos(i), math.sin(i)), )) outline_points_array = numpy.array(outline_points, dtype=[("vertex", numpy.float32, 2) ]) self._outline_vbo = VBO(outline_points_array, GL.GL_STATIC_DRAW) GL.glObjectLabel(GL.GL_BUFFER, int(self._sq_vbo), -1, "Via Outline VBO") self.__dtype = numpy.dtype([ ("pos", numpy.float32, 2), ("r", numpy.float32), ("r_inside_frac_sq", numpy.float32), ]) self.__filled_vao = VAO() self.__outline_vao = VAO() with self.__filled_vao, self._sq_vbo: VBOBind(self._filled_shader.program, self._sq_vbo.data.dtype, "vertex").assign() # Use a fake array to get a zero-length VBO for initial binding filled_instance_array = numpy.ndarray(0, dtype=self.__dtype) self.filled_instance_vbo = VBO(filled_instance_array) GL.glObjectLabel(GL.GL_BUFFER, int(self._sq_vbo), -1, "Via Filled Instance VBO") with self.__filled_vao, self.filled_instance_vbo: VBOBind(self._filled_shader.program, self.__dtype, "pos", div=1).assign() VBOBind(self._filled_shader.program, self.__dtype, "r", div=1).assign() VBOBind(self._filled_shader.program, self.__dtype, "r_inside_frac_sq", div=1).assign() with self.__outline_vao, self._outline_vbo: VBOBind(self._outline_shader.program, self._outline_vbo.data.dtype, "vertex").assign() # Build instance for outline rendering # We don't have an inner 'r' for this because we just do two instances per vertex # Use a fake array to get a zero-length VBO for initial binding outline_instance_array = numpy.ndarray(0, dtype=self.__dtype) self.outline_instance_vbo = VBO(outline_instance_array) GL.glObjectLabel(GL.GL_BUFFER, int(self.outline_instance_vbo), -1, "Via Outline Instance VBO") with self.__outline_vao, self.outline_instance_vbo: VBOBind(self._outline_shader.program, self.__dtype, "pos", div=1).assign() VBOBind(self._outline_shader.program, self.__dtype, "r", div=1).assign()
def initializeGL(self, gls): self.__uniform_shader_vao = VAO() self.__attribute_shader_vao = VAO() # Load two versions of the shader, one for rendering a single line through uniforms # (no additional bound instance info), and one for rendering instanced geometry self.__uniform_shader = gls.shader_cache.get( "line_vertex_shader", "frag1", defines={"INPUT_TYPE": "uniform"}) self.__attribute_shader = gls.shader_cache.get( "line_vertex_shader", "frag1", defines={"INPUT_TYPE": "in"}) # Generate geometry for trace and endcaps # ptid is a variable with value 0 or 1 that indicates which endpoint the geometry is associated with # Build trace vertex VBO and associated vertex data dtype = [("vertex", numpy.float32, 2), ("ptid", numpy.uint32)] self.working_array = numpy.zeros(NUM_ENDCAP_SEGMENTS * 2 + 2, dtype=dtype) self.trace_vbo = VBO(self.working_array, GL.GL_DYNAMIC_DRAW) self.__build_trace() # Now we build an index buffer that allows us to render filled geometry from the same # VBO. arr = [] for i in range(NUM_ENDCAP_SEGMENTS - 1): arr.append(0) arr.append(i + 2) arr.append(i + 3) for i in range(NUM_ENDCAP_SEGMENTS - 1): arr.append(1) arr.append(i + NUM_ENDCAP_SEGMENTS + 2) arr.append(i + NUM_ENDCAP_SEGMENTS + 3) arr.append(2) arr.append(2 + NUM_ENDCAP_SEGMENTS - 1) arr.append(2 + NUM_ENDCAP_SEGMENTS) arr.append(2 + NUM_ENDCAP_SEGMENTS) arr.append(2 + NUM_ENDCAP_SEGMENTS * 2 - 1) arr.append(2) arr = numpy.array(arr, dtype=numpy.uint32) self.index_vbo = VBO(arr, target=GL.GL_ELEMENT_ARRAY_BUFFER) # And bind the entire state together with self.__uniform_shader_vao, self.trace_vbo: vbobind(self.__uniform_shader, self.trace_vbo.dtype, "vertex").assign() vbobind(self.__uniform_shader, self.trace_vbo.dtype, "ptid").assign() self.index_vbo.bind() self.instance_dtype = numpy.dtype([ ("pos_a", numpy.float32, 2), ("pos_b", numpy.float32, 2), ("thickness", numpy.float32, 1), #("color", numpy.float32, 4) ]) # Use a fake array to get a zero-length VBO for initial binding instance_array = numpy.ndarray(0, dtype=self.instance_dtype) self.instance_vbo = VBO(instance_array) with self.__attribute_shader_vao, self.trace_vbo: vbobind(self.__attribute_shader, self.trace_vbo.dtype, "vertex").assign() vbobind(self.__attribute_shader, self.trace_vbo.dtype, "ptid").assign() with self.__attribute_shader_vao, self.instance_vbo: self.__bind_pos_a = vbobind(self.__attribute_shader, self.instance_dtype, "pos_a", div=1) self.__bind_pos_b = vbobind(self.__attribute_shader, self.instance_dtype, "pos_b", div=1) self.__bind_thickness = vbobind(self.__attribute_shader, self.instance_dtype, "thickness", div=1) #vbobind(self.__attribute_shader, self.instance_dtype, "color", div=1).assign() self.__base_rebind(0) self.index_vbo.bind() self.__last_prepared = weakref.WeakKeyDictionary()
def initializeGL(self, glshared): self.__filled_shader = glshared.shader_cache.get( "via_filled_vertex_shader", "via_filled_fragment_shader") self.__outline_shader = glshared.shader_cache.get( "via_outline_vertex_shader", "frag1") self.__filled_vao = VAO() self.__outline_vao = VAO() # Build geometry for filled rendering using the frag shader for circle borders filled_points = [ ((-1, -1), ), ((1, -1), ), ((-1, 1), ), ((1, 1), ), ] ar = numpy.array(filled_points, dtype=[("vertex", numpy.float32, 2)]) self.__sq_vbo = VBO(ar, GL.GL_STATIC_DRAW) with self.__filled_vao, self.__sq_vbo: vbobind(self.__filled_shader, ar.dtype, "vertex").assign() # Build and bind an instance array for the "filled" geometry self.filled_instance_dtype = numpy.dtype([("pos", numpy.float32, 2), ("r", numpy.float32, 1), ("r_inside_frac_sq", numpy.float32, 1), ("color", numpy.float32, 4)]) # Use a fake array to get a zero-length VBO for initial binding filled_instance_array = numpy.ndarray(0, dtype=self.filled_instance_dtype) self.filled_instance_vbo = VBO(filled_instance_array) with self.__filled_vao, self.filled_instance_vbo: vbobind(self.__filled_shader, self.filled_instance_dtype, "pos", div=1).assign() vbobind(self.__filled_shader, self.filled_instance_dtype, "r", div=1).assign() vbobind(self.__filled_shader, self.filled_instance_dtype, "r_inside_frac_sq", div=1).assign() vbobind(self.__filled_shader, self.filled_instance_dtype, "color", div=1).assign() # Build geometry for outline rendering outline_points = [] for i in numpy.linspace(0, math.pi * 2, N_OUTLINE_SEGMENTS, False): outline_points.append(((math.cos(i), math.sin(i)), )) ar = numpy.array(outline_points, dtype=[("vertex", numpy.float32, 2)]) self.__outline_vbo = VBO(ar, GL.GL_STATIC_DRAW) with self.__outline_vao, self.__outline_vbo: vbobind(self.__outline_shader, ar.dtype, "vertex").assign() # Build instance for outline rendering # We don't have an inner 'r' for this because we just do two instances per vertex self.outline_instance_dtype = numpy.dtype([("pos", numpy.float32, 2), ("r", numpy.float32, 1), ("color", numpy.float32, 4) ]) # Use a fake array to get a zero-length VBO for initial binding outline_instance_array = numpy.ndarray( 0, dtype=self.outline_instance_dtype) self.outline_instance_vbo = VBO(outline_instance_array) with self.__outline_vao, self.outline_instance_vbo: vbobind(self.__outline_shader, self.outline_instance_dtype, "pos", div=1).assign() vbobind(self.__outline_shader, self.outline_instance_dtype, "r", div=1).assign() vbobind(self.__outline_shader, self.outline_instance_dtype, "color", div=1).assign()
def initializeGL(self, gls: 'GLShared') -> None: # Build trace vertex VBO and associated vertex data dtype = [("vertex", numpy.float32, 2), ("ptid", numpy.uint32)] self.working_array = numpy.zeros(NUM_ENDCAP_SEGMENTS * 2 + 2, dtype=dtype) self.trace_vbo = VBO(self.working_array, GL.GL_DYNAMIC_DRAW) GL.glObjectLabel(GL.GL_BUFFER, int(self.trace_vbo), -1, "Thickline Trace VBO") # Generate geometry for trace and endcaps # ptid is a variable with value 0 or 1 that indicates which endpoint the geometry is associated with self.__build_trace() self.__attribute_shader_vao = VAO( debug_name="Thickline attribute shader VAO") shader = gls.shader_cache.get("line_vertex_shader", "basic_fill_frag", defines={"INPUT_TYPE": "in"}) assert shader is not None self.__attribute_shader: 'EnhShaderProgram' = shader # Now we build an index buffer that allows us to render filled geometry from the same # VBO. arr = [] for i in range(NUM_ENDCAP_SEGMENTS - 1): arr.append(0) arr.append(i + 2) arr.append(i + 3) for i in range(NUM_ENDCAP_SEGMENTS - 1): arr.append(1) arr.append(i + NUM_ENDCAP_SEGMENTS + 2) arr.append(i + NUM_ENDCAP_SEGMENTS + 3) arr.append(2) arr.append(2 + NUM_ENDCAP_SEGMENTS - 1) arr.append(2 + NUM_ENDCAP_SEGMENTS) arr.append(2 + NUM_ENDCAP_SEGMENTS) arr.append(2 + NUM_ENDCAP_SEGMENTS * 2 - 1) arr.append(2) arr2 = numpy.array(arr, dtype=numpy.uint32) self.index_vbo = VBO(arr2, target=GL.GL_ELEMENT_ARRAY_BUFFER) GL.glObjectLabel(GL.GL_BUFFER, int(self.index_vbo), -1, "Thickline Index VBO") self.instance_dtype = numpy.dtype([ ("pos_a", numpy.float32, 2), ("pos_b", numpy.float32, 2), ("thickness", numpy.float32), # ("color", numpy.float32, 4) ]) # Use a fake array to get a zero-length VBO for initial binding instance_array: 'npt.NDArray[Any]' = numpy.ndarray( 0, dtype=self.instance_dtype) self.instance_vbo = VBO(instance_array) GL.glObjectLabel(GL.GL_BUFFER, int(self.instance_vbo), -1, "Thickline Instance VBO") with self.__attribute_shader_vao, self.trace_vbo: VBOBind(self.__attribute_shader.program, self.trace_vbo.dtype, "vertex").assign() VBOBind(self.__attribute_shader.program, self.trace_vbo.dtype, "ptid").assign() with self.__attribute_shader_vao, self.instance_vbo: self.__bind_pos_a = VBOBind(self.__attribute_shader.program, self.instance_dtype, "pos_a", div=1) self.__bind_pos_b = VBOBind(self.__attribute_shader.program, self.instance_dtype, "pos_b", div=1) self.__bind_thickness = VBOBind(self.__attribute_shader.program, self.instance_dtype, "thickness", div=1) # vbobind(self.__attribute_shader, self.instance_dtype, "color", div=1).assign() self.__base_rebind(0) self.index_vbo.bind()