def get_num_active(self, variable_type: gl.GLenum) -> int:
        """Get the number of active variables of the passed GL type.

        variable_type can be GL_ACTIVE_ATTRIBUTES, GL_ACTIVE_UNIFORMS, etc.
        """
        num_active = gl.GLint(0)
        gl.glGetProgramiv(self.prog_id, variable_type, byref(num_active))
        return num_active.value
Exemple #2
0
    def primitives_generated(self) -> int:
        """
        How many primitives a vertex or geometry shader processed

        :type: int
        """
        value = gl.GLint()
        gl.glGetQueryObjectiv(self._glo_primitives_generated, gl.GL_QUERY_RESULT, value)
        return value.value
Exemple #3
0
 def time_elapsed(self) -> int:
     """
     The time elapsed in nanoseconds
     
     :type: int
     """
     value = gl.GLint()
     gl.glGetQueryObjectiv(self._glo_time_elapsed, gl.GL_QUERY_RESULT, value)
     return value.value
Exemple #4
0
 def samples_passed(self) -> int:
     """
     How many samples was written. These are per component (RGBA)
     
     :type: int
     """
     value = gl.GLint()
     gl.glGetQueryObjectiv(self._glo_samples_passed, gl.GL_QUERY_RESULT, value)
     return value.value
    def _introspect_attributes(self):
        """Introspect and store detailed info about an attribute"""
        # TODO: Ensure gl_* attributes are ignored
        num_attrs = gl.GLint()
        gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_ATTRIBUTES, num_attrs)
        num_varyings = gl.GLint()
        gl.glGetProgramiv(self._glo, gl.GL_TRANSFORM_FEEDBACK_VARYINGS,
                          num_varyings)
        # print(f"attrs {num_attrs.value} varyings={num_varyings.value}")

        for i in range(num_attrs.value):
            c_name = create_string_buffer(256)
            c_size = gl.GLint()
            c_type = gl.GLenum()
            gl.glGetActiveAttrib(
                self._glo,  # program to query
                i,  # index (not the same as location)
                256,  # max attr name size
                None,  # c_length,  # length of name
                c_size,  # size of attribute (array or not)
                c_type,  # attribute type (enum)
                c_name,  # name buffer
            )

            # Get the actual location. Do not trust the original order
            location = gl.glGetAttribLocation(self._glo, c_name)

            # print(c_name.value, c_size, c_type)
            type_info = GLTypes.get(c_type.value)
            # print(type_info)
            self._attributes.append(
                AttribFormat(
                    c_name.value.decode(),
                    type_info.gl_type,
                    type_info.components,
                    type_info.gl_size,
                    location=location,
                ))

        # The attribute key is used to cache VertexArrays
        self.attribute_key = ":".join(
            f"{attr.name}[{attr.gl_type}/{attr.components}]"
            for attr in self._attributes)
    def _introspect_uniform_blocks(self):
        active_uniform_blocks = gl.GLint(0)
        gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_UNIFORM_BLOCKS,
                          byref(active_uniform_blocks))
        # print('GL_ACTIVE_UNIFORM_BLOCKS', active_uniform_blocks)

        for loc in range(active_uniform_blocks.value):
            index, size, name = self._query_uniform_block(loc)
            block = UniformBlock(self._glo, index, size, name)
            self._uniforms[name] = block
Exemple #7
0
def link_program(program):
    gl.glLinkProgram(program)

    length = gl.GLint(0)
    gl.glGetProgramiv(program, gl.GL_INFO_LOG_LENGTH, ctypes.byref(length))
    log_buffer = ctypes.create_string_buffer(length.value)
    gl.glGetProgramInfoLog(program, length, None, log_buffer)

    for line in log_buffer.value[:length.value].decode('ascii').splitlines():
        print('GLSL: ' + line)
 def _query_uniform_block(self, location: int) -> Tuple[int, int, str]:
     """Query active uniform block by retrieving the name and index and size"""
     # Query name
     u_size = gl.GLint()
     buf_size = 192  # max uniform character length
     u_name = create_string_buffer(buf_size)
     gl.glGetActiveUniformBlockName(
         self._glo,  # program to query
         location,  # location to query
         256,  # max size if the name
         u_size,  # length
         u_name,
     )
     # Query index
     index = gl.glGetUniformBlockIndex(self._glo, u_name)
     # Query size
     b_size = gl.GLint()
     gl.glGetActiveUniformBlockiv(self._glo, index,
                                  gl.GL_UNIFORM_BLOCK_DATA_SIZE, b_size)
     return index, b_size.value, u_name.value.decode()
Exemple #9
0
def link_program(program_name):
    '''
    link a glsl program and print error messages.
    '''
    gl.glLinkProgram(program_name)

    success = gl.GLint(0)
    gl.glGetProgramiv(program_name, gl.GL_LINK_STATUS, ctypes.byref(success))

    length = gl.GLint(0)
    gl.glGetProgramiv(program_name, gl.GL_INFO_LOG_LENGTH,
                      ctypes.byref(length))
    log_buffer = ctypes.create_string_buffer(length.value)
    gl.glGetProgramInfoLog(program_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('Linking of the shader program failed.')
Exemple #10
0
    def link(self):
        """
        Main steps to link the program:
        1. glLinkProgram:
                linke the shaders in the program to create an executable
        2. glGetProgramiv:
                retrieve the link status
        3. glGetProgramInfoLog:
                print the error log if link failed
        """
        gl.glLinkProgram(self.program)

        link_status = gl.GLint(0)
        gl.glGetProgramiv(self.program, gl.GL_LINK_STATUS, ct.byref(link_status))

        if not link_status:
            info_length = gl.GLint(0)
            gl.glGetProgramiv(self.program, gl.GL_INFO_LOG_LENGTH, ct.byref(info_length))
            error_info = ct.create_string_buffer(info_length.value)
            gl.glGetProgramInfoLog(self.program, info_length, None, error_info)
            print(error_info.value)
Exemple #11
0
    def draw(self):
        previous_draw_mode = gl.GLint(0)
        gl.glGetIntegerv(gl.GL_POLYGON_MODE, byref(previous_draw_mode))
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)

        self.shader.use()
        gl.glBindVertexArray(self.array)
        # gl.glDrawElements(gl.GL_TRIANGLES, self.width * self.height * 6, gl.GL_UNSIGNED_INT, None)
        gl.glDrawElementsInstanced(gl.GL_TRIANGLES, Chunk.cells * 6, gl.GL_UNSIGNED_INT, None, self.instances)
        gl.glBindVertexArray(0)
        self.shader.clear()

        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, previous_draw_mode.value)
 def link(self):
     if self._shaders_empty:
         raise RuntimeError("No shaders attached to program")
     gl.glLinkProgram(self.gl_id)
     rc = gl.GLint(0)
     gl.glGetProgramiv(self.gl_id, gl.GL_LINK_STATUS, ctypes.byref(rc))
     if not rc:
         gl.glGetProgramiv(self.gl_id, gl.GL_INFO_LOG_LENGTH,
                           ctypes.byref(rc))
         buffer = ctypes.create_string_buffer(rc.value)
         gl.glGetProgramInfoLog(self.gl_id, rc, None, buffer)
         raise GLObjectException(buffer.value.decode())
     else:
         self._done_link = True
Exemple #13
0
def compile_shader(shader_type, shader_source):
    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)

    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 #14
0
    def query_uniform(self, index: int) -> Tuple[str, int, int]:
        """Retrieve Uniform information at given location.

        Returns the name, the type as a GLenum (GL_FLOAT, ...) and the size. Size is
        greater than 1 only for Uniform arrays, like an array of floats or an array
        of Matrices.
        """
        usize = gl.GLint()
        utype = gl.GLenum()
        buf_size = 192
        uname = create_string_buffer(buf_size)
        gl.glGetActiveUniform(self.prog_id, index, buf_size, None, usize,
                              utype, uname)
        return uname.value.decode(), utype.value, usize.value
Exemple #15
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 #16
0
def useFBO(fbo):
    """Context manager for Framebuffer Object bindings. This function yields
    the framebuffer name as an integer.

    Parameters
    ----------
    fbo :obj:`int` or :obj:`Framebuffer`
        OpenGL Framebuffer Object name/ID or descriptor.

    Yields
    -------
    int
        OpenGL name of the framebuffer bound in the context.

    Returns
    -------
    None

    Examples
    --------
    # FBO bound somewhere deep in our code
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, someOtherFBO)

    ...

    # create a new FBO, but we have no idea what the currently bound FBO is
    fbo = createFBO()

    # use a context to bind attachments
    with bindFBO(fbo):
        attach(GL.GL_COLOR_ATTACHMENT0, colorTex)
        attach(GL.GL_DEPTH_ATTACHMENT, depthRb)
        attach(GL.GL_STENCIL_ATTACHMENT, depthRb)
        isComplete = gltools.isComplete()

    # someOtherFBO is still bound!

    """
    prevFBO = GL.GLint()
    GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, ctypes.byref(prevFBO))
    toBind = fbo.id if isinstance(fbo, Framebuffer) else int(fbo)
    GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, toBind)
    try:
        yield toBind
    finally:
        GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, prevFBO.value)
Exemple #17
0
def getIntegerv(parName):
    """Get a single integer parameter value, return it as a Python integer.

    Parameters
    ----------
    pName : :obj:`int'
        OpenGL property enum to query (e.g. GL_MAJOR_VERSION).

    Returns
    -------
    int

    """
    val = GL.GLint()
    GL.glGetIntegerv(parName, val)

    return int(val.value)
Exemple #18
0
    def __init__(self, source_file: str = None, source: str = None):
        self.name = gl.glCreateShader(self.kind)
        if source_file:
            self.source = open(source_file, "rb").read()
        else:
            self.source = source
        src_buffer = create_string_buffer(self.source)
        buf_pointer = cast(pointer(pointer(src_buffer)),
                           POINTER(POINTER(c_char)))
        gl.glShaderSource(self.name, 1, buf_pointer, None)
        gl.glCompileShader(self.name)
        success = gl.GLint(0)

        gl.glGetShaderiv(self.name, gl.GL_COMPILE_STATUS, byref(success))
        if not success.value:
            self._log_error()
            raise RuntimeError('Compiling of the shader failed.')
    def _query_uniform(self, location: int) -> Tuple[str, int, int]:
        """Retrieve Uniform information at given location.

        Returns the name, the type as a GLenum (GL_FLOAT, ...) and the size. Size is
        greater than 1 only for Uniform arrays, like an array of floats or an array
        of Matrices.
        """
        u_size = gl.GLint()
        u_type = gl.GLenum()
        buf_size = 192  # max uniform character length
        u_name = create_string_buffer(buf_size)
        gl.glGetActiveUniform(
            self._glo,  # program to query
            location,  # location to query
            buf_size,  # size of the character/name buffer
            None,  # the number of characters actually written by OpenGL in the string
            u_size,  # size of the uniform variable
            u_type,  # data type of the uniform variable
            u_name,  # string buffer for storing the name
        )
        return u_name.value.decode(), u_type.value, u_size.value
Exemple #20
0
    def refresh_font_texture(self):
        # save texture state

        last_texture = gl.GLint()
        gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture))

        width, height, pixels = self.io.fonts.get_tex_data_as_rgba32()

        if self._font_texture is not None:
            gl.glDeleteTextures(1, self._font_texture)

        self._font_texture = gl.GLuint()
        gl.glGenTextures(1, byref(self._font_texture))

        gl.glBindTexture(gl.GL_TEXTURE_2D, self._font_texture)
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
        gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, pixels)

        self.io.fonts.texture_id = self._font_texture
        gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents)
        self.io.fonts.clear_tex_data()
    def _introspect_uniforms(self):
        """Figure out what uniforms are available and build an internal map"""
        # Number of active uniforms in the program
        active_uniforms = gl.GLint(0)
        gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_UNIFORMS,
                          byref(active_uniforms))

        # Loop all the active uniforms
        for index in range(active_uniforms.value):
            # Query uniform information like name, type, size etc.
            u_name, u_type, u_size = self._query_uniform(index)
            u_location = gl.glGetUniformLocation(self._glo, u_name.encode())

            # Skip uniforms that may be in Uniform Blocks
            # TODO: We should handle all uniforms
            if u_location == -1:
                # print(f"Uniform {u_location} {u_name} {u_size} {u_type} skipped")
                continue

            u_name = u_name.replace("[0]", "")  # Remove array suffix
            self._uniforms[u_name] = Uniform(self._glo, u_location, u_name,
                                             u_type, u_size)
Exemple #22
0
    def render(self, draw_data):
        # perf: local for faster access
        io = self.io

        display_width, display_height = io.display_size
        fb_width = int(display_width * io.display_fb_scale[0])
        fb_height = int(display_height * io.display_fb_scale[1])

        if fb_width == 0 or fb_height == 0:
            return

        draw_data.scale_clip_rects(*io.display_fb_scale)

        # backup GL state
        # todo: provide cleaner version of this backup-restore code
        last_program = gl.GLint()
        gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM, byref(last_program))
        last_texture = gl.GLint()
        gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture))
        last_active_texture = gl.GLint()
        gl.glGetIntegerv(gl.GL_ACTIVE_TEXTURE, byref(last_active_texture))
        last_array_buffer = gl.GLint()
        gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING, byref(last_array_buffer))
        last_element_array_buffer = gl.GLint()
        gl.glGetIntegerv(gl.GL_ELEMENT_ARRAY_BUFFER_BINDING, byref(last_element_array_buffer))
        last_vertex_array = gl.GLint()
        gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING, byref(last_vertex_array))
        last_blend_src = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_SRC, byref(last_blend_src))
        last_blend_dst = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_DST, byref(last_blend_dst))
        last_blend_equation_rgb = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_EQUATION_RGB, byref(last_blend_equation_rgb))
        last_blend_equation_alpha = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_EQUATION_ALPHA, byref(last_blend_equation_alpha))
        last_viewport = (gl.GLint*4)()
        gl.glGetIntegerv(gl.GL_VIEWPORT, last_viewport)
        last_scissor_box = (gl.GLint*4)()
        gl.glGetIntegerv(gl.GL_SCISSOR_BOX, last_scissor_box)
        last_enable_blend = gl.GLint()
        gl.glIsEnabled(gl.GL_BLEND, byref(last_enable_blend))
        last_enable_cull_face = gl.GLint()
        gl.glIsEnabled(gl.GL_CULL_FACE, byref(last_enable_cull_face))
        last_enable_depth_test = gl.GLint()
        gl.glIsEnabled(gl.GL_DEPTH_TEST, byref(last_enable_depth_test))
        last_enable_scissor_test = gl.GLint()
        gl.glIsEnabled(gl.GL_SCISSOR_TEST, byref(last_enable_scissor_test))

        gl.glEnable(gl.GL_BLEND)
        gl.glBlendEquation(gl.GL_FUNC_ADD)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
        gl.glDisable(gl.GL_CULL_FACE)
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glEnable(gl.GL_SCISSOR_TEST)
        gl.glActiveTexture(gl.GL_TEXTURE0)

        gl.glViewport(0, 0, int(fb_width), int(fb_height))

        ortho_projection = [
            2.0/display_width, 0.0,                   0.0, 0.0,
            0.0,               2.0/-display_height,   0.0, 0.0,
            0.0,               0.0,                  -1.0, 0.0,
            -1.0,               1.0,                   0.0, 1.0
        ]

        gl.glUseProgram(self._shader_handle)
        gl.glUniform1i(self._attrib_location_tex, 0)
        gl.glUniformMatrix4fv(self._attrib_proj_mtx, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*ortho_projection))
        gl.glBindVertexArray(self._vao_handle)

        for commands in draw_data.commands_lists:
            idx_buffer_offset = 0

            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle)
            # todo: check this (sizes)
            gl.glBufferData(gl.GL_ARRAY_BUFFER, commands.vtx_buffer_size * imgui.VERTEX_SIZE, c_void_p(commands.vtx_buffer_data), gl.GL_STREAM_DRAW)

            gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._elements_handle)
            # todo: check this (sizes)
            gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, commands.idx_buffer_size * imgui.INDEX_SIZE, c_void_p(commands.idx_buffer_data), gl.GL_STREAM_DRAW)

            # todo: allow to iterate over _CmdList
            for command in commands.commands:
                gl.glBindTexture(gl.GL_TEXTURE_2D, command.texture_id)

                # todo: use named tuple
                x, y, z, w = command.clip_rect
                gl.glScissor(int(x), int(fb_height - w), int(z - x), int(w - y))

                if imgui.INDEX_SIZE == 2:
                    gltype = gl.GL_UNSIGNED_SHORT
                else:
                    gltype = gl.GL_UNSIGNED_INT

                gl.glDrawElements(gl.GL_TRIANGLES, command.elem_count, gltype, c_void_p(idx_buffer_offset))

                idx_buffer_offset += command.elem_count * imgui.INDEX_SIZE

        # restore modified GL state
        gl.glUseProgram(cast((c_int*1)(last_program), POINTER(c_uint)).contents)
        gl.glActiveTexture(cast((c_int*1)(last_active_texture), POINTER(c_uint)).contents)
        gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents)
        gl.glBindVertexArray(cast((c_int*1)(last_vertex_array), POINTER(c_uint)).contents)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, cast((c_int*1)(last_array_buffer), POINTER(c_uint)).contents)
        gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, cast((c_int*1)(last_element_array_buffer), POINTER(c_uint)).contents)
        gl.glBlendEquationSeparate(cast((c_int*1)(last_blend_equation_rgb), POINTER(c_uint)).contents,
                                   cast((c_int*1)(last_blend_equation_alpha), POINTER(c_uint)).contents)
        gl.glBlendFunc(cast((c_int*1)(last_blend_src), POINTER(c_uint)).contents,
                       cast((c_int*1)(last_blend_dst), POINTER(c_uint)).contents)

        if last_enable_blend:
            gl.glEnable(gl.GL_BLEND)
        else:
            gl.glDisable(gl.GL_BLEND)

        if last_enable_cull_face:
            gl.glEnable(gl.GL_CULL_FACE)
        else:
            gl.glDisable(gl.GL_CULL_FACE)

        if last_enable_depth_test:
            gl.glEnable(gl.GL_DEPTH_TEST)
        else:
            gl.glDisable(gl.GL_DEPTH_TEST)

        if last_enable_scissor_test:
            gl.glEnable(gl.GL_SCISSOR_TEST)
        else:
            gl.glDisable(gl.GL_SCISSOR_TEST)

        gl.glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3])
        gl.glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
Exemple #23
0
 def binding(self) -> int:
     """int: Get or set the binding point for this uniform block"""
     binding = gl.GLint()
     gl.glGetActiveUniformBlockiv(self.glo, self.index, gl.GL_UNIFORM_BLOCK_BINDING, binding)
     return binding.value
Exemple #24
0
def get_max_texture_size():
    max_texture_size = gl.GLint()
    gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE, byref(max_texture_size))
    return max_texture_size.value
    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)
Exemple #26
0
def get_max_color_attachments():
    """Get the maximum allow Framebuffer Color attachements"""
    number = gl.GLint()
    gl.glGetIntegerv(gl.GL_MAX_COLOR_ATTACHMENTS, number)
    return number.value