class MeshVertexBuffer(object): def __init__(self, vertices=0): self.update(vertices) self.uniforms = dict() self.buffer = None def update(self, vertices): self.vertices = vertices self.attributes = dict() self.offsets = dict() self.size = 0 self.changed = True def add(self, name, data, count=3, datatype=GL.GL_FLOAT): self.attributes[name] = MeshVertexAttribute(name, data, count, datatype) self.changed = True def remove(self, name): if name in self.attributes: del self.attributes[name] self.changed = True def create(self, gl): if not self.buffer: self.buffer = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer) if not self.buffer.isCreated() and not self.buffer.create(): raise Exception("buffer creation failed!") self.buffer.bind() self.offsets = dict() self.size = 0 for item in self.attributes.values(): self.offsets[item.name] = self.size self.size += self.vertices * item.count * item.datasize self.buffer.allocate(self.size) for item in self.attributes.values(): self.buffer.write(self.offsets[item.name], item.data.data, self.vertices * item.count * item.datasize) self.buffer.release() self.changed = False def destroy(self, gl): if not self.buffer: return self.buffer.destroy() self.buffer = None self.changed = True def enable(self, gl, shader): if self.changed: self.create(gl) shader.setUniforms(self.uniforms) self.buffer.bind() for item in self.attributes.values(): if item.enabled: shader.setAttributeArray(item.name, item.datatype, self.offsets[item.name], item.count) self.buffer.release() def disable(self, gl, shader): for item in self.attributes.values(): if item.enabled: shader.unsetAttributeArray(item.name)
class MeshIndexBuffer(object): def __init__(self, elements=0, data=np.zeros((0), dtype=np.uint32), primitives=GL.GL_POINTS, datatype=GL.GL_UNSIGNED_INT): self.update(elements, data, primitives, datatype) self.uniforms = dict() self.buffer = None def update(self, elements, data, primitives=GL.GL_POINTS, datatype=GL.GL_UNSIGNED_INT): self.elements = elements self.data = data self.primitives = primitives self.datatype = datatype if datatype == GL.GL_UNSIGNED_BYTE: self.datasize = 1 elif datatype == GL.GL_UNSIGNED_SHORT: self.datasize = 2 elif datatype == GL.GL_UNSIGNED_INT: self.datasize = 4 else: raise Exception("unsupported index type") self.size = 0 self.changed = True def create(self, gl): if not self.buffer: self.buffer = QOpenGLBuffer(QOpenGLBuffer.IndexBuffer) if not self.buffer.isCreated() and not self.buffer.create(): raise Exception("buffer creation failed!") self.buffer.bind() self.size = self.elements * self.datasize self.buffer.allocate(self.size) self.buffer.write(0, self.data.data, self.elements * self.datasize) self.buffer.release() self.changed = False def destroy(self, gl): if not self.buffer: return self.buffer.destroy() self.buffer = None self.changed = True def enable(self, gl, shader): if self.changed: self.create(gl) shader.setUniforms(self.uniforms) self.buffer.bind() def disable(self, gl, shader): self.buffer.release()