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()
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()
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()