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 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 Structure: 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: 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