def custom_batch(shader, type, content, indices=None): """ shader type: 'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ' """ from gpu.types import ( GPUBatch, GPUIndexBuf, GPUVertBuf, ) for data in content.values(): vbo_len = len(data) break else: raise ValueError("Empty 'content'") vbo_format = shader.format_calc() vbo = GPUVertBuf(vbo_format, vbo_len) for id, data in content.items(): if len(data) != vbo_len: raise ValueError("Length mismatch for 'content' values") vbo.attr_fill(id, data) if indices is None: return GPUBatch(type=type, buf=vbo) else: ibo = GPUIndexBuf(type=type, seq=indices) return GPUBatch(type=type, buf=vbo, elem=ibo)
def draw_lines(self, context, obj, vertices, indices, topology=None): region = context.region region3d = context.region_data color = context.scene.DocProperties.decorations_colour fmt = GPUVertFormat() fmt.attr_add(id="pos", comp_type="F32", len=3, fetch_mode="FLOAT") if topology: fmt.attr_add(id="topo", comp_type="U8", len=1, fetch_mode="INT") vbo = GPUVertBuf(len=len(vertices), format=fmt) vbo.attr_fill(id="pos", data=vertices) if topology: vbo.attr_fill(id="topo", data=topology) ibo = GPUIndexBuf(type="LINES", seq=indices) batch = GPUBatch(type="LINES", buf=vbo, elem=ibo) bgl.glEnable(bgl.GL_LINE_SMOOTH) bgl.glHint(bgl.GL_LINE_SMOOTH_HINT, bgl.GL_NICEST) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) self.shader.bind() self.shader.uniform_float self.shader.uniform_float("viewMatrix", region3d.perspective_matrix) self.shader.uniform_float("winsize", (region.width, region.height)) self.shader.uniform_float("color", color) # Horrific prototype code factor = self.camera_zoom_to_factor( context.space_data.region_3d.view_camera_zoom) camera_width_px = factor * context.region.width mm_to_px = camera_width_px / self.camera_width_mm # 0.00025 is a magic constant number I visually discovered to get the right number. # It probably should be dynamically calculated using system.dpi or something. viewport_drawing_scale = 0.00025 * mm_to_px self.shader.uniform_float("viewportDrawingScale", viewport_drawing_scale) batch.draw(self.shader)
def batch(*args, **attr_data): """ Positional arguments: vbo format | shader | built-in shader name, primitive type, [indices] Keyword arguments: data for the corresponding shader attributes """ arg_count = len(args) if (arg_count < 2) or (arg_count > 3): raise TypeError( f"batch() takes from 2 to 3 positional arguments but {arg_count} were given" ) vbo_len = 0 for data in attr_data.values(): if not data: continue data_len = len(data) if data_len == vbo_len: continue if vbo_len == 0: vbo_len = data_len else: raise ValueError( "Length mismatch for vertex attribute data") vbo_format = args[0] if isinstance(vbo_format, str): vbo_format = shader_from_builtin(vbo_format) if isinstance(vbo_format, GPUShader): vbo_format = vbo_format.format_calc() primitive_type = args[1] indices = (args[2] if arg_count > 2 else None) vbo = GPUVertBuf(vbo_format, vbo_len) for id, data in attr_data.items(): vbo.attr_fill(id, data) if indices is None: return GPUBatch(type=primitive_type, buf=vbo) else: ibo = GPUIndexBuf(type=primitive_type, seq=indices) return GPUBatch(type=primitive_type, buf=vbo, elem=ibo)
def batch_for_shader(shader, type, content, indices=None): """ Return a batch already configured and compatible with the shader. :arg shader: shader for which a compatible format will be computed. :type shader: :class:`gpu.types.GPUShader` :arg type: "'POINTS', 'LINES', 'TRIS' or 'LINES_ADJ'". :type type: str :arg content: Maps the name of the shader attribute with the data to fill the vertex buffer. :type content: dict :return: compatible batch :rtype: :class:`gpu.types.Batch` """ import gpu from gpu.types import ( GPUBatch, GPUIndexBuf, GPUVertBuf, ) for data in content.values(): vbo_len = len(data) break else: raise ValueError("Empty 'content'") vbo_format = shader.format_calc() vbo = GPUVertBuf(vbo_format, vbo_len) for id, data in content.items(): if len(data) != vbo_len: raise ValueError("Length mismatch for 'content' values") vbo.attr_fill(id, data) if indices is None: return GPUBatch(type=type, buf=vbo) else: ibo = GPUIndexBuf(type=type, seq=indices) return GPUBatch(type=type, buf=vbo, elem=ibo)