Beispiel #1
0
    def getWidgetPreviewImage(self,
                              widgetType,
                              previewWidth=128,
                              previewHeight=64):
        """Renders and retrieves a widget preview image (as QImage).

        This is useful for various widget selection lists as a preview.
        """

        self.ensureIsInitialised()
        self.makeGLContextCurrent()

        system = PyCEGUI.System.getSingleton()

        renderer = system.getRenderer()

        renderTarget = PyCEGUIOpenGLRenderer.OpenGLViewportTarget(renderer)
        renderTarget.setArea(PyCEGUI.Rectf(0, 0, previewWidth, previewHeight))
        renderingSurface = PyCEGUI.RenderingSurface(renderTarget)

        widgetInstance = PyCEGUI.WindowManager.getSingleton().createWindow(
            widgetType, "preview")
        widgetInstance.setRenderingSurface(renderingSurface)
        # set it's size and position so that it shows up
        widgetInstance.setPosition(
            PyCEGUI.UVector2(PyCEGUI.UDim(0, 0), PyCEGUI.UDim(0, 0)))
        widgetInstance.setSize(
            PyCEGUI.USize(PyCEGUI.UDim(0, previewWidth),
                          PyCEGUI.UDim(0, previewHeight)))
        # fake update to ensure everything is set
        widgetInstance.update(1)

        temporaryFBO = QtOpenGL.QGLFramebufferObject(previewWidth,
                                                     previewHeight,
                                                     GL.GL_TEXTURE_2D)
        temporaryFBO.bind()

        renderingSurface.invalidate()

        renderer.beginRendering()

        try:
            widgetInstance.render()

        finally:
            # no matter what happens we have to clean after ourselves!
            renderer.endRendering()
            temporaryFBO.release()
            PyCEGUI.WindowManager.getSingleton().destroyWindow(widgetInstance)

        return temporaryFBO.toImage()
Beispiel #2
0
    def toImage(self, width, height):
        """Renders the scene into an offline buffer and returns is as QImage instance"""
        self.makeCurrent()
        fbo = QtOpenGL.QGLFramebufferObject(
            width, height, QtOpenGL.QGLFramebufferObject.CombinedDepthStencil)
        fbo.bind()
        self.sceneManager.resize(width, height)
        self.sceneManager.render()
        fbo.release()

        # restore original viewport size
        self.sceneManager.resize(self.resizeGLWidth, self.resizeGLHeight)

        return fbo.toImage()
Beispiel #3
0
    def drawBackground(self, painter, rect):
        """We override this and draw CEGUI instead of the whole background.
        This method uses a FBO to implement zooming, scrolling around, etc...

        FBOs are therefore required by CEED and it won't run without a GPU that supports them.
        """

        # be robust, this is usually caused by recursive repainting
        if painter.paintEngine() is None:
            return

        painterType = painter.paintEngine().type()
        if painterType != QtGui.QPaintEngine.OpenGL and painterType != QtGui.QPaintEngine.OpenGL2:
            QtCore.qWarning("cegui.GraphicsScene: drawBackground needs a "
                            "QGLWidget to be set as viewport on the "
                            "graphics view")

            return

        system = PyCEGUI.System.getSingleton()
        self.lastDelta = time.time() - self.timeOfLastRender
        self.ceguiInstance.lastRenderTimeDelta = self.lastDelta
        system.injectTimePulse(self.lastDelta)
        system.getDefaultGUIContext().injectTimePulse(self.lastDelta)
        self.timeOfLastRender = time.time()

        painter.setPen(QtGui.QPen(QtCore.Qt.transparent))
        painter.setBrush(
            qtwidgets.getCheckerboardBrush(self.checkerWidth.value,
                                           self.checkerHeight.value,
                                           self.checkerFirstColour.value,
                                           self.checkerSecondColour.value))
        painter.drawRect(0, 0, self.ceguiDisplaySize.d_width,
                         self.ceguiDisplaySize.d_height)

        painter.beginNativePainting()

        self.ceguiInstance.ensureIsInitialised()

        if self.ceguiDisplaySize != PyCEGUI.System.getSingleton().getRenderer(
        ).getDisplaySize():
            # FIXME: Change when multi root is in CEGUI core
            PyCEGUI.System.getSingleton().notifyDisplaySizeChanged(
                self.ceguiDisplaySize)

        # markAsDirty is called on the default GUI context to work around potential issues with dangling
        # references in the rendering code for some versions of CEGUI.
        system.getDefaultGUIContext().markAsDirty()

        # we have to render to FBO and then scale/translate that since CEGUI doesn't allow
        # scaling the whole rendering root directly

        # this makes sure the FBO is the correct size
        if not self.fbo:
            desiredSize = QtCore.QSize(
                math.ceil(self.ceguiDisplaySize.d_width),
                math.ceil(self.ceguiDisplaySize.d_height))
            self.fbo = QtOpenGL.QGLFramebufferObject(desiredSize,
                                                     GL.GL_TEXTURE_2D)

        self.fbo.bind()

        GL.glClearColor(0, 0, 0, 0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        system.renderAllGUIContexts()

        self.fbo.release()

        # the stretch and translation should be done automatically by QPainter at this point so just
        # this code will do
        if bool(GL.glActiveTexture):
            GL.glActiveTexture(GL.GL_TEXTURE0)

        GL.glEnable(GL.GL_TEXTURE_2D)
        GL.glBindTexture(GL.GL_TEXTURE_2D, self.fbo.texture())

        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)

        # TODO: I was told that this is the slowest method to draw with OpenGL,
        #       with which I certainly agree.
        #
        #       No profiling has been done at all and I don't suspect this to be
        #       a painful performance problem.
        #
        #       Still, changing this to a less pathetic rendering method would be great.

        GL.glBegin(GL.GL_TRIANGLES)

        # top left
        GL.glTexCoord2f(0, 1)
        GL.glVertex3f(0, 0, 0)

        # top right
        GL.glTexCoord2f(1, 1)
        GL.glVertex3f(self.fbo.size().width(), 0, 0)

        # bottom right
        GL.glTexCoord2f(1, 0)
        GL.glVertex3f(self.fbo.size().width(), self.fbo.size().height(), 0)

        # bottom right
        GL.glTexCoord2f(1, 0)
        GL.glVertex3f(self.fbo.size().width(), self.fbo.size().height(), 0)

        # bottom left
        GL.glTexCoord2f(0, 0)
        GL.glVertex3f(0, self.fbo.size().height(), 0)

        # top left
        GL.glTexCoord2f(0, 1)
        GL.glVertex3f(0, 0, 0)

        system.getDefaultGUIContext().markAsDirty()

        GL.glEnd()

        painter.endNativePainting()