from wsgiref.validate import check_errors from OpenGL.GL.ARB.vertex_array_object import glDeleteVertexArrays from OpenGL.GL.framebufferobjects import glBindFramebuffer from OpenGL.GLUT import * import OpenGL.GLUT.freeglut from OpenGL.GLU import * from OpenGL.GL import * import numpy as np from OpenGL.extensions import alternate from Objects.Objects import Object from MatrixStuff.Transformations import translate def check_error(message): gl_error = glGetError() if (gl_error != GL_NO_ERROR): print("Error: " + message) if (gluErrorString(gl_error)): print(gluErrorString(gl_error)) else: print(hex(gl_error)) return True return False class Renderable: def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): pass class Structure(Renderable): def __init__(self): self.Objects = {} self.vais = {} self.Matrix = np.identity(4, np.float32) self.dirty = False def addShape(self, program, shape): if not program in self.Objects.keys(): self.Objects[program] = [] self.Objects[program].append(shape) self.dirty = True def removeShape(self, program, shape): if program in self.Objects.keys(): self.Objects[program].remove(shape) if len(self.Objects[program]) == 0: self.Objects.pop(program) self.dirty = True def buildvertexArrays(self): if self.dirty: self.clearVertexArrays() glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_TEXTURE_COORD_ARRAY) glEnableClientState(GL_NORMAL_ARRAY) glEnableClientState(GL_COLOR_ARRAY) self.vais = {} for key, objects in self.Objects.items(): tvai = GLuint(0) tpbi = GLuint(0) tcbi = GLuint(0) tsbi = GLuint(0) glGenVertexArrays(1, tvai) glBindVertexArray(tvai) vid = glGetAttribLocation(key, "in_position") glEnableVertexAttribArray(vid) tpbi = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, tpbi) positions = [] for o in objects: positions.append(o.pos[0]) positions.append(o.pos[1]) positions.append(o.pos[2]) glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW) glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None) check_error("Could not create position buffer") colors = [] for o in objects: colors.append(o.color[0]) colors.append(o.color[1]) colors.append(o.color[2]) tcbi = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, tcbi) glBufferData(GL_ARRAY_BUFFER, np.array(colors, dtype=np.float32), GL_STATIC_DRAW) vc = glGetAttribLocation(key, "MyInColor") if vc != -1: glEnableVertexAttribArray(vc) glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None) check_error("Could not create color buffer") if hasattr(objects[0], 'size'): sizes = [] for o in objects: sizes.append(o.size[0]) sizes.append(o.size[1]) sizes.append(o.size[2]) tsbi = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, tsbi) glBufferData(GL_ARRAY_BUFFER, np.array(sizes, dtype=np.float32), GL_STATIC_DRAW) vs = glGetAttribLocation(key, "MyInSize") if vs != -1: glEnableVertexAttribArray(vs) glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None) check_error("Could not create size buffer") glBindVertexArray(0) self.vais[key] = (tvai, tpbi, tcbi, tsbi) self.dirty = False def clearVertexArrays(self): for key, (a, p, c, s) in self.vais.items(): if p != -1: glDisableVertexAttribArray(p) glDeleteBuffers(1, [p]) if c != -1: glDisableVertexAttribArray(c) glDeleteBuffers(1, [c]) if s != -1 and s != GLuint(-1): glDisableVertexAttribArray(s) glDeleteBuffers(1, [s]) glDeleteVertexArrays(1, a) check_error("Could not destroy vertex array") def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): for key, tupel in self.vais.items(): if alternateprograms == None: program_id = key else: assert key in alternateprograms program_id = alternateprograms[key] glUseProgram(program_id) check_error("Renderingprogram is not initialized!") projection = glGetUniformLocation(program_id, 'projModelViewMatrix') rot = glGetUniformLocation(program_id, 'rotMatrix') glUniformMatrix4fv(projection, 1, GL_FALSE, np.array(projMatrix)) glUniformMatrix3fv(rot, 1, GL_FALSE, np.array(geometryRotMatrix)) glBindVertexArray(tupel[0]) glDrawArrays(GL_POINTS, 0, len(self.Objects[key])) check_error("Rendering problem") glBindVertexArray(0) glUseProgram(0) def __eq__(self, other): if type(other) is type(self): return self.vais == other.vais and self.Objects == other.Objects else: return False class CompoundStructure(Renderable): def __init__(self): self.Structures = [] def addStructure(self, structure: Structure, M: np.matrix = np.identity(4, np.float), R: np.matrix = np.identity(3, np.float)): self.Structures.append((structure, M, R)) def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): for (structure, M, R) in self.Structures: structure.buildvertexArrays() structure.render(M * projMatrix, R * geometryRotMatrix, alternateprograms) def __eq__(self, other): if type(other) is type(self): return self.Structures == other.Structures else: return False class WorldChunk(Renderable): def __init__(self, width, length, height): assert width > 0, 'Width must be greater than 0' assert length > 0, 'length must be greater than 0' assert height > 0, 'height must be greater than 0' self.visible = [] self.content = [] self.entities = [] self.width = width self.length = length self.height = height for x in range(width): self.content.append([]) self.visible.append([]) for y in range(length): self.content[x].append([]) self.visible[x].append([]) for z in range(height): self.content[x][y].append(None) self.visible[x][y].append(4) def put_object(self, x: int, y: int, z: int, new_object: Object): assert 0 <= x < self.width, 'Put out of bounds for x coordinate! Must be between 0 and %i' % self.width assert 0 <= y < self.length, 'Put out of bounds for y coordinate! Must be between 0 and %i' % self.length assert 0 <= z < self.height, 'Put out of bounds for z coordinate! Must be between 0 and %i' % self.height self.content[x][y][z] = new_object change = -1 if new_object is not None else 1 visible_carry_over = [] if x + 1 >= self.width: visible_carry_over.append((1, 0, 0, change)) else: self.visible[x + 1][y][z] += change if x - 1 < 0: visible_carry_over.append((-1, 0, 0, change)) else: self.visible[x - 1][y][z] += change if y + 1 >= self.length: visible_carry_over.append((0, 1, 0, change)) else: self.visible[x][y + 1][z] += change if y - 1 < 0: visible_carry_over.append((0, -1, 0, change)) else: self.visible[x][y - 1][z] += change if z + 1 >= self.height: visible_carry_over.append((0, 0, 1, change)) else: self.visible[x][y][z + 1] += change if z - 1 < 0: visible_carry_over.append((0, 0, -1, change)) else: self.visible[x][y][z - 1] += change return visible_carry_over def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): for x in range(self.width): for y in range(self.length): for z in range(self.height): if self.visible[x][y][z] > 0 and self.content[x][y][z] is not None: self.content[x][y][z].render(translate(x, y, z) * projMatrix, geometryRotMatrix, alternateprograms) for entity in self.entities: entity.render(projMatrix, geometryRotMatrix, alternateprograms)