[Interest] Qt3D Rendering offscreen

Laszlo Agocs laszlo.agocs at qt.io
Wed Aug 16 07:57:53 CEST 2017


The formats look a bit strange. Try rather Texture.RGBA8_UNorm and Texture.DepthFormat (or maybe Texture.D24) for color and depth, respectively.

The node hierarchy looks somewhat incorrect as well. (where’s the Viewport/Camera/Clear for the custom render target? What is the FilterKey for? (are there multiple renderpasses?) etc.)
There is some QML-based example code in https://github.com/alpqr/q3dpostproc showing rendering into textures (in multiple passes even) and then compositing these on-screen, which may provide some inspiration. Prototyping the framegraph with QML is usually a good idea even when the final target is constructing it from C++ since the latter can quickly become hard to follow, esp. when getting started.

Best regards,
Laszlo


From: Interest [mailto:interest-bounces+laszlo.agocs=qt.io at qt-project.org] On Behalf Of Andy
Sent: onsdag 16. august 2017 07.19
To: Sean Harmer <sean.harmer at kdab.com>
Cc: Qt Project <interest at qt-project.org>
Subject: Re: [Interest] Qt3D Rendering offscreen

Does anybody have any hints? I've tried all kinds of node configurations and can't get this to work.
Thanks.

---
Andy Maloney  //  https://asmaloney.com
twitter ~ @asmaloney<https://twitter.com/asmaloney>


On Sat, Aug 12, 2017 at 2:03 PM, Andy <asmaloney at gmail.com<mailto:asmaloney at gmail.com>> wrote:
Based on your outline, here is the hierarchy I have set up (but I still get images of size (1,1)):

Qt3DRender::QRenderCapture::
    Qt3DExtras::QForwardRenderer::
        Qt3DRender::QRenderSurfaceSelector::
            Qt3DRender::QViewport::
                Qt3DRender::QCameraSelector::
                    Qt3DRender::QClearBuffers::
                        Qt3DRender::QFrustumCulling::
        Qt3DRender::QFilterKey::
        Qt3DRender::QRenderTargetSelector::
            Qt3DRender::QRenderTarget::
                Qt3DRender::QRenderTargetOutput::
                    Qt3DRender::QTexture2D::
                Qt3DRender::QRenderTargetOutput::
                    Qt3DRender::QTexture2D::
Am I attaching things in the right place?

This is how I'm creating it:

   const QSize cTargetSize( 1024, 768 );

   m_forwardRenderer->setExternalRenderTargetSize( cTargetSize );

   Qt3DRender::QTexture2D  *color0Texture = new Qt3DRender::QTexture2D;
   color0Texture->setSize( cTargetSize.width(), cTargetSize.height() );
   color0Texture->setFormat( Qt3DRender::QAbstractTexture::RGBA32F );
   color0Texture->setGenerateMipMaps( false) ;

   Qt3DRender::QTexture2D  *depthTexture = new Qt3DRender::QTexture2D;
   depthTexture->setSize( cTargetSize.width(), cTargetSize.height() );
   depthTexture->setFormat( Qt3DRender::QAbstractTexture::D32F );
   depthTexture->setGenerateMipMaps( false );

   Qt3DRender::QRenderTargetOutput  *colorOutput = new Qt3DRender::QRenderTargetOutput;
   colorOutput->setTexture( color0Texture );
   colorOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Color0 );

   Qt3DRender::QRenderTargetOutput  *depthOutput = new Qt3DRender::QRenderTargetOutput;
   depthOutput->setTexture( depthTexture );
   depthOutput->setAttachmentPoint( Qt3DRender::QRenderTargetOutput::Depth );

   Qt3DRender::QRenderTarget  *renderTarget = new Qt3DRender::QRenderTarget;
   renderTarget->addOutput( colorOutput );
   renderTarget->addOutput( depthOutput );

   Qt3DRender::QRenderTargetSelector   *renderTargetSelector = new Qt3DRender::QRenderTargetSelector( m_forwardRenderer );

   renderTargetSelector->setTarget( renderTarget );

   m_forwardRenderer->setParent( mRenderCapturer );
   m_renderSettings->setActiveFrameGraph( mRenderCapturer );

---
Andy Maloney  //  https://asmaloney.com
twitter ~ @asmaloney<https://twitter.com/asmaloney>


On Sat, Aug 12, 2017 at 8:58 AM, Andy <asmaloney at gmail.com<mailto:asmaloney at gmail.com>> wrote:
On Sat, Aug 12, 2017 at 8:40 AM, Sean Harmer <sean.harmer at kdab.com<mailto:sean.harmer at kdab.com>> wrote:
Hi,

On Friday 11 August 2017 14:34:34 Andy wrote:
> Goal: With Qt3D (C++), render my scene offscreen, use render capture on it,
> and save image to disk.
>
> With my Qt3DWindow-based solution the scene looks fine and I can do the
> render capture part (on macOS anyways - Windows doesn't work for me -
> https://bugreports.qt.io/browse/QTBUG-61223 ).
>
> Now I need to be able to do it offscreen (without the window open).
>
> I thought this was going to be as simple as setting a QOffscreenSurface as
> my forward renderer surface - something like:
>
>    QOffscreenSurface *surface = new QOffscreenSurface;
>
>    surface->create();
>
>    Qt3DExtras::QForwardRenderer  *forwardRenderer = new
> Qt3DExtras::QForwardRenderer;
>
>    forwardRenderer->setSurface( surface );
>    forwardRenderer->setExternalRenderTargetSize( QSize( 800, 600 ) );
>
>    qDebug() << surface->format() << surface->size() << surface->isValid();
>
> While this gives me a valid surface and the format is correct, its size is
> always (1,1) and the render capture gives me images of that size.
>
> How do I set the size of the QOffscreenSurface?

You don't :) An offscreen surface is only good for making a GL context
current. It is not suitable as a render target. If you want to do offscreen

I guess I find that class name confusing then... One draws on a surface, right? :-)

rendering with QOffscreenSurface, you will need to provide your own render
target in the form of a framebuffer object.

You will need to create an FBO by way of a QRenderTarget with a 2D texture of
the desired size attached to the color0 attachment point, and a depth format
texture of the same size attached to the depth attachment point.

So that's a QTexture2D for colo0 and... what for the "depth format texture"? Another QTexture2D?


Select this with a QRenderTargetSelector in a custom framegraph to direct
rendering into the attached textures. You can then do a pixel read back
operation with the QRenderCapure and save the resulting image.

You make it sound so easy!


I suppose this could be wrapped in a convenience that allows the rest of the
framegraph beyond the render target selector and render capture to be set.

+1. If I ever get anything working, I'd be happy to work with someone to get it into shape for Qt3DExtras.

Thanks Sean!


Cheers,

Sean

>
> Or am I going about this the wrong way?
>
> (It would be nice to have a class like the Qt3DWindow one specifically for
> offscreen rendering.)
>
> ---
> Andy Maloney  //  https://asmaloney.com
> twitter ~ @asmaloney <https://twitter.com/asmaloney>

--
Dr Sean Harmer | sean.harmer at kdab.com<mailto:sean.harmer at kdab.com> | Managing Director UK
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel. UK +44 (0)1625 809908<tel:%2B44%20%280%291625%20809908>, Sweden (HQ) +46-563-540090<tel:%2B46-563-540090>
KDAB - Qt Experts - Platform-independent software solutions

---
Andy Maloney  //  https://asmaloney.com
twitter ~ @asmaloney<https://twitter.com/asmaloney>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20170816/9d1d723b/attachment.html>


More information about the Interest mailing list