def create_shader(target, source_path):
	# read shader source

	source_file = open(source_path, "rb")
	source = source_file.read()
	source_file.close()

	source_length = ctypes.c_int(len(source) + 1)
	source_buffer = ctypes.create_string_buffer(source)

	buffer_pointer = ctypes.cast(
		ctypes.pointer(ctypes.pointer(source_buffer)),
		ctypes.POINTER(ctypes.POINTER(ctypes.c_char)))

	# compile shader

	gl.glShaderSource(target, 1, buffer_pointer, ctypes.byref(source_length))
	gl.glCompileShader(target)

	# handle potential errors

	log_length = gl.GLint(0)
	gl.glGetShaderiv(target, gl.GL_INFO_LOG_LENGTH, ctypes.byref(log_length))
	
	log_buffer = ctypes.create_string_buffer(log_length.value)
	gl.glGetShaderInfoLog(target, log_length, None, log_buffer)

	if log_length:
		raise Shader_error(str(log_buffer.value))
Exemple #2
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
Exemple #3
0
    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 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)
Exemple #5
0
def shader(stype, src):
    '''
    create and compile a shader of type stype with source code src
    return the shader (the return value of glCreateShader)
    '''
    handle = gl.glCreateShader(stype)
    buffer = ctypes.create_string_buffer(src)
    buf_pointer = ctypes.cast(ctypes.pointer(ctypes.pointer(buffer)),
                              ctypes.POINTER(ctypes.POINTER(ctypes.c_char)))
    length = ctypes.c_int(len(src) + 1)
    gl.glShaderSource(handle, 1, buf_pointer, ctypes.byref(length))
    gl.glCompileShader(handle)
    success = gl.GLint(0)
    gl.glGetShaderiv(handle, gl.GL_COMPILE_STATUS, ctypes.pointer(success))
    length = gl.GLint(0)
    gl.glGetShaderiv(handle, gl.GL_INFO_LOG_LENGTH, ctypes.pointer(length))
    buffer = ctypes.create_string_buffer(length.value)
    gl.glGetShaderInfoLog(handle, length, None, buffer)
    log = buffer.value[:length.value].decode('ascii')
    for line in log.splitlines():
        logging.debug('GLSL: ' + line)

    if not success:
        raise Exception('Compiling of the shader failed.')
    return handle
Exemple #6
0
    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 compile_shader(shader_type, shader_source):
    '''
    Compile a shader and print error messages.
    '''
    shader_name = gl.glCreateShader(shader_type)
    src_buffer = ctypes.create_string_buffer(shader_source)
    buf_pointer = ctypes.cast(ctypes.pointer(ctypes.pointer(src_buffer)), ctypes.POINTER(ctypes.POINTER(ctypes.c_char)))
    length = ctypes.c_int(len(shader_source) + 1)
    gl.glShaderSource(shader_name, 1, buf_pointer, ctypes.byref(length))
    gl.glCompileShader(shader_name)

    # test if compilation is succesful and print status messages
    success = gl.GLint(0)
    gl.glGetShaderiv(shader_name, gl.GL_COMPILE_STATUS, ctypes.byref(success))

    length = gl.GLint(0)
    gl.glGetShaderiv(shader_name, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length))
    log_buffer = ctypes.create_string_buffer(length.value)
    gl.glGetShaderInfoLog(shader_name, length, None, log_buffer)

    for line in log_buffer.value[:length.value].decode('ascii').splitlines():
        print('GLSL: ' + line)

    assert success, 'Compiling of the shader failed.'

    return shader_name
Exemple #8
0
def compile_shader(source: str, shader_type: gl.GLenum) -> gl.GLuint:
    """Compile the shader code of the given type.

    `shader_type` could be GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, ...

    Returns the shader id as a GLuint
    """
    shader = gl.glCreateShader(shader_type)
    source_bytes = source.encode('utf-8')
    # Turn the source code string into an array of c_char_p arrays.
    strings = byref(cast(c_char_p(source_bytes), POINTER(c_char)))
    # Make an array with the strings lengths
    lengths = pointer(c_int(len(source_bytes)))
    gl.glShaderSource(shader, 1, strings, lengths)
    gl.glCompileShader(shader)
    result = c_int()
    gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(result))
    if result.value == gl.GL_FALSE:
        msg = create_string_buffer(512)
        length = c_int()
        gl.glGetShaderInfoLog(shader, 512, byref(length), msg)
        raise ShaderException(
            f"Shader compile failure ({result.value}): {msg.value.decode('utf-8')}"
        )
    return shader
Exemple #9
0
def check_shader(shader, filename):
    """check_shader(shader, filename)

    Raises a RuntimeError if the shader hasn't compiled correctly."""

    # See if the shader compiled correctly
    compile_ok = gl.GLint(0)

    gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS,
                     c.pointer(compile_ok))

    # If the compilation fails, get the error description from OpenGL
    # and raise it
    if not compile_ok:
        log_len = gl.GLint(0)

        gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH,
                         c.pointer(log_len))

        log_buf = c.create_string_buffer(log_len.value)

        gl.glGetShaderInfoLog(shader, log_len, None, log_buf)

        raise RuntimeError(
            "Shader from %s could not compile: %s" % (
                filename, log_buf.value))
    def compile_shader(source: str, shader_type: gl.GLenum) -> gl.GLuint:
        """Compile the shader code of the given type.

        `shader_type` could be GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, ...

        Returns the shader id as a GLuint
        """
        shader = gl.glCreateShader(shader_type)
        source_bytes = source.encode("utf-8")
        # Turn the source code string into an array of c_char_p arrays.
        strings = byref(cast(c_char_p(source_bytes), POINTER(c_char)))
        # Make an array with the strings lengths
        lengths = pointer(c_int(len(source_bytes)))
        gl.glShaderSource(shader, 1, strings, lengths)
        gl.glCompileShader(shader)
        result = c_int()
        gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(result))
        if result.value == gl.GL_FALSE:
            msg = create_string_buffer(512)
            length = c_int()
            gl.glGetShaderInfoLog(shader, 512, byref(length), msg)
            raise ShaderException(
                (f"Error compiling {SHADER_TYPE_NAMES[shader_type]} "
                 f"({result.value}): {msg.value.decode('utf-8')}\n"
                 f"---- [{SHADER_TYPE_NAMES[shader_type]}] ---\n") +
                "\n".join(f"{str(i+1).zfill(3)}: {line} "
                          for i, line in enumerate(source.split("\n"))))
        return shader
Exemple #11
0
def compile_shader(shader_type, shader_source):
    '''
    Compile a shader and print error messages.
    '''
    shader_name = gl.glCreateShader(shader_type)
    src_buffer = ctypes.create_string_buffer(shader_source)
    buf_pointer = ctypes.cast(ctypes.pointer(ctypes.pointer(src_buffer)),
                              ctypes.POINTER(ctypes.POINTER(ctypes.c_char)))
    length = ctypes.c_int(len(shader_source) + 1)
    gl.glShaderSource(shader_name, 1, buf_pointer, ctypes.byref(length))
    gl.glCompileShader(shader_name)

    # test if compilation is succesful and print status messages
    success = gl.GLint(0)
    gl.glGetShaderiv(shader_name, gl.GL_COMPILE_STATUS, ctypes.byref(success))

    length = gl.GLint(0)
    gl.glGetShaderiv(shader_name, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length))
    log_buffer = ctypes.create_string_buffer(length.value)
    gl.glGetShaderInfoLog(shader_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('Compiling of the shader failed.')

    return shader_name
Exemple #12
0
 def get_info_log(self):
     length = self.get_info_log_length()
     if length == 0:
         return ''
     buffer = create_string_buffer(length)
     gl.glGetShaderInfoLog(self.id, length, None, buffer)
     return buffer.value
Exemple #13
0
def compile_shader(shader_type, shader_source):
    '''
	Compile a shader and print error messages.
	'''
    shader_name = gl.glCreateShader(shader_type)
    src_buffer = ctypes.create_string_buffer(shader_source)
    buf_pointer = ctypes.cast(ctypes.pointer(ctypes.pointer(src_buffer)),
                              ctypes.POINTER(ctypes.POINTER(ctypes.c_char)))
    length = ctypes.c_int(len(shader_source) + 1)
    gl.glShaderSource(shader_name, 1, buf_pointer, ctypes.byref(length))
    gl.glCompileShader(shader_name)

    # test if compilation is succesful and print status messages
    success = gl.GLint(0)
    gl.glGetShaderiv(shader_name, gl.GL_COMPILE_STATUS, ctypes.byref(success))

    length = gl.GLint(0)
    gl.glGetShaderiv(shader_name, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length))
    log_buffer = ctypes.create_string_buffer(length.value)
    gl.glGetShaderInfoLog(shader_name, length, None, log_buffer)

    for line in log_buffer.value[:length.value].decode('ascii').splitlines():
        print('GLSL: ' + line)

    assert success, 'Compiling of the shader failed.'

    return shader_name
 def __init__(self, shader_type, source):
     if shader_type not in GLShader.shader_type_name:
         raise ValueError
     self._shader_type = shader_type
     self._source = source
     super().__init__(gl.glCreateShader(shader_type))
     if isinstance(source, str):
         source = source.encode()
     if not isinstance(source, bytes):
         raise TypeError
     c_source = ctypes.create_string_buffer(source)
     c_source = ctypes.cast(
         ctypes.pointer(ctypes.pointer(c_source)),
         ctypes.POINTER(ctypes.POINTER(gl.GLchar)),
     )
     gl.glShaderSource(self.gl_id, 1, c_source, None)
     gl.glCompileShader(self.gl_id)
     rc = gl.GLint(0)
     gl.glGetShaderiv(self.gl_id, gl.GL_COMPILE_STATUS, ctypes.byref(rc))
     if not rc:
         gl.glGetShaderiv(self.gl_id, gl.GL_INFO_LOG_LENGTH,
                          ctypes.byref(rc))
         buffer = ctypes.create_string_buffer(rc.value)
         gl.glGetShaderInfoLog(self.gl_id, rc, None, buffer)
         raise GLObjectException("{}\n{}".format(
             GLShader.shader_type_name[shader_type], buffer.value.decode()))
Exemple #15
0
 def get_info_log(self):
     length = self.get_info_log_length()
     if length == 0:
         return ''
     buffer = create_string_buffer(length)
     gl.glGetShaderInfoLog(self.id, length, None, buffer)
     return buffer.value
Exemple #16
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)
Exemple #17
0
def print_log(shader):
    length = c_int()
    GL.glGetShaderiv(shader, GL.GL_INFO_LOG_LENGTH, byref(length))

    if length.value > 0:
        log = create_string_buffer(length.value)
        GL.glGetShaderInfoLog(shader, length, byref(length), log)
        print >> sys.stderr, log.value
Exemple #18
0
def print_log(shader):
    length = c_int()
    GL.glGetShaderiv(shader, GL.GL_INFO_LOG_LENGTH, byref(length))
    
    if length.value > 0:
        log = create_string_buffer(length.value)
        GL.glGetShaderInfoLog(shader, length, byref(length), log)
        print >> sys.stderr, log.value
Exemple #19
0
 def was_compile_successful(self, shader):
     status = c_int(0)
     glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status))
     if not status:
         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(status))
         buffer = create_string_buffer(status.value)
         glGetShaderInfoLog(shader, status, None, buffer)
         self.log.error(f"{buffer.value}")
     return status
Exemple #20
0
    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)
Exemple #21
0
    def __init__(self, source="", type='vertex'):
        """
        Vertex, Fragment, or Geometry shader.

        Parameters
        ----------
        source : string or list
            String or list of strings.  The GLSL source code for the shader.
        type : {'vertex', 'fragment', 'geometry'}
            Type of shader.

        """
        shader_type = {'vertex': gl.GL_VERTEX_SHADER,
                       'fragment': gl.GL_FRAGMENT_SHADER,}
        ##             'geometry': gl.GL_GEOMETRY_SHADER}

        if isinstance(source, basestring):
            source = [source]

        count = len(source)
        # if we have no source code, ignore this shader
        if count < 1:
            raise GLSLError("No GLSL source provided.")

        # create the shader handle
        shader = gl.glCreateShader(shader_type[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!
        src = (c_char_p * count)(*source)
        gl.glShaderSource(shader, count,
                          cast(pointer(src), POINTER(POINTER(c_char))),
                       None)

        # compile the shader
        gl.glCompileShader(shader)

        temp = c_int(0)
        # retrieve the compile status
        gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, byref(temp))

        # if compilation failed, print the log
        if not temp:
            # retrieve the log length
            gl.glGetShaderiv(shader, gl.GL_INFO_LOG_LENGTH, byref(temp))
            # create a buffer for the log
            buffer = create_string_buffer(temp.value)
            # retrieve the log text
            gl.glGetShaderInfoLog(shader, temp, None, buffer)
            # print the log to the console
            raise GLSLError(buffer.value)

        self.handle = shader
        self.source = "\n".join(source)
Exemple #22
0
    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)
Exemple #23
0
    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)
Exemple #24
0
    def _log_error(self):
        log_length = gl.GLint(0)
        gl.glGetShaderiv(self.name, gl.GL_INFO_LOG_LENGTH, byref(log_length))

        log_buffer = create_string_buffer(log_length.value)
        gl.glGetShaderInfoLog(self.name, log_length.value, None, log_buffer)
        self.logger.error("Error compiling GLSL (type %s) shader!", self.kind)
        self.logger.error("---Shader---")
        self.logger.error("\n".join(
            f"{i+1: 3d}: {line}" for i, line in enumerate(
                self.source.decode("ascii").splitlines())))
        self.logger.error("---Message---")
        for line in log_buffer.value[:log_length.value].decode(
                'ascii').splitlines():
            self.logger.error('GLSL: ' + line)
        self.logger.error("------")
Exemple #25
0
    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)
Exemple #26
0
def compile_shader(type_, src):
    shader = gl.glCreateShader(type_)
    gl.glShaderSource(
        shader,
        1,
        ctypes.cast(
            ctypes.pointer(ctypes.pointer(ctypes.create_string_buffer(src))),
            ctypes.POINTER(ctypes.POINTER(ctypes.c_char)),
        ),
        ctypes.byref(ctypes.c_int(len(src) + 1)),
    )
    gl.glCompileShader(shader)
    status = ctypes.c_int(0)
    gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS, ctypes.byref(status))
    if not status.value:
        log = ctypes.create_string_buffer(4096)
        gl.glGetShaderInfoLog(shader, len(log), None, log)
        raise Exception('Error compiling shader: ' + log.value.decode('utf8'))
    return shader
Exemple #27
0
    def _compile(self, source, kind):
        """Compile a shader from its source code.

        :param source: Source code of the shader to be compiled.
        :type source: str

        :param kind: The kind of shader we are compiling.
        :type kind: int

        :returns: The shader id of the compiled shader.
        :rtype: int

        """
        shader_id = gl.glCreateShader(kind)
        _src = ct.c_char_p(source.encode('utf-8'))
        src = ct.cast(ct.pointer(_src), ct.POINTER(ct.POINTER(ct.c_char)))
        gl.glShaderSource(shader_id, 1, src, None)

        gl.glCompileShader(shader_id)
        status_code = ct.c_int(0)
        status_code_pointer = ct.pointer(status_code)
        gl.glGetShaderiv(shader_id, gl.GL_COMPILE_STATUS, status_code_pointer)

        log_size = ct.c_int(0)
        log_size_pointer = ct.pointer(log_size)
        gl.glGetShaderiv(shader_id, gl.GL_INFO_LOG_LENGTH, log_size_pointer)

        log_message = ct.create_string_buffer(log_size.value)
        gl.glGetShaderInfoLog(shader_id, log_size, None, log_message)
        log_message = log_message.value.decode('utf-8')

        if len(log_message) > 0:
            print(source)
            print(log_message)
            # In Windows (OpenGL 3.3 + intel card) the log_message
            # is set to "No errors" on a successful compilation
            # and the code raises the Exception even though it
            # shouldn't. There should be a proper fix, but getting
            # rid of this line for now, will fix it.
            #
            # raise Exception(log_message)

        return shader_id
Exemple #28
0
def shader(stype, src):
    handle = gl.glCreateShader(stype)
    buffer = ctypes.create_string_buffer(src)
    buf_pointer = ctypes.cast(ctypes.pointer(ctypes.pointer(buffer)), POINTER(POINTER(ctypes.c_char)))
    length = ctypes.c_int(len(src) + 1)
    gl.glShaderSource(handle, 1, buf_pointer, byref(length))
    gl.glCompileShader(handle)
    success = gl.GLint(0)
    gl.glGetShaderiv(handle, gl.GL_COMPILE_STATUS, pointer(success))
    length = gl.GLint(0)
    gl.glGetShaderiv(handle, gl.GL_INFO_LOG_LENGTH, pointer(length))
    buffer = ctypes.create_string_buffer(length.value)
    gl.glGetShaderInfoLog(handle, length, None, buffer)
    log = buffer.value[:length.value].decode('ascii')
    for line in log.splitlines():
        logging.debug('GLSL: ' + line)

    if not success:
        raise Exception('Compiling of the shader failed.')
    return handle
Exemple #29
0
    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)
Exemple #30
0
    def print_error(message):
        nonlocal error
        error = True

        status = GLint()
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(status))

        output = create_string_buffer(status.value)
        glGetShaderInfoLog(shader, status, None, output)

        shader_source = '\n'.join([
            '{:<3} | '.format(row) + line
            for row, line in enumerate(shader.source.splitlines(), start=1)
        ])

        print(message,
              output.value.decode('utf-8'),
              'Shader source:',
              shader_source,
              file=sys.stderr,
              sep='\n')
Exemple #31
0
    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)
Exemple #32
0
    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)
Exemple #33
0
    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);
Exemple #34
0
    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)
Exemple #35
0
    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)
Exemple #36
0
    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
Exemple #37
0
    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