Exemple #1
0
 def __init__(self, project, filename, parent):
   self.mutex = QMutex()
   self.project = project
   self.filename = filename
   self.parent = parent
   self.surface = QOffscreenSurface()
   self.surface.setFormat(QSurfaceFormat.defaultFormat())
   self.surface.create()
Exemple #2
0
class ExportViewTarget(object):
  def __init__(self, project, filename, parent):
    self.mutex = QMutex()
    self.project = project
    self.filename = filename
    self.parent = parent
    self.surface = QOffscreenSurface()
    self.surface.setFormat(QSurfaceFormat.defaultFormat())
    self.surface.create()

  def destroy(self):
    self.surface.destroy()

  def render(self, view, uniforms=dict()):
    self.project.setCameraMode('view')
    self.project.setCameraViewRef(view)
    self.project.setCameraAtOrigin()
    self.project.render(self.ctx.functions(), view.info.width, view.info.height, uniforms)
    depth = self.project.renderer.depthmap(self.ctx.functions(), view.info.width, view.info.height)
    return depth

  def __enter__(self):
    self.mutex.lock()
    self.ctx = QOpenGLContext()
    self.ctx.setShareContext(self.parent)
    self.ctx.create()
    if not self.ctx.makeCurrent(self.surface):
      raise Exception("cannot make context current")
    self.project.renderer.lock()

  def __exit__(self, type, value, tb):
    self.project.renderer.unlock()
    self.ctx.doneCurrent()
    del self.ctx
    self.mutex.unlock()
Exemple #3
0
    def __init__(self, display: Union[str, int], qml_view: QUrl,
                 gl_context: QOpenGLContext):
        super().__init__()
        self.qml_view = qml_view
        self.display = display
        self.wl_display = Display(display)
        self.wl_compositor = None
        self.wl_shm = None
        self.wl_embedder = None
        self.views = {}
        self.fd_notifier = None
        self.engine = Engine()
        self.component = None
        self.qml_view = qml_view
        self.connected = False
        self.gl_context = gl_context

        assert gl_context.isOpenGLES()
        surface = QOffscreenSurface()
        surface.setFormat(gl_context.format())
        surface.create()
        gl_context.makeCurrent(surface)
Exemple #4
0
    def initialize(self, size: QSize, shareContext: QOpenGLContext) -> None:
        """
        Initialize offscreen renderer.

        Args:
            size: The size of the area available for rendering.
            shareContext: OpenGL context used as a share context.

        Raises:
            RuntimeError: If the renderer has already been initialized.
        """
        print(f'QmlOffscreenRenderer.initialize: {size}')
        if self.initialized:
            raise RuntimeError('Already initialized')

        context = QOpenGLContext()
        context.setShareContext(shareContext)
        context.setFormat(get_default_format(gles=False))
        context.create()
        assert not context.isOpenGLES(), "We need glGetTexImage from OpenGL"

        self.size = size

        # Create offscreen surface with initialized format
        surface = QOffscreenSurface()
        surface.setFormat(context.format())
        surface.create()
        self.ctx = RenderContext(context, surface)

        # Set up quick rendering
        self._control = control = QQuickRenderControl()
        self._window = window = QQuickWindow(control)
        self._cursor = self._window.cursor()

        # Don't polish/sync/render immediately for better performance, use a timer
        self._renderTimer = renderTimer = QTimer()
        renderTimer.setSingleShot(True)
        renderTimer.setInterval(5)
        renderTimer.timeout.connect(self._onRenderTimer)
        self._syncTimer = syncTimer = QTimer()
        syncTimer.setSingleShot(True)
        syncTimer.setInterval(5)
        syncTimer.timeout.connect(self._onSyncTimer)
        syncTimer.destroyed.connect(self._onSyncTimerDestroyed)

        # Request to create frame buffer
        window.sceneGraphInitialized.connect(self._onSceneGraphInitialized)
        # Request to release frame buffer
        window.sceneGraphInvalidated.connect(self._onSceneGraphInvalidated)
        # Only render is needed
        control.renderRequested.connect(self._onRenderRequested)
        # Polish, sync & render
        control.sceneChanged.connect(self._onSceneChanged)

        self.initialized = True

        # Attach root item
        self.rootItem.setParentItem(self._window.contentItem())
        self._window.contentItem().forceActiveFocus()
        self._updateSizes()
        self.ctx.makeCurrent()
        self._control.initialize(self.ctx.glContext)
Exemple #5
0
    def initialize(self, size: QSize, shareContext: QOpenGLContext) -> None:
        """
        Initialize offscreen renderer.

        Args:
            size: The size of the area available for rendering.
            shareContext: OpenGL context used as a share context.

        Raises:
            RuntimeError: If the renderer has already been initialized.
        """
        print(f'QmlOffscreenRenderer.initialize: {size}')
        if self.initialized:
            raise RuntimeError('Already initialized')

        format = QSurfaceFormat()
        format.setDepthBufferSize(16)
        format.setStencilBufferSize(8)
        context = QOpenGLContext()
        context.setFormat(format)
        context.setShareContext(shareContext)
        context.create()

        self.size = size
        self.context = context

        # Create offscreen surface with initialized format
        self._surface = surface = QOffscreenSurface()
        surface.setFormat(context.format())
        surface.create()

        # Set up quick rendering
        self._control = control = QQuickRenderControl()
        self._window = window = QQuickWindow(control)
        self._engine = engine = QQmlEngine()
        if not engine.incubationController():
            engine.setIncubationController(window.incubationController())

        # Don't polish/sync/render immediately for better performance, use a timer
        self._renderTimer = renderTimer = QTimer()
        renderTimer.setSingleShot(True)
        renderTimer.setInterval(5)
        renderTimer.timeout.connect(self._onRenderTimer)
        self._syncTimer = syncTimer = QTimer()
        syncTimer.setSingleShot(True)
        syncTimer.setInterval(5)
        syncTimer.timeout.connect(self._onSyncTimer)
        syncTimer.destroyed.connect(self._onSyncTimerDestroyed)

        # Request to create frame buffer
        window.sceneGraphInitialized.connect(self._onSceneGraphInitialized)
        # Request to release frame buffer
        window.sceneGraphInvalidated.connect(self._onSceneGraphInvalidated)
        # Only render is needed
        control.renderRequested.connect(self._onRenderRequested)
        # Polish, sync & render
        control.sceneChanged.connect(self._onSceneChanged)

        self.initialized = True

        # Load QML component
        self._component = component = QQmlComponent(self._engine, self.qmlUrl)
        if component.isLoading():
            component.statusChanged.connect(self._onComponentStatusChanged)
        else:
            self._attachRootItem()
Exemple #6
0
    def __init__(self, window):

        self.window = window

        self.offscreenSurface = QOffscreenSurface()
        sformat = QSurfaceFormat.defaultFormat()
        sformat.setDepthBufferSize(32)
        self.offscreenSurface.setFormat( sformat )
        self.offscreenSurface.create()

        self.overlayCamera = Qt3DRender.QCamera()
        self.overlayCamera.setViewCenter( vec3d() )
        self.overlayCamera.setPosition( vec3d( 0, 0, -1 ) )
        self.overlayCamera.setUpVector( vec3d( 0, 1, 0 ) )
        self.overlayCamera.lens().setOrthographicProjection( -1, 1, -1, 1, -1, 1 )

        # Framegraph root #1 -- onscreen rendering
        self.surfaceSelector = Qt3DRender.QRenderSurfaceSelector()
        self.surfaceSelector.setSurface(window)
        self.root = self.surfaceSelector


        # Framgraph root #2 -- Used for offscreen renders, not in the graph by default
        # During screenshots, offscreenSurfaceSelector becomes the root
        # and the branch roots will become a child of renderTargetSelector
        self.offscreenSurfaceSelector = Qt3DRender.QRenderSurfaceSelector()
        self.offscreenSurfaceSelector.setSurface(self.offscreenSurface)
        self.renderTargetSelector = Qt3DRender.QRenderTargetSelector(self.offscreenSurfaceSelector)
        self.targetTexture = OffscreenRenderTarget(self.renderTargetSelector)
        self.renderTargetSelector.setTarget(self.targetTexture)
        self.noDraw2 = Qt3DRender.QNoDraw(self.renderTargetSelector)

        # Branch 1: clear buffers
        self.clearBuffers = Qt3DRender.QClearBuffers(self.surfaceSelector)
        self.clearBuffers.setBuffers(Qt3DRender.QClearBuffers.ColorDepthBuffer)
        self.clearBuffers.setClearColor(Qt.white)
        self.noDraw = Qt3DRender.QNoDraw(self.clearBuffers)

        # Branch 2: main drawing branches using the Athena camera
        self.cameraSelector = Qt3DRender.QCameraSelector(self.surfaceSelector)
        self.cameraSelector.setCamera(window.camera())

        # Branch 2A: solid objects
        self.viewport = Qt3DRender.QViewport(self.cameraSelector)
        self.viewport.setNormalizedRect(QRectF(0, 0, 1.0, 1.0))
        self.qfilt = Qt3DRender.QTechniqueFilter(self.viewport)
        self.solidPassFilter = Qt3DRender.QFilterKey(self.qfilt)
        self.solidPassFilter.setName('pass')
        self.solidPassFilter.setValue('solid')
        self.qfilt.addMatch(self.solidPassFilter)

        # Branch 2B: transparent objects
        self.viewport2 = Qt3DRender.QViewport(self.cameraSelector)
        self.viewport2.setNormalizedRect(QRectF(0, 0, 1.0, 1.0))
        self.qfilt2 = Qt3DRender.QTechniqueFilter(self.viewport2)
        self.transPassFilter = Qt3DRender.QFilterKey(self.qfilt2)
        self.transPassFilter.setName('pass')
        self.transPassFilter.setValue('transp')
        self.qfilt2.addMatch(self.transPassFilter)

        # Branch 3: 2D screen overlays
        self.cameraSelector2 = Qt3DRender.QCameraSelector(self.surfaceSelector)
        self.cameraSelector2.setCamera(self.overlayCamera)
        self.viewport3 = Qt3DRender.QViewport(self.cameraSelector2)
        self.viewport3.setNormalizedRect(QRectF(0, 0, 1.0, 1.0))
        self.qfilt3 = Qt3DRender.QTechniqueFilter(self.viewport3)
        self.overlayPassFilter = Qt3DRender.QFilterKey(self.viewport3)
        self.overlayPassFilter.setName('pass')
        self.overlayPassFilter.setValue('overlay')
        self.qfilt3.addMatch(self.overlayPassFilter)

        # Branch 4: render capture branch for taking screenshots
        self.renderCapture = Qt3DRender.QRenderCapture(self.surfaceSelector)
        self.noDraw3 = Qt3DRender.QNoDraw(self.renderCapture)

        # Branch roots are the bits that need reparenting when switching between
        # offscreen and onscreen rendering
        self.branchRoots = [ self.clearBuffers, self.cameraSelector, self.cameraSelector2, self.renderCapture ]
Exemple #7
0
class AthenaFrameGraph:
    '''
    Class to manage the Qt3D framegraph on behalf of the Athena viewer
    '''

    def __init__(self, window):

        self.window = window

        self.offscreenSurface = QOffscreenSurface()
        sformat = QSurfaceFormat.defaultFormat()
        sformat.setDepthBufferSize(32)
        self.offscreenSurface.setFormat( sformat )
        self.offscreenSurface.create()

        self.overlayCamera = Qt3DRender.QCamera()
        self.overlayCamera.setViewCenter( vec3d() )
        self.overlayCamera.setPosition( vec3d( 0, 0, -1 ) )
        self.overlayCamera.setUpVector( vec3d( 0, 1, 0 ) )
        self.overlayCamera.lens().setOrthographicProjection( -1, 1, -1, 1, -1, 1 )

        # Framegraph root #1 -- onscreen rendering
        self.surfaceSelector = Qt3DRender.QRenderSurfaceSelector()
        self.surfaceSelector.setSurface(window)
        self.root = self.surfaceSelector


        # Framgraph root #2 -- Used for offscreen renders, not in the graph by default
        # During screenshots, offscreenSurfaceSelector becomes the root
        # and the branch roots will become a child of renderTargetSelector
        self.offscreenSurfaceSelector = Qt3DRender.QRenderSurfaceSelector()
        self.offscreenSurfaceSelector.setSurface(self.offscreenSurface)
        self.renderTargetSelector = Qt3DRender.QRenderTargetSelector(self.offscreenSurfaceSelector)
        self.targetTexture = OffscreenRenderTarget(self.renderTargetSelector)
        self.renderTargetSelector.setTarget(self.targetTexture)
        self.noDraw2 = Qt3DRender.QNoDraw(self.renderTargetSelector)

        # Branch 1: clear buffers
        self.clearBuffers = Qt3DRender.QClearBuffers(self.surfaceSelector)
        self.clearBuffers.setBuffers(Qt3DRender.QClearBuffers.ColorDepthBuffer)
        self.clearBuffers.setClearColor(Qt.white)
        self.noDraw = Qt3DRender.QNoDraw(self.clearBuffers)

        # Branch 2: main drawing branches using the Athena camera
        self.cameraSelector = Qt3DRender.QCameraSelector(self.surfaceSelector)
        self.cameraSelector.setCamera(window.camera())

        # Branch 2A: solid objects
        self.viewport = Qt3DRender.QViewport(self.cameraSelector)
        self.viewport.setNormalizedRect(QRectF(0, 0, 1.0, 1.0))
        self.qfilt = Qt3DRender.QTechniqueFilter(self.viewport)
        self.solidPassFilter = Qt3DRender.QFilterKey(self.qfilt)
        self.solidPassFilter.setName('pass')
        self.solidPassFilter.setValue('solid')
        self.qfilt.addMatch(self.solidPassFilter)

        # Branch 2B: transparent objects
        self.viewport2 = Qt3DRender.QViewport(self.cameraSelector)
        self.viewport2.setNormalizedRect(QRectF(0, 0, 1.0, 1.0))
        self.qfilt2 = Qt3DRender.QTechniqueFilter(self.viewport2)
        self.transPassFilter = Qt3DRender.QFilterKey(self.qfilt2)
        self.transPassFilter.setName('pass')
        self.transPassFilter.setValue('transp')
        self.qfilt2.addMatch(self.transPassFilter)

        # Branch 3: 2D screen overlays
        self.cameraSelector2 = Qt3DRender.QCameraSelector(self.surfaceSelector)
        self.cameraSelector2.setCamera(self.overlayCamera)
        self.viewport3 = Qt3DRender.QViewport(self.cameraSelector2)
        self.viewport3.setNormalizedRect(QRectF(0, 0, 1.0, 1.0))
        self.qfilt3 = Qt3DRender.QTechniqueFilter(self.viewport3)
        self.overlayPassFilter = Qt3DRender.QFilterKey(self.viewport3)
        self.overlayPassFilter.setName('pass')
        self.overlayPassFilter.setValue('overlay')
        self.qfilt3.addMatch(self.overlayPassFilter)

        # Branch 4: render capture branch for taking screenshots
        self.renderCapture = Qt3DRender.QRenderCapture(self.surfaceSelector)
        self.noDraw3 = Qt3DRender.QNoDraw(self.renderCapture)

        # Branch roots are the bits that need reparenting when switching between
        # offscreen and onscreen rendering
        self.branchRoots = [ self.clearBuffers, self.cameraSelector, self.cameraSelector2, self.renderCapture ]

        #self.dump()

    def setOffscreenRendering ( self, size = QSize(1200,1200) ):
        self.targetTexture.setSize(size)
        for node in self.branchRoots:
            node.setParent( self.renderTargetSelector )
        self.root = self.offscreenSurfaceSelector
        self.offscreenSurfaceSelector.setExternalRenderTargetSize(size)

    def setOnscreenRendering (self):
        for node in self.branchRoots:
            node.setParent( self.surfaceSelector )
        self.root = self.surfaceSelector


    def dump(self):
        # Framegraph display and testing code
        def frameGraphLeaf(node, prefix=' '):
            print(prefix, node, node.objectName())
            children = node.children()
            for c in children:
                frameGraphLeaf(c, prefix+'-')

        frameGraphLeaf(self.root)