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)
Beispiel #2
0
    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)
Beispiel #4
0
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)