Ejemplo n.º 1
0
    def __init__(self, vertex_shader, fragment_shader, geom_shader=None):
        self.shaders = list()
        self.attribs = dict()
        self.ubos    = dict()
        GLVariable = namedtuple('GLVariable', ['loc', 'size'])

        # Compile shaders and link program
        self.compile_shader(vertex_shader, gl.GL_VERTEX_SHADER)
        self.compile_shader(fragment_shader, gl.GL_FRAGMENT_SHADER)
        if geom_shader:
            self.compile_shader(geom_shader, gl.GL_GEOMETRY_SHADER)
        self.link()

        size = gl.GLint()
        name = (ctypes.c_char * 20)()

        # Obtain list of attributes with location and size info
        n_attrs = gl.glGetProgramiv(self.program, gl.GL_ACTIVE_ATTRIBUTES)
        for a in range(n_attrs):
            atype = gl.GLint()
            gl.glGetActiveAttrib(self.program, a, 20, None,
                ctypes.pointer(size), ctypes.pointer(atype), ctypes.pointer(name))
            loc = gl.glGetAttribLocation(self.program, name.value)
            typesize = _glvar_sizes.get(atype.value, 1)
            self.attribs[name.value.decode('utf8')] = GLVariable(loc, size.value * typesize)

        n_uniforms = gl.glGetProgramiv(self.program, gl.GL_ACTIVE_UNIFORMS)
        all_uids = set(range(n_uniforms))

        n_ub = gl.glGetProgramiv(self.program, gl.GL_ACTIVE_UNIFORM_BLOCKS)
        for ub in range(n_ub):
            gl.glGetActiveUniformBlockName(self.program, ub, 20, None, ctypes.pointer(name))
            gl.glGetActiveUniformBlockiv(self.program, ub, gl.GL_UNIFORM_BLOCK_DATA_SIZE, ctypes.pointer(size))
            self.ubos[name.value.decode('utf-8')] = size.value
            ubsize = gl.GLint()
            gl.glGetActiveUniformBlockiv(self.program, ub, gl.GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, ctypes.pointer(ubsize))
            indices = (ctypes.c_int * ubsize.value)()
            gl.glGetActiveUniformBlockiv(self.program, ub, gl.GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, ctypes.pointer(indices))
            all_uids -= set(indices)
            # print('Uniform block: ', name.value.decode('utf8'), 'size =', ubsize.value)
            # for i in indices:
            #     usize = gl.GLint()
            #     utype = gl.GLint()
            #     uname = (ctpes.c_char * 20)()
            #     # gl.glGetActiveUniform(self.program, i, 20, None, ctypes.pointer(usize), ctypes.pointer(utype), ctypes.pointer(uname))
            #     # print('block uniform', i, '=', uname.value.decode('utf8'), 'size =', usize.value)
            #     print(gl.glGetActiveUniform(self.program, i))

            for u in all_uids:
                name, size, utype = gl.glGetActiveUniform(self.program, u)
                setattr(self, name.decode('utf-8'), GLVariable(u, size * _glvar_sizes.get(utype, 1)))
Ejemplo n.º 2
0
    def get_fence_signalled(self):
        ''' Returns a boolean describing whether 
        the fence has been signalled.
        '''
        if self.__sync is not None:
            fence_status = GL.GLint(0)
            GL_sync.glGetSynciv(self.__sync,
                    GL_sync.GL_SYNC_STATUS,
                    GL.GLint(1), GL.GLint(0), fence_status)
            
            return (GL_sync.GL_SIGNALED == fence_status.value)

        else:
            return False
Ejemplo n.º 3
0
    def build_attribute_map(self):
        """
        Builds an internal attribute map by querying the program.
        This way we don't have to query OpenGL (can cause slowdowns)
        This information is also used when the shader and VAO negotiates the buffer binding.
        """
        attribute_count = GL.glGetProgramiv(self.program,
                                            GL.GL_ACTIVE_ATTRIBUTES)
        bufsize = GL.glGetProgramiv(self.program,
                                    GL.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH)
        print("Shader {} has {} attribute(s)".format(self.name,
                                                     attribute_count))
        for i in range(attribute_count):
            # Unlike glGetActiveUniform the attrib version do not return a convenient tuple
            # and we'll have to use to ugly version. (Most people make wrappers for this one)
            length, size, type, name = GL.GLsizei(), GL.GLint(), GL.GLenum(), (
                GL.GLchar * bufsize)()
            GL.glGetActiveAttrib(self.program, i, bufsize, length, size, type,
                                 name)

            # Get the actual location. Do not trust the original order
            location = GL.glGetAttribLocation(self.program, name.value)
            attribute = Attribute(name.value, type.value, location)
            self.attribute_map[attribute.name] = attribute
            self.attribute_list.append(attribute)
            print(" - {}".format(attribute))

        self.attribute_key = ','.join(
            name for name in sorted(self.attribute_map.keys()))
        print("Shader attribute key:", self.attribute_key)
Ejemplo n.º 4
0
def create_program_attribute_layout(program):

    active_attribute = c_int(0)
    GL.glGetProgramiv(program, GL.GL_ACTIVE_ATTRIBUTES, active_attribute)

    max_name_length = GL.glGetProgramiv(program, GL.GL_ACTIVE_ATTRIBUTE_MAX_LENGTH)
    name_length = GL.GLsizei(0)
    attribute_size = GL.GLint(0)
    attribute_type = GL.GLenum(0)
    name = (GL.GLchar * max_name_length)()

    attribute_layout = []
    for index in range(active_attribute.value):
        GL.glGetActiveAttrib(program, index, max_name_length, name_length, attribute_size, attribute_type, name)
        attribute_location = GL.glGetAttribLocation(program, name.value)
        attribute_layout.append((attribute_location, ATTRIBUTE_SIZE_BY_TYPES[attribute_type.value]))

    attribute_layout.sort(key=lambda pair: pair[0])

    attribute_locations = []
    attribute_sizes = []
    for attribute_location, attribute_size in attribute_layout:
        attribute_locations.append(attribute_location)
        attribute_sizes.append(attribute_size)

    return attribute_locations, attribute_sizes
Ejemplo n.º 5
0
    def _get_attribs(self) -> Dict[str, IndexSizeType]:
        _active_attrib = GL.glGetProgramiv(self.program,
                                           GL.GL_ACTIVE_ATTRIBUTES)

        # For some reason the PyOpenGL Binding is sorta broken
        # use the full ctypes-style access
        bufSize = 50
        ct_nameSize = GL.GLsizei()
        ct_size = GL.GLint()
        ct_type = GL.GLenum()
        ct_name = (GL.GLchar * bufSize)()

        _attribs = {}

        for attrib_index in range(_active_attrib):
            GL.glGetActiveAttrib(self.program, attrib_index, bufSize,
                                 ct_nameSize, ct_size, ct_type, ct_name)

            #in python3 attribute names are bytestrings. Convert to UTF8
            name = ct_name.value.decode("ascii")

            _attribs[name] = IndexSizeType(attrib_index, ct_size.value,
                                           ct_type.value)

        return _attribs
Ejemplo n.º 6
0
        def tkCreateContext(self):
            self.__window = XOpenDisplay(self.winfo_screen().encode('utf-8'))
            # Check glx version:
            major = c_int(0)
            minor = c_int(0)
            GLX.glXQueryVersion(self.__window, major, minor)
            print("GLX version: %d.%d" % (major.value, minor.value))
            if major.value == 1 and minor.value < 3:  # e.g. 1.2 and down
                visual = GLX.glXChooseVisual(self.__window, 0,
                                             (GL.GLint * len(att))(*att))
                if not visual:
                    _log.error("glXChooseVisual call failed")
                self.__context = GLX.glXCreateContext(self.__window, visual,
                                                      None, GL.GL_TRUE)
                GLX.glXMakeCurrent(self.__window, self._wid, self.__context)
                return  # OUT HERE FOR 1.2 and less
            else:
                # 1.3 or higher
                # which screen - should it be winfo_screen instead ??
                XDefaultScreen = _x11lib.XDefaultScreen
                XDefaultScreen.argtypes = [POINTER(Display)]
                XDefaultScreen.restype = c_int
                screen = XDefaultScreen(self.__window)
                print("Screen is ", screen)
                # Look at framebuffer configs
                ncfg = GL.GLint(0)
                cfgs = GLX.glXChooseFBConfig(self.__window, screen,
                                             (GL.GLint * len(fbatt))(*fbatt),
                                             ncfg)
                print("Number of FBconfigs", ncfg.value)
                #
                # Try to match to the current window
                # ... might also be possible to set this for the frame
                # ... but for now we just take what Tk gave us
                ideal = int(self.winfo_visualid(), 16)  # convert from hex
                best = -1
                for i in range(ncfg.value):
                    vis = GLX.glXGetVisualFromFBConfig(self.__window, cfgs[i])
                    if ideal == vis.contents.visualid:
                        best = i
                        print("Got a matching visual: index %d %d xid %s" %
                              (best, vis.contents.visualid, hex(ideal)))
                if best < 0:
                    print("oh dear - visual does not match")
                    # Take the first in the list (should be another I guess)
                    best = 0
                # Here we insist on RGBA - but didn't check earlier
                self.__context = GLX.glXCreateNewContext(
                    self.__window,
                    cfgs[best],
                    GLX.GLX_RGBA_TYPE,
                    None,  # share list
                    GL.GL_TRUE)  # direct
                print("Is Direct?: ",
                      GLX.glXIsDirect(self.__window, self.__context))
                # Not creating another window ... some tutorials do
                #                print("wid: ",self._wid)
                #                self._wid = GLX.glXCreateWindow( self.__window, cfgs[best], self._wid, None)
                #                print("wid: ",self._wid)
                GLX.glXMakeContextCurrent(self.__window, self._wid, self._wid,
                                          self.__context)
                print("Done making a first context")
                extensions = GLX.glXQueryExtensionsString(
                    self.__window, screen)
                # Here we quit - getting a modern context needs further work below
                return
                if "GLX_ARB_create_context" in extensions:
                    # We can try to upgrade it ??
                    print("Trying to upgrade context")
                    s = "glXCreateContextAttribsARB"
                    p = GLX.glXGetProcAddress(c_char_p(s))

                    print(p)
                    if not p:
                        p = GLX.glXGetProcAddressARB(
                            (GL.GLubyte * len(s)).from_buffer_copy(s))
                    print(p)
                    if p:
                        print(" p is true")
                    p.restype = GLX.GLXContext
                    p.argtypes = [
                        POINTER(Display), GLX.GLXFBConfig, GLX.GLXContext,
                        c_bool,
                        POINTER(c_int)
                    ]
                    arb_attrs = fbatt[:-1] + []

                    #    GLX.GLX_CONTEXT_MAJOR_VERSION_ARB , 3
                    #    GLX.GLX_CONTEXT_MINOR_VERSION_ARB , 1,
                    #    0 ]
                    #
                    #    GLX.GLX_CONTEXT_FLAGS_ARB
                    #    GLX.GLX_CONTEXT_PROFILE_MASK_ARB
                    #]
                    #                    import pdb
                    #                    pdb.set_trace()
                    self.__context = p(self.__window, cfgs[best], None,
                                       GL.GL_TRUE,
                                       (GL.GLint * len(arb_attrs))(*arb_attrs))
Ejemplo n.º 7
0
def CreateTexture(target: GL.GLenum) -> int:
    _id = GL.GLint()
    GL.glCreateTextures(target, 1, _id)

    return _id.value
Ejemplo n.º 8
0
def CreateFramebuffer() -> int:
    _id = GL.GLint()
    GL.glCreateFramebuffers(1, _id)

    return _id.value
Ejemplo n.º 9
0
def CreateVertexArray() -> int:
    _id = GL.GLint()
    GL.glCreateVertexArrays(1, _id)

    return _id.value