def link(self): result = True if self._is_linked: return result # compile and attach all shaders self._attach_all_shaders() gl.glBindAttribLocation(self._id, 0, "aPos") gl.glBindAttribLocation(self._id, 1, "debugColor") gl.glLinkProgram(self._id) # free shader objects from memory (no longer needed once they have been # compiled and attached to the shader program) # check success of shader program linking success = gl.glGetProgramiv(self._id, gl.GL_LINK_STATUS) if not success: info_log = gl.glGetProgramInfoLog(self._id) print(info_log) result = False if result: for ID in self._shaders: self._shaders[ID].delete_shader() self._is_linked = result return result
def bind_attrib_location(self, vertex_attrib: VertexAttrib, name: str): gl.glBindAttribLocation(self.handle, vertex_attrib.index, name)
def initialize(self): vertex_shader = shaders.compileShader("""#version 330 in vec3 vPosition; uniform mat4 MVP; void main() { gl_Position = MVP * vec4(vPosition, 1.0); }""", gl.GL_VERTEX_SHADER) fragment_shader = shaders.compileShader("""#version 330 void main() { gl_FragColor = vec4( 0, 1, 1, 1 ); }""", gl.GL_FRAGMENT_SHADER) self._shader = shaders.compileProgram(vertex_shader, fragment_shader) self._position_handle = 0 gl.glBindAttribLocation(self._shader, self._position_handle, b"vPosition") self._mvp_handle = gl.glGetUniformLocation(self._shader, b"MVP") self._vertex_vbo = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vertex_vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, len(self._model._vertex_buffer), self._model._vertex_buffer, gl.GL_STATIC_DRAW) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) self._index_vbo = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._index_vbo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, len(self._model._index_buffer), self._model._index_buffer, gl.GL_STATIC_DRAW) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0)
def paintGL(self): gl.glClear (gl.GL_COLOR_BUFFER_BIT|gl.GL_DEPTH_BUFFER_BIT) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() glu.gluPerspective(45.0, 4.0/3.0, 0.1, 100.0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() glu.gluLookAt(4, 3, 3, 0, 0, 0, 0, 1, 0) self._texture_id = gl.glGenTextures(1) gl.glBindTexture(gl.GL_TEXTURE_2D, self._texture_id) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGB, self._width, self._height, 0, gl.GL_BGR, gl.GL_UNSIGNED_BYTE, self._texture_data) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR_MIPMAP_LINEAR) gl.glGenerateMipmap(gl.GL_TEXTURE_2D) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo) gl.glVertexPointer(3, gl.GL_FLOAT, 0, None) gl.glEnableVertexAttribArray(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._uv_buffer) gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glBindAttribLocation(self._shader_program, 1, "vertex_uv") gl.glLinkProgram(self._shader_program) gl.glUseProgram(self._shader_program) print gl.glGetProgramiv(self._shader_program, gl.GL_LINK_STATUS) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 12*3)
def init_attribute_locs(self): l = 0 for a in sorted(self._vars.values(), key=lambda a: a.name): if a.qual != 'attribute': continue G.glBindAttribLocation(self._shader, l, a.name) self._locs[a.name] = l l += 1
def __init__(self, shader_dir): """ Constructor - create and initialise a shader program. """ # Note: see the following, which was referenced in the PyOpenGL # documentation: # https://bitbucket.org/rndblnch/opengl-programmable/src/tip/10-g # l3.2core.py?fileviewer=file-view-default # Create the program object. self.__shader_program = GL.glCreateProgram() # We're going to build up a list of inputs. program_uniforms = set() program_attributes = set() self.__attribute_types = {} # Compile all of the source files and attach the resulting # shader objects to our shader program. for (filename, shader_type) in self.__list_shader_files(shader_dir): (file_uniforms, file_attributes, attribute_types) = \ self.__parse_uniforms_and_attributes(filename) program_uniforms.update(file_uniforms); program_attributes.update(file_attributes); self.__attribute_types.update(attribute_types) shader = GL.glCreateShader(shader_type) GL.glShaderSource(shader, open(filename, 'r').read()) GL.glCompileShader(shader) if GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS) != GL.GL_TRUE: raise Exception(GL.glGetShaderInfoLog(shader)) GL.glAttachShader(self.__shader_program, shader) # Assign locations to vertex attributes. We'll bind them in the program later... self.__attrib_locations = dict((k, v) for (v, k) in enumerate(program_attributes)) # Uniform locations will be determined by OpenGL, we'll get them later. self.__uniform_locations = {} # Now we can bind all of the vertex attributes to their # assigned locations. for attrib in program_attributes: GL.glBindAttribLocation(self.__shader_program, self.__attrib_locations[attrib], attrib) # Now link the program. GL.glLinkProgram(self.__shader_program) if GL.glGetProgramiv(self.__shader_program, GL.GL_LINK_STATUS) != GL.GL_TRUE: raise Exception(GL.glGetProgramInfoLog(self.__shader_program)) # Retrieve the uniform locations and remember them. for uniform in program_uniforms: self.__uniform_locations[uniform] = GL.glGetUniformLocation(self.__shader_program, uniform) if self.__uniform_locations[uniform] == -1: print ("Warning: Uniform '%s' does not exist." % uniform)
def link(self, shader_objs, bindings=[]): prog = gl.glCreateProgram() for shader in shader_objs: gl.glAttachShader(prog, shader) for index, name in bindings: gl.glBindAttribLocation(prog, index, name) gl.glLinkProgram(prog) link_status = gl.glGetProgramiv(prog, gl.GL_LINK_STATUS) if link_status == gl.GL_FALSE: raise RuntimeError("""Link failure (%s): %s""" % ( link_status, gl.glGetProgramInfoLog(prog), )) for shader in shader_objs: gl.glDeleteShader(shader) return prog
def link(self, shader_objs, bindings=[]): prog = gl.glCreateProgram() for shader in shader_objs: gl.glAttachShader(prog, shader) for index, name in bindings: gl.glBindAttribLocation(prog, index, name) gl.glLinkProgram(prog) link_status = gl.glGetProgramiv(prog, gl.GL_LINK_STATUS) if link_status == gl.GL_FALSE: raise RuntimeError( """Link failure (%s): %s"""%( link_status, gl.glGetProgramInfoLog(prog), )) for shader in shader_objs: gl.glDeleteShader(shader) return prog
def paintGL(self): gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() glu.gluPerspective(45.0, 4.0 / 3.0, 0.1, 100.0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() glu.gluLookAt(4, 3, 3, 0, 0, 0, 0, 1, 0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo) gl.glVertexPointer(3, gl.GL_FLOAT, 0, None) gl.glEnableVertexAttribArray(1) # TODO: bind uv buffer. # gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._uv_buffer) # gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._color_buffer) gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glBindAttribLocation(self._shader_program, 1, "InColor") gl.glLinkProgram(self._shader_program) gl.glUseProgram(self._shader_program) print gl.glGetProgramiv(self._shader_program, gl.GL_LINK_STATUS) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 12 * 3)
def __init__(self, *shaders, **attributes): self._handle = GL.glCreateProgram() self.shaders = shaders _attributes = {} # attach our shaders for shader in shaders: _attributes.update(shader._attributes) GL.glAttachShader(self._handle, shader.handle) # use the manually sent ones in preference _attributes.update(attributes) # set attributes for name, value in _attributes.iteritems(): GL.glBindAttribLocation(self._handle, value, name) self.link() # initialise attributes and uniforms self.attributes = Attributes(self) self.uniforms = Uniforms(self)
def paintGL(self): gl.glClear (gl.GL_COLOR_BUFFER_BIT|gl.GL_DEPTH_BUFFER_BIT) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() glu.gluPerspective(45.0, 4.0/3.0, 0.1, 100.0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() glu.gluLookAt(4, 3, 3, 0, 0, 0, 0, 1, 0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo) gl.glVertexPointer(3, gl.GL_FLOAT, 0, None) gl.glEnableVertexAttribArray(1) # TODO: bind uv buffer. # gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._uv_buffer) # gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._color_buffer) gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glBindAttribLocation(self._shader_program, 1, "InColor") gl.glLinkProgram(self._shader_program) gl.glUseProgram(self._shader_program) print gl.glGetProgramiv(self._shader_program, gl.GL_LINK_STATUS) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 12*3)
def location( self, location ): """Sets the attributes location. """ GL.glBindAttribLocation( self.program.handle, location, self.name )
def _build_program(self, force=False): """ This builds the initial shader program, and rebuilds its fragment shader whenever the OCIO GPU renderer changes. :param bool force: Whether to force a rebuild even if the OCIO shader cache ID has not changed. """ if not self._gl_ready: return self.makeCurrent() # If new shader cache ID matches previous cache ID existing program # can be reused. shader_cache_id = self._ocio_shader_cache_id if self._ocio_shader_desc and not force: shader_cache_id = self._ocio_shader_desc.getCacheID() if self._ocio_shader_cache_id == shader_cache_id: return # Init shader program if not self._shader_program: self._shader_program = GL.glCreateProgram() # Vert shader only needs to be built once if not self._vert_shader: self._vert_shader = self._compile_shader(GLSL_VERT_SRC, GL.GL_VERTEX_SHADER) if not self._vert_shader: return GL.glAttachShader(self._shader_program, self._vert_shader) # Frag shader needs recompile each build (for OCIO changes) if self._frag_shader: GL.glDetachShader(self._shader_program, self._frag_shader) GL.glDeleteShader(self._frag_shader) frag_src = GLSL_FRAG_SRC if self._ocio_shader_desc: # Inject OCIO shader block frag_src = GLSL_FRAG_OCIO_SRC_FMT.format( ocio_src=self._ocio_shader_desc.getShaderText()) self._frag_shader = self._compile_shader(frag_src, GL.GL_FRAGMENT_SHADER) if not self._frag_shader: return GL.glAttachShader(self._shader_program, self._frag_shader) # Link program GL.glBindAttribLocation(self._shader_program, 0, "in_position") GL.glBindAttribLocation(self._shader_program, 1, "in_texCoord") GL.glLinkProgram(self._shader_program) link_status = GL.glGetProgramiv(self._shader_program, GL.GL_LINK_STATUS) if not link_status: link_log = GL.glGetProgramInfoLog(self._shader_program) logger.error( "Shader program link error: {log}".format(log=link_log)) return # Store cache ID to detect reuse self._ocio_shader_cache_id = shader_cache_id
def bind_attrib_location(self, index, var_name): """ This is necessary if GLDL 330 is not available (@ 130) """ gl.glBindAttribLocation(self.program_id, index, var_name)
def bindAttribLocation(self, name): if name not in self._enableAttrib: GL.glBindAttribLocation(self.id, self._last_id, name.encode()) self._enableAttrib[name] = self._last_id self._last_id += 1
def sync(self): if self._dirty: GL.glBindAttribLocation(self.program.handle, location, name) self._dirty = False
def __bind_attribute(self, attribute_number: int, variable_name: str): gl.glBindAttribLocation(self.program_ID, attribute_number, variable_name)
def location(self, location): """Sets the attributes location. """ GL.glBindAttribLocation(self.program.handle, location, self.name)
def glBindAttribLocation(program, index, name): name = name.encode('utf-8') return GL.glBindAttribLocation(program, index, name)
def __init__(self, shaders, frag_locations=None, **attributes): super(Program, self).__init__() self._loaded = False self._attributes = None self._uniforms = None for shader in shaders: self._attach(shader) if frag_locations: if isinstance(frag_locations, basestring): frag_locations = ((frag_locations, 0), ) for name, number in frag_locations: self._set_frag_location(name, number) # set our attributes before link time for name, location in list(attributes.items()): GL.glBindAttribLocation(self._handle, location, name) self._link() # detach shaders so they can be free'ed by opengl for shader in shaders: self._detach(shader) # mark the program as loaded # from now onwards, any calls to unknown variables or assignments # will the program variables to load if they aren't already # we do this, because loading the variables now will stall the pipeline # until the gpu finishes linking, it's better to link programs in parallel # and then query only when initially needed self._loaded = True