diff options
10 files changed, 90 insertions, 10 deletions
diff --git a/src/Authoring/Studio/Render/StudioRenderer.cpp b/src/Authoring/Studio/Render/StudioRenderer.cpp index 6689f867..928d504b 100644 --- a/src/Authoring/Studio/Render/StudioRenderer.cpp +++ b/src/Authoring/Studio/Render/StudioRenderer.cpp @@ -88,7 +88,8 @@ struct SRendererImpl : public IStudioRenderer, public IReloadListener, public CPresentationChangeListener, public CSceneDragListener, - public CToolbarChangeListener + public CToolbarChangeListener, + public IOffscreenRenderer::IOffscreenRendererCallback { typedef eastl::vector<Option<SEditCameraPersistentInformation>> TEditCameraInfoList; std::shared_ptr<CWGLRenderContext> m_RenderContext; @@ -115,6 +116,7 @@ struct SRendererImpl : public IStudioRenderer, float m_pixelRatio; QHash<QString, StudioSubPresentation> m_subpresentations; QScopedPointer<Q3DSQmlStreamProxy> m_proxy; + QMap<QString, int> m_initialFrameMap; SRendererImpl() : m_Dispatch(*g_StudioApp.GetCore()->GetDispatch()) @@ -201,6 +203,7 @@ struct SRendererImpl : public IStudioRenderer, offscreenMgr.RegisterOffscreenRenderer( qt3ds::render::SOffscreenRendererKey(rid), *theOffscreenRenderer); m_subpresentations[toRegister[i].m_id].renderer = theOffscreenRenderer; + theOffscreenRenderer->addCallback(this); } else { qt3ds::render::IOffscreenRenderer *theOffscreenRenderer = QT3DS_NEW(m_Context->GetAllocator(), @@ -210,9 +213,19 @@ struct SRendererImpl : public IStudioRenderer, offscreenMgr.RegisterOffscreenRenderer( qt3ds::render::SOffscreenRendererKey(rid), *theOffscreenRenderer); m_subpresentations[toRegister[i].m_id].renderer = theOffscreenRenderer; + theOffscreenRenderer->addCallback(this); } m_subpresentations[toRegister[i].m_id].subpresentation = toRegister[i]; } + // Process qml proxy events so that we have initialized the qml producer, + // then get the desired environment to initialize the qml renderer. + QCoreApplication::processEvents(); + for (int i = 0; i < toRegister.size(); ++i) { + QByteArray data = toRegister[i].m_id.toLocal8Bit(); + if (toRegister[i].m_type == QLatin1String("presentation-qml")) + m_subpresentations[toRegister[i].m_id].renderer + ->GetDesiredEnvironment(QT3DSVec2(1.0f, 1.0f)); + } RequestRender(); } @@ -235,7 +248,20 @@ struct SRendererImpl : public IStudioRenderer, = m_Context->GetStringTable().RegisterStr(data.data()); offscreenMgr.ReleaseOffscreenRenderer(qt3ds::render::SOffscreenRendererKey(rid)); } + } + + void onOffscreenRendererInitialized(const QString &id) override + { + // Request render after first frame rendered by the offscreen renderer + m_initialFrameMap[id] = 1; + } + void onOffscreenRendererFrame(const QString &id) override + { + if (m_initialFrameMap.contains(id)) { + RequestRender(); + m_initialFrameMap.remove(id); + } } ITextRenderer *GetTextRenderer() override diff --git a/src/Authoring/Studio/Render/StudioSubPresentationRenderer.cpp b/src/Authoring/Studio/Render/StudioSubPresentationRenderer.cpp index 47e1311b..02383dda 100644 --- a/src/Authoring/Studio/Render/StudioSubPresentationRenderer.cpp +++ b/src/Authoring/Studio/Render/StudioSubPresentationRenderer.cpp @@ -125,6 +125,7 @@ public: m_surfaceViewer->initialize(m_surface.data(), m_context.data(), m_fbo->handle()); #endif m_running = true; + m_semaphore.release(); m_context->doneCurrent(); @@ -185,6 +186,7 @@ StudioSubpresentationRenderer::StudioSubpresentationRenderer( , m_program(nullptr) , m_vao(nullptr) , m_vertices(nullptr) + , m_callback(nullptr) , m_rendererType(inRenderContext.GetStringTable().RegisterStr("StudioPresentationRenderer")) , mRefCount(0) { @@ -211,15 +213,14 @@ StudioSubpresentationRenderer::GetDesiredEnvironment(QT3DSVec2 inPresentationSca { // If we aren't using a clear color, then we are expected to blend with the background if (!m_thread->m_initialized) { - m_thread->initialize(m_presentation, m_path); - m_thread->start(); + initialize(); } bool hasTransparency = true; NVRenderTextureFormats::Enum format = hasTransparency ? NVRenderTextureFormats::RGBA8 : NVRenderTextureFormats::RGB8; return SOffscreenRendererEnvironment( - (QT3DSU32)(m_thread->m_size.width() * inPresentationScaleFactor.x), - (QT3DSU32)(m_thread->m_size.height() * inPresentationScaleFactor.y), + QT3DSU32(m_thread->m_size.width() * inPresentationScaleFactor.x), + QT3DSU32(m_thread->m_size.height() * inPresentationScaleFactor.y), format, OffscreenRendererDepthValues::Depth24, false, AAModeValues::NoAA); } @@ -235,6 +236,15 @@ SOffscreenRenderFlags StudioSubpresentationRenderer::NeedsRender( return SOffscreenRenderFlags(true, true); } +void StudioSubpresentationRenderer::initialize() +{ + m_thread->initialize(m_presentation, m_path); + m_thread->start(); + m_thread->m_semaphore.acquire(); + if (m_callback) + m_callback->onOffscreenRendererInitialized(m_id); +} + void StudioSubpresentationRenderer::Render(const SOffscreenRendererEnvironment &inEnvironment, NVRenderContext &inRenderContext, QT3DSVec2 inPresentationScaleFactor, SScene::RenderClearCommand inColorBufferNeedsClear, @@ -246,8 +256,7 @@ void StudioSubpresentationRenderer::Render(const SOffscreenRendererEnvironment & Q_UNUSED(instanceId) inRenderContext.PushPropertySet(); if (!m_thread->m_initialized) { - m_thread->initialize(m_presentation, m_path); - m_thread->start(); + initialize(); } QMutexLocker lock(&m_thread->m_mutex); if (m_thread->m_initialized && m_thread->m_updated) { @@ -273,9 +282,9 @@ void StudioSubpresentationRenderer::Render(const SOffscreenRendererEnvironment & m_program->enableAttributeArray(0); m_program->enableAttributeArray(1); - func->glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(float), 0); + func->glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(float), nullptr); func->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(float), - (const void *)(4 * sizeof(GLfloat))); + reinterpret_cast<const void *>(4 * sizeof(GLfloat))); m_vertices->release(); } else { m_vao->bind(); @@ -289,6 +298,9 @@ void StudioSubpresentationRenderer::Render(const SOffscreenRendererEnvironment & m_program->release(); m_vao->release(); + + if (m_callback) + m_callback->onOffscreenRendererFrame(m_id); } inRenderContext.PopPropertySet(true); } diff --git a/src/Authoring/Studio/Render/StudioSubPresentationRenderer.h b/src/Authoring/Studio/Render/StudioSubPresentationRenderer.h index 183919f8..8be062e1 100644 --- a/src/Authoring/Studio/Render/StudioSubPresentationRenderer.h +++ b/src/Authoring/Studio/Render/StudioSubPresentationRenderer.h @@ -98,8 +98,14 @@ public: return false; } + void addCallback(IOffscreenRendererCallback *cb) override + { + m_callback = cb; + } + private: void initializeFboCopy(); + void initialize(); qt3ds::render::IQt3DSRenderContext &m_renderContext; QString m_id; @@ -110,7 +116,7 @@ private: QOpenGLShaderProgram *m_program; QOpenGLVertexArrayObject *m_vao; QOpenGLBuffer *m_vertices; - + IOffscreenRendererCallback *m_callback; qt3ds::render::CRegisteredString m_rendererType; volatile qt3ds::render::QT3DSI32 mRefCount; }; diff --git a/src/QtExtras/qmlstreamer/q3dsqmlstreamrenderer.cpp b/src/QtExtras/qmlstreamer/q3dsqmlstreamrenderer.cpp index e93900b5..d50c2d82 100644 --- a/src/QtExtras/qmlstreamer/q3dsqmlstreamrenderer.cpp +++ b/src/QtExtras/qmlstreamer/q3dsqmlstreamrenderer.cpp @@ -449,6 +449,8 @@ void Q3DSQmlStreamRenderer::render() QOpenGLFunctions *func = context->functions(); GLuint texture = m_frameBuffer->texture(); func->glDisable(GL_DEPTH_TEST); + func->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, + GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (!m_program) initializeFboCopy(); diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h index e3a269c9..57dcf430 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOffscreenRenderManager.h @@ -130,9 +130,20 @@ namespace render { class IOffscreenRenderer : public NVRefCounted { + public: + class IOffscreenRendererCallback + { + public: + virtual void onOffscreenRendererInitialized(const QString &id) = 0; + virtual void onOffscreenRendererFrame(const QString &id) = 0; + protected: + virtual ~IOffscreenRendererCallback() {} + }; + protected: virtual ~IOffscreenRenderer() {} public: + virtual void addCallback(IOffscreenRendererCallback *cb) = 0; // Arbitrary const char* returned to indicate the type of this renderer // Can be overloaded to form the basis of an RTTI type system. // Not currently used by the rendering system. diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h index 6d2ba9ea..86f20a78 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSOldNBustedRenderPlugin.h @@ -87,6 +87,10 @@ namespace render { Q_UNUSED(instanceId); return false; } + void addCallback(IOffscreenRendererCallback *cb) override + { + + } // Used for RTTI purposes so we can safely static-cast an offscreen renderer to a // CPluginRenderer static const char *GetRendererName() { return "Plugin"; } diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h index 6a01290d..9eb51450 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderSubpresentation.h @@ -91,6 +91,10 @@ namespace render { { return false; } + void addCallback(IOffscreenRendererCallback *cb) override + { + + } // Used for RTTI purposes so we can safely static-cast an offscreen renderer to a // CSubPresentationRenderer static const char *GetRendererName() { return "SubPresentation"; } diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h index 3fbba777..12d459cf 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Include/q3dsqmlrender.h @@ -81,6 +81,10 @@ public: Q_UNUSED(instanceId) return false; } + void addCallback(IOffscreenRendererCallback *cb) override + { + m_callback = cb; + } static const char *GetRendererName() { return "qml-render"; } private: @@ -90,6 +94,7 @@ private: IQ3DSQmlStreamRenderer *m_qmlStreamRenderer; CRegisteredString m_offscreenRenderType; CRegisteredString m_assetString; + IOffscreenRendererCallback *m_callback; volatile QT3DSI32 mRefCount; }; diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp index 3db8b75e..aca90ce3 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderPlugin.cpp @@ -296,6 +296,10 @@ struct InstanceImpl : public IRenderPluginInstance QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation.getAllocator()) + void addCallback(IOffscreenRendererCallback *cb) override + { + + } void CreateScriptProxy(script_State *state) override { if (m_Class.CreateInstanceScriptProxy) diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp index d825f1d9..8c2683ad 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Source/q3dsqmlrender.cpp @@ -39,6 +39,7 @@ Q3DSQmlRender::Q3DSQmlRender(IQt3DSRenderContext &inRenderContext, const char *a , m_qmlStreamRenderer(nullptr) , m_offscreenRenderType(inRenderContext.GetStringTable().RegisterStr(GetRendererName())) , m_assetString(inRenderContext.GetStringTable().RegisterStr(asset)) + , m_callback(nullptr) , mRefCount(0) { @@ -112,6 +113,9 @@ void Q3DSQmlRender::Render(const SOffscreenRendererEnvironment &inEnvironment, m_qmlStreamRenderer->render(); inRenderContext.PopPropertySet(true); + + if (m_callback) + m_callback->onOffscreenRendererFrame(QString(m_assetString.c_str())); } } @@ -124,6 +128,8 @@ void Q3DSQmlRender::initializeRenderer() QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext(), QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->surface())) { m_qmlStreamRenderer = nullptr; + } else if (m_callback) { + m_callback->onOffscreenRendererInitialized(QString(m_assetString.c_str())); } } } |