def copy_from_buffer(self, source: "Buffer", size=-1, offset=0, source_offset=0):
        """Copy data into this buffer from another buffer

        :param Buffer source: The buffer to copy from
        :param int size: The amount of bytes to copy
        :param int offset: The byte offset to write the data in this buffer
        :param int source_offset: The byte offset to read from the source buffer
        """
        # Read the entire source buffer into this buffer
        if size == -1:
            size = source.size

        # TODO: Check buffer bounds
        if size + source_offset > source.size:
            raise ValueError("Attempting to read outside the source buffer")

        if size + offset > self._size:
            raise ValueError("Attempting to write outside the buffer")

        gl.glBindBuffer(gl.GL_COPY_READ_BUFFER, source.glo)
        gl.glBindBuffer(gl.GL_COPY_WRITE_BUFFER, self._glo)
        gl.glCopyBufferSubData(
            gl.GL_COPY_READ_BUFFER,
            gl.GL_COPY_WRITE_BUFFER,
            gl.GLintptr(source_offset),  # readOffset
            gl.GLintptr(offset),  # writeOffset
            size,  # size (number of bytes to copy)
        )
    def _refresh_shape(self, group):
        # Create a buffer large enough to hold all the shapes buffers
        batch = self.batches[group]
        total_vbo_bytes = sum(s.vbo.size for s in batch.items)
        vbo = shader.Buffer.create_with_size(total_vbo_bytes)
        offset = 0
        gl.glBindBuffer(gl.GL_COPY_WRITE_BUFFER, vbo.buffer_id)
        # Copy all the shapes buffer in our own vbo
        for shape in batch.items:
            gl.glBindBuffer(gl.GL_COPY_READ_BUFFER, shape.vbo.buffer_id)
            gl.glCopyBufferSubData(
                gl.GL_COPY_READ_BUFFER,
                gl.GL_COPY_WRITE_BUFFER,
                gl.GLintptr(0),
                gl.GLintptr(offset),
                shape.vbo.size)
            offset += shape.vbo.size

        # Create an index buffer object. It should count starting from 0. We need to
        # use a reset_idx to indicate that a new shape will start.
        reset_idx = 2 ** 32 - 1
        indices = []
        counter = itertools.count()
        for shape in batch.items:
            indices.extend(itertools.islice(counter, shape.vao.num_vertices))
            indices.append(reset_idx)
        del indices[-1]
        indices = np.array(indices)
        ibo = shader.Buffer(indices.astype('i4').tobytes())

        vao_content = [
            shader.BufferDescription(
                vbo,
                '2f 4B',
                ('in_vert', 'in_color'),
                normalized=['in_color']
            )
        ]
        vao = shader.vertex_array(self.program, vao_content, ibo)
        with self.program:
            self.program['Projection'] = get_projection().flatten()
            self.program['Position'] = [self.center_x, self.center_y]
            self.program['Angle'] = self.angle

        batch.shape.vao = vao
        batch.shape.vbo = vbo
        batch.shape.ibo = ibo
        batch.shape.program = self.program
        mode, line_width = group
        batch.shape.mode = mode
        batch.shape.line_width = line_width
Exemple #3
0
    def _read(self, size):
        """ Debug method to read data from the buffer. """

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffer_id)
        ptr = gl.glMapBufferRange(gl.GL_ARRAY_BUFFER, gl.GLintptr(0), size,
                                  gl.GL_MAP_READ_BIT)
        print(f"Reading back from buffer:\n{string_at(ptr, size=size)}")
        gl.glUnmapBuffer(gl.GL_ARRAY_BUFFER)
    def write(self, data: Any, offset: int = 0):
        """Write byte data to the buffer.

        :param bytes data: The byte data to write. This can be bytes or any object supporting the buffer protocol.
        :param int offset: The byte offset
        """
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo)
        size, data = data_to_ctypes(data)
        gl.glBufferSubData(gl.GL_ARRAY_BUFFER, gl.GLintptr(offset), size, data)
Exemple #5
0
 def write(self, data: bytes, offset: int = 0):
     gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffer_id)
     gl.glBufferSubData(gl.GL_ARRAY_BUFFER, gl.GLintptr(offset), len(data),
                        data)