def active_uniforms(self): """Query OpenGL for a list of active uniforms. This is needed, because we are only allowed to set and query the values of active uniforms. """ # Query number of active uniforms nr_uniforms = gl.GLint() gl.glGetProgramiv(self.handle, gl.GL_ACTIVE_UNIFORMS, byref(nr_uniforms)) nr_uniforms = nr_uniforms.value length = gl.GLsizei() size = gl.GLsizei() enum = gl.GLenum() name = create_string_buffer(self._ACTIVE_UNIFORM_MAX_LENGTH) uniforms = [] for i in range(nr_uniforms): gl.glGetActiveUniform(self.handle, i, 20, byref(length), byref(size), byref(enum), name) uniforms.append(name.value) return uniforms
def check_program(program): """check_program(program) Raises a RuntimeError if the program hasn't linked correctly.""" # See if the program linkd correctly link_ok = gl.GLint(0) gl.glGetProgramiv(program, gl.GL_LINK_STATUS, c.pointer(link_ok)) # If linking fails, get the error description from OpenGL and raise # it if not link_ok: log_len = gl.GLint(0) gl.glGetProgramiv(program, gl.GL_INFO_LOG_LENGTH, c.pointer(log_len)) log_buf = c.create_string_buffer(log_len.value) gl.glGetProgramInfoLog(program, log_len, None, log_buf) raise RuntimeError( "Program %d could not link: %s" % ( program, log_buf.value))
def __init__(self, *shaders: Shader): self.name = gl.glCreateProgram() for shader in shaders: gl.glAttachShader(self.name, shader.name) gl.glLinkProgram(self.name) success = gl.GLint(0) gl.glGetProgramiv(self.name, gl.GL_LINK_STATUS, byref(success)) if not success: log_length = gl.GLint(0) gl.glGetProgramiv(self.name, gl.GL_INFO_LOG_LENGTH, byref(log_length)) log_buffer = create_string_buffer(log_length.value) gl.glGetProgramInfoLog(self.name, log_length.value, None, log_buffer) self.logger.error("Error linking program %s, error # %d", self.name, success.value) self.logger.error("---Message---") for line in log_buffer.value.decode("ascii").splitlines(): self.logger.error("Program: " + line) self.logger.error("------") raise RuntimeError("Linking program failed.") # free resources for shader in shaders: gl.glDeleteShader(shader.name)
def get_uniform_data(program): """ Args: program: Returns: """ uniforms = {} count = pointer(GLint()) buffer_size = GLsizei(32) length = GLsizei() size = GLint() data_type = GLenum() uniform_name = c_string('', size=buffer_size.value) glGetProgramiv(program, GL_ACTIVE_UNIFORMS, count) for i in range(count.contents.value): glGetActiveUniform(program, GLuint(i), buffer_size, length, size, data_type, uniform_name) uniform_name_ = uniform_name.value.decode('utf-8') data_type_string = temp[data_type.value] uniforms[uniform_name_] = { 'dtype': table[data_type_string]['dtype'], 'index': i, 'size': size.value, 'value': None, 'location': glGetUniformLocation(program, uniform_name), 'function': table[data_type_string]['function'], } print(uniform_name_, uniforms[uniform_name_]) return uniforms
def get_num_active(self, variable_type: gl.GLenum) -> int: """Get the number of active variables of the passed GL type. variable_type can be GL_ACTIVE_ATTRIBUTES, GL_ACTIVE_UNIFORMS, etc. """ num_active = gl.GLint(0) gl.glGetProgramiv(self.prog_id, variable_type, byref(num_active)) return num_active.value
def _get(self, paramId): outvalue = c_int(0) gl.glGetProgramiv(self.id, paramId, byref(outvalue)) value = outvalue.value if value in shader_errors.keys(): msg = '%s from glGetProgram(%s, %s, &value)' raise ValueError(msg % (shader_errors[value], self.id, paramId)) return value
def was_link_successful(self): status = c_int(0) glGetProgramiv(self.handle, GL_LINK_STATUS, byref(status)) if not status: glGetProgramiv(self.handle, GL_INFO_LOG_LENGTH, byref(status)) buffer = create_string_buffer(status.value) glGetProgramInfoLog(self.handle, status, None, buffer) self.log.error(f"{buffer.value}") return status
def link_program(program): gl.glLinkProgram(program) length = gl.GLint(0) gl.glGetProgramiv(program, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length)) log_buffer = ctypes.create_string_buffer(length.value) gl.glGetProgramInfoLog(program, length, None, log_buffer) for line in log_buffer.value[:length.value].decode('ascii').splitlines(): print('GLSL: ' + line)
def _introspect_uniform_blocks(self): active_uniform_blocks = gl.GLint(0) gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_UNIFORM_BLOCKS, byref(active_uniform_blocks)) # print('GL_ACTIVE_UNIFORM_BLOCKS', active_uniform_blocks) for loc in range(active_uniform_blocks.value): index, size, name = self._query_uniform_block(loc) block = UniformBlock(self._glo, index, size, name) self._uniforms[name] = block
def link_program(program): ''' link a glsl program and print error messages.''' gl.glLinkProgram(program) length = gl.GLint(0) gl.glGetProgramiv(program, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length)) log_buffer = ctypes.create_string_buffer(length.value) gl.glGetProgramInfoLog(program, length, None, log_buffer) for line in log_buffer.value[:length.value].decode('ascii').splitlines(): print('GLSL: ' + line)
def link(self): """link the program""" gl.glLinkProgram(self.id) # Check if linking was successful. If not, print the log. link_status = c_int(0) gl.glGetProgramiv(self.id, gl.GL_LINK_STATUS, byref(link_status)) if not link_status: gl.glGetProgramiv(self.id, gl.GL_INFO_LOG_LENGTH, byref(link_status)) # retrieve the log length buffer = create_string_buffer(link_status.value) # create a buffer for the log gl.glGetProgramInfoLog(self.id, link_status, None, buffer) # retrieve the log text print(buffer.value) # print the log to the console
def print_error(message): nonlocal error error = True status = GLint() glGetProgramiv(program, GL_INFO_LOG_LENGTH, byref( status)) # Getting the number of char in info log to 'status' output = create_string_buffer(status.value) # status.value) glGetProgramInfoLog(program, status, None, output) print(message, output.value.decode('utf-8'), file=sys.stderr)
def link(glo): """Link a shader program""" gl.glLinkProgram(glo) status = c_int() gl.glGetProgramiv(glo, gl.GL_LINK_STATUS, status) if not status.value: length = c_int() gl.glGetProgramiv(glo, gl.GL_INFO_LOG_LENGTH, length) log = c_buffer(length.value) gl.glGetProgramInfoLog(glo, len(log), None, log) raise ShaderException("Program link error: {}".format( log.value.decode()))
def link(self): if self._shaders_empty: raise RuntimeError("No shaders attached to program") gl.glLinkProgram(self.gl_id) rc = gl.GLint(0) gl.glGetProgramiv(self.gl_id, gl.GL_LINK_STATUS, ctypes.byref(rc)) if not rc: gl.glGetProgramiv(self.gl_id, gl.GL_INFO_LOG_LENGTH, ctypes.byref(rc)) buffer = ctypes.create_string_buffer(rc.value) gl.glGetProgramInfoLog(self.gl_id, rc, None, buffer) raise GLObjectException(buffer.value.decode()) else: self._done_link = True
def link(self): gl.glLinkProgram(self.__value) err_status = ct.c_int() gl.glGetProgramiv(self.__value, gl.GL_LINK_STATUS, ct.byref(err_status)) if err_status.value != gl.GL_TRUE: log_length = ct.c_int() gl.glGetProgramiv(self.__value, gl.GL_INFO_LOG_LENGTH, ct.byref(log_length)) log_buf = (ct.c_char * (log_length.value))() log_buf_ptr = ct.cast(ct.pointer(log_buf), ct.c_char_p) gl.glGetProgramInfoLog(self.__value, log_length.value, None, log_buf_ptr) raise GLException("Program failed to link:\n%s" % log_buf.value)
def link(self): """link the program""" gl.glLinkProgram(self.id) # Check if linking was successful. If not, print the log. link_status = c_int(0) gl.glGetProgramiv(self.id, gl.GL_LINK_STATUS, byref(link_status)) if not link_status: gl.glGetProgramiv(self.id, gl.GL_INFO_LOG_LENGTH, byref(link_status)) # retrieve the log length buffer = create_string_buffer( link_status.value) # create a buffer for the log gl.glGetProgramInfoLog(self.id, link_status, None, buffer) # retrieve the log text print(buffer.value) # print the log to the console
def link(self): gl.glLinkProgram(self.handle) # Retrieve the link status status = c_int(0) gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, byref(status)) # If linking failed, get log and abort. if not status: #Retrieve the log and pass it up with an exception. gl.glGetProgramiv(self.handle, gl.GL_INFO_LOG_LENGTH, byref(status)) log = create_string_buffer(status.value) gl.glGetProgramInfoLog(self.handle, status, None, log) raise Exception("Linking shaders failed {0}".format(log.value)) else: self.linked = True
def link(self): # link the program glLinkProgram(self.handle) temp = c_int(0) # retrieve the link status glGetProgramiv(self.handle, GL_LINK_STATUS, byref(temp)) # if linking failed, print the log if not temp: # retrieve the log length glGetProgramiv(self.handle, GL_INFO_LOG_LENGTH, byref(temp)) # create a buffer for the log buffer = create_string_buffer(temp.value) # retrieve the log text glGetProgramInfoLog(self.handle, temp, None, buffer) # print the log to the console self.log.error(f"{buffer.value}") else: # all is well, so we are linked self.linked = True
def program_status(program: GLuint, status_type: int) -> int: """ Args: program: The handle to the program. status_type: GL_DELETE_STATUS, GL_LINK_STATUS, GL_VALIDATE_STATUS, GL_INFO_LOG_LENGTH, GL_ATTACHED_SHADERS, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, GL_ACTIVE_ATTRIBUTES, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, GL_ACTIVE_UNIFORMS, GL_ACTIVE_UNIFORM_BLOCKS, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, GL_ACTIVE_UNIFORM_MAX_LENGTH, GL_COMPUTE_WORK_GROUP_SIZE GL_PROGRAM_BINARY_LENGTH, GL_TRANSFORM_FEEDBACK_BUFFER_MODE, GL_TRANSFORM_FEEDBACK_VARYINGS, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, GL_GEOMETRY_VERTICES_OUT, GL_GEOMETRY_INPUT_TYPE, GL_GEOMETRY_OUTPUT_TYPE. Returns: Status code. """ status = GLint() glGetProgramiv(program, status_type, byref(status)) return status.value
def _introspect_attributes(self): """Introspect and store detailed info about an attribute""" # TODO: Ensure gl_* attributes are ignored num_attrs = gl.GLint() gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_ATTRIBUTES, num_attrs) num_varyings = gl.GLint() gl.glGetProgramiv(self._glo, gl.GL_TRANSFORM_FEEDBACK_VARYINGS, num_varyings) # print(f"attrs {num_attrs.value} varyings={num_varyings.value}") for i in range(num_attrs.value): c_name = create_string_buffer(256) c_size = gl.GLint() c_type = gl.GLenum() gl.glGetActiveAttrib( self._glo, # program to query i, # index (not the same as location) 256, # max attr name size None, # c_length, # length of name c_size, # size of attribute (array or not) c_type, # attribute type (enum) c_name, # name buffer ) # Get the actual location. Do not trust the original order location = gl.glGetAttribLocation(self._glo, c_name) # print(c_name.value, c_size, c_type) type_info = GLTypes.get(c_type.value) # print(type_info) self._attributes.append( AttribFormat( c_name.value.decode(), type_info.gl_type, type_info.components, type_info.gl_size, location=location, )) # The attribute key is used to cache VertexArrays self.attribute_key = ":".join( f"{attr.name}[{attr.gl_type}/{attr.components}]" for attr in self._attributes)
def link(self): """Main steps to link the program: 1. glLinkProgram: linke the shaders in the program to create an executable 2. glGetProgramiv: retrieve the link status 3. glGetProgramInfoLog: print the error log if link failed """ gl.glLinkProgram(self.program) link_status = gl.GLint(0) gl.glGetProgramiv(self.program, gl.GL_LINK_STATUS, ct.byref(link_status)) if not link_status: info_length = gl.GLint(0) gl.glGetProgramiv(self.program, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetProgramInfoLog(self.program, info_length, None, error_info) print(error_info.value)
def link(self): """link the program, making it the active shader. .. note:: Shader.bind() is preferred here, because link() Requires the Shader to be compiled already. """ gl.glLinkProgram(self.id) # Check if linking was successful. If not, print the log. link_status = c_int(0) gl.glGetProgramiv(self.id, gl.GL_LINK_STATUS, byref(link_status)) if not link_status: gl.glGetProgramiv(self.id, gl.GL_INFO_LOG_LENGTH, byref(link_status)) # retrieve the log length buffer = create_string_buffer( link_status.value) # create a buffer for the log gl.glGetProgramInfoLog(self.id, link_status, None, buffer) # retrieve the log text print(buffer.value) # print the log to the console self.is_linked = True
def link_program(program_name): ''' link a glsl program and print error messages. ''' gl.glLinkProgram(program_name) success = gl.GLint(0) gl.glGetProgramiv(program_name, gl.GL_LINK_STATUS, ctypes.byref(success)) length = gl.GLint(0) gl.glGetProgramiv(program_name, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length)) log_buffer = ctypes.create_string_buffer(length.value) gl.glGetProgramInfoLog(program_name, length, None, log_buffer) log_message = log_buffer.value[:length.value].decode('ascii').strip() if log_message: sys.stderr.write(log_message + '\n') if not success: raise ValueError('Linking of the shader program failed.')
def link(self): # link the program glLinkProgram(self.handle) temp = c_int(0) # retrieve the link status glGetProgramiv(self.handle, GL_LINK_STATUS, byref(temp)) # if linking failed, print the log if not temp: # retrieve the log length glGetProgramiv(self.handle, GL_INFO_LOG_LENGTH, byref(temp)) # create a buffer for the log buffer = create_string_buffer(temp.value) # retrieve the log text glGetProgramInfoLog(self.handle, temp, None, buffer) # print the log to the console print(buffer.value) else: # all is well, so we are linked self.linked = True
def link(self): """ Main steps to link the program: 1. glLinkProgram: linke the shaders in the program to create an executable 2. glGetProgramiv: retrieve the link status 3. glGetProgramInfoLog: print the error log if link failed """ gl.glLinkProgram(self.program) link_status = gl.GLint(0) gl.glGetProgramiv(self.program, gl.GL_LINK_STATUS, ct.byref(link_status)) if not link_status: info_length = gl.GLint(0) gl.glGetProgramiv(self.program, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetProgramInfoLog(self.program, info_length, None, error_info) print(error_info.value)
def _link(self): for shader in self: gl.glAttachShader(self.handle, shader.handle); # link the program gl.glLinkProgram(self.handle) temp = c_int(0) # retrieve the link status gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, byref(temp)) # if linking failed, print the log if not temp: # retrieve the log length gl.glGetProgramiv(self.handle, gl.GL_INFO_LOG_LENGTH, byref(temp)) # create a buffer for the log buffer = create_string_buffer(temp.value) # retrieve the log text gl.glGetProgramInfoLog(self.handle, temp, None, buffer) # print the log to the console raise GLSLError(buffer.value) # Query maximum uniform name length AUL = gl.GLint() gl.glGetProgramiv(self.handle, gl.GL_ACTIVE_UNIFORM_MAX_LENGTH, byref(AUL)) self._ACTIVE_UNIFORM_MAX_LENGTH = AUL.value self._update_uniform_types()
def _introspect_uniforms(self): """Figure out what uniforms are available and build an internal map""" # Number of active uniforms in the program active_uniforms = gl.GLint(0) gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_UNIFORMS, byref(active_uniforms)) # Loop all the active uniforms for index in range(active_uniforms.value): # Query uniform information like name, type, size etc. u_name, u_type, u_size = self._query_uniform(index) u_location = gl.glGetUniformLocation(self._glo, u_name.encode()) # Skip uniforms that may be in Uniform Blocks # TODO: We should handle all uniforms if u_location == -1: # print(f"Uniform {u_location} {u_name} {u_size} {u_type} skipped") continue u_name = u_name.replace("[0]", "") # Remove array suffix self._uniforms[u_name] = Uniform(self._glo, u_location, u_name, u_type, u_size)
def __init__(self, *shaders): pid = False try: pid = glCreateProgramObjectARB() except GLException: raise ShaderError("Can't create program object!") for s in shaders: glAttachObjectARB(pid, s.sid) glLinkProgram(pid) v = GLint(0) glGetProgramiv(pid, GL_LINK_STATUS, byref(v)) if not v: log = _get_infolog(pid) e = ShaderError("Error linking program!") e.infolog = log raise e self.pid = pid self.uniform = _UniformAccesser(self) self.attrib = _AttributeAccesser(self)
def __init__( self, ctx: "Context", *, vertex_shader: str, fragment_shader: str = None, geometry_shader: str = None, tess_control_shader: str = None, tess_evaluation_shader: str = None, out_attributes: List[str] = None, ): """Create a Program. :param Context ctx: The context this program belongs to :param str vertex_shader: vertex shader source :param str fragment_shader: fragment shader source :param str geometry_shader: geometry shader source :param str tess_control_shader: tessellation control shader source :param str tess_evaluation_shader: tessellation evaluation shader source :param List[str] out_attributes: List of out attributes used in transform feedback. """ self._ctx = ctx self._glo = glo = gl.glCreateProgram() self._out_attributes = out_attributes or [] self._geometry_info = (0, 0, 0) self._attributes = [] # type: List[AttribFormat] #: Internal cache key used with vertex arrays self.attribute_key = "INVALID" # type: str self._uniforms: Dict[str, Uniform] = {} shaders = [(vertex_shader, gl.GL_VERTEX_SHADER)] if fragment_shader: shaders.append((fragment_shader, gl.GL_FRAGMENT_SHADER)) if geometry_shader: shaders.append((geometry_shader, gl.GL_GEOMETRY_SHADER)) if tess_control_shader: shaders.append((tess_control_shader, gl.GL_TESS_CONTROL_SHADER)) if tess_evaluation_shader: shaders.append( (tess_evaluation_shader, gl.GL_TESS_EVALUATION_SHADER)) shaders_id = [] for shader_code, shader_type in shaders: shader = Program.compile_shader(shader_code, shader_type) gl.glAttachShader(self._glo, shader) shaders_id.append(shader) # For now we assume varyings can be set up if no fragment shader if not fragment_shader: self._setup_out_attributes() Program.link(self._glo) if geometry_shader: geometry_in = gl.GLint() geometry_out = gl.GLint() geometry_vertices = gl.GLint() gl.glGetProgramiv(self._glo, gl.GL_GEOMETRY_INPUT_TYPE, geometry_in) gl.glGetProgramiv(self._glo, gl.GL_GEOMETRY_OUTPUT_TYPE, geometry_out) gl.glGetProgramiv(self._glo, gl.GL_GEOMETRY_VERTICES_OUT, geometry_vertices) self._geometry_info = ( geometry_in.value, geometry_out.value, geometry_vertices.value, ) # Flag shaders for deletion. Will only be deleted once detached from program. for shader in shaders_id: gl.glDeleteShader(shader) # Handle uniforms self._introspect_attributes() self._introspect_uniforms() self._introspect_uniform_blocks() self.ctx.stats.incr("program") weakref.finalize(self, Program._delete, self.ctx, shaders_id, glo)
def validate(self): gl.glValidateProgram(self.program_no) self.validation_status = gl.GLint() gl.glGetProgramiv(self.program_no, gl.GL_VALIDATE_STATUS, self.validation_status) if not self.validation_status: raise gl.GLSLException(_infolog(self.program_no, log_type="program"))
def create(cls, vertex_source, fragment_source, attributes, uniforms): number_of_string = 1 # Create vertex shader. vertex_handle = glCreateShader(GL_VERTEX_SHADER) glShaderSource(vertex_handle, number_of_string, c_pointer_to_char_pointers(vertex_source), None) glCompileShader(vertex_handle) # Create fragment shader. fragment_handle = glCreateShader(GL_FRAGMENT_SHADER) glShaderSource(fragment_handle, number_of_string, c_pointer_to_char_pointers(fragment_source), None) glCompileShader(fragment_handle) # Create attributes. attribute_mapping = [] for attribute in attributes: attribute_mapping.append(c_string(attribute)) try: # Create program. program_handle = glCreateProgram() glAttachShader(program_handle, vertex_handle) glAttachShader(program_handle, fragment_handle) for index, name in enumerate(attribute_mapping): glBindAttribLocation(program_handle, index, name) glLinkProgram(program_handle) glValidateProgram(program_handle) glUseProgram(program_handle) except GLException as error: # Print vertex shader errors. status = GLint() glGetShaderiv(vertex_handle, GL_INFO_LOG_LENGTH, byref(status)) output = create_string_buffer(status.value) glGetShaderInfoLog(vertex_handle, status, None, output) print(output.value.decode('utf-8')) # Print fragment shader errors. status = GLint() glGetShaderiv(fragment_handle, GL_INFO_LOG_LENGTH, byref(status)) output = create_string_buffer(status.value) glGetShaderInfoLog(fragment_handle, status, None, output) print(output.value.decode('utf-8')) # Print program errors. status = GLint() glGetProgramiv(program_handle, GL_INFO_LOG_LENGTH, byref( status)) # Getting the number of char in info log to 'status' output = create_string_buffer(status.value) # status.value) glGetProgramInfoLog(program_handle, status, None, output) print(output.value.decode('utf-8')) raise error # Get uniform location. uniform_mapping = {} for uniform in uniforms: name = c_string(uniform) location = glGetUniformLocation( program_handle, cast(pointer(name), POINTER(c_char))) uniform_mapping[uniform] = location return cls(program_handle, uniform_mapping)
def link(self): gl.glLinkProgram(self.program_no) gl.glGetProgramiv(self.program_no, gl.GL_LINK_STATUS, self.link_status) if not self.link_status: raise gl.GLSLException(_infolog(self.program_no, log_type="program"))
def __init__(self, shaders, attributes, uniforms): # Create vertex shader. vertex_shader = shaders[0] vertex_handle = glCreateShader(GL_VERTEX_SHADER) glShaderSource(vertex_handle, 1, c_string_array(vertex_shader), None) glCompileShader(vertex_handle) # Create fragment shader. fragment_shader = shaders[1] fragment_handle = glCreateShader(GL_FRAGMENT_SHADER) glShaderSource(fragment_handle, 1, c_string_array(fragment_shader), None) glCompileShader(fragment_handle) try: # Create program. program_handle = glCreateProgram() # Attach shaders glAttachShader(program_handle, vertex_handle) glAttachShader(program_handle, fragment_handle) # Bind attributes. for index, name in enumerate(attributes): glBindAttribLocation(program_handle, index, c_string(name)) # Link, validate and use. glLinkProgram(program_handle) glValidateProgram(program_handle) glUseProgram(program_handle) except GLException: # Print errors. status = GLint() glGetShaderiv(vertex_handle, GL_INFO_LOG_LENGTH, byref(status)) output = create_string_buffer(status.value) glGetShaderInfoLog(vertex_handle, status, None, output) print(output.value.decode('utf-8')) status = GLint() glGetShaderiv(fragment_handle, GL_INFO_LOG_LENGTH, byref(status)) output = create_string_buffer(status.value) glGetShaderInfoLog(fragment_handle, status, None, output) print(output.value.decode('utf-8')) status = GLint() glGetProgramiv(program_handle, GL_INFO_LOG_LENGTH, byref( status)) # Getting the number of char in info log to 'status' output = create_string_buffer(status.value) # status.value) glGetProgramInfoLog(program_handle, status, None, output) print(output.value.decode('utf-8')) # Query uniform data. active_uniforms = GLint() glGetProgramiv(program_handle, GL_ACTIVE_UNIFORMS, active_uniforms) buffer_size = GLsizei(255) data_type = GLenum(0) string_buffer = create_string_buffer(buffer_size.value) name = c_char_p(addressof(string_buffer)) uniform_mapping = {} for index in range(active_uniforms.value): glGetActiveUniform(program_handle, index, buffer_size, None, None, byref(data_type), name) if name.value in uniforms: location = glGetUniformLocation( program_handle, cast(pointer(name), POINTER(GLchar))) uniform = Uniform(name.value, location, data_type.value) uniform_mapping[name.value] = uniform self.id = GLuint(program_handle) self.uniforms = uniform_mapping self.attributes = attributes
def __get__(self, instance, cls): glGetProgramiv(instance.pid, self.pname, byref(self.buffer)) return self.buffer.value
def linked(self): temp = c_int(0) # retrieve the link status gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, byref(temp)) return bool(temp)
def __init__(self, shaders, attributes, uniforms): vertex_shader = shaders[0] fragment_shader = shaders[1] vertex_handle = glCreateShader(GL_VERTEX_SHADER) glShaderSource( vertex_handle, 1, cast(pointer(pointer(create_string_buffer(vertex_shader))), POINTER(POINTER(GLchar))), None) glCompileShader(vertex_handle) fragment_handle = glCreateShader(GL_FRAGMENT_SHADER) glShaderSource( fragment_handle, 1, cast(pointer(pointer(create_string_buffer(fragment_shader))), POINTER(POINTER(GLchar))), None) glCompileShader(fragment_handle) # Create attributes. attribute_mapping = [] for attribute in attributes: attribute_mapping.append(create_string_buffer(attribute)) try: # Create program. program_handle = glCreateProgram() glAttachShader(program_handle, vertex_handle) glAttachShader(program_handle, fragment_handle) for index, name in enumerate(attributes): # CHANGED glBindAttribLocation(program_handle, index, name) glLinkProgram(program_handle) glValidateProgram(program_handle) glUseProgram(program_handle) except GLException: # Print errors. status = GLint() glGetShaderiv(vertex_handle, GL_INFO_LOG_LENGTH, byref(status)) output = create_string_buffer(status.value) glGetShaderInfoLog(vertex_handle, status, None, output) print(output.value.decode('utf-8')) status = GLint() glGetShaderiv(fragment_handle, GL_INFO_LOG_LENGTH, byref(status)) output = create_string_buffer(status.value) glGetShaderInfoLog(fragment_handle, status, None, output) print(output.value.decode('utf-8')) status = GLint() glGetProgramiv(program_handle, GL_INFO_LOG_LENGTH, byref( status)) # Getting the number of char in info log to 'status' output = create_string_buffer(status.value) # status.value) glGetProgramInfoLog(program_handle, status, None, output) print(output.value.decode('utf-8')) # # Get uniform location. # uniform_mapping = {} # for uniform in uniforms: # name = create_string_buffer(uniform) # location = glGetUniformLocation(program_handle, cast(pointer(name), POINTER(GLchar))) # uniform_mapping[uniform] = location active_shaders = GLint() glGetProgramiv(program_handle, GL_ACTIVE_UNIFORMS, active_shaders) buffer_size = GLsizei(255) data_type = GLenum(0) string_buffer = create_string_buffer(buffer_size.value) name = c_char_p(addressof(string_buffer)) uniform_mapping = {} for index in range(active_shaders.value): glGetActiveUniform(program_handle, index, buffer_size, None, None, byref(data_type), name) if name.value in uniforms: location = glGetUniformLocation( program_handle, cast(pointer(name), POINTER(GLchar))) uniform = Uniform(name.value, location, data_type.value) uniform_mapping[name.value] = uniform super().__init__(program_handle) self.uniforms = uniform_mapping self.attributes = attribute_mapping