Beispiel #1
0
    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)
Beispiel #2
0
    def compileShader(source, shaderType):
        """Compile shader source of given type (only needed by compileProgram)"""
        shader = gl.glCreateShaderObjectARB(shaderType)

        #were we given a source string or a ShaderCode object?
        if hasattr(source, 'src'): source = source.src

        prog = c_char_p(source)
        length = c_int(-1)
        gl.glShaderSourceARB(shader, 1,
                             cast(byref(prog), POINTER(POINTER(c_char))),
                             byref(length))
        gl.glCompileShaderARB(shader)

        #check for errors
        status = c_int()
        gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(status))
        if not status.value:
            #	retrieve the log length
            gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, byref(status))
            # create a buffer for the log
            buffer = create_string_buffer(status.value)  #from ctypes
            # retrieve the log text
            gl.glGetProgramInfoLog(shader, status, None, buffer)
            # print the log to the console
            print buffer.value
            gl.glDeleteShader(shader)
            raise ValueError, 'Shader compilation failed'
        return shader
Beispiel #3
0
    def compileShader( source, shaderType ):
            """Compile shader source of given type (only needed by compileProgram)"""
            shader = gl.glCreateShaderObjectARB(shaderType)

            #were we given a source string or a ShaderCode object?
            if hasattr(source, 'src'): source = source.src

            prog = c_char_p(source)
            length = c_int(-1)
            gl.glShaderSourceARB(shader,
                              1,
                              cast(byref(prog), POINTER(POINTER(c_char))),
                              byref(length))
            gl.glCompileShaderARB(shader)

            #check for errors
            status = c_int()
            gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(status))
            if not status.value:
                #	retrieve the log length
                gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, byref(status))
                # create a buffer for the log
                buffer = create_string_buffer(status.value)#from ctypes
                # retrieve the log text
                gl.glGetProgramInfoLog(shader, status, None, buffer)
                # print the log to the console
                print buffer.value
                gl.glDeleteShader(shader)
                raise ValueError, 'Shader compilation failed'
            return shader
Beispiel #4
0
    def __init__(self, source, shader_type):
        self.__value = None
        type_dict = {"vert": gl.GL_VERTEX_SHADER, "geom": gl.GL_GEOMETRY_SHADER, "frag": gl.GL_FRAGMENT_SHADER}

        # create and compile shader
        shader = gl.glCreateShader(type_dict[shader_type])
        source_ptr = ct.c_char_p(source)
        source_ptr_ptr = ct.cast(ct.pointer(source_ptr), ct.POINTER(ct.POINTER(ct.c_char)))
        gl.glShaderSource(shader, 1, source_ptr_ptr, None)
        gl.glCompileShader(shader)

        # check for error
        err_status = ct.c_int()
        gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ct.byref(err_status))
        if err_status.value != gl.GL_TRUE:
            # error occurred
            log_length = ct.c_int()
            gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, ct.byref(log_length))

            log_buffer = (ct.c_char * log_length.value)()
            log_buffer_ptr = ct.cast(ct.pointer(log_buffer), ct.c_char_p)
            gl.glGetShaderInfoLog(shader, log_length.value, None, log_buffer_ptr)

            gl.glDeleteShader(shader)

            raise gl.GLException("Shader failed to compile: \n%s" % log_buffer.value)
        else:
            self.__value = shader
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #8
0
 def test_freeing(self):
     " Test if the shaders are freed correctly"
     vert_obj = ShaderObject.vertex()
     
     # Warning, borrowed_obj do not own the underlying shader so it will not be freed automatically
     borrowed_obj = ShaderObject(glCreateShader(GL_VERTEX_SHADER), owned=False)          
     
     borrowed_sid = borrowed_obj.sid
     sid = vert_obj.sid
     del vert_obj
     del borrowed_obj
     gc.collect()
     
     self.assertEqual(GL_FALSE, glIsShader(sid), 'shader object is still valid')
     self.assertEqual(GL_TRUE, glIsShader(borrowed_sid), 'shader object was deleted')
     
     #Free the shader object
     glDeleteShader(borrowed_sid)
Beispiel #9
0
    def compileShader(source, shaderType):
        """Compile shader source of given type (only needed by compileProgram)"""
        shader = GL.glCreateShaderObjectARB(shaderType)

        prog = c_char_p(source)
        length = c_int(-1)
        GL.glShaderSourceARB(shader, 1,
                             cast(byref(prog), POINTER(POINTER(c_char))),
                             byref(length))
        GL.glCompileShaderARB(shader)

        #check for errors
        status = c_int()
        GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS, byref(status))
        if not status.value:
            print_log(shader)
            GL.glDeleteShader(shader)
            raise ValueError, 'Shader compilation failed'
        return shader
Beispiel #10
0
        def compileShader( source, shaderType ):
                """Compile shader source of given type (only needed by compileProgram)"""
                shader = GL.glCreateShaderObjectARB(shaderType)
                
                prog = c_char_p(source)
                length = c_int(-1)
                GL.glShaderSourceARB(shader,
                                  1,
                                  cast(byref(prog), POINTER(POINTER(c_char))),
                                  byref(length))
                GL.glCompileShaderARB(shader)

                #check for errors
                status = c_int()
                GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS, byref(status))
                if not status.value:
                    print_log(shader)
                    GL.glDeleteShader(shader)
                    raise ValueError, 'Shader compilation failed'
                return 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)
Beispiel #12
0
        def compileShader(source, shaderType):
            """Compile shader source of given type (only needed by compileProgram)
            """
            shader = GL.glCreateShaderObjectARB(shaderType)
            # if Py3 then we need to convert our (unicode) str into bytes for C
            if type(source) != bytes:
                source = source.encode()
            prog = c_char_p(source)
            length = c_int(-1)
            GL.glShaderSourceARB(shader, 1,
                                 cast(byref(prog), POINTER(POINTER(c_char))),
                                 byref(length))
            GL.glCompileShaderARB(shader)

            # check for errors
            status = c_int()
            GL.glGetShaderiv(shader, GL.GL_COMPILE_STATUS, byref(status))
            if not status.value:
                GL.glDeleteShader(shader)
                raise ValueError('Shader compilation failed')
            return shader
Beispiel #13
0
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
Beispiel #14
0
 def __del__(self):
     if self.owned and self.valid():
         glDeleteShader(self.sid)
Beispiel #15
0
    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)
Beispiel #16
0
 def delete(self):
     """Delete the current shader."""
     gl.glDeleteProgram(self._pid)
     gl.glDeleteShader(self._fid)
     gl.glDeleteShader(self._vid)
 def __del__(self):
     gl.glDeleteShader(self.gl_id)
Beispiel #18
0
 def __del__(self):
     if self.__value is not None:
         gl.glDeleteShader(self.__value)