Пример #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)))
Пример #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
Пример #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)
Пример #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
Пример #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
Пример #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))
Пример #7
0
def CreateTexture(target: GL.GLenum) -> int:
    _id = GL.GLint()
    GL.glCreateTextures(target, 1, _id)

    return _id.value
Пример #8
0
def CreateFramebuffer() -> int:
    _id = GL.GLint()
    GL.glCreateFramebuffers(1, _id)

    return _id.value
Пример #9
0
def CreateVertexArray() -> int:
    _id = GL.GLint()
    GL.glCreateVertexArrays(1, _id)

    return _id.value