示例#1
0
    def __initSoundtrack(self):
        if muteState():
            return

        if self.__soundtrack:
            return self.__soundtrack

        path = None
        song = None
        for ext in ('.wav', '.mp3'):
            for path in currentProjectDirectory().iter(join=True):
                if not path.hasExt(ext):
                    continue
                try:
                    song = createSong(path)
                except:
                    print ('Found a soundtrack that we could not play. pyglet or mp3 libs missing?\n%s' % e.message)
                    return
                break
            if song:
                break
        if not song:
            return

        self.__soundtrackPath = path
        self.__soundtrack = song
        return self.__soundtrack
示例#2
0
    def __onAddImage(self):
        uniformName = QInputDialog.getText(self, 'Add texture', 'Uniform name', QLineEdit.Normal, 'uTextures[0]')
        if not uniformName[0] or not uniformName[1]:
            return
        uniformName = uniformName[0]

        imagePath = FileDialog.getOpenFileName(self, currentProjectDirectory(), '', 'Image files (*.png;*.bmp;*.jpg;*.jpeg;*.tiff);;Raw Gray F32 map (*.r32)')
        if imagePath and imagePath.exists():
            relPath = imagePath.relativeTo(currentProjectDirectory())
            self.__target.textures[uniformName] = relPath

            nameItem = QStandardItem(uniformName)
            nameItem.setIcon(QIcon(imagePath))
            pathItem = QStandardItem(relPath)
            pathItem.setFlags(pathItem.flags() & ~Qt.ItemIsEditable)
            self.__model.appendRow([nameItem, pathItem])
示例#3
0
    def fetchAndUse(fileName):
        assert not '\\' in fileName

        key = fileName.lower().replace('//', '/')
        if key in TexturePool.__cache:
            glBindTexture(GL_TEXTURE_2D, TexturePool.__cache[key])
            return TexturePool.__cache[key]
        parentPath = currentProjectDirectory()
        fullName = parentPath.join(fileName)

        # texture is a single channel raw32 heightmap
        if fileName.endswith('.r32'):
            tex = loadHeightfield(fullName)
            TexturePool.__cache[key] = tex.id()
            return tex.id()

        # read file into openGL texture
        img = QImage(fullName)
        if img.isNull():
            print('Warning, could not load texture %s.' % fullName)
            TexturePool.__cache[key] = 0  # no texture
            return 0
        img = QGLWidget.convertToGLFormat(img)
        tex = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, tex)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(),
                     0, GL_RGBA, GL_UNSIGNED_BYTE,
                     ctypes.c_void_p(int(img.bits())))
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        TexturePool.__cache[key] = tex
        return tex
示例#4
0
    def paintGL(self):
        newTime = time.time()
        deltaTime = newTime - self._prevTime

        # work around double repaint events collecting in the queue
        if deltaTime == 0.0:
            return

        self._prevTime = newTime

        width, height = self.calculateAspect(self.width(), self.height())
        viewport = (int((self.width() - width) * 0.5),
                    int((self.height() - height) * 0.5),
                    width,
                    height)

        if self._scene:
            uniforms = self._animator.evaluate(self._timer.time)
            textureUniforms = self._animator.additionalTextures(self._timer.time)

            cameraData = self._cameraData
            scene = self._scene
            modifier = currentProjectDirectory().join('animationprocessor.py')
            if modifier.exists():
                beats = self._timer.time
                execfile(modifier, globals(), locals())

            for name in self._textures:
                uniforms[name] = self._textures[name]._id

            self._scene.drawToScreen(self._timer.beatsToSeconds(self._timer.time), self._timer.time, uniforms, viewport, additionalTextureUniforms=textureUniforms)

        else:
            # no scene active, time cursor outside any enabled shots?
            global _noSignalImage
            if _noSignalImage is None:
                _noSignalImage = loadImage(FilePath(__file__).parent().join('icons', 'nosignal.png'))
            glDisable(GL_DEPTH_TEST)
            if _noSignalImage:
                glEnable(GL_BLEND)
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
                Scene.drawColorBufferToScreen(_noSignalImage, viewport)
                glDisable(GL_BLEND)

        if self.__overlays:
            image = self.__overlays.colorBuffer()
            if image:
                color = (self.__overlays.overlayColor().red() / 255.0,
                         self.__overlays.overlayColor().green() / 255.0,
                         self.__overlays.overlayColor().blue() / 255.0,
                         self.__overlays.overlayColor().alpha() / 255.0)
                glDisable(GL_DEPTH_TEST)
                glEnable(GL_BLEND)
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
                Scene.drawColorBufferToScreen(image, viewport, color)
                glDisable(GL_BLEND)
示例#5
0
    def __init__(self, target, parent=None):
        super(TextureManager, self).__init__(parent)

        self.setWindowTitle('TextureManager')

        main = vlayout()
        self.setLayout(main)

        belt = hlayout()
        main.addLayout(belt)

        addImage = QPushButton(icons.get('Add Image-48'), '')
        addImage.clicked.connect(self.__onAddImage)
        addImage.setIconSize(QSize(24, 24))
        addImage.setToolTip('Add texture')
        addImage.setStatusTip('Add texture')
        belt.addWidget(addImage)

        delImage = QPushButton(icons.get('Remove Image-48'), '')
        delImage.clicked.connect(self.__onDeleteImages)
        delImage.setIconSize(QSize(24, 24))
        delImage.setToolTip('Delete selected images')
        delImage.setStatusTip('Delete selected images')
        belt.addWidget(delImage)

        belt.addStretch(1)

        self.__model = QStandardItemModel()
        self.__view = QTableView()
        self.__view.setModel(self.__model)
        self.__view.horizontalHeader().hide()
        self.__view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.__view.verticalHeader().hide()
        main.addWidget(self.__view)
        main.setStretch(1, 1)

        self.__target = target
        for uniformName in target.textures:
            relPath = target.textures[uniformName]
            nameItem = QStandardItem(uniformName)
            nameItem.setIcon(QIcon(currentProjectDirectory().join(relPath)))
            pathItem = QStandardItem(relPath)
            pathItem.setFlags(pathItem.flags() & ~Qt.ItemIsEditable)
            self.__model.appendRow([nameItem, pathItem])
示例#6
0
    def __record(self):
        diag = QDialog()
        fId = gSettings.value('RecordFPS', 2)
        rId = gSettings.value('RecordResolution', 3)
        layout = QGridLayout()
        diag.setLayout(layout)
        layout.addWidget(QLabel('FPS: '), 0, 0)
        fps = QComboBox()
        fps.addItems(['12', '24', '30', '48', '60', '120'])
        fps.setCurrentIndex(fId)
        layout.addWidget(fps, 0, 1)
        layout.addWidget(QLabel('Vertical resolution: '), 1, 0)
        resolution = QComboBox()
        resolution.addItems(['144', '288', '360', '720', '1080', '2160'])
        resolution.setCurrentIndex(rId)
        layout.addWidget(resolution, 1, 1)
        ok = QPushButton('Ok')
        ok.clicked.connect(diag.accept)
        cancel = QPushButton('Cancel')
        cancel.clicked.connect(diag.reject)
        layout.addWidget(ok, 2, 0)
        layout.addWidget(cancel, 2, 1)
        diag.exec_()
        if diag.result() != QDialog.Accepted:
            return
        gSettings.setValue('RecordFPS', fps.currentIndex())
        gSettings.setValue('RecordResolution', resolution.currentIndex())

        FPS = int(fps.currentText())
        HEIGHT = int(resolution.currentText())
        WIDTH = (HEIGHT * 16) / 9
        FMT = 'jpg'

        data = (ctypes.c_ubyte * (WIDTH * HEIGHT * 3))()  # alloc buffer once
        flooredStart = self._timer.secondsToBeats(
            int(self._timer.beatsToSeconds(self._timer.start) * FPS) /
            float(FPS))
        duration = self._timer.beatsToSeconds(self._timer.end - flooredStart)

        captureDir = currentProjectDirectory().join('capture')
        captureDir.ensureExists(isFolder=True)

        progress = QProgressDialog(self)
        progress.setMaximum(int(duration * FPS))
        prevFrame = 0
        for frame in range(int(duration * FPS)):
            deltaTime = (frame - prevFrame) / float(FPS)
            prevFrame = frame
            progress.setValue(frame)
            QApplication.processEvents()
            if progress.wasCanceled():
                break
            beats = flooredStart + self._timer.secondsToBeats(
                frame / float(FPS))

            shot = self.__shotsManager.shotAtTime(beats)
            if shot is None:
                continue
            sceneFile = currentScenesDirectory().join(
                shot.sceneName).ensureExt(SCENE_EXT)
            scene = Scene.getScene(sceneFile)
            scene.setSize(WIDTH, HEIGHT)

            uniforms = self.__shotsManager.evaluate(beats)
            textureUniforms = self.__shotsManager.additionalTextures(beats)
            self.__sceneView._cameraInput.setData(
                *(uniforms['uOrigin'] + uniforms['uAngles'])
            )  # feed animation into camera so animationprocessor can read it again
            cameraData = self.__sceneView._cameraInput.data()

            modifier = currentProjectDirectory().join('animationprocessor.py')
            if modifier.exists():
                execfile(str(modifier), globals(), locals())

            for name in self.__sceneView._textures:
                uniforms[name] = self.__sceneView._textures[name]._id

            scene.drawToScreen(self._timer.beatsToSeconds(beats), beats,
                               uniforms, (0, 0, WIDTH, HEIGHT),
                               textureUniforms)
            scene.colorBuffers[-1][0].use()

            from OpenGL.GL import glGetTexImage, GL_TEXTURE_2D, GL_RGB, GL_UNSIGNED_BYTE
            glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data)

            captureDir = currentProjectDirectory().join('capture')
            QImage(data, WIDTH, HEIGHT, QImage.Format_RGB888).mirrored(
                False, True
            ).save(
                captureDir.join(
                    'dump_%s_%05d.%s' %
                    (FPS,
                     int(self._timer.beatsToSeconds(self._timer.start) * FPS) +
                     frame, FMT)))
        progress.close()

        convertCaptureDir = currentProjectDirectory().join('convertcapture')
        convertCaptureDir.ensureExists(isFolder=True)

        with convertCaptureDir.join('convert.bat').edit() as fh:
            start = ''
            start2 = ''
            if int(self._timer.start * FPS) > 0:
                start = '-start_number {} '.format(
                    int(self._timer.beatsToSeconds(self._timer.start) * FPS))
                start2 = '-vframes {} '.format(
                    int(
                        self._timer.beatsToSeconds(self._timer.end -
                                                   self._timer.start) * FPS))

            fh.write(
                'cd "../capture"\n"{}" -framerate {} {}-i dump_{}_%%05d.{} {}-c:v libx264 -r {} -pix_fmt yuv420p "../convertcapture/output.mp4"'
                .format(FFMPEG_PATH, FPS, start, FPS, FMT, start2, FPS))
        with convertCaptureDir.join('convertGif.bat').edit() as fh:
            start = ''
            start2 = ''
            iln = ''
            if int(self._timer.start * FPS) > 0:
                start = '-start_number {} '.format(
                    int(self._timer.beatsToSeconds(self._timer.start) * FPS))
                start2 = '-vframes {} '.format(
                    int(
                        self._timer.beatsToSeconds(self._timer.end -
                                                   self._timer.start) * FPS))
                iln = '-t {:03f} '.format(
                    self._timer.beatsToSeconds(self._timer.end -
                                               self._timer.start))
            fh.write(
                'REM File format is actually %5d but in a .bat file we need to escape % or something, so you can\'t copy paste this into a cmd prompt without fixing up the %%05d to be %5d.\n'
            )
            fh.write(
                'cd "../capture"\n"{}" -framerate {} {}{}-i dump_{}_%%05d.{} -vf "fps={},scale={}:-1:flags=lanczos,palettegen" palette.png\n'
                .format(FFMPEG_PATH, FPS, start, iln, FPS, FMT, FPS, HEIGHT))
            fh.write(
                '"{}" -framerate {} {}-i dump_{}_%%05d.{} -i "palette.png" -filter_complex "fps=12,scale=360:-1:flags=lanczos[x];[x][1:v]paletteuse" {}-r {} "../convertcapture/output.gif"'
                .format(FFMPEG_PATH, FPS, start, FPS, FMT, start2, FPS))

        sound = self.timeSlider.soundtrackPath()
        if not sound:
            return

        with convertCaptureDir.join('merge.bat').edit() as fh:
            startSeconds = self._timer.beatsToSeconds(self._timer.start)
            fh.write(
                '{} -i output.mp4 -itsoffset {} -i "{}" -vcodec copy -shortest merged.mp4'
                .format(FFMPEG_PATH, -startSeconds, sound))
示例#7
0
def _deserializePasses(sceneFile):
    """
    :type sceneFile: FilePath
    :rtype: list[PassData]
    """
    assert isinstance(sceneFile, FilePath)
    sceneDir = sceneFile.stripExt()
    templatePath = templatePathFromScenePath(sceneFile)
    templateDir = templatePath.stripExt()
    xTemplate = parseXMLWithIncludes(templatePath)
    passes = []
    frameBufferMap = {}
    for xPass in xTemplate:
        buffer = -1
        if 'buffer' in xPass.attrib:
            buffer = xPass.attrib['buffer']
            if buffer not in frameBufferMap:
                frameBufferMap[buffer] = len(frameBufferMap)

        size = None
        if 'size' in xPass.attrib:
            size = int(xPass.attrib['size']), int(xPass.attrib['size'])
        elif 'width' in xPass.attrib and 'height' in xPass.attrib:
            size = int(xPass.attrib['width']), int(xPass.attrib['height'])

        tile = size is not None
        if 'tile' in xPass.attrib:
            tile = xPass.attrib['tile'].lower() == 'true'

        factor = None
        if 'factor' in xPass.attrib:
            factor = int(xPass.attrib['factor'])

        realtime = int(xPass.attrib.get('static', 0)) == 0

        is3d = int(xPass.attrib.get('is3d', 0)) != 0
        if is3d:
            assert (size[0]**0.5) == size[1]
            size = size[0], size[1]

        outputs = int(xPass.attrib.get('outputs', 1))

        inputs = []
        i = 0
        key = 'input%s' % i
        while key in xPass.attrib:
            # input is filename?
            parentPath = currentProjectDirectory()
            fullName = parentPath.join(xPass.attrib[key])
            if fullName.exists():
                inputs.append(FilePath(xPass.attrib[key]))
            else:
                # input is buffer
                if '.' in xPass.attrib[key]:
                    frameBuffer, subTexture = xPass.attrib[key].split('.')
                    frameBuffer, subTexture = frameBuffer, int(subTexture)
                else:
                    frameBuffer, subTexture = xPass.attrib[key], 0

                if frameBuffer not in frameBufferMap:
                    frameBufferMap[frameBuffer] = len(frameBufferMap)
                inputs.append((frameBufferMap[frameBuffer], subTexture))

            i += 1
            key = 'input%s' % i
        vertStitches = []
        fragStitches = []
        uniforms = {}
        for xElement in xPass:
            path = FilePath(xElement.attrib['path'])
            stitches = vertStitches if path.hasExt('vert') else fragStitches
            if xElement.tag.lower() == 'section':
                stitches.append(sceneDir.join(path))
            elif xElement.tag.lower() in ('shared', 'global'):
                stitches.append(templateDir.join(path))
            else:
                raise ValueError('Unknown XML tag in pass: "******"' %
                                 xElement.tag)
            for xUniform in xElement:
                uniforms[xUniform.attrib['name']] = [
                    float(x.strip())
                    for x in xUniform.attrib['value'].split(',')
                ]

        passes.append(
            PassData(vertStitches, fragStitches, uniforms, inputs,
                     frameBufferMap.get(buffer, -1), realtime, size,
                     tile, factor, outputs,
                     xPass.attrib.get('drawcommand', None), is3d,
                     xPass.attrib.get('name', None)))
    return passes
示例#8
0
def _deserializePasses(sceneFile, models):
    """
    :type sceneFile: FilePath
    :rtype: list[PassData]
    """
    assert isinstance(sceneFile, FilePath)
    sceneDir = sceneFile.stripExt()
    templatePath = templatePathFromScenePath(sceneFile)
    templateDir = templatePath.stripExt()
    modelsDir = currentModelsDirectory()
    xTemplate = parseXMLWithIncludes(templatePath)
    passes = []
    frameBufferMap = {}

    # # Start with adding the models here as passes. Stored by their model name
    # for model in models.models:
    #     inputs = []
    #     if model.name not in frameBufferMap:
    #         frameBufferMap[model.name] = len(frameBufferMap)
    #     size = 256,256
    #     fragStitches = []
    #     fragStitches.append(templateDir.join("header.glsl"))
    #     fragStitches.append(templateDir.join("noiselib.glsl"))
    #     fragStitches.append(templateDir.join("sdf.glsl"))
    #     #fragStitches.append(templateDir.join("test3d.glsl"))
    #     fragStitches.append(modelsDir.join("%s.glsl" % model.name))
    #
    #     # Add a pass for rendering a 3D texture
    #     passes.append(
    #         PassData([], fragStitches, {}, inputs, frameBufferMap.get(model.name, -1), False, size, False, False, 1, None, True, None))

    for xPass in xTemplate:
        buffer = -1
        if 'buffer' in xPass.attrib:
            buffer = xPass.attrib['buffer']
            if buffer not in frameBufferMap:
                frameBufferMap[buffer] = len(frameBufferMap)

        size = None
        if 'size' in xPass.attrib:
            size = int(xPass.attrib['size']), int(xPass.attrib['size'])
        elif 'width' in xPass.attrib and 'height' in xPass.attrib:
            size = int(xPass.attrib['width']), int(xPass.attrib['height'])

        tile = size is not None
        if 'tile' in xPass.attrib:
            tile = xPass.attrib['tile'].lower() == 'true'

        factor = None
        if 'factor' in xPass.attrib:
            factor = int(xPass.attrib['factor'])

        realtime = int(xPass.attrib.get('static', 0)) == 0

        is3d = int(xPass.attrib.get('is3d', 0)) != 0
        if is3d:
            assert (size[0] == size[1])
            size = size[0], size[0]

        outputs = int(xPass.attrib.get('outputs', 1))

        inputs = []
        inputsUniformOverrideNames = {}
        i = 0
        key = 'input%s' % i
        while key in xPass.attrib:
            # input is filename?
            parentPath = currentProjectDirectory()
            fullName = parentPath.join(xPass.attrib[key])
            if fullName.exists():
                inputs.append(FilePath(xPass.attrib[key]))
            else:
                # input is buffer
                if '.' in xPass.attrib[key]:
                    frameBuffer, subTexture = xPass.attrib[key].split('.')
                    frameBuffer, subTexture = frameBuffer, int(subTexture)
                else:
                    frameBuffer, subTexture = xPass.attrib[key], 0

                if frameBuffer not in frameBufferMap:
                    frameBufferMap[frameBuffer] = len(frameBufferMap)
                inputs.append((frameBufferMap[frameBuffer], subTexture))

            i += 1
            key = 'input%s' % i

        inputModels = False
        if 'inputModels' in xPass.attrib:
            inputModels = xPass.attrib['inputModels'].lower() == 'true'

        # Add all model's output buffers as inputs to this pass
        if inputModels:
            for model in models.models:
                bufferIndex = (frameBufferMap[model.name], 0)
                inputs.append(bufferIndex)
                inputsUniformOverrideNames[
                    bufferIndex] = "uModel%s" % model.name

        vertStitches = []
        fragStitches = []
        uniforms = {}
        for xElement in xPass:
            if xElement.tag.lower() == 'section':
                path = FilePath(xElement.attrib['path'])
                stitches = vertStitches if path.hasExt(
                    'vert') else fragStitches
                stitches.append(sceneDir.join(path))
            elif xElement.tag.lower() in ('shared', 'global'):
                path = FilePath(xElement.attrib['path'])
                stitches = vertStitches if path.hasExt(
                    'vert') else fragStitches
                stitches.append(templateDir.join(path))
            elif xElement.tag.lower() == 'models':
                for model in models.models:
                    fragStitches.append(modelsDir.join("%s.glsl" % model.name))
            else:
                raise ValueError('Unknown XML tag in pass: "******"' %
                                 xElement.tag)
            for xUniform in xElement:
                uniforms[xUniform.attrib['name']] = [
                    float(x.strip())
                    for x in xUniform.attrib['value'].split(',')
                ]

        passes.append(
            PassData(vertStitches, fragStitches, uniforms, inputs,
                     frameBufferMap.get(buffer, -1), realtime, size,
                     tile, factor, outputs,
                     xPass.attrib.get('drawcommand', None), is3d,
                     xPass.attrib.get('name',
                                      None), inputsUniformOverrideNames))
    return passes