def createShader(self, strings, shadertype): # create the shader handle shader = gl.glCreateShader(shadertype) # convert the source strings into a ctypes pointer-to-char array, and upload them # this is deep, dark, dangerous black magick - don't try stuff like this at home! strings = tuple(s.encode('ascii') for s in strings) # Nick added, for python3 src = (c_char_p * len(strings))(*strings) gl.glShaderSource(shader, len(strings), cast(pointer(src), POINTER(POINTER(c_char))), None) # compile the shader gl.glCompileShader(shader) # retrieve the compile status compile_success = c_int(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(compile_success)) # if compilation failed, print the log if compile_success: gl.glAttachShader(self.id, shader) else: gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, byref(compile_success)) # retrieve the log length buffer = create_string_buffer( compile_success.value) # create a buffer for the log gl.glGetShaderInfoLog(shader, compile_success, None, buffer) # retrieve the log text print(buffer.value) # print the log to the console
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 setup_copy_program(): ''' Create the glsl copy_program for copying the rendered texture ''' vertex_shader = b''' attribute vec2 position; attribute vec2 texcoord; varying vec2 var_texcoord; void main() { gl_Position = vec4(position, 0.0, 1.0); var_texcoord = texcoord; } ''' fragment_shader = b''' uniform sampler2D texture; varying vec2 var_texcoord; void main() { gl_FragColor = texture2D(texture, var_texcoord); } ''' global copy_program copy_program = gl.glCreateProgram() gl.glAttachShader(copy_program, compile_shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader(copy_program, compile_shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) link_program(copy_program)
def setup_render_program(): ''' Create the glsl program for rendering the colored triangle ''' vertex_shader = b''' attribute vec2 position; attribute vec4 color; varying vec4 var_color; void main() { gl_Position = vec4(position, 0.0, 1.0); var_color = color; } ''' fragment_shader = b''' varying vec4 var_color; void main() { gl_FragColor = var_color; } ''' global render_program render_program = gl.glCreateProgram() gl.glAttachShader(render_program, compile_shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader(render_program, compile_shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) link_program(render_program)
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 setupShaders(self): self.programA = gl.glCreateProgram() gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_VERTEX_SHADER, self.vertex_source)) if args["operation"] == "similar": gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_FRAGMENT_SHADER, self.fragment_source_a)) elif args["operation"] == "intersect": gl.glAttachShader( self.programA, pyglet_helper.compile_shader( gl.GL_FRAGMENT_SHADER, self.fragment_source_intersection)) elif args["operation"] == "union": gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_FRAGMENT_SHADER, self.fragment_source_union)) elif args["operation"] == "difference": gl.glAttachShader( self.programA, pyglet_helper.compile_shader( gl.GL_FRAGMENT_SHADER, self.fragment_source_difference)) else: print("not a valid operation") pyglet_helper.link_program(self.programA)
def createShader(self, strings, type): count = len(strings) #If no code if count < 1: return shader = gl.glCreateShader(type) # ctypes magic: convert python [strings] to C (char**). src = (c_char_p * count)(*strings) gl.glShaderSource(shader, count, cast(pointer(src), POINTER(POINTER(c_char))), None) gl.glCompileShader(shader) # Retrieve the compile status status = c_int(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(status)) # If compilation failed, get log and abort. if not status: gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, byref(status)) log = create_string_buffer(status.value) gl.glGetShaderInfoLog(shader, status, None, log) raise Exception("Compiling shaders failed: {0}".format(log.value)) else: # If all is well, attach the shader to the program gl.glAttachShader(self.handle, shader)
def setup_program(): ''' Create the glsl program ''' vertex_shader = b''' attribute vec2 position; attribute vec4 color; varying vec4 var_color; void main() { gl_Position = vec4(position, 0.0, 1.0); var_color = color; } ''' fragment_shader = b''' varying vec4 var_color; void main() { gl_FragColor = var_color; } ''' program = gl.glCreateProgram() gl.glAttachShader(program, shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader(program, shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) gl.glLinkProgram(program) gl.glUseProgram(program) return program
def createShader(self, strings, shadertype): # create the shader handle shader = gl.glCreateShader(shadertype) # convert the source strings into a ctypes pointer-to-char array, and upload them # this is deep, dark, dangerous black magick - don't try stuff like this at home! strings = tuple(s.encode('ascii') for s in strings) # Nick added, for python3 src = (c_char_p * len(strings))(*strings) gl.glShaderSource(shader, len(strings), cast(pointer(src), POINTER(POINTER(c_char))), None) # compile the shader gl.glCompileShader(shader) # retrieve the compile status compile_success = c_int(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(compile_success)) # if compilation failed, print the log if compile_success: gl.glAttachShader(self.id, shader) else: gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, byref(compile_success)) # retrieve the log length buffer = create_string_buffer(compile_success.value) # create a buffer for the log gl.glGetShaderInfoLog(shader, compile_success, None, buffer) # retrieve the log text print(buffer.value) # print the log to the console
def add(self, shader: GLShader): if shader is not None: if not isinstance(shader, GLShader): raise TypeError gl.glAttachShader(self.gl_id, shader.gl_id) self._shaders_empty = False self._done_link = False
def compile_and_attach_shader(self, shader_files, shader_type): """ Parameters ---------- :shader_files: a list of shader files. :shader_type: `GL_VERTEX_SHADER` or `GL_FRAGMENT_SHADER`. Main steps to compile and attach a shader: 1. glCreateShader: create a shader of given type. 2. glShaderSource: load source code into the shader. 3. glCompileShader: compile the shader. 4. glGetShaderiv: retrieve the compiling status. 5. glGetShaderInfoLog: print the error info if compiling failed. 6. glAttachShader: attach the shader to our program if compiling succeeded. """ src = [] for src_f in shader_files: with open(src_f, "r") as f: src.append(f.read().encode("ascii")) # 1. create a shader shader = gl.glCreateShader(shader_type) # 2. load source code into the shader src_p = (ct.c_char_p * len(src))(*src) gl.glShaderSource( shader, len(src), ct.cast(ct.pointer(src_p), ct.POINTER(ct.POINTER(ct.c_char))), None, ) # 3. compile the shader gl.glCompileShader(shader) # 4. retrieve the compiling status compile_status = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ct.byref(compile_status)) # 5. if compiling failed then print the error log if not compile_status: info_length = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetShaderInfoLog(shader, info_length, None, error_info) print(error_info.value.decode("ascii")) # 6. else attach the shader to our program else: gl.glAttachShader(self.program, shader) gl.glDeleteShader(shader)
def _create_device_objects(self): # save state last_texture = gl.GLint() gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture)) last_array_buffer = gl.GLint() gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING, byref(last_array_buffer)) last_vertex_array = gl.GLint() gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING, byref(last_vertex_array)) self._shader_handle = gl.glCreateProgram() # note: no need to store shader parts handles after linking vertex_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) fragment_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) gl.glShaderSource(vertex_shader, 1, make_string_buffer(self.VERTEX_SHADER_SRC), None) gl.glShaderSource(fragment_shader, 1, make_string_buffer(self.FRAGMENT_SHADER_SRC), None) gl.glCompileShader(vertex_shader) gl.glCompileShader(fragment_shader) gl.glAttachShader(self._shader_handle, vertex_shader) gl.glAttachShader(self._shader_handle, fragment_shader) gl.glLinkProgram(self._shader_handle) # note: after linking shaders can be removed gl.glDeleteShader(vertex_shader) gl.glDeleteShader(fragment_shader) self._attrib_location_tex = gl.glGetUniformLocation(self._shader_handle, create_string_buffer(b"Texture")) self._attrib_proj_mtx = gl.glGetUniformLocation(self._shader_handle, create_string_buffer(b"ProjMtx")) self._attrib_location_position = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"Position")) self._attrib_location_uv = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"UV")) self._attrib_location_color = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"Color")) self._vbo_handle = gl.GLuint() gl.glGenBuffers(1, byref(self._vbo_handle)) self._elements_handle = gl.GLuint() gl.glGenBuffers(1, byref(self._elements_handle)) self._vao_handle = gl.GLuint() gl.glGenVertexArrays(1, byref(self._vao_handle)) gl.glBindVertexArray(self._vao_handle) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle) gl.glEnableVertexAttribArray(self._attrib_location_position) gl.glEnableVertexAttribArray(self._attrib_location_uv) gl.glEnableVertexAttribArray(self._attrib_location_color) gl.glVertexAttribPointer(self._attrib_location_position, 2, gl.GL_FLOAT, gl.GL_FALSE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_POS_OFFSET)) gl.glVertexAttribPointer(self._attrib_location_uv, 2, gl.GL_FLOAT, gl.GL_FALSE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_UV_OFFSET)) gl.glVertexAttribPointer(self._attrib_location_color, 4, gl.GL_UNSIGNED_BYTE, gl.GL_TRUE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_COL_OFFSET)) # restore state gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, cast((c_int*1)(last_array_buffer), POINTER(c_uint)).contents) gl.glBindVertexArray(cast((c_int*1)(last_vertex_array), POINTER(c_uint)).contents)
def __init__(self, ec, fill_color, line_color, line_width, line_loop): self._ec = ec self._line_width = line_width self._line_loop = line_loop # whether or not lines drawn are looped # initialize program and shaders from pyglet import gl self._program = gl.glCreateProgram() vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER) buf = create_string_buffer(tri_vert.encode('ASCII')) ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char))) gl.glShaderSource(vertex, 1, ptr, None) gl.glCompileShader(vertex) _check_log(vertex, gl.glGetShaderInfoLog) fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) buf = create_string_buffer(tri_frag.encode('ASCII')) ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char))) gl.glShaderSource(fragment, 1, ptr, None) gl.glCompileShader(fragment) _check_log(fragment, gl.glGetShaderInfoLog) gl.glAttachShader(self._program, vertex) gl.glAttachShader(self._program, fragment) gl.glLinkProgram(self._program) _check_log(self._program, gl.glGetProgramInfoLog) gl.glDetachShader(self._program, vertex) gl.glDetachShader(self._program, fragment) gl.glUseProgram(self._program) # Prepare buffers and bind attributes loc = gl.glGetUniformLocation(self._program, b'u_view') view = ec.window_size_pix view = np.diag([2. / view[0], 2. / view[1], 1., 1.]) view[-1, :2] = -1 view = view.astype(np.float32).ravel() gl.glUniformMatrix4fv(loc, 1, False, (c_float * 16)(*view)) self._counts = dict() self._colors = dict() self._buffers = dict() self._points = dict() self._tris = dict() for kind in ('line', 'fill'): self._counts[kind] = 0 self._colors[kind] = (0., 0., 0., 0.) self._buffers[kind] = dict(array=gl.GLuint()) gl.glGenBuffers(1, pointer(self._buffers[kind]['array'])) self._buffers['fill']['index'] = gl.GLuint() gl.glGenBuffers(1, pointer(self._buffers['fill']['index'])) gl.glUseProgram(0) self.set_fill_color(fill_color) self.set_line_color(line_color)
def attach(self, *objs): """ Attach shader objects to the program. Objs must be a list of ShaderObject. Ownership of the underlying shaders is transferred to the program . """ for obj in objs: glAttachShader(self.pid, obj.sid) obj.owned = False
def __init__(self, vertex_shader, fragment_shader): self.handle = gl.glCreateProgram() logging.debug('GLProgram.__init__: self.handle = %r', self.handle) gl.glAttachShader(self.handle, shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader(self.handle, shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) gl.glLinkProgram(self.handle) #call use() early so some programm errors are caught early self.use()
def compile_and_attach_shader(self, source_strings, shader_type): ''' source_strings: a list of one or more strings that are possibly read from some files. shader_type: must be one of gl.GL_VERTEX_SHADER, gl.GL_FRAGMENT_SHADER, gl.GL_GEOMETRY_SHADER main steps to compile and attach a shader: 1. glCreateShader: create a shader of given type 2. glShaderSource: load source code into the shader 3. glCompileShader: compile the shader 4. glGetShaderiv: retrieve the compile status 5. glGetShaderInfoLog: print the error info if compiling failed 6. glAttachShader: attach the shader to our program if compiling successed ''' # a preprocessing to make the code compatible with python3. src = tuple(s.encode('ascii') for s in source_strings) # 1. create a shader shader = gl.glCreateShader(shader_type) # 2. load source code into the shader src_p = (ct.c_char_p * len(src))(*src) gl.glShaderSource( shader, len(src), ct.cast(ct.pointer(src_p), ct.POINTER(ct.POINTER(ct.c_char))), None) # 3. compile the shader gl.glCompileShader(shader) # 4. retrieve the compile status compile_status = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ct.byref(compile_status)) # 5. if compiling failed then print the error log if not compile_status: info_length = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetShaderInfoLog(shader, info_length, None, error_info) print(error_info.value) # 6. else attach the shader to our program else: gl.glAttachShader(self.program, shader)
def __init__(self, vertex_source, fragment_source): self.program = gl.glCreateProgram() self.vertex_shader = self.create_shader(vertex_source, gl.GL_VERTEX_SHADER) self.fragment_shader = self.create_shader(fragment_source, gl.GL_FRAGMENT_SHADER) gl.glAttachShader(self.program, self.vertex_shader) gl.glAttachShader(self.program, self.fragment_shader) gl.glLinkProgram(self.program) message = self.get_program_log(self.program) if message: raise ShaderException(message)
def setupShaders(self): self.programA = gl.glCreateProgram() gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_VERTEX_SHADER, self.vertex_source)) gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_FRAGMENT_SHADER, self.fragment_source_a)) pyglet_helper.link_program(self.programA)
def __init__(self, vertex_shader: Shader, fragment_shader: Shader, attributes=(), uniforms=None): """ The process of creating a shader can be divided into 6 steps: 1. Create an ID. 2. Attach shaders. 3. Bind attributes. 4. Link program. 5. Validate program. 6. Bind uniforms. Args: vertex_shader: fragment_shader: attributes: uniforms: A dictionary with the names of the uniform as the key, and the uniform (glsl value) as value. """ if uniforms is None: uniforms = {} handle = -1 attribute_location = {} uniform_location = {} try: handle = glCreateProgram() glAttachShader(handle, vertex_shader) glAttachShader(handle, fragment_shader) for index, name in enumerate(attributes): glBindAttribLocation(handle, index, c_string(name)) attribute_location[name] = index glLinkProgram(handle) glValidateProgram(handle) for uniform in uniforms: uniform_location[uniform] = glGetUniformLocation( handle, c_string(uniform)) except GLException: debug_program(handle) super(Program, self).__init__(handle) self.vertex_shader = vertex_shader self.fragment_shader = fragment_shader self.attribute_location = attribute_location self.uniform_location = uniform_location self.uniforms = uniforms if CHECK_ERROR: debug_program(self)
def compile(self): self.id = gl.glCreateProgram() for shader in self.shaders: shader.compile() gl.glAttachShader(self.id, shader.id) gl.glLinkProgram(self.id) message = self._get_message() if not self.get_link_status(): raise LinkError(message) return message
def compile_and_attach_shader(self, source_strings, shader_type): ''' source_strings: a list of one or more strings that are possibly read from some files. shader_type: must be one of gl.GL_VERTEX_SHADER, gl.GL_FRAGMENT_SHADER, gl.GL_GEOMETRY_SHADER main steps to compile and attach a shader: 1. glCreateShader: create a shader of given type 2. glShaderSource: load source code into the shader 3. glCompileShader: compile the shader 4. glGetShaderiv: retrieve the compile status 5. glGetShaderInfoLog: print the error info if compiling failed 6. glAttachShader: attach the shader to our program if compiling successed ''' # a preprocessing to make the code compatible with python3. src = tuple(s.encode('ascii') for s in source_strings) # 1. create a shader shader = gl.glCreateShader(shader_type) # 2. load source code into the shader src_p = (ct.c_char_p * len(src))(*src) gl.glShaderSource(shader, len(src), ct.cast(ct.pointer(src_p), ct.POINTER(ct.POINTER(ct.c_char))), None) # 3. compile the shader gl.glCompileShader(shader) # 4. retrieve the compile status compile_status = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ct.byref(compile_status)) # 5. if compiling failed then print the error log if not compile_status: info_length = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetShaderInfoLog(shader, info_length, None, error_info) print(error_info.value) # 6. else attach the shader to our program else: gl.glAttachShader(self.program, shader)
def compile_and_attach_shader(self, shader_file, shader_type): """Main steps to compile and attach a shader: 1. glCreateShader: create a shader of given type. 2. glShaderSource: load source code into the shader. 3. glCompileShader: compile the shader. 4. glGetShaderiv: retrieve the compile status. 5. glGetShaderInfoLog: print the error info if compiling failed. 6. glAttachShader: attach the shader to our program if compiling successed. """ with open(shader_file, 'r') as f: src = f.read().encode('ascii') # 1. create a shader shader = gl.glCreateShader(shader_type) # 2. load source code into the shader src_p = ct.c_char_p(src) gl.glShaderSource( shader, 1, ct.cast(ct.pointer(src_p), ct.POINTER(ct.POINTER(ct.c_char))), None) # 3. compile the shader gl.glCompileShader(shader) # 4. retrieve the compile status compile_status = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ct.byref(compile_status)) # 5. if compiling failed then print the error log if not compile_status: info_length = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetShaderInfoLog(shader, info_length, None, error_info) print(error_info.value) # 6. else attach the shader to our program else: gl.glAttachShader(self.program, shader)
def __init__(self, source): self.source = source self.shader_no = gl.glCreateShader(self.shader_type) if not self.shader_no: raise Exception("could not create shader") prog = (c_char_p * 1)(source + chr(0)) length = (c_int * 1)(0) gl.glShaderSource(self.shader_no, 1, cast(prog, POINTER(POINTER(c_char))), cast(0, POINTER(c_int))) gl.glCompileShader(self.shader_no) self.program_no = gl.glCreateProgram() if not self.program_no: raise Exception("could not create program") gl.glAttachShader(self.program_no, self.shader_no) gl.glLinkProgram(self.program_no)
def __init__(self, vertex, fragment, version=None): self._pid = gl.glCreateProgram() self._vertex_source = preprocess_shader(vertex, 'vert', version) self._fragment_source = preprocess_shader(fragment, 'frag', version) self.compile_vertex_shader() self.compile_fragment_shader() gl.glAttachShader(self._pid, self._vid) gl.glAttachShader(self._pid, self._fid) gl.glLinkProgram(self._pid) self._uniforms = {} self._attributes = {}
def __init__(self, *shaders: Shader): self.prog_id = prog_id = gl.glCreateProgram() shaders_id = [] for shader_code, shader_type in shaders: shader = compile_shader(shader_code, shader_type) gl.glAttachShader(self.prog_id, shader) shaders_id.append(shader) gl.glLinkProgram(self.prog_id) for shader in shaders_id: # Flag shaders for deletion. Will only be deleted once detached from program. gl.glDeleteShader(shader) self._uniforms: Dict[str, Uniform] = {} self._introspect_uniforms() weakref.finalize(self, Program._delete, shaders_id, prog_id)
def __setup_shaders(self): import os vertex_source_path = os.path.sep.join( [\ os.path.dirname(os.path.realpath(__file__)), "vs_vert.glsl"]) vertex_source = open(vertex_source_path, "r").read() self.__vert_shader = util.shader(vertex_source, "vert") frag_source_path = os.path.sep.join( [\ os.path.dirname(os.path.realpath(__file__)), "vs_frag.glsl"]) frag_source = open(frag_source_path, "r").read() self.__frag_shader = util.shader(frag_source, "frag") self.__prog = util.program() gl.glAttachShader(self.__prog.value, self.__vert_shader.value) gl.glAttachShader(self.__prog.value, self.__frag_shader.value) self.__prog.link()
def compile_and_attach_shader(self, shader_file, shader_type): """Main steps to compile and attach a shader: 1. glCreateShader: create a shader of given type. 2. glShaderSource: load source code into the shader. 3. glCompileShader: compile the shader. 4. glGetShaderiv: retrieve the compile status. 5. glGetShaderInfoLog: print the error info if compiling failed. 6. glAttachShader: attach the shader to our program if compiling successed. """ with open(shader_file, 'r') as f: src = f.read().encode('ascii') # 1. create a shader shader = gl.glCreateShader(shader_type) # 2. load source code into the shader src_p = ct.c_char_p(src) gl.glShaderSource(shader, 1, ct.cast(ct.pointer(src_p), ct.POINTER(ct.POINTER(ct.c_char))), None) # 3. compile the shader gl.glCompileShader(shader) # 4. retrieve the compile status compile_status = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ct.byref(compile_status)) # 5. if compiling failed then print the error log if not compile_status: info_length = gl.GLint(0) gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length)) error_info = ct.create_string_buffer(info_length.value) gl.glGetShaderInfoLog(shader, info_length, None, error_info) print(error_info.value) # 6. else attach the shader to our program else: gl.glAttachShader(self.program, shader)
def create_shader(self, strings, shader_type): count = len(strings) # if we have no source code, ignore this shader if count < 1: return # create the shader handle shader = glCreateShader(shader_type) shaderstrings = [] for string in strings: shaderstrings.append(bytes(string, 'ascii')) # convert the source strings into a ctypes pointer-to-char array, and # upload them this is deep, dark, dangerous black magic - don't try # stuff like this at home! src = (c_char_p * count)(*shaderstrings) glShaderSource(shader, count, cast( pointer(src), POINTER(POINTER(c_char))), None) # compile the shader glCompileShader(shader) temp = c_int(0) # retrieve the compile status glGetShaderiv(shader, GL_COMPILE_STATUS, byref(temp)) # if compilation failed, print the log if not temp: # retrieve the log length glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(temp)) # create a buffer for the log buffer = create_string_buffer(temp.value) # retrieve the log text glGetShaderInfoLog(shader, temp, None, buffer) # print the log to the console print(buffer.value) else: # all is well, so attach the shader to the program glAttachShader(self.handle, shader)
def __init__(self, vert_path, frag_path): self.program = gl.glCreateProgram() # create vertex shader self.vert_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) create_shader(self.vert_shader, vert_path) gl.glAttachShader(self.program, self.vert_shader) # create fragment shader self.frag_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) create_shader(self.frag_shader, frag_path) gl.glAttachShader(self.program, self.frag_shader) # link program and clean up gl.glLinkProgram(self.program) gl.glDeleteShader(self.vert_shader) gl.glDeleteShader(self.frag_shader)
def build_program(name): """build_program(name) Loads and compiles the shaders and afterwards link them into a program.""" # Compile the shaders vs = load_shader(name, 'v') fs = load_shader(name, 'f') # Create and link the program program = gl.glCreateProgram() gl.glAttachShader(program, vs) gl.glAttachShader(program, fs) gl.glLinkProgram(program) # If everything is ok -- return the program check_program(program) return program
def __init__(self, vertex_shader, fragment_shader, attributes): # compile and link self.program_name = gl.glCreateProgram() gl.glAttachShader(self.program_name, compile_shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader( self.program_name, compile_shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) link_program(self.program_name) # vertex type class VERTEX(ctypes.Structure): _fields_ = [(name, TYPE_NAME_TO_TYPE[tname] * size) for (name, tname, size) in attributes] self.VERTEX = VERTEX # vertex array and buffer self.vertex_array_name = gl.GLuint(0) self.vertex_buffer_name = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vertex_array_name)) gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer_name)) gl.glBindVertexArray(self.vertex_array_name) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer_name) for (name, tname, size) in attributes: location = gl.glGetAttribLocation( self.program_name, ctypes.create_string_buffer(name.encode('ascii'))) if location < 0: warnings.warn('Attribute %r is not present.' % name, stacklevel=2) continue gl.glEnableVertexAttribArray(location) gl.glVertexAttribPointer( location, size, tname, False, ctypes.sizeof(VERTEX), ctypes.c_void_p(getattr(VERTEX, name).offset)) gl.glBindVertexArray(0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
def create_shader(self, strings, t): count = len(strings) # if we have no source code, ignore this shader if count <= 0: self.log.info("Source string was empty. Not doing anything") return shader = glCreateShader(t) string_buffers = [ create_string_buffer(bytes(s, "utf-8")) for s in strings ] src = (c_char_p * count)(*map(addressof, string_buffers)) glShaderSource(shader, count, cast(pointer(src), POINTER(POINTER(c_char))), None) glCompileShader(shader) if self.was_compile_successful(shader): glAttachShader(self.handle, shader) else: self.log.warn("Could not compile shader")
def createShader(self, strings, type): count = len(strings) # if we have no source code, ignore this shader if count < 1: return # create the shader handle shader = GL.glCreateShader(type) # convert the source strings into a ctypes pointer-to-char array, # and upload them. This is deep, dark, dangerous black magick - # don't try stuff like this at home! """ Next line added """ strings = [s.encode("ascii") for s in strings] src = (ctypes.c_char_p * count)(*strings) GL.glShaderSource( shader, count, ctypes.cast(ctypes.pointer(src), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))), None) # compile the shader GL.glCompileShader(shader) temp = ctypes.c_int(0) # retrieve the compile status GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS, ctypes.byref(temp)) # if compilation failed, print the log if not temp: # retrieve the log length GL.glGetShaderiv(shader, GL.GL_INFO_LOG_LENGTH, ctypes.byref(temp)) # create a buffer for the log buffer = ctypes.create_string_buffer(temp.value) # retrieve the log text GL.glGetShaderInfoLog(shader, temp, None, buffer) # print the log to the console self.logError(buffer.value) else: # all is well, so attach the shader to the program GL.glAttachShader(self.handle, shader)
def createShader(self, strings, type): count = len(strings) # if we have no source code, ignore this shader if count < 1: return # create the shader handle shader = GL.glCreateShader(type) # convert the source strings into a ctypes pointer-to-char array, # and upload them. This is deep, dark, dangerous black magick - # don't try stuff like this at home! """ Next line added """ strings = [s.encode("ascii") for s in strings] src = (ctypes.c_char_p * count)(*strings) GL.glShaderSource(shader, count, ctypes.cast(ctypes.pointer(src), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))), None) # compile the shader GL.glCompileShader(shader) temp = ctypes.c_int(0) # retrieve the compile status GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS, ctypes.byref(temp)) # if compilation failed, print the log if not temp: # retrieve the log length GL.glGetShaderiv(shader, GL.GL_INFO_LOG_LENGTH, ctypes.byref(temp)) # create a buffer for the log buffer = ctypes.create_string_buffer(temp.value) # retrieve the log text GL.glGetShaderInfoLog(shader, temp, None, buffer) # print the log to the console self.logError(buffer.value) else: # all is well, so attach the shader to the program GL.glAttachShader(self.handle, shader);
def _build_shader(self, strings, stype): ''' Actual building of the shader ''' count = len(strings) # if we have no source code, ignore this shader if count < 1: return # create the shader handle shader = gl.glCreateShader(stype) # convert the source strings into a ctypes pointer-to-char array, and upload them # this is deep, dark, dangerous black magick - don't try stuff like this at home! src = (ctypes.c_char_p * count)(*strings) gl.glShaderSource(shader, count, ctypes.cast(ctypes.pointer(src), ctypes.POINTER(ctypes.POINTER(ctypes.c_char))), None) # compile the shader gl.glCompileShader(shader) temp = ctypes.c_int(0) # retrieve the compile status gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ctypes.byref(temp)) # if compilation failed, print the log if not temp: # retrieve the log length gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ctypes.byref(temp)) # create a buffer for the log buffer = ctypes.create_string_buffer(temp.value) # retrieve the log text gl.glGetShaderInfoLog(shader, temp, None, buffer) # print the log to the console print buffer.value else: # all is well, so attach the shader to the program gl.glAttachShader(self.handle, shader)
def create_shader(self, strings, t): count = len(strings) # if we have no source code, ignore this shader if count < 1: return # create the shader handle shader = glCreateShader(t) # convert the source strings into a ctypes pointer-to-char array, and upload them string_buffers = [ self.process_and_convert_to_string_buffer(s) for s in strings] # noinspection PyTypeChecker, PyCallingNonCallable src = (c_char_p * count)(*map(addressof, string_buffers)) glShaderSource(shader, count, cast( pointer(src), POINTER(POINTER(c_char))), None) # compile the shader glCompileShader(shader) temp = c_int(0) # retrieve the compile status glGetShaderiv(shader, GL_COMPILE_STATUS, byref(temp)) # if compilation failed, print the log if not temp: # retrieve the log length glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(temp)) # create a buffer for the log buffer = create_string_buffer(temp.value) # retrieve the log text glGetShaderInfoLog(shader, temp, None, buffer) # print the log to the console self.log.error(f"{buffer.value}") else: # all is well, so attach the shader to the program glAttachShader(self.handle, shader)
def setup_render_program(code): vertex_shader = b''' attribute vec2 position; attribute vec2 texcoord; varying vec2 tex_coord; void main() { gl_Position = vec4(position, 0.0, 1.0); tex_coord = texcoord; } ''' fragment_shader = (''' #version 420 uniform float depth; uniform vec3 texelSize; uniform sampler3D tex; in vec2 tex_coord; layout (location=0) out vec4 out_color; float getlum(vec3 p) {''' + code + '''} void main() { float lum = getlum(vec3(tex_coord.x,tex_coord.y,depth)); out_color = vec4(lum,lum,lum,1.); } ''').encode() global render_program render_program = gl.glCreateProgram() gl.glAttachShader(render_program, compile_shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader(render_program, compile_shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) link_program(render_program)
def _compile_shader(vs_src, fs_src): vs = gl.glCreateShader(gl.GL_VERTEX_SHADER) vs_src_buf = c.create_string_buffer(vs_src) c_vs_src = c.cast(c.pointer(vs_src_buf), c.POINTER(c.c_char)) i = c.c_int32(len(vs_src)) gl.glShaderSource(vs, 1, c_vs_src, c.byref(i)) gl.glCompileShader(vs) fs = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) fs_src_buf = c.create_string_buffer(fs_src) c_fs_src = c.cast(c.pointer(fs_src_buf), c.POINTER(c.c_char)) i = c.c_int32(len(fs_src)) gl.glShaderSource(fs, 1, c_fs_src, c.byref(i)) gl.glCompileShader(fs) program = gl.glCreateProgram() gl.glAttachShader(program, vs) gl.glAttachShader(program, fs) gl.glLinkProgram(program) gl.glDeleteShader(vs) gl.glDeleteShader(fs) return program
def setupShaders(self): self.programA = gl.glCreateProgram() gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_VERTEX_SHADER, self.vertex_source)) if args["shape"] == "sphere": gl.glAttachShader( self.programA, pyglet_helper.compile_shader(gl.GL_FRAGMENT_SHADER, self.fragment_source_a)) elif args["shape"] == "cylinder": gl.glAttachShader( self.programA, pyglet_helper.compile_shader( gl.GL_FRAGMENT_SHADER, self.fragment_source_cylinder)) pyglet_helper.link_program(self.programA)
def attach(self, shader): gl.glAttachShader(self.program_no, shader.shader_no)
def __init__(self, vertex_shader, fragment_shader): self.handle = gl.glCreateProgram() gl.glAttachShader(self.handle, shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader(self.handle, shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) gl.glLinkProgram(self.handle) self.use() # early error
def program(*shaders): p = gl.glCreateProgram() for s in shaders: gl.glAttachShader(p, s) gl.glLinkProgram(p) return check_shader_or_program_status(p)