class RenderSide: # On the sides, we only have component outlines and component text def __init__(self) -> None: self.va_outlines = VA_xy(1024) self.va_text = VA_tex(1024) def clear(self) -> None: self.va_outlines.clear() self.va_text.clear() def extend(self, other: 'RenderSide') -> None: self.va_outlines.extend(other.va_outlines) self.va_text.extend(other.va_text)
class RenderVia: # Multilayer, we only have vias, and pin labels def __init__(self) -> None: self.va_vias = VA_via(1024) self.va_text = VA_tex(1024) def clear(self) -> None: self.va_vias.clear() self.va_text.clear() def extend(self, other: 'RenderVia') -> None: self.va_vias.extend(other.va_vias) self.va_text.extend(other.va_text)
class RenderPCBLayer: # PCB layers have traces, text def __init__(self) -> None: self.va_traces = VA_thickline(1024) self.va_text = VA_tex(1024) def clear(self) -> None: self.va_traces.clear() self.va_text.clear() def extend(self, other: 'RenderPCBLayer') -> None: self.va_traces.extend(other.va_traces) self.va_text.extend(other.va_text)
class TextBatcher: _render_tag = namedtuple("_render_tag", ["textinfo", "matrix", "color"]) def __init__(self, tr: 'TextRender') -> None: self.text_render = tr self.__cached: Dict[str, '_StringMetrics'] = {} self._va = VA_tex(1024) self.restart() def restart(self) -> None: self.__render_tags: Dict[ Any, List['TextBatcher._render_tag']] = defaultdict(list) self._va.clear() def initializeGL(self) -> None: # Working VBO that will contain glyph data self.vbo = VBO(numpy.ndarray([], 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 render(self, key: Any = None) -> None: return if self.__vbo_needs_update: self.vbo.data = self._va.buffer()[:] self.vbo.bind() self.__vbo_needs_update = False self.text_render.updateTexture() with self.text_render.sdf_shader.program, self.text_render.tex.on( GL.GL_TEXTURE_2D), self.vao: GL.glUniform1i(self.text_render.sdf_shader.program.uniforms.tex1, 0) GL.glUniform4ui(self.text_render.sdf_shader.uniforms.layer_info, 255, COL_TEXT, 0, 255) for tag in self.__render_tags[key]: mat_calc = tag.matrix GL.glUniformMatrix3fv(self.text_render.sdf_shader.uniforms.mat, 1, True, mat_calc.astype(numpy.float32)) GL.glDrawArrays(GL.GL_TRIANGLES, tag.textinfo.start, tag.textinfo.count) def submit(self, ts: '_StringMetrics', mat: 'npt.NDArray[numpy.float64]', color: Any, k: Any = None) -> None: self.__render_tags[k].append(self._render_tag(ts, mat, color)) def submit_text_box(self, premat: 'npt.NDArray[numpy.float64]', text: str, box: Rect, color: Any, k: Any = None) -> None: ts = self.get_string(text) mat = premat.dot(ts.get_render_to_mat(box)) self.submit(ts, mat, color, k) def get_string(self, text: str) -> '_StringMetrics': if text in self.__cached: return self.__cached[text] self.__cached[text] = ti = self.text_render.getStringMetrics(text) ti.start = self._va.tell() self._va.extend(ti.arr) ti.count = ti.arr.count() self.__vbo_needs_update = True return ti
class TextBatch: __tag = namedtuple("__tag", ['mat', 'inf']) def __init__(self, tr: 'TextRender') -> None: self.__text_render = tr self.__elem_count = 0 self.__color = (255, COL_TEXT, 0, 0) def initializeGL(self) -> None: self.vbo = VBO( numpy.ndarray([], dtype=self.__text_render.buffer_dtype), GL.GL_STATIC_DRAW, GL.GL_ARRAY_BUFFER) self.vao = VAO() self._va = VA_tex(1024) with self.vao, self.vbo: self.__text_render.b1.assign() self.__text_render.b2.assign() def restart(self) -> None: self.__strs: List[TextBatch.__tag] = [] # TEMP def get_string(self, text: str) -> '_StringMetrics': """ :param text: :return: :returns: _StringMetrics """ return self.__text_render.getStringMetrics(text) def add(self, mat: 'npt.NDArray[numpy.float64]', str_info: '_StringMetrics') -> None: """ Queues a text string to be rendered in the batch :param mat: location matrix :param str_info: :type str_info: _StringMetrics :return: """ self.__strs.append(TextBatch.__tag(mat, str_info)) def prepare(self) -> None: self.__text_render.updateTexture() self._va.clear() for mat, str_info in self.__strs: self._va.extend_project(mat, str_info.arr) self.vbo.set_array(self._va.buffer()[:]) self.vbo.bind() self.__elem_count = self._va.count() def render(self, mat: 'npt.NDArray[numpy.float64]') -> None: with self.__text_render.sdf_shader.program, self.__text_render.tex.on( GL.GL_TEXTURE_2D), self.vao: GL.glUniform1i(self.__text_render.sdf_shader.uniforms.tex1, 0) GL.glUniformMatrix3fv(self.__text_render.sdf_shader.uniforms.mat, 1, True, mat.astype(numpy.float32)) GL.glUniform4ui(self.__text_render.sdf_shader.uniforms.layer_info, *self.__color) GL.glDrawArrays(GL.GL_TRIANGLES, 0, self.__elem_count)