Source code for vbo


"""
This module processes an application's vertex buffer objects (VBOs)

NOTE:
- VBOs are buffer objects we use for vertex processing
- In reality, we can use buffer objects for means outside of vertex processing 
"""

# Import Python modules
if __name__ == '__main__':
    import numpy as np
    import pywavefront


[docs] class VBO: def __init__(self, ctx): self.vbos = {} self.vbos['cube'] = CubeVBO(ctx) self.vbos['cat'] = CatVBO(ctx) self.vbos['skybox'] = SkyBoxVBO(ctx) self.vbos['advanced_skybox'] = AdvancedSkyBoxVBO(ctx)
[docs] def destroy(self): [vbo.destroy() for vbo in self.vbos.values()]
[docs] class BaseVBO: def __init__(self, ctx): self.ctx = ctx self.vbo = self.get_vbo() self.format: str = None self.attribs: list = None # NOTE: Override get_vertex_data() in a subclass because it is geometry-dependant
[docs] def get_vertex_data(self): ...
[docs] def get_vbo(self): vertex_data = self.get_vertex_data() vbo = self.ctx.buffer(vertex_data) return vbo
[docs] def destroy(self): self.vbo.release()
[docs] class CubeVBO(BaseVBO): def __init__(self, ctx): super().__init__(ctx) self.format = '2f 3f 3f' self.attribs = ['in_texcoord_0', 'in_normal', 'in_position']
[docs] @staticmethod def get_data(vertices, indices): # NOTE: Uses list comprehension to Outputs large list of tuples! data = [vertices[ind] for triangle in indices for ind in triangle] return np.array(data, dtype='f4')
[docs] def get_vertex_data(self): # Get vertex coordinates vertices = [(-1, -1, 1), ( 1, -1, 1), (1, 1, 1), (-1, 1, 1), (-1, 1, -1), (-1, -1, -1), (1, -1, -1), ( 1, 1, -1)] indices = [(0, 2, 3), (0, 1, 2), (1, 7, 2), (1, 6, 7), (6, 5, 4), (4, 7, 6), (3, 4, 5), (3, 5, 0), (3, 7, 4), (3, 2, 7), (0, 6, 1), (0, 5, 6)] vertex_data = self.get_data(vertices, indices) # Get texture coordinates tex_coord_vertices = [(0, 0), (1, 0), (1, 1), (0, 1)] tex_coord_indices = [(0, 2, 3), (0, 1, 2), (0, 2, 3), (0, 1, 2), (0, 1, 2), (2, 3, 0), (2, 3, 0), (2, 0, 1), (0, 2, 3), (0, 1, 2), (3, 1, 2), (3, 0, 1),] tex_coord_data = self.get_data(tex_coord_vertices, tex_coord_indices) # Get normals # NOTE: Multiply tuples by 6 because each face, which has 6 vertices, have the same normal normals = [( 0, 0, 1) * 6, ( 1, 0, 0) * 6, ( 0, 0,-1) * 6, (-1, 0, 0) * 6, ( 0, 1, 0) * 6, ( 0,-1, 0) * 6,] normals = np.array(normals, dtype='f4').reshape(36, 3) # NOTE: We horizontally concat per-vertex data vertex_data = np.hstack([normals, vertex_data]) vertex_data = np.hstack([tex_coord_data, vertex_data]) return vertex_data
[docs] class CatVBO(BaseVBO): def __init__(self, app): super().__init__(app) self.format = '2f 3f 3f' self.attribs = ['in_texcoord_0', 'in_normal', 'in_position']
[docs] def get_vertex_data(self): objs = pywavefront.Wavefront('objects/cat/20430_Cat_v1_NEW.obj', cache=True, parse=True) obj = objs.materials.popitem()[1] vertex_data = obj.vertices vertex_data = np.array(vertex_data, dtype='f4') return vertex_data
[docs] class SkyBoxVBO(BaseVBO): def __init__(self, ctx): super().__init__(ctx) self.format = '3f' self.attribs = ['in_position']
[docs] @staticmethod def get_data(vertices, indices): # NOTE: Uses list comprehension to Outputs large list of tuples! data = [vertices[ind] for triangle in indices for ind in triangle] return np.array(data, dtype='f4')
[docs] def get_vertex_data(self): # Get vertex coordinates vertices = [(-1, -1, 1), ( 1, -1, 1), (1, 1, 1), (-1, 1, 1), (-1, 1, -1), (-1, -1, -1), (1, -1, -1), ( 1, 1, -1)] indices = [(0, 2, 3), (0, 1, 2), (1, 7, 2), (1, 6, 7), (6, 5, 4), (4, 7, 6), (3, 4, 5), (3, 5, 0), (3, 7, 4), (3, 2, 7), (0, 6, 1), (0, 5, 6)] vertex_data = self.get_data(vertices, indices) vertex_data = np.flip(vertex_data, 1).copy(order='C') return vertex_data
[docs] class AdvancedSkyBoxVBO(BaseVBO): def __init__(self, ctx): super().__init__(ctx) self.format = '3f' self.attribs = ['in_position']
[docs] def get_vertex_data(self): # NOTE: Generates a fullscreen quad through a large triangle z = 0.9999 vertices = [(-1, -1, z), (3, -1, z), (-1, 3, z)] vertex_data = np.array(vertices, dtype='f4') return vertex_data