class Primitive: def __init__(self): self.vertex_count = 0 self.vertices = [] self.indices = [] self.material = None self.va = None self.ib = None self.vbo = None self.layout = None self.shader = None def setup_prim(self): self.va = VertexArray() self.vbo = VertexBuffer(self.vertices) self.layout = VertexBufferLayout() self.layout.push_float(3) self.layout.push_float(2) self.layout.push_float(3) self.va.add_buffer(self.vbo, self.layout) self.ib = IndexBuffer(self.indices) self.shader = Shader('resources/shaders/BasicTextureMVP.glsl') self.material.textures.basecolor.setup_texture() def draw_prim(self, modeltransform): self.shader.bind() mvp = Global.ProjMat * Global.ViewMat * modeltransform self.shader.set_uniformMat4f('u_MVP', mvp) self.material.textures.basecolor.bind() self.shader.set_uniform1i('u_Texture', 0) self.va.bind() self.ib.bind() glDrawElements(GL_TRIANGLES, self.ib.get_count(), GL_UNSIGNED_INT, None)
class FullScreenQuad: def __init__(self , fname): self.shader = Shader(fname) self.mat = MaterialData() self.identityMat = pyrr.matrix44.create_identity() vertices = [-1 , 1 , -1 , -1 , 1 , 1 , 1 , -1] vertices = np.array(vertices, dtype='float32') self.vao = glGenVertexArrays(1) glBindVertexArray(self.vao) self.vbo = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vbo); glBufferData(GL_ARRAY_BUFFER,8*4 , vertices, GL_STATIC_DRAW) glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, None); glBindVertexArray(0); def renderFullScreenQuad(self): self.shader.bind() self.shader.updateUniforms(self.identityMat , self.identityMat ,self.identityMat , self.mat) glBindVertexArray(self.vao) glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0);
def draw_line(self, va: VertexArray, shader: Shader, point_count): shader.bind() va.bind() glDrawArrays(GL_LINES, 0, point_count)
class Grid: def __init__(self, step, cell_size): self.step = step self.cell_size = cell_size self.grid = [] self.grid_sdr = Shader('resources/shaders/Grid.glsl') self.grid_sdr.bind() self.layout = VertexBufferLayout() self.layout.push_float(2) self.VA = VertexArray() self.VA.unbind() self.grid_sdr.unbind() distance = cell_size * step grid_array = [] if step == 0: xline = [cell_size, 0.0, -cell_size, 0.0] yline = [0.0, cell_size, 0.0, -cell_size] else: xline = [distance, 0.0, -distance, 0.0] yline = [0.0, distance, 0.0, -distance] grid_array.extend(xline) grid_array.extend(yline) if step > 0: for i in range(step): i = i + 1 grid_array.extend( [distance, i * cell_size, -distance, i * cell_size]) grid_array.extend( [distance, -i * cell_size, -distance, -i * cell_size]) grid_array.extend( [i * cell_size, distance, i * cell_size, -distance]) grid_array.extend( [-i * cell_size, distance, -i * cell_size, -distance]) else: print("Grid step count can't be negative.") self.grid = numpy.array(grid_array, 'f') self.VB = VertexBuffer(self.get_grid_array()) self.VA.add_buffer(self.VB, self.layout) def get_grid_array(self): return self.grid def get_point_count(self): # if self.step == 0: # return 4 return 4 + (self.step * 8) def unbind_shader(self): self.grid_sdr.bind() def bind_shader(self): self.grid_sdr.unbind() def draw_grid(self, proj, view): if Settings.GridEnabled: glEnable(GL_LINE_SMOOTH) self.grid_sdr.bind() self.VA.bind() self.grid_sdr.set_uniformMat4f( 'u_MVP', proj * view * rotate(mat4(1.0), radians(90), vec3(1.0, 0.0, 0.0))) glDrawArrays(GL_LINES, 0, self.get_point_count()) self.grid_sdr.unbind() self.VA.unbind()
class Mesh: def __init__(self, OBJname, MATname): #loads .obj and .mat files self.meshData = [] self.materialData = [] self.count = 0 self.VBOs = [] self.VAOs = [] self.shader = Shader("./shaders/diffuseSpec") #loads the master shader self.textures = [] self.loadMesh(OBJname) self.loadMaterial(MATname) self.loadDataInGPU() def loadMaterial(self, fname): for line in open(fname, 'r'): if line.startswith('#'): continue values = line.split() if not values: continue if values[0] == 'o': data = [] data = MaterialData.MaterialData() self.materialData.append(data) if values[0] == 'diffuse': data.diffuse = values[2] self.textures.append(Texture.Texture("./res/" + data.diffuse)) if values[0] == 'specularIntensity': data.specularIntensity = np.float32(float(values[2])) if values[0] == 'specularPower': data.specularPower = np.float32(float(values[2])) if values[0] == 'reflectAmt': data.reflectAmt = np.float32(float(values[2])) if values[0] == 'reflectColor': data.reflectColor[0] = np.float32(float(values[1])) data.reflectColor[1] = np.float32(float(values[2])) data.reflectColor[2] = np.float32(float(values[3])) if values[0] == 'refractAmt': data.refractAmt = np.float32(float(values[2])) if values[0] == 'refractColor': data.refractColor[0] = np.float32(float(values[1])) data.refractColor[1] = np.float32(float(values[2])) data.refractColor[2] = np.float32(float(values[3])) def loadMesh(self, fname): data = [] for line in open(fname, 'r'): if line.startswith('#'): continue values = line.split() if not values: continue if values[0] == 'o': data = [] data = MeshData.MeshData() self.meshData.append(data) self.count = self.count + 1 for c in values[1:]: data.name += c if values[0] == 'v': data.vert_coords.append(values[1:4]) if values[0] == 'vt': data.text_coords.append(values[1:3]) if values[0] == 'vn': data.norm_coords.append(values[1:4]) if values[0] == 'f': face_i = [] text_i = [] norm_i = [] for v in values[1:4]: w = v.split('/') vOffset = 0 tOffset = 0 nOffset = 0 if (self.count >= 2): for g in range(self.count - 1): vOffset += len(self.meshData[g].vert_coords) tOffset += len(self.meshData[g].text_coords) nOffset += len(self.meshData[g].norm_coords) face_i.append(int(w[0]) - 1 - vOffset) text_i.append(int(w[1]) - 1 - tOffset) norm_i.append(int(w[2]) - 1 - nOffset) data.vertex_index.append(face_i) data.texture_index.append(text_i) data.normal_index.append(norm_i) for k in range(self.count): self.meshData[k].vertex_index = [ y for x in self.meshData[k].vertex_index for y in x ] self.meshData[k].texture_index = [ y for x in self.meshData[k].texture_index for y in x ] self.meshData[k].normal_index = [ y for x in self.meshData[k].normal_index for y in x ] for i in self.meshData[k].vertex_index: self.meshData[k].model.extend(self.meshData[k].vert_coords[i]) for i in self.meshData[k].texture_index: self.meshData[k].model.extend(self.meshData[k].text_coords[i]) for i in self.meshData[k].normal_index: self.meshData[k].model.extend(self.meshData[k].norm_coords[i]) self.meshData[k].model = np.array(self.meshData[k].model, dtype='float32') def loadDataInGPU(self): for i in range(self.count): texture_offset = len(self.meshData[i].vertex_index) * 12 normal_offset = (texture_offset + len(self.meshData[i].texture_index) * 8) self.VAOs.append(glGenVertexArrays(1)) glBindVertexArray(self.VAOs[i]) self.VBOs.append(glGenBuffers(1)) glBindBuffer(GL_ARRAY_BUFFER, self.VBOs[i]) glBufferData( GL_ARRAY_BUFFER, self.meshData[i].model.itemsize * len(self.meshData[i].model), self.meshData[i].model, GL_STATIC_DRAW) # position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, self.meshData[i].model.itemsize * 3, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) # texture glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, self.meshData[i].model.itemsize * 2, ctypes.c_void_p(texture_offset)) glEnableVertexAttribArray(1) #normal glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, self.meshData[i].model.itemsize * 3, ctypes.c_void_p(normal_offset)) glEnableVertexAttribArray(2) glBindVertexArray(0) def renderALL(self, view, projection, model): self.shader.bind() for i in range(self.count): self.textures[i].bind(GL_TEXTURE0) self.shader.updateUniforms(view, projection, model, self.materialData[i]) glBindVertexArray(self.VAOs[i]) glDrawArrays(GL_TRIANGLES, 0, len(self.meshData[i].vertex_index)) glBindVertexArray(0)
def draw_array(self, va: VertexArray, shader: Shader, vertex_count): shader.bind() va.bind() glDrawArrays(GL_TRIANGLES, 0, vertex_count)
def draw_element(self, va: VertexArray, ib: IndexBuffer, shader: Shader): shader.bind() va.bind() ib.bind() glDrawElements(GL_TRIANGLES, ib.get_count(), GL_UNSIGNED_INT, None)