def create_program_attribute_layout(program): active_attribute = c_int(0) GL.glGetProgramiv(program, GL.GL_ACTIVE_ATTRIBUTES, active_attribute) max_name_length = GL.glGetProgramiv(program, GL.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) name_length = GL.GLsizei(0) attribute_size = GL.GLint(0) attribute_type = GL.GLenum(0) name = (GL.GLchar * max_name_length)() attribute_layout = [] for index in range(active_attribute.value): GL.glGetActiveAttrib(program, index, max_name_length, name_length, attribute_size, attribute_type, name) attribute_location = GL.glGetAttribLocation(program, name.value) attribute_layout.append((attribute_location, ATTRIBUTE_SIZE_BY_TYPES[attribute_type.value])) attribute_layout.sort(key=lambda pair: pair[0]) attribute_locations = [] attribute_sizes = [] for attribute_location, attribute_size in attribute_layout: attribute_locations.append(attribute_location) attribute_sizes.append(attribute_size) return attribute_locations, attribute_sizes
def build_attribute_map(self): """ Builds an internal attribute map by querying the program. This way we don't have to query OpenGL (can cause slowdowns) This information is also used when the shader and VAO negotiates the buffer binding. """ attribute_count = GL.glGetProgramiv(self.program, GL.GL_ACTIVE_ATTRIBUTES) bufsize = GL.glGetProgramiv(self.program, GL.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) print("Shader {} has {} attribute(s)".format(self.name, attribute_count)) for i in range(attribute_count): # Unlike glGetActiveUniform the attrib version do not return a convenient tuple # and we'll have to use to ugly version. (Most people make wrappers for this one) length, size, type, name = GL.GLsizei(), GL.GLint(), GL.GLenum(), ( GL.GLchar * bufsize)() GL.glGetActiveAttrib(self.program, i, bufsize, length, size, type, name) # Get the actual location. Do not trust the original order location = GL.glGetAttribLocation(self.program, name.value) attribute = Attribute(name.value, type.value, location) self.attribute_map[attribute.name] = attribute self.attribute_list.append(attribute) print(" - {}".format(attribute)) self.attribute_key = ','.join( name for name in sorted(self.attribute_map.keys())) print("Shader attribute key:", self.attribute_key)
def _get_attribs(self) -> Dict[str, IndexSizeType]: _active_attrib = GL.glGetProgramiv(self.program, GL.GL_ACTIVE_ATTRIBUTES) # For some reason the PyOpenGL Binding is sorta broken # use the full ctypes-style access bufSize = 50 ct_nameSize = GL.GLsizei() ct_size = GL.GLint() ct_type = GL.GLenum() ct_name = (GL.GLchar * bufSize)() _attribs = {} for attrib_index in range(_active_attrib): GL.glGetActiveAttrib(self.program, attrib_index, bufSize, ct_nameSize, ct_size, ct_type, ct_name) #in python3 attribute names are bytestrings. Convert to UTF8 name = ct_name.value.decode("ascii") _attribs[name] = IndexSizeType(attrib_index, ct_size.value, ct_type.value) return _attribs
def prepare_rendering(self, render_option): if render_option.primitive == renderoption.Primitive.Point: gl.glPointSize(gl.GLfloat(render_option.point_size)) else: gl.glLineWidth(gl.GLfloat(render_option.line_width)) gl.glEnable(gl.GL_DEPTH_TEST) gl.glDepthFunc(gl.GLenum(render_option.get_depth_func())) return True
def prepare_rendering(self, render_option): if render_option.primitive.Line: gl.glLineWidth(gl.GLfloat(2.0)) else: gl.glPointSize(gl.GLfloat(5.0)) gl.glEnable(gl.GL_DEPTH_TEST) gl.glDepthFunc(gl.GLenum(gl.GL_LEQUAL)) return True
def prepare_rendering(self, render_option): mesh_show_back_face = True mesh_show_wireframe = False if mesh_show_back_face: gl.glDisable(gl.GL_CULL_FACE) else: gl.glEnable(gl.GL_CULL_FACE) gl.glEnable(gl.GL_DEPTH_TEST) gl.glDepthFunc(gl.GLenum(render_option.get_depth_func())) gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL) if mesh_show_wireframe: gl.glEnable(gl.GL_POLYGON_OFFSET_FILL) gl.glPolygonOffset(1.0, 1.0) else: gl.glDisable(gl.GL_POLYGON_OFFSET_FILL) return True