Beispiel #1
0
    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)
Beispiel #2
0
 def validate(self):
     gl.glValidateProgram(self.program_no)
     self.validation_status = gl.GLint()
     gl.glGetProgramiv(self.program_no, gl.GL_VALIDATE_STATUS, self.validation_status)
     if not self.validation_status:
         raise gl.GLSLException(_infolog(self.program_no, log_type="program"))
Beispiel #3
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
Beispiel #4
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
Beispiel #5
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)