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
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)
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)