def createTexture(self, gl, width=None, height=None, 
            wrapMode=QOpenGLTexture.ClampToEdge, format=QOpenGLTexture.RGBA8U, filter=QOpenGLTexture.Linear, 
            filename=None, allocate=True, **kwparams):
        ''' Creates texture object with required parameters '''
        assert width is not None or filename is not None
        if height is None: height = width

        if filename:
            texture = QOpenGLTexture(QImage('{}/{}'.format(Resources.directory, filename)).mirrored(), QOpenGLTexture.DontGenerateMipMaps)
        else:
            texture = QOpenGLTexture(QOpenGLTexture.Target2D)
            texture.setFormat(format)
            texture.setSize(width, height)
            if allocate: texture.allocateStorage()

        texture.setMinificationFilter(filter)
        texture.setMagnificationFilter(filter)
        texture.setWrapMode(wrapMode)

        assert texture.create()

        texture.bind()
        for k, v in kwparams.items():
            gl.glTexParameteri(gl.GL_TEXTURE_2D, getattr(gl, k), v)
        texture.release()

        return texture
Example #2
0
    def asQOpenGLTexture(self, gl, context):
        if not self.data:
            return

        if self.glFormat.requirements:
            minVersion, extensions = self.glFormat.requirements
            glVersion = (gl.glGetIntegerv(gl.GL_MAJOR_VERSION),
                         gl.glGetIntegerv(gl.GL_MINOR_VERSION))
            if glVersion < minVersion or minVersion < (1, 0):
                compatible = False
                for extension in extensions:
                    if context.hasExtension(extension):
                        compatible = True
                        break
                if not compatible:
                    qCritical(
                        self.__tr(
                            "OpenGL driver incompatible with texture format."))
                    return None

        if self.header.dwCaps2 & DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP:
            texture = QOpenGLTexture(QOpenGLTexture.TargetCubeMap)
            if self.header.dwWidth != self.header.dwHeight:
                qCritical(self.__tr("Cubemap faces must be square"))
                return None
        else:
            # Assume GL_TEXTURE_2D for now
            texture = QOpenGLTexture(QOpenGLTexture.Target2D)
        # Assume single layer for now
        # self.texture.setLayers(1)
        mipCount = self.mipLevels()
        texture.setAutoMipMapGenerationEnabled(False)
        texture.setMipLevels(mipCount)
        texture.setMipLevelRange(0, mipCount - 1)
        texture.setSize(self.header.dwWidth, self.header.dwHeight)
        texture.setFormat(self.glFormat.internalFormat)
        texture.allocateStorage()

        if self.header.dwCaps2 & DDSDefinitions.DDS_HEADER.Caps2.DDSCAPS2_CUBEMAP:
            # Lisa hasn't whipped David Wang into shape yet. At least there are fewer bugs than under Raja.
            # The specific bug has been reported and AMD "will try to reproduce it soon"
            noDSA = "Radeon" in gl.glGetString(
                gl.GL_RENDERER) and self.glFormat.compressed
            if noDSA:
                texture.bind()
            faceIndex = 0
            for face in ddsCubemapFaces:
                if self.header.dwCaps2 & face:
                    for i in range(mipCount):
                        if self.glFormat.compressed:
                            if not noDSA:
                                texture.setCompressedData(
                                    i, 0, ddsCubemapFaces[face],
                                    len(self.data[faceIndex * mipCount + i]),
                                    self.data[faceIndex * mipCount + i])
                            else:
                                gl.glCompressedTexSubImage2D(
                                    ddsCubemapFaces[face], i, 0, 0,
                                    max(self.header.dwWidth // 2**i, 1),
                                    max(self.header.dwHeight // 2**i,
                                        1), self.glFormat.internalFormat,
                                    len(self.data[faceIndex * mipCount + i]),
                                    self.data[faceIndex * mipCount + i])
                        else:
                            texture.setData(
                                i, 0, ddsCubemapFaces[face],
                                self.glFormat.format, self.glFormat.type,
                                self.glFormat.converter(
                                    self.data[faceIndex * mipCount + i]))
                    faceIndex += 1
            if noDSA:
                texture.release()
        else:
            for i in range(mipCount):
                if self.glFormat.compressed:
                    texture.setCompressedData(i, 0, len(self.data[i]),
                                              self.data[i])
                else:
                    texture.setData(i, 0, self.glFormat.format,
                                    self.glFormat.type,
                                    self.glFormat.converter(self.data[i]))

        texture.setWrapMode(QOpenGLTexture.ClampToEdge)

        if self.glFormat.samplerType != "F":
            # integer textures can't be filtered
            texture.setMinMagFilters(QOpenGLTexture.NearestMipMapNearest,
                                     QOpenGLTexture.Nearest)

        return texture