diff options
Diffstat (limited to 'src/render')
200 files changed, 613 insertions, 25364 deletions
diff --git a/src/render/backend/apishadermanager_p.h b/src/render/backend/apishadermanager_p.h index ec17b2196..9ebf49710 100644 --- a/src/render/backend/apishadermanager_p.h +++ b/src/render/backend/apishadermanager_p.h @@ -169,7 +169,7 @@ public: return std::move(m_updatedShaders); } - QVector<Qt3DCore::QNodeId> shaderIdsForProgram(GLShader *glShader) const + QVector<Qt3DCore::QNodeId> shaderIdsForProgram(APIShader *glShader) const { QReadLocker lock(&m_readWriteLock); return m_apiShaders.value(glShader); diff --git a/src/render/backend/attachmentpack_p.h b/src/render/backend/attachmentpack_p.h index a3a2586dd..32ea774b6 100644 --- a/src/render/backend/attachmentpack_p.h +++ b/src/render/backend/attachmentpack_p.h @@ -52,6 +52,7 @@ // #include <Qt3DRender/qrendertargetoutput.h> +#include <Qt3DRender/private/qt3drender_global_p.h> #include <QVector> QT_BEGIN_NAMESPACE @@ -59,7 +60,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -struct Attachment +struct Q_3DRENDERSHARED_PRIVATE_EXPORT Attachment { Attachment() : m_mipLevel(0) @@ -80,7 +81,7 @@ class RenderTarget; class RenderTargetSelector; class AttachmentManager; -class AttachmentPack +class Q_3DRENDERSHARED_PRIVATE_EXPORT AttachmentPack { public: AttachmentPack(); diff --git a/src/render/backend/backendnode.cpp b/src/render/backend/backendnode.cpp index f85ece1b9..18e7af256 100644 --- a/src/render/backend/backendnode.cpp +++ b/src/render/backend/backendnode.cpp @@ -38,10 +38,11 @@ ****************************************************************************/ #include <private/backendnode_p.h> -#include <private/renderer_p.h> +#include <private/abstractrenderer_p.h> #include <private/resourceaccessor_p.h> #include <private/nodemanagers_p.h> #include <Qt3DCore/private/qbackendnode_p.h> +#include <Qt3DCore/qnode.h> QT_BEGIN_NAMESPACE diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp index e1d72efda..ab74e8b56 100644 --- a/src/render/backend/cameralens.cpp +++ b/src/render/backend/cameralens.cpp @@ -39,10 +39,11 @@ #include "cameralens_p.h" #include <Qt3DRender/qcameralens.h> +#include <Qt3DRender/qrenderaspect.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/private/entity_p.h> #include <Qt3DRender/private/sphere_p.h> #include <Qt3DRender/private/computefilteredboundingvolumejob_p.h> diff --git a/src/render/backend/commandexecuter.cpp b/src/render/backend/commandexecuter.cpp deleted file mode 100644 index 8e45fb924..000000000 --- a/src/render/backend/commandexecuter.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com> -** Contact: http://www.qt-project.org/legal -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "commandexecuter_p.h" - -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DCore/private/qabstractaspect_p.h> -#include <Qt3DCore/qbackendnode.h> -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/renderview_p.h> -#include <Qt3DRender/private/rendercommand_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/geometryrenderermanager_p.h> -#include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DRender/private/submissioncontext_p.h> -#include <QJsonObject> -#include <QJsonDocument> -#include <QJsonArray> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Debug { - -namespace { - -template<typename Type> -QJsonObject typeToJsonObj(const Type &) -{ - return QJsonObject(); -} - -template<typename Type> -QJsonValue typeToJsonValue(const Type &t) -{ - Q_UNUSED(t); - return QJsonValue(); -} - -template<> -QJsonObject typeToJsonObj<QRectF>(const QRectF &rect) -{ - QJsonObject obj; - - obj.insert(QLatin1String("x"), rect.x()); - obj.insert(QLatin1String("y"), rect.y()); - obj.insert(QLatin1String("width"), rect.width()); - obj.insert(QLatin1String("height"), rect.height()); - - return obj; -} - -template<> -QJsonValue typeToJsonValue<QRectF>(const QRectF &rect) -{ - QJsonArray value; - - value.push_back(rect.x()); - value.push_back(rect.y()); - value.push_back(rect.width()); - value.push_back(rect.height()); - - return value; -} - -template<> -QJsonObject typeToJsonObj<QSize>(const QSize &s) -{ - QJsonObject obj; - - obj.insert(QLatin1String("width"), s.width()); - obj.insert(QLatin1String("height"), s.height()); - - return obj; -} - -template<> -QJsonValue typeToJsonValue<QSize>(const QSize &s) -{ - QJsonArray value; - - value.push_back(s.width()); - value.push_back(s.height()); - - return value; -} - -template<> -QJsonObject typeToJsonObj<QVector3D>(const QVector3D &v) -{ - QJsonObject obj; - - obj.insert(QLatin1String("x"), v.x()); - obj.insert(QLatin1String("y"), v.y()); - obj.insert(QLatin1String("z"), v.z()); - - return obj; -} - -template<> -QJsonValue typeToJsonValue<QVector3D>(const QVector3D &v) -{ - QJsonArray value; - - value.push_back(v.x()); - value.push_back(v.y()); - value.push_back(v.z()); - - return value; -} - -template<> -QJsonObject typeToJsonObj<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v) -{ - QJsonObject obj; - obj.insert(QLatin1String("id"), qint64(v.id())); - return obj; -} - -template<> -QJsonValue typeToJsonValue<Qt3DCore::QNodeId>(const Qt3DCore::QNodeId &v) -{ - QJsonValue value(qint64(v.id())); - return value; -} - -template<> -QJsonObject typeToJsonObj<QVector4D>(const QVector4D &v) -{ - QJsonObject obj; - - obj.insert(QLatin1String("x"), v.x()); - obj.insert(QLatin1String("y"), v.y()); - obj.insert(QLatin1String("z"), v.z()); - obj.insert(QLatin1String("w"), v.w()); - - return obj; -} - -template<> -QJsonValue typeToJsonValue<QVector4D>(const QVector4D &v) -{ - QJsonArray value; - - value.push_back(v.x()); - value.push_back(v.y()); - value.push_back(v.z()); - value.push_back(v.w()); - - return value; -} - -template<> -QJsonObject typeToJsonObj<QMatrix4x4>(const QMatrix4x4 &v) -{ - QJsonObject obj; - - obj.insert(QLatin1String("row 0"), typeToJsonObj(v.row(0))); - obj.insert(QLatin1String("row 1"), typeToJsonObj(v.row(0))); - obj.insert(QLatin1String("row 2"), typeToJsonObj(v.row(0))); - obj.insert(QLatin1String("row 3"), typeToJsonObj(v.row(0))); - - return obj; -} - -template<> -QJsonValue typeToJsonValue<QMatrix4x4>(const QMatrix4x4 &v) -{ - QJsonArray value; - - value.push_back(typeToJsonValue(v.row(0))); - value.push_back(typeToJsonValue(v.row(1))); - value.push_back(typeToJsonValue(v.row(2))); - value.push_back(typeToJsonValue(v.row(3))); - - return value; -} - -template<> -QJsonValue typeToJsonValue<QVariant>(const QVariant &v) -{ - const int nodeTypeId = qMetaTypeId<Qt3DCore::QNodeId>(); - - if (v.userType() == nodeTypeId) - return typeToJsonValue(v.value<Qt3DCore::QNodeId>()); - - switch (v.userType()) { - case QMetaType::QVector3D: - return typeToJsonValue(v.value<QVector3D>()); - case QMetaType::QVector4D: - return typeToJsonValue(v.value<QVector4D>()); - case QMetaType::QMatrix4x4: - return typeToJsonValue(v.value<QMatrix4x4>()); - default: - return QJsonValue::fromVariant(v); - } -} - -template<typename Handle, typename Manager> -QJsonObject backendNodeToJSon(Handle handle, Manager *manager) -{ - Qt3DCore::QBackendNode *node = manager->data(handle); - QJsonObject obj; - Qt3DCore::QNodeId id; - if (node != nullptr) - id = node->peerId(); - obj.insert(QLatin1String("id"), qint64(id.id())); - return obj; -} - -QJsonObject parameterPackToJson(const Render::ShaderParameterPack &pack) -{ - QJsonObject obj; - - const Render::PackUniformHash &uniforms = pack.uniforms(); - QJsonArray uniformsArray; - for (int i = 0, m = uniforms.keys.size(); i < m; ++i) { - QJsonObject uniformObj; - uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(uniforms.keys.at(i))); - const Render::UniformValue::ValueType type = uniforms.values.at(i).valueType(); - uniformObj.insert(QLatin1String("type"), - type == Render::UniformValue::ScalarValue - ? QLatin1String("value") - : QLatin1String("texture")); - uniformsArray.push_back(uniformObj); - } - obj.insert(QLatin1String("uniforms"), uniformsArray); - - QJsonArray texturesArray; - const QVector<Render::ShaderParameterPack::NamedResource> &textures = pack.textures(); - for (const auto & texture : textures) { - QJsonObject textureObj; - textureObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(texture.glslNameId)); - textureObj.insert(QLatin1String("id"), qint64(texture.nodeId.id())); - texturesArray.push_back(textureObj); - } - obj.insert(QLatin1String("textures"), texturesArray); - - const QVector<Render::BlockToUBO> &ubos = pack.uniformBuffers(); - QJsonArray ubosArray; - for (const auto &ubo : ubos) { - QJsonObject uboObj; - uboObj.insert(QLatin1String("index"), ubo.m_blockIndex); - uboObj.insert(QLatin1String("bufferId"), qint64(ubo.m_bufferID.id())); - ubosArray.push_back(uboObj); - - } - obj.insert(QLatin1String("ubos"), ubosArray); - - const QVector<Render::BlockToSSBO> &ssbos = pack.shaderStorageBuffers(); - QJsonArray ssbosArray; - for (const auto &ssbo : ssbos) { - QJsonObject ssboObj; - ssboObj.insert(QLatin1String("index"), ssbo.m_blockIndex); - ssboObj.insert(QLatin1String("bufferId"), qint64(ssbo.m_bufferID.id())); - ssbosArray.push_back(ssboObj); - } - obj.insert(QLatin1String("ssbos"), ssbosArray); - - return obj; -} - -} // anonymous - -CommandExecuter::CommandExecuter(Render::Renderer *renderer) - : m_renderer(renderer) -{ -} - -// Render thread -void CommandExecuter::performAsynchronousCommandExecution(const QVector<Render::RenderView *> &views) -{ - QMutexLocker lock(&m_pendingCommandsMutex); - const QVector<Qt3DCore::Debug::AsynchronousCommandReply *> shellCommands = std::move(m_pendingCommands); - lock.unlock(); - - for (auto *reply : shellCommands) { - if (reply->commandName() == QLatin1String("glinfo")) { - QJsonObject replyObj; - const GraphicsApiFilterData *contextInfo = m_renderer->submissionContext()->contextInfo(); - if (contextInfo != nullptr) { - replyObj.insert(QLatin1String("api"), - contextInfo->m_api == QGraphicsApiFilter::OpenGL - ? QLatin1String("OpenGL") - : QLatin1String("OpenGLES")); - const QString versionString = - QString::number(contextInfo->m_major) - + QStringLiteral(".") - + QString::number(contextInfo->m_minor); - replyObj.insert(QLatin1String("version"), versionString); - replyObj.insert(QLatin1String("profile"), - contextInfo->m_profile == QGraphicsApiFilter::CoreProfile - ? QLatin1String("Core") - : contextInfo->m_profile == QGraphicsApiFilter::CompatibilityProfile - ? QLatin1String("Compatibility") - : QLatin1String("None")); - } - reply->setData(QJsonDocument(replyObj).toJson()); - } else if (reply->commandName() == QLatin1String("rendercommands")) { - QJsonObject replyObj; - - QJsonArray viewArray; - for (Render::RenderView *v : views) { - QJsonObject viewObj; - viewObj.insert(QLatin1String("viewport"), typeToJsonValue(v->viewport())); - viewObj.insert(QLatin1String("surfaceSize"), typeToJsonValue(v->surfaceSize())); - viewObj.insert(QLatin1String("devicePixelRatio"), v->devicePixelRatio()); - viewObj.insert(QLatin1String("noDraw"), v->noDraw()); - viewObj.insert(QLatin1String("frustumCulling"), v->frustumCulling()); - viewObj.insert(QLatin1String("compute"), v->isCompute()); - viewObj.insert(QLatin1String("clearDepthValue"), v->clearDepthValue()); - viewObj.insert(QLatin1String("clearStencilValue"), v->clearStencilValue()); - - QJsonArray renderCommandsArray; - for (const Render::RenderCommand &c : v->commands()) { - QJsonObject commandObj; - Render::NodeManagers *nodeManagers = m_renderer->nodeManagers(); - commandObj.insert(QLatin1String("shader"), int(c.m_shaderId.id())); - commandObj.insert(QLatin1String("vao"), double(c.m_vao.handle())); - commandObj.insert(QLatin1String("instanceCount"), c.m_instanceCount); - commandObj.insert(QLatin1String("geometry"), backendNodeToJSon(c.m_geometry, nodeManagers->geometryManager())); - commandObj.insert(QLatin1String("geometryRenderer"), backendNodeToJSon(c.m_geometryRenderer, nodeManagers->geometryRendererManager())); - commandObj.insert(QLatin1String("shaderParameterPack"), parameterPackToJson(c.m_parameterPack)); - - renderCommandsArray.push_back(commandObj); - } - viewObj.insert(QLatin1String("commands"), renderCommandsArray); - viewArray.push_back(viewObj); - } - - replyObj.insert(QLatin1String("renderViews"), viewArray); - reply->setData(QJsonDocument(replyObj).toJson()); - } - reply->setFinished(true); - } -} - -// Main thread -QVariant CommandExecuter::executeCommand(const QStringList &args) -{ - // Note: The replies will be deleted by the AspectCommandDebugger - if (args.length() > 0 && - (args.first() == QLatin1String("glinfo") || - args.first() == QLatin1String("rendercommands"))) { - auto reply = new Qt3DCore::Debug::AsynchronousCommandReply(args.first()); - QMutexLocker lock(&m_pendingCommandsMutex); - m_pendingCommands.push_back(reply); - return QVariant::fromValue(reply); - } - return QVariant(); -} - -} // Debug - -} // Qt3DRenderer - -QT_END_NAMESPACE diff --git a/src/render/backend/commandexecuter_p.h b/src/render/backend/commandexecuter_p.h deleted file mode 100644 index 2d90bf4d6..000000000 --- a/src/render/backend/commandexecuter_p.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire <paul.lemire350@gmail.com> -** Contact: http://www.qt-project.org/legal -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_DEBUG_COMMANDEXECUTER_H -#define QT3DRENDER_DEBUG_COMMANDEXECUTER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QVector> -#include <QVariant> -#include <QMutex> - -QT_BEGIN_NAMESPACE - -namespace Qt3DCore { - -namespace Debug { -class AsynchronousCommandReply; -} // Debug - -} // Qt3DCore - -namespace Qt3DRender { - -namespace Render { -class Renderer; -class RenderView; -} // Render - -namespace Debug { - -class CommandExecuter -{ -public: - explicit CommandExecuter(Render::Renderer *renderer); - - void performAsynchronousCommandExecution(const QVector<Render::RenderView *> &views); - - QVariant executeCommand(const QStringList &args); - -private: - Render::Renderer *m_renderer; - QVector<Qt3DCore::Debug::AsynchronousCommandReply *> m_pendingCommands; - QMutex m_pendingCommandsMutex; -}; - -} // Debug - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_DEBUG_COMMANDEXECUTER_H diff --git a/src/render/backend/computecommand_p.h b/src/render/backend/computecommand_p.h index 5012930ae..00e238474 100644 --- a/src/render/backend/computecommand_p.h +++ b/src/render/backend/computecommand_p.h @@ -62,7 +62,7 @@ namespace Render { class ComputeJobPrivate; -class Q_AUTOTEST_EXPORT ComputeCommand : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT ComputeCommand : public BackendNode { public: ComputeCommand(); diff --git a/src/render/backend/entity_p.h b/src/render/backend/entity_p.h index d13d96784..8ac10454e 100644 --- a/src/render/backend/entity_p.h +++ b/src/render/backend/entity_p.h @@ -53,7 +53,7 @@ // #include <Qt3DRender/private/backendnode_p.h> -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DCore/qnodecreatedchange.h> #include <Qt3DCore/private/qentity_p.h> @@ -81,7 +81,7 @@ class Renderer; class NodeManagers; class EntityPrivate; -class Q_AUTOTEST_EXPORT Entity : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Entity : public BackendNode { public: Entity(); diff --git a/src/render/backend/levelofdetail_p.h b/src/render/backend/levelofdetail_p.h index 8399e19b7..b559b3114 100644 --- a/src/render/backend/levelofdetail_p.h +++ b/src/render/backend/levelofdetail_p.h @@ -67,7 +67,7 @@ namespace Render { class LevelOfDetailManager; -class Q_AUTOTEST_EXPORT LevelOfDetail : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT LevelOfDetail : public BackendNode { public: LevelOfDetail(); diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h index 24b161b6e..db12a8a7b 100644 --- a/src/render/backend/managers_p.h +++ b/src/render/backend/managers_p.h @@ -91,7 +91,7 @@ namespace Qt3DRender { namespace Render { -class AttachmentManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT AttachmentManager : public Qt3DCore::QResourceManager< RenderTargetOutput, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -100,7 +100,7 @@ public: AttachmentManager() {} }; -class CameraManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT CameraManager : public Qt3DCore::QResourceManager< CameraLens, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -109,7 +109,7 @@ public: CameraManager() {} }; -class FilterKeyManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT FilterKeyManager : public Qt3DCore::QResourceManager< FilterKey, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -119,7 +119,7 @@ public: FilterKeyManager() {} }; -class EffectManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT EffectManager : public Qt3DCore::QResourceManager< Effect, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -128,7 +128,7 @@ public: EffectManager() {} }; -class Q_AUTOTEST_EXPORT EntityManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT EntityManager : public Qt3DCore::QResourceManager< Entity, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -146,7 +146,7 @@ public: class FrameGraphNode; -class Q_AUTOTEST_EXPORT FrameGraphManager +class Q_3DRENDERSHARED_PRIVATE_EXPORT FrameGraphManager { public: FrameGraphManager() {} @@ -161,7 +161,7 @@ private: QHash<Qt3DCore::QNodeId, FrameGraphNode*> m_nodes; }; -class LayerManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT LayerManager : public Qt3DCore::QResourceManager< Layer, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -170,7 +170,7 @@ public: LayerManager() {} }; -class LevelOfDetailManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT LevelOfDetailManager : public Qt3DCore::QResourceManager< LevelOfDetail, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -179,7 +179,7 @@ public: LevelOfDetailManager() {} }; -class MaterialManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT MaterialManager : public Qt3DCore::QResourceManager< Material, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -188,7 +188,7 @@ public: MaterialManager() {} }; -class MatrixManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT MatrixManager : public Qt3DCore::QResourceManager< Matrix4x4, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -197,7 +197,7 @@ public: MatrixManager() {} }; -class ShaderManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ShaderManager : public Qt3DCore::QResourceManager< Shader, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -221,7 +221,7 @@ private: QVector<Qt3DCore::QNodeId> m_shaderIdsToCleanup; }; -class ShaderBuilderManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ShaderBuilderManager : public Qt3DCore::QResourceManager< ShaderBuilder, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -230,7 +230,7 @@ public: ShaderBuilderManager() {} }; -class TextureManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT TextureManager : public Qt3DCore::QResourceManager< Texture, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -269,7 +269,7 @@ private: QVector<Qt3DCore::QNodeId> m_textureIdsToCleanup; }; -class TransformManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT TransformManager : public Qt3DCore::QResourceManager< Transform, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -278,7 +278,7 @@ public: TransformManager() {} }; -class RenderTargetManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderTargetManager : public Qt3DCore::QResourceManager< RenderTarget, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -287,7 +287,7 @@ public: RenderTargetManager() {} }; -class RenderPassManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderPassManager : public Qt3DCore::QResourceManager< RenderPass, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -297,7 +297,7 @@ public: }; -class ParameterManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ParameterManager : public Qt3DCore::QResourceManager< Parameter, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -306,7 +306,7 @@ public: ParameterManager() {} }; -class ShaderImageManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ShaderImageManager : public Qt3DCore::QResourceManager< ShaderImage, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -315,7 +315,7 @@ public: ShaderImageManager() {} }; -class ShaderDataManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ShaderDataManager : public Qt3DCore::QResourceManager< ShaderData, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -324,35 +324,35 @@ public: ShaderDataManager() {} }; -class TextureImageManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT TextureImageManager : public Qt3DCore::QResourceManager< TextureImage, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> { }; -class AttributeManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT AttributeManager : public Qt3DCore::QResourceManager< Attribute, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> { }; -class GeometryManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT GeometryManager : public Qt3DCore::QResourceManager< Geometry, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> { }; -class ObjectPickerManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ObjectPickerManager : public Qt3DCore::QResourceManager< ObjectPicker, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> { }; -class RayCasterManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT RayCasterManager : public Qt3DCore::QResourceManager< RayCaster, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -368,7 +368,7 @@ class BoundingVolumeDebugManager : public Qt3DCore::QResourceManager< }; #endif -class LightManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT LightManager : public Qt3DCore::QResourceManager< Light, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -377,7 +377,7 @@ public: LightManager() {} }; -class EnvironmentLightManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT EnvironmentLightManager : public Qt3DCore::QResourceManager< EnvironmentLight, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -386,7 +386,7 @@ public: EnvironmentLightManager() {} }; -class ComputeCommandManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ComputeCommandManager : public Qt3DCore::QResourceManager< ComputeCommand, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -395,21 +395,21 @@ public: ComputeCommandManager() {} }; -class RenderStateManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderStateManager : public Qt3DCore::QResourceManager< RenderStateNode, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> { }; -class ArmatureManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT ArmatureManager : public Qt3DCore::QResourceManager< Armature, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> { }; -class SkeletonManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT SkeletonManager : public Qt3DCore::QResourceManager< Skeleton, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> @@ -428,7 +428,7 @@ private: QVector<HSkeleton> m_dirtyTransformSkeletons; }; -class JointManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT JointManager : public Qt3DCore::QResourceManager< Joint, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> diff --git a/src/render/backend/offscreensurfacehelper_p.h b/src/render/backend/offscreensurfacehelper_p.h index 8dc86d9a4..6ec82db2f 100644 --- a/src/render/backend/offscreensurfacehelper_p.h +++ b/src/render/backend/offscreensurfacehelper_p.h @@ -52,6 +52,7 @@ // #include <QObject> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -62,7 +63,7 @@ namespace Render { class AbstractRenderer; -class Q_AUTOTEST_EXPORT OffscreenSurfaceHelper : public QObject +class Q_3DRENDERSHARED_PRIVATE_EXPORT OffscreenSurfaceHelper : public QObject { Q_OBJECT public: diff --git a/src/render/backend/platformsurfacefilter.cpp b/src/render/backend/platformsurfacefilter.cpp index 891e30c44..115fb637f 100644 --- a/src/render/backend/platformsurfacefilter.cpp +++ b/src/render/backend/platformsurfacefilter.cpp @@ -39,7 +39,7 @@ #include "platformsurfacefilter_p.h" -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <QMetaObject> #include <QPlatformSurfaceEvent> diff --git a/src/render/backend/platformsurfacefilter_p.h b/src/render/backend/platformsurfacefilter_p.h index 4fb43bae1..0bb425989 100644 --- a/src/render/backend/platformsurfacefilter_p.h +++ b/src/render/backend/platformsurfacefilter_p.h @@ -67,7 +67,7 @@ namespace Render { class AbstractRenderer; -class PlatformSurfaceFilter : public QObject +class Q_3DRENDERSHARED_PRIVATE_EXPORT PlatformSurfaceFilter : public QObject { Q_OBJECT diff --git a/src/render/backend/qgraphicsutils_p.h b/src/render/backend/qgraphicsutils_p.h deleted file mode 100644 index 40ff99f0e..000000000 --- a/src/render/backend/qgraphicsutils_p.h +++ /dev/null @@ -1,410 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_QGRAPHICSUTILS_P_H -#define QT3DRENDER_RENDER_QGRAPHICSUTILS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qt3drender_global.h> -#include <Qt3DRender/private/shadervariables_p.h> -#include <QMatrix2x2> -#include <QMatrix3x3> -#include <QMatrix4x4> -#include <QGenericMatrix> -#include <QVector2D> -#include <QVarLengthArray> -#include <QColor> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace { - -const int QMatrix2x2Type = qMetaTypeId<QMatrix2x2>(); -const int QMatrix2x3Type = qMetaTypeId<QMatrix2x3>(); -const int QMatrix2x4Type = qMetaTypeId<QMatrix2x4>(); -const int QMatrix3x2Type = qMetaTypeId<QMatrix3x2>(); -const int QMatrix3x3Type = qMetaTypeId<QMatrix3x3>(); -const int QMatrix3x4Type = qMetaTypeId<QMatrix3x4>(); -const int QMatrix4x2Type = qMetaTypeId<QMatrix4x2>(); -const int QMatrix4x3Type = qMetaTypeId<QMatrix4x3>(); - -} - -class QGraphicsUtils -{ - -public: - - template<typename T> - static const char *bytesFromVariant(const QVariant &v) - { - uint byteSize = sizeof(T); - // Max 16 float that we may want as doubles - // 64 should be best for most cases - static QVarLengthArray<char, 64> array(16 * byteSize); - memset(array.data(), 0, array.size()); - - switch (static_cast<QMetaType::Type>(v.type())) { - - // 1 byte - case QMetaType::Bool: { - T data = v.value<bool>(); - memcpy(array.data(), &data, byteSize); - break; - } - case QMetaType::Char: { - T data = v.value<char>(); - memcpy(array.data(), &data, byteSize); - break; - } - - // 4 bytes - case QMetaType::Float: { - T data = v.value<float>(); - memcpy(array.data(), &data, byteSize); - break; - } - case QMetaType::Int: { - T data = v.value<int>(); - memcpy(array.data(), &data, byteSize); - break; - - } - case QMetaType::UInt: { - qDebug() << "UINT"; - T data = v.value<uint>(); - memcpy(array.data(), &data, byteSize); - break; - } - - // 8 bytes - case QMetaType::Double: { - T data = v.value<double>(); - memcpy(array.data(), &data, byteSize); - break; - } - - // 2 floats - case QMetaType::QPointF: { - QPointF vv = v.value<QPointF>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - break; - } - case QMetaType::QSizeF: { - QSizeF vv = v.value<QSizeF>(); - T data = vv.width(); - memcpy(array.data(), &data, byteSize); - data = vv.height(); - memcpy(array.data() + byteSize, &data, byteSize); - break; - } - - case QMetaType::QVector2D: { - QVector2D vv = v.value<QVector2D>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - break; - } - - // 2 ints - case QMetaType::QPoint: { - QPointF vv = v.value<QPoint>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - break; - } - - case QMetaType::QSize: { - QSize vv = v.value<QSize>(); - T data = vv.width(); - memcpy(array.data(), &data, byteSize); - data = vv.height(); - memcpy(array.data() + byteSize, &data, byteSize); - break; - } - - // 3 floats - case QMetaType::QVector3D: { - QVector3D vv = v.value<QVector3D>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - data = vv.z(); - memcpy(array.data() + 2 * byteSize, &data, byteSize); - break; - } - - // 4 floats - case QMetaType::QVector4D: { - QVector4D vv = v.value<QVector4D>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - data = vv.z(); - memcpy(array.data() + 2 * byteSize, &data, byteSize); - data = vv.w(); - memcpy(array.data() + 3 * byteSize, &data, byteSize); - break; - } - - case QMetaType::QQuaternion: { - - break; - } - - case QMetaType::QRectF: { - QRectF vv = v.value<QRectF>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - data = vv.width(); - memcpy(array.data() + 2 * byteSize, &data, byteSize); - data = vv.height(); - memcpy(array.data() + 3 * byteSize, &data, byteSize); - break; - } - - case QMetaType::QColor: { - QColor vv = v.value<QColor>(); - T data = vv.redF(); - memcpy(array.data(), &data, byteSize); - data = vv.greenF(); - memcpy(array.data() + byteSize, &data, byteSize); - data = vv.blueF(); - memcpy(array.data() + 2 * byteSize, &data, byteSize); - data = vv.alphaF(); - memcpy(array.data() + 3 * byteSize, &data, byteSize); - break; - } - - // 4 ints - case QMetaType::QRect: { - QRectF vv = v.value<QRect>(); - T data = vv.x(); - memcpy(array.data(), &data, byteSize); - data = vv.y(); - memcpy(array.data() + byteSize, &data, byteSize); - data = vv.width(); - memcpy(array.data() + 2 * byteSize, &data, byteSize); - data = vv.height(); - memcpy(array.data() + 3 * byteSize, &data, byteSize); - break; - } - - // 16 floats - case QMetaType::QMatrix4x4: { - QMatrix4x4 mat = v.value<QMatrix4x4>(); - float *data = mat.data(); - for (int i = 0; i < 16; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - break; - } - - default: { - - float *data = nullptr; - if (v.userType() == QMatrix3x3Type) { - QMatrix3x3 mat = v.value<QMatrix3x3>(); - data = mat.data(); - for (int i = 0; i < 9; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix2x2Type) { - QMatrix2x2 mat = v.value<QMatrix2x2>(); - data = mat.data(); - for (int i = 0; i < 4; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix2x3Type) { - QMatrix2x3 mat = v.value<QMatrix2x3>(); - data = mat.data(); - for (int i = 0; i < 6; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix3x2Type) { - QMatrix3x2 mat = v.value<QMatrix3x2>(); - data = mat.data(); - for (int i = 0; i < 6; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix2x4Type) { - QMatrix2x4 mat = v.value<QMatrix2x4>(); - data = mat.data(); - for (int i = 0; i < 8; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix4x2Type) { - QMatrix4x2 mat = v.value<QMatrix4x2>(); - data = mat.data(); - for (int i = 0; i < 8; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix3x4Type) { - QMatrix3x4 mat = v.value<QMatrix3x4>(); - data = mat.data(); - for (int i = 0; i < 12; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else if (v.userType() == QMatrix4x3Type) { - QMatrix4x3 mat = v.value<QMatrix4x3>(); - data = mat.data(); - for (int i = 0; i < 12; i++) { - T d = data[i]; - memcpy(array.data() + i * byteSize, &d, byteSize); - } - } - else - qWarning() << Q_FUNC_INFO << "QVariant type conversion not handled for " << v.type(); - break; - } - - } - return array.constData(); - } - - - template<typename T> - static const T *valueArrayFromVariant(const QVariant &v, int count, int tupleSize) - { - uint byteSize = sizeof(T); - uint offset = byteSize * tupleSize; - static QVarLengthArray<char, 1024> uniformValuesArray(1024); - uniformValuesArray.resize(count * offset); - char *data = uniformValuesArray.data(); - memset(data, 0, uniformValuesArray.size()); - - QVariantList vList = v.toList(); - // Handles list of QVariant: usually arrays of float - if (!vList.isEmpty()) { - for (int i = 0; i < vList.length() && uint(i) * offset < uint(uniformValuesArray.size()); i++) { - const char *subBuffer = QGraphicsUtils::bytesFromVariant<T>(vList.at(i)); - memcpy(data + i * offset, subBuffer, offset); - } - } - else { - memcpy(data, QGraphicsUtils::bytesFromVariant<T>(v), offset); - } - return reinterpret_cast<const T *>(uniformValuesArray.constData()); - } - - template<typename T> - static void fillDataArray(void *buffer, const T *data, const ShaderUniform &description, int tupleSize) - { - uint offset = description.m_offset / sizeof(T); - uint stride = description.m_arrayStride / sizeof(T); - T *bufferData = (T*)buffer; - - for (int i = 0; i < description.m_size; ++i) { - for (int j = 0; j < tupleSize; j++) { - int idx = i * tupleSize + j; - bufferData[offset + j] = data[idx]; - } - offset += stride; - } - } - - template<typename T> - static void fillDataMatrixArray(void *buffer, const T *data, const ShaderUniform &description, int cols, int rows) - { - uint offset = description.m_offset / sizeof(T); - uint arrayStride = description.m_arrayStride / sizeof(T); - uint matrixStride = description.m_matrixStride / sizeof(T); - T *bufferData = (T*)buffer; - - for (int i = 0; i < description.m_size; ++i) { - for (int col = 0; col < cols; ++col) { - for (int row = 0; row < rows; ++row) { - int idx = i * cols * rows + rows * col + row; - bufferData[offset + row] = data[idx]; - } - offset += matrixStride; - } - offset += arrayStride; - } - } - -}; - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_QGRAPHICSUTILS_P_H diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri index 87083312f..2815ee0ab 100644 --- a/src/render/backend/render-backend.pri +++ b/src/render/backend/render-backend.pri @@ -5,7 +5,6 @@ HEADERS += \ $$PWD/parameterpack_p.h \ $$PWD/rendertarget_p.h \ $$PWD/attachmentpack_p.h \ - $$PWD/qgraphicsutils_p.h \ $$PWD/managers_p.h \ $$PWD/handle_types_p.h \ $$PWD/platformsurfacefilter_p.h \ @@ -38,7 +37,6 @@ HEADERS += \ $$PWD/visitorutils_p.h \ $$PWD/segmentsvisitor_p.h \ $$PWD/pointsvisitor_p.h \ - $$PWD/commandexecuter_p.h \ $$PWD/apishadermanager_p.h SOURCES += \ @@ -69,5 +67,4 @@ SOURCES += \ $$PWD/offscreensurfacehelper.cpp \ $$PWD/resourceaccessor.cpp \ $$PWD/segmentsvisitor.cpp \ - $$PWD/pointsvisitor.cpp \ - $$PWD/commandexecuter.cpp + $$PWD/pointsvisitor.cpp diff --git a/src/render/backend/rendersettings_p.h b/src/render/backend/rendersettings_p.h index 317fca957..af1ee58ec 100644 --- a/src/render/backend/rendersettings_p.h +++ b/src/render/backend/rendersettings_p.h @@ -62,7 +62,7 @@ namespace Render { class AbstractRenderer; -class Q_AUTOTEST_EXPORT RenderSettings : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderSettings : public BackendNode { public: RenderSettings(); diff --git a/src/render/backend/rendertarget_p.h b/src/render/backend/rendertarget_p.h index 30769dcfc..eeaf94940 100644 --- a/src/render/backend/rendertarget_p.h +++ b/src/render/backend/rendertarget_p.h @@ -65,7 +65,7 @@ namespace Render { class RenderTargetManager; -class Q_AUTOTEST_EXPORT RenderTarget : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderTarget : public BackendNode { public: RenderTarget(); diff --git a/src/render/backend/rendertargetoutput_p.h b/src/render/backend/rendertargetoutput_p.h index d72f6d231..3a8828eeb 100644 --- a/src/render/backend/rendertargetoutput_p.h +++ b/src/render/backend/rendertargetoutput_p.h @@ -65,7 +65,7 @@ namespace Render { class AttachmentManager; -class RenderTargetOutput : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderTargetOutput : public BackendNode { public: RenderTargetOutput(); diff --git a/src/render/backend/renderthread_p.h b/src/render/backend/renderthread_p.h index 56a7ec3bc..cdbb4f8c5 100644 --- a/src/render/backend/renderthread_p.h +++ b/src/render/backend/renderthread_p.h @@ -52,7 +52,7 @@ // #include <QThread> - +#include <Qt3DRender/private/qt3drender_global_p.h> #include <QtCore/QSemaphore> QT_BEGIN_NAMESPACE @@ -63,7 +63,7 @@ namespace Render { class AbstractRenderer; -class Q_AUTOTEST_EXPORT RenderThread : public QThread +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderThread : public QThread { Q_OBJECT public: diff --git a/src/render/backend/resourceaccessor.cpp b/src/render/backend/resourceaccessor.cpp index 846caca58..ebc55c7ca 100644 --- a/src/render/backend/resourceaccessor.cpp +++ b/src/render/backend/resourceaccessor.cpp @@ -40,7 +40,6 @@ #include <private/qrendertargetoutput_p.h> #include <private/nodemanagers_p.h> -#include <private/glresourcemanagers_p.h> #include <private/rendertargetoutput_p.h> #include <private/managers_p.h> diff --git a/src/render/backend/stringtoint_p.h b/src/render/backend/stringtoint_p.h index 996cecf33..1aa6f0b08 100644 --- a/src/render/backend/stringtoint_p.h +++ b/src/render/backend/stringtoint_p.h @@ -54,6 +54,7 @@ #include <QVector> #include <QString> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -61,7 +62,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT StringToInt +class Q_3DRENDERSHARED_PRIVATE_EXPORT StringToInt { public: static int lookupId(const QString &str); diff --git a/src/render/backend/transform_p.h b/src/render/backend/transform_p.h index 8c0cd826a..3023a19d1 100644 --- a/src/render/backend/transform_p.h +++ b/src/render/backend/transform_p.h @@ -65,7 +65,7 @@ namespace Render { class Renderer; class TransformManager; -class Q_AUTOTEST_EXPORT Transform : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Transform : public BackendNode { public: Transform(); diff --git a/src/render/backend/uniform_p.h b/src/render/backend/uniform_p.h index c8731637c..eb959923a 100644 --- a/src/render/backend/uniform_p.h +++ b/src/render/backend/uniform_p.h @@ -56,7 +56,7 @@ #include <Qt3DCore/private/matrix4x4_p.h> #include <Qt3DCore/private/vector3d_p.h> #include <Qt3DCore/private/vector4d_p.h> - +#include <Qt3DRender/private/qt3drender_global_p.h> #include <QMatrix4x4> #include <QVector2D> #include <QVector3D> @@ -105,7 +105,7 @@ enum UniformType { Unknown }; -class Q_AUTOTEST_EXPORT UniformValue +class Q_3DRENDERSHARED_PRIVATE_EXPORT UniformValue { public: enum ValueType { @@ -238,7 +238,7 @@ private: }; template<> -Q_AUTOTEST_EXPORT void UniformValue::setData<QMatrix4x4>(const QVector<QMatrix4x4> &v); +Q_3DRENDERSHARED_PRIVATE_EXPORT void UniformValue::setData<QMatrix4x4>(const QVector<QMatrix4x4> &v); } // namespace Render } // namespace Qt3DRender diff --git a/src/render/framegraph/blitframebuffer_p.h b/src/render/framegraph/blitframebuffer_p.h index fa9ddacd9..773833eb5 100644 --- a/src/render/framegraph/blitframebuffer_p.h +++ b/src/render/framegraph/blitframebuffer_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT BlitFramebuffer : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT BlitFramebuffer : public FrameGraphNode { public: BlitFramebuffer(); diff --git a/src/render/framegraph/buffercapture_p.h b/src/render/framegraph/buffercapture_p.h index d638f35d5..dfade50eb 100644 --- a/src/render/framegraph/buffercapture_p.h +++ b/src/render/framegraph/buffercapture_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT BufferCapture : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT BufferCapture : public FrameGraphNode { public: BufferCapture(); diff --git a/src/render/framegraph/cameraselectornode.cpp b/src/render/framegraph/cameraselectornode.cpp index 3beb0ef71..00772c502 100644 --- a/src/render/framegraph/cameraselectornode.cpp +++ b/src/render/framegraph/cameraselectornode.cpp @@ -39,7 +39,8 @@ #include "cameraselectornode_p.h" #include <Qt3DRender/private/qcameraselector_p.h> -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> +#include <Qt3DCore/private/qchangearbiter_p.h> #include <Qt3DCore/qentity.h> #include <Qt3DRender/private/renderlogging_p.h> diff --git a/src/render/framegraph/cameraselectornode_p.h b/src/render/framegraph/cameraselectornode_p.h index dd7e050d0..24590f960 100644 --- a/src/render/framegraph/cameraselectornode_p.h +++ b/src/render/framegraph/cameraselectornode_p.h @@ -64,7 +64,7 @@ namespace Render { class Renderer; -class CameraSelector : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT CameraSelector : public FrameGraphNode { public: CameraSelector(); diff --git a/src/render/framegraph/clearbuffers_p.h b/src/render/framegraph/clearbuffers_p.h index ca55d2a98..746d58da7 100644 --- a/src/render/framegraph/clearbuffers_p.h +++ b/src/render/framegraph/clearbuffers_p.h @@ -62,7 +62,7 @@ namespace Render { class FrameGraphManager; -class ClearBuffers : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT ClearBuffers : public FrameGraphNode { public: ClearBuffers(); diff --git a/src/render/framegraph/dispatchcompute_p.h b/src/render/framegraph/dispatchcompute_p.h index 24a641938..7df8db1da 100644 --- a/src/render/framegraph/dispatchcompute_p.h +++ b/src/render/framegraph/dispatchcompute_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class DispatchCompute : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT DispatchCompute : public FrameGraphNode { public: DispatchCompute(); diff --git a/src/render/framegraph/framegraphnode.cpp b/src/render/framegraph/framegraphnode.cpp index 40d8fca3d..92116af7d 100644 --- a/src/render/framegraph/framegraphnode.cpp +++ b/src/render/framegraph/framegraphnode.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "framegraphnode_p.h" -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/qframegraphnodecreatedchange.h> diff --git a/src/render/framegraph/framegraphnode_p.h b/src/render/framegraph/framegraphnode_p.h index 55bede5fd..92d7ae2f1 100644 --- a/src/render/framegraph/framegraphnode_p.h +++ b/src/render/framegraph/framegraphnode_p.h @@ -74,7 +74,7 @@ namespace Render { class FrameGraphManager; -class Q_AUTOTEST_EXPORT FrameGraphNode : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT FrameGraphNode : public BackendNode { public: FrameGraphNode(); diff --git a/src/render/framegraph/framegraphvisitor.cpp b/src/render/framegraph/framegraphvisitor.cpp index 9af0297a0..b0eb1ac00 100644 --- a/src/render/framegraph/framegraphvisitor.cpp +++ b/src/render/framegraph/framegraphvisitor.cpp @@ -42,7 +42,7 @@ #include "framegraphnode_p.h" #include "subtreeenabler_p.h" -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/private/managers_p.h> #include <QThreadPool> diff --git a/src/render/framegraph/framegraphvisitor_p.h b/src/render/framegraph/framegraphvisitor_p.h index 5706a169d..0bb6cf0d4 100644 --- a/src/render/framegraph/framegraphvisitor_p.h +++ b/src/render/framegraph/framegraphvisitor_p.h @@ -54,6 +54,7 @@ #include <qglobal.h> #include <Qt3DCore/qaspectjob.h> +#include <Qt3DRender/private/qt3drender_global_p.h> #include <QVector> @@ -66,7 +67,7 @@ class FrameGraphNode; class Renderer; class FrameGraphManager; -class Q_AUTOTEST_EXPORT FrameGraphVisitor +class Q_3DRENDERSHARED_PRIVATE_EXPORT FrameGraphVisitor { public: explicit FrameGraphVisitor(const FrameGraphManager *nodeManager); diff --git a/src/render/framegraph/frustumculling_p.h b/src/render/framegraph/frustumculling_p.h index 7f9959c6e..ac11b7306 100644 --- a/src/render/framegraph/frustumculling_p.h +++ b/src/render/framegraph/frustumculling_p.h @@ -59,7 +59,7 @@ namespace Qt3DRender { namespace Render { -class FrustumCulling : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT FrustumCulling : public FrameGraphNode { public: FrustumCulling(); diff --git a/src/render/framegraph/layerfilternode_p.h b/src/render/framegraph/layerfilternode_p.h index 27cdc49d3..f075d5ec4 100644 --- a/src/render/framegraph/layerfilternode_p.h +++ b/src/render/framegraph/layerfilternode_p.h @@ -64,7 +64,7 @@ namespace Render { class Renderer; -class LayerFilterNode : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT LayerFilterNode : public FrameGraphNode { public: LayerFilterNode(); diff --git a/src/render/framegraph/memorybarrier_p.h b/src/render/framegraph/memorybarrier_p.h index ce545cd09..78bb91c40 100644 --- a/src/render/framegraph/memorybarrier_p.h +++ b/src/render/framegraph/memorybarrier_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT MemoryBarrier : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT MemoryBarrier : public FrameGraphNode { public: MemoryBarrier(); diff --git a/src/render/framegraph/nodraw_p.h b/src/render/framegraph/nodraw_p.h index ae9fa6713..ace625250 100644 --- a/src/render/framegraph/nodraw_p.h +++ b/src/render/framegraph/nodraw_p.h @@ -59,7 +59,7 @@ namespace Qt3DRender { namespace Render { -class NoDraw : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT NoDraw : public FrameGraphNode { public: NoDraw(); diff --git a/src/render/framegraph/proximityfilter_p.h b/src/render/framegraph/proximityfilter_p.h index 5c2f7ad66..27d89f76d 100644 --- a/src/render/framegraph/proximityfilter_p.h +++ b/src/render/framegraph/proximityfilter_p.h @@ -59,7 +59,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT ProximityFilter : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT ProximityFilter : public FrameGraphNode { public: ProximityFilter(); diff --git a/src/render/framegraph/rendercapture_p.h b/src/render/framegraph/rendercapture_p.h index 5714fb44d..f2a2a55b7 100644 --- a/src/render/framegraph/rendercapture_p.h +++ b/src/render/framegraph/rendercapture_p.h @@ -57,7 +57,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT RenderCapture : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderCapture : public FrameGraphNode { public: RenderCapture(); diff --git a/src/render/framegraph/renderpassfilternode_p.h b/src/render/framegraph/renderpassfilternode_p.h index 157a162bb..c9084573e 100644 --- a/src/render/framegraph/renderpassfilternode_p.h +++ b/src/render/framegraph/renderpassfilternode_p.h @@ -67,7 +67,7 @@ class QHandle; namespace Render { -class RenderPassFilter : public Render::FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderPassFilter : public Render::FrameGraphNode { public: RenderPassFilter(); diff --git a/src/render/framegraph/rendersurfaceselector.cpp b/src/render/framegraph/rendersurfaceselector.cpp index a1e639df5..c7e46efa7 100644 --- a/src/render/framegraph/rendersurfaceselector.cpp +++ b/src/render/framegraph/rendersurfaceselector.cpp @@ -40,7 +40,6 @@ #include "rendersurfaceselector_p.h" #include <Qt3DRender/qrendersurfaceselector.h> #include <Qt3DRender/private/qrendersurfaceselector_p.h> - #include <QtGui/qwindow.h> #include <QtGui/qscreen.h> #include <QtGui/qoffscreensurface.h> diff --git a/src/render/framegraph/rendersurfaceselector_p.h b/src/render/framegraph/rendersurfaceselector_p.h index f1a139e84..3378ececa 100644 --- a/src/render/framegraph/rendersurfaceselector_p.h +++ b/src/render/framegraph/rendersurfaceselector_p.h @@ -60,7 +60,7 @@ class QSurface; namespace Qt3DRender { namespace Render { -class RenderSurfaceSelector : public Qt3DRender::Render::FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderSurfaceSelector : public Qt3DRender::Render::FrameGraphNode { public: RenderSurfaceSelector(); diff --git a/src/render/framegraph/rendertargetselectornode.cpp b/src/render/framegraph/rendertargetselectornode.cpp index 614a749a5..f32b8c7d9 100644 --- a/src/render/framegraph/rendertargetselectornode.cpp +++ b/src/render/framegraph/rendertargetselectornode.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "rendertargetselectornode_p.h" -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DCore/private/qchangearbiter_p.h> #include <Qt3DRender/qrendertargetselector.h> #include <Qt3DRender/private/qrendertargetselector_p.h> diff --git a/src/render/framegraph/rendertargetselectornode_p.h b/src/render/framegraph/rendertargetselectornode_p.h index 232ee9ecc..04032045a 100644 --- a/src/render/framegraph/rendertargetselectornode_p.h +++ b/src/render/framegraph/rendertargetselectornode_p.h @@ -61,7 +61,7 @@ class QRenderTargetSelector; namespace Render { -class RenderTargetSelector : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderTargetSelector : public FrameGraphNode { public: RenderTargetSelector(); diff --git a/src/render/framegraph/setfence_p.h b/src/render/framegraph/setfence_p.h index 31072581c..0f54d65ee 100644 --- a/src/render/framegraph/setfence_p.h +++ b/src/render/framegraph/setfence_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT SetFence : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT SetFence : public FrameGraphNode { public: SetFence(); diff --git a/src/render/framegraph/sortpolicy_p.h b/src/render/framegraph/sortpolicy_p.h index 8d572ead7..2015adf87 100644 --- a/src/render/framegraph/sortpolicy_p.h +++ b/src/render/framegraph/sortpolicy_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT SortPolicy : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT SortPolicy : public FrameGraphNode { public: SortPolicy(); diff --git a/src/render/framegraph/statesetnode_p.h b/src/render/framegraph/statesetnode_p.h index 5081f3215..618b52338 100644 --- a/src/render/framegraph/statesetnode_p.h +++ b/src/render/framegraph/statesetnode_p.h @@ -59,7 +59,7 @@ namespace Qt3DRender { namespace Render { -class StateSetNode : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT StateSetNode : public FrameGraphNode { public: StateSetNode(); diff --git a/src/render/framegraph/subtreeenabler.cpp b/src/render/framegraph/subtreeenabler.cpp index 4d912dc1d..37989df1a 100644 --- a/src/render/framegraph/subtreeenabler.cpp +++ b/src/render/framegraph/subtreeenabler.cpp @@ -39,7 +39,6 @@ #include "subtreeenabler_p.h" #include <Qt3DRender/private/qsubtreeenabler_p.h> -#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE diff --git a/src/render/framegraph/techniquefilternode_p.h b/src/render/framegraph/techniquefilternode_p.h index e424e37e5..2e71e31d4 100644 --- a/src/render/framegraph/techniquefilternode_p.h +++ b/src/render/framegraph/techniquefilternode_p.h @@ -70,7 +70,7 @@ class QHandle; namespace Render { -class TechniqueFilter +class Q_3DRENDERSHARED_PRIVATE_EXPORT TechniqueFilter : public FrameGraphNode { public: diff --git a/src/render/framegraph/viewportnode_p.h b/src/render/framegraph/viewportnode_p.h index 3e291a9da..f673b1e21 100644 --- a/src/render/framegraph/viewportnode_p.h +++ b/src/render/framegraph/viewportnode_p.h @@ -64,7 +64,7 @@ namespace Render { class Renderer; -class Q_AUTOTEST_EXPORT ViewportNode : public FrameGraphNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT ViewportNode : public FrameGraphNode { public: ViewportNode(); diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index d8551fd1b..da5abe4ac 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -41,7 +41,7 @@ #include "qrenderaspect_p.h" #include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/private/scenemanager_p.h> #include <Qt3DRender/private/geometryrenderermanager_p.h> @@ -56,8 +56,10 @@ #include <Qt3DRender/qmesh.h> #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qrenderpassfilter.h> +#include <Qt3DRender/qrenderpass.h> #include <Qt3DRender/qrendertargetselector.h> #include <Qt3DRender/qtechniquefilter.h> +#include <Qt3DRender/qtechnique.h> #include <Qt3DRender/qviewport.h> #include <Qt3DRender/qrendertarget.h> #include <Qt3DRender/qclearbuffers.h> @@ -103,7 +105,7 @@ #include <Qt3DRender/private/cameralens_p.h> #include <Qt3DRender/private/filterkey_p.h> #include <Qt3DRender/private/entity_p.h> -#include <Qt3DRender/private/renderer_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/private/shaderdata_p.h> #include <Qt3DRender/private/renderpassfilternode_p.h> #include <Qt3DRender/private/rendertargetselectornode_p.h> @@ -165,6 +167,8 @@ #include <private/qrenderpluginfactory_p.h> #include <private/qrenderplugin_p.h> +#include <Qt3DRender/private/qrendererpluginfactory_p.h> + #include <Qt3DCore/qentity.h> #include <Qt3DCore/qtransform.h> @@ -599,8 +603,9 @@ void QRenderAspect::onRegistered() Q_D(QRenderAspect); d->m_nodeManagers = new Render::NodeManagers(); - // TO DO: Load proper Renderer class based on Qt configuration preferences - d->m_renderer = new Render::Renderer(d->m_renderType); + // Load proper Renderer class based on Qt configuration preferences + d->m_renderer = d->loadRendererPlugin(); + Q_ASSERT(d->m_renderer); d->m_renderer->setScreen(d->m_screen); d->m_renderer->setNodeManagers(d->m_nodeManagers); @@ -689,6 +694,20 @@ void QRenderAspectPrivate::loadSceneParsers() } } +Render::AbstractRenderer *QRenderAspectPrivate::loadRendererPlugin() +{ + // Note: for now we load the first renderer plugin that is successfully loaded + // In the future we might want to offer the user a way to hint at which renderer + // plugin would best be loaded + const QStringList keys = Render::QRendererPluginFactory::keys(); + for (const QString &key : keys) { + Render::AbstractRenderer *renderer = Render::QRendererPluginFactory::create(key, m_renderType); + if (renderer) + return renderer; + } + return nullptr; +} + void QRenderAspectPrivate::loadRenderPlugin(const QString &pluginName) { Q_Q(QRenderAspect); diff --git a/src/render/frontend/qrenderaspect_p.h b/src/render/frontend/qrenderaspect_p.h index 0a9f4ec46..0eb04cee9 100644 --- a/src/render/frontend/qrenderaspect_p.h +++ b/src/render/frontend/qrenderaspect_p.h @@ -99,6 +99,7 @@ public: void renderShutdown(); void registerBackendType(const QMetaObject &, const Qt3DCore::QBackendNodeMapperPtr &functor); QVector<Qt3DCore::QAspectJobPtr> createGeometryRendererJobs(); + Render::AbstractRenderer *loadRendererPlugin(); Render::NodeManagers *m_nodeManagers; Render::AbstractRenderer *m_renderer; diff --git a/src/render/frontend/sphere_p.h b/src/render/frontend/sphere_p.h index b7585f85a..448704cf4 100644 --- a/src/render/frontend/sphere_p.h +++ b/src/render/frontend/sphere_p.h @@ -56,8 +56,6 @@ #include <Qt3DCore/private/matrix4x4_p.h> #include <Qt3DRender/private/boundingsphere_p.h> -#include <QMatrix4x4> - QT_BEGIN_NAMESPACE namespace Qt3DRender { diff --git a/src/render/geometry/armature_p.h b/src/render/geometry/armature_p.h index 39baa4a79..db9d28bd6 100644 --- a/src/render/geometry/armature_p.h +++ b/src/render/geometry/armature_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT Armature : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Armature : public BackendNode { public: Armature(); diff --git a/src/render/geometry/attribute_p.h b/src/render/geometry/attribute_p.h index 4b47146e1..87b3cbb4f 100644 --- a/src/render/geometry/attribute_p.h +++ b/src/render/geometry/attribute_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT Attribute : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Attribute : public BackendNode { public: Attribute(); diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h index a3f52d1b3..3490b7bc9 100644 --- a/src/render/geometry/buffer_p.h +++ b/src/render/geometry/buffer_p.h @@ -66,7 +66,7 @@ namespace Render { class BufferManager; -class Q_AUTOTEST_EXPORT Buffer : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Buffer : public BackendNode { public: Buffer(); diff --git a/src/render/geometry/buffermanager_p.h b/src/render/geometry/buffermanager_p.h index df97a5193..bafcf8812 100644 --- a/src/render/geometry/buffermanager_p.h +++ b/src/render/geometry/buffermanager_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT BufferManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT BufferManager : public Qt3DCore::QResourceManager< Buffer, Qt3DCore::QNodeId, Qt3DCore::ObjectLevelLockingPolicy> diff --git a/src/render/geometry/geometry_p.h b/src/render/geometry/geometry_p.h index 429a577b0..fdad63286 100644 --- a/src/render/geometry/geometry_p.h +++ b/src/render/geometry/geometry_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT Geometry : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Geometry : public BackendNode { public: Geometry(); diff --git a/src/render/geometry/geometryrenderer_p.h b/src/render/geometry/geometryrenderer_p.h index d2ddad4bb..a38233d6c 100644 --- a/src/render/geometry/geometryrenderer_p.h +++ b/src/render/geometry/geometryrenderer_p.h @@ -73,7 +73,7 @@ struct GeometryFunctorResult QMesh::Status status; }; -class Q_AUTOTEST_EXPORT GeometryRenderer : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT GeometryRenderer : public BackendNode { public: GeometryRenderer(); diff --git a/src/render/geometry/geometryrenderermanager_p.h b/src/render/geometry/geometryrenderermanager_p.h index becf1bcc1..7b7b629bd 100644 --- a/src/render/geometry/geometryrenderermanager_p.h +++ b/src/render/geometry/geometryrenderermanager_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT GeometryRendererManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT GeometryRendererManager : public Qt3DCore::QResourceManager< GeometryRenderer, Qt3DCore::QNodeId, Qt3DCore::ObjectLevelLockingPolicy> diff --git a/src/render/geometry/joint_p.h b/src/render/geometry/joint_p.h index de875459e..c178fdcf8 100644 --- a/src/render/geometry/joint_p.h +++ b/src/render/geometry/joint_p.h @@ -63,7 +63,7 @@ namespace Render { class JointManager; class SkeletonManager; -class Q_AUTOTEST_EXPORT Joint : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Joint : public BackendNode { public: Joint(); diff --git a/src/render/geometry/skeleton_p.h b/src/render/geometry/skeleton_p.h index 7a5299944..ac475a3c0 100644 --- a/src/render/geometry/skeleton_p.h +++ b/src/render/geometry/skeleton_p.h @@ -72,7 +72,7 @@ namespace Render { class JointManager; class SkeletonManager; -class Q_AUTOTEST_EXPORT Skeleton : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Skeleton : public BackendNode { public: enum SkeletonDataType { diff --git a/src/render/io/scene_p.h b/src/render/io/scene_p.h index bf625b369..cf927bc23 100644 --- a/src/render/io/scene_p.h +++ b/src/render/io/scene_p.h @@ -67,7 +67,7 @@ namespace Render { class SceneManager; -class Q_AUTOTEST_EXPORT Scene : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Scene : public BackendNode { public: Scene(); diff --git a/src/render/io/scenemanager_p.h b/src/render/io/scenemanager_p.h index 470846b83..badef2bf9 100644 --- a/src/render/io/scenemanager_p.h +++ b/src/render/io/scenemanager_p.h @@ -82,7 +82,7 @@ private: typedef QSharedPointer<SceneDownloader> SceneDownloaderPtr; -class Q_AUTOTEST_EXPORT SceneManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT SceneManager : public Qt3DCore::QResourceManager< Scene, Qt3DCore::QNodeId, Qt3DCore::ObjectLevelLockingPolicy> diff --git a/src/render/jobs/abstractpickingjob.cpp b/src/render/jobs/abstractpickingjob.cpp index 092ab7d3b..ea2916006 100644 --- a/src/render/jobs/abstractpickingjob.cpp +++ b/src/render/jobs/abstractpickingjob.cpp @@ -39,7 +39,6 @@ #include "abstractpickingjob_p.h" #include <Qt3DRender/qgeometryrenderer.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/entity_p.h> #include <Qt3DRender/private/objectpicker_p.h> diff --git a/src/render/jobs/abstractpickingjob_p.h b/src/render/jobs/abstractpickingjob_p.h index c0c6ed7e9..f53805ac5 100644 --- a/src/render/jobs/abstractpickingjob_p.h +++ b/src/render/jobs/abstractpickingjob_p.h @@ -57,6 +57,7 @@ #include <Qt3DRender/private/qboundingvolumeprovider_p.h> #include <Qt3DRender/private/qcollisionqueryresult_p.h> #include <Qt3DRender/private/pickboundingvolumeutils_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -72,7 +73,7 @@ class Renderer; class NodeManagers; class RenderSettings; -class Q_AUTOTEST_EXPORT AbstractPickingJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT AbstractPickingJob : public Qt3DCore::QAspectJob { public: AbstractPickingJob(); diff --git a/src/render/jobs/computefilteredboundingvolumejob.cpp b/src/render/jobs/computefilteredboundingvolumejob.cpp index 0cdbc8b6d..0be3cb489 100644 --- a/src/render/jobs/computefilteredboundingvolumejob.cpp +++ b/src/render/jobs/computefilteredboundingvolumejob.cpp @@ -39,7 +39,6 @@ #include "computefilteredboundingvolumejob_p.h" -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/entity_p.h> #include <Qt3DRender/private/renderlogging_p.h> #include <Qt3DRender/private/sphere_p.h> diff --git a/src/render/jobs/expandboundingvolumejob.cpp b/src/render/jobs/expandboundingvolumejob.cpp index 8587634cb..ec783e5e0 100644 --- a/src/render/jobs/expandboundingvolumejob.cpp +++ b/src/render/jobs/expandboundingvolumejob.cpp @@ -39,7 +39,6 @@ #include "expandboundingvolumejob_p.h" -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/entity_p.h> #include <Qt3DRender/private/renderlogging_p.h> #include <Qt3DRender/private/sphere_p.h> diff --git a/src/render/jobs/filterproximitydistancejob_p.h b/src/render/jobs/filterproximitydistancejob_p.h index 935d4036f..e058f011a 100644 --- a/src/render/jobs/filterproximitydistancejob_p.h +++ b/src/render/jobs/filterproximitydistancejob_p.h @@ -42,6 +42,7 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DCore/qnodeid.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -52,7 +53,7 @@ namespace Render { class Entity; class NodeManagers; -class Q_AUTOTEST_EXPORT FilterProximityDistanceJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT FilterProximityDistanceJob : public Qt3DCore::QAspectJob { public: FilterProximityDistanceJob(); diff --git a/src/render/jobs/framecleanupjob.cpp b/src/render/jobs/framecleanupjob.cpp index fb63f005b..eddea12e8 100644 --- a/src/render/jobs/framecleanupjob.cpp +++ b/src/render/jobs/framecleanupjob.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "framecleanupjob_p.h" -#include <private/renderer_p.h> #include <private/nodemanagers_p.h> #include <private/entity_p.h> #include <private/shaderdata_p.h> @@ -69,9 +68,6 @@ void FrameCleanupJob::setRoot(Entity *root) void FrameCleanupJob::run() { - // mark each ShaderData clean - ShaderData::cleanup(m_managers); - // Debug bounding volume debug updateBoundingVolumesDebug(m_root); } diff --git a/src/render/jobs/frustumcullingjob.cpp b/src/render/jobs/frustumcullingjob.cpp index e22d625df..aa1a57a31 100644 --- a/src/render/jobs/frustumcullingjob.cpp +++ b/src/render/jobs/frustumcullingjob.cpp @@ -41,7 +41,6 @@ #include <Qt3DRender/private/job_common_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/entity_p.h> -#include <Qt3DRender/private/renderview_p.h> #include <Qt3DRender/private/sphere_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/nodemanagers_p.h> diff --git a/src/render/jobs/frustumcullingjob_p.h b/src/render/jobs/frustumcullingjob_p.h index cddbbd409..636585c2f 100644 --- a/src/render/jobs/frustumcullingjob_p.h +++ b/src/render/jobs/frustumcullingjob_p.h @@ -42,7 +42,10 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DCore/private/matrix4x4_p.h> +#include <Qt3DCore/private/vector3d_p.h> +#include <Qt3DCore/private/vector4d_p.h> #include <Qt3DRender/private/aligned_malloc_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> // // W A R N I N G @@ -66,7 +69,7 @@ class EntityManager; class NodeManagers; struct Plane; -class FrustumCullingJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT FrustumCullingJob : public Qt3DCore::QAspectJob { public: FrustumCullingJob(); @@ -85,6 +88,19 @@ public: void run() final; private: + struct Q_AUTOTEST_EXPORT Plane + { + explicit Plane(const Vector4D &planeEquation) + : planeEquation(planeEquation) + , normal(Vector3D(planeEquation).normalized()) + , d(planeEquation.w() / Vector3D(planeEquation).length()) + {} + + const Vector4D planeEquation; + const Vector3D normal; + const float d; + }; + void cullScene(Entity *e, const Plane *planes); Matrix4x4 m_viewProjection; Entity *m_root; diff --git a/src/render/jobs/lightgatherer.cpp b/src/render/jobs/lightgatherer.cpp index b79976aef..b878b0a78 100644 --- a/src/render/jobs/lightgatherer.cpp +++ b/src/render/jobs/lightgatherer.cpp @@ -41,6 +41,7 @@ #include <Qt3DRender/private/job_common_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/entity_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE diff --git a/src/render/jobs/lightgatherer_p.h b/src/render/jobs/lightgatherer_p.h index d0090ccd0..59e64ad74 100644 --- a/src/render/jobs/lightgatherer_p.h +++ b/src/render/jobs/lightgatherer_p.h @@ -53,6 +53,7 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DRender/private/lightsource_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -63,7 +64,7 @@ namespace Render { class EntityManager; class EnvironmentLight; -class Q_AUTOTEST_EXPORT LightGatherer : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT LightGatherer : public Qt3DCore::QAspectJob { public: LightGatherer(); diff --git a/src/render/jobs/loadbufferjob.cpp b/src/render/jobs/loadbufferjob.cpp index 0f4feb5d4..fd57248e1 100644 --- a/src/render/jobs/loadbufferjob.cpp +++ b/src/render/jobs/loadbufferjob.cpp @@ -41,9 +41,9 @@ #include <Qt3DRender/private/buffer_p.h> #include <Qt3DRender/private/qbuffer_p.h> #include <Qt3DRender/private/buffermanager_p.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/job_common_p.h> #include <Qt3DCore/private/qaspectmanager_p.h> +#include <Qt3DRender/private/renderlogging_p.h> QT_BEGIN_NAMESPACE diff --git a/src/render/jobs/loadbufferjob_p.h b/src/render/jobs/loadbufferjob_p.h index e86e4f835..5f20bfb00 100644 --- a/src/render/jobs/loadbufferjob_p.h +++ b/src/render/jobs/loadbufferjob_p.h @@ -65,7 +65,7 @@ namespace Render { class NodeManagers; class LoadBufferJobPrivate; -class Q_AUTOTEST_EXPORT LoadBufferJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT LoadBufferJob : public Qt3DCore::QAspectJob { public: explicit LoadBufferJob(const HBuffer &handle); diff --git a/src/render/jobs/loadgeometryjob_p.h b/src/render/jobs/loadgeometryjob_p.h index 998d543ac..e5edf0100 100644 --- a/src/render/jobs/loadgeometryjob_p.h +++ b/src/render/jobs/loadgeometryjob_p.h @@ -54,6 +54,7 @@ #include <QSharedPointer> #include <Qt3DCore/qaspectjob.h> #include <Qt3DRender/private/handle_types_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -64,7 +65,7 @@ namespace Render { class NodeManagers; class LoadGeometryJobPrivate; -class Q_AUTOTEST_EXPORT LoadGeometryJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT LoadGeometryJob : public Qt3DCore::QAspectJob { public: explicit LoadGeometryJob(const HGeometryRenderer &handle); diff --git a/src/render/jobs/loadscenejob.cpp b/src/render/jobs/loadscenejob.cpp index be855c608..959cbe3eb 100644 --- a/src/render/jobs/loadscenejob.cpp +++ b/src/render/jobs/loadscenejob.cpp @@ -38,9 +38,9 @@ ****************************************************************************/ #include "loadscenejob_p.h" -#include <private/renderer_p.h> #include <private/nodemanagers_p.h> #include <private/scenemanager_p.h> +#include <QCoreApplication> #include <Qt3DCore/qentity.h> #include <Qt3DCore/private/qaspectmanager_p.h> #include <Qt3DRender/private/job_common_p.h> diff --git a/src/render/jobs/loadscenejob_p.h b/src/render/jobs/loadscenejob_p.h index 3675d94c1..39d2d8d6e 100644 --- a/src/render/jobs/loadscenejob_p.h +++ b/src/render/jobs/loadscenejob_p.h @@ -58,6 +58,7 @@ #include <QSharedPointer> #include <QUrl> #include <functional> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -88,7 +89,7 @@ private: LoadSceneJob *q_ptr; }; -class Q_AUTOTEST_EXPORT LoadSceneJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT LoadSceneJob : public Qt3DCore::QAspectJob { public: explicit LoadSceneJob(const QUrl &source, Qt3DCore::QNodeId sceneComponent); diff --git a/src/render/jobs/loadskeletonjob.cpp b/src/render/jobs/loadskeletonjob.cpp index e696cc434..de12b7e39 100644 --- a/src/render/jobs/loadskeletonjob.cpp +++ b/src/render/jobs/loadskeletonjob.cpp @@ -47,6 +47,9 @@ #include <Qt3DRender/private/job_common_p.h> #include <Qt3DRender/private/qurlhelper_p.h> #include <Qt3DRender/private/gltfskeletonloader_p.h> +#include <Qt3DRender/private/renderlogging_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QFileInfo> QT_BEGIN_NAMESPACE diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 2973ee100..dce184f46 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -46,7 +46,6 @@ #include <Qt3DRender/qviewport.h> #include <Qt3DRender/qgeometryrenderer.h> #include <Qt3DRender/private/qobjectpicker_p.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/entity_p.h> #include <Qt3DRender/private/objectpicker_p.h> diff --git a/src/render/jobs/pickboundingvolumejob_p.h b/src/render/jobs/pickboundingvolumejob_p.h index 49b11b775..4f2c4340e 100644 --- a/src/render/jobs/pickboundingvolumejob_p.h +++ b/src/render/jobs/pickboundingvolumejob_p.h @@ -58,6 +58,7 @@ #include <Qt3DRender/private/qboundingvolumeprovider_p.h> #include <Qt3DRender/private/qcollisionqueryresult_p.h> #include <Qt3DRender/private/pickboundingvolumeutils_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> #include <Qt3DRender/qpickevent.h> #include <QMouseEvent> #include <QKeyEvent> @@ -76,7 +77,7 @@ namespace PickingUtils { typedef QVector<RayCasting::QCollisionQueryResult::Hit> HitList; } -class Q_AUTOTEST_EXPORT PickBoundingVolumeJob : public AbstractPickingJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT PickBoundingVolumeJob : public AbstractPickingJob { public: PickBoundingVolumeJob(); diff --git a/src/render/jobs/raycastingjob.cpp b/src/render/jobs/raycastingjob.cpp index 380447873..50dcaecde 100644 --- a/src/render/jobs/raycastingjob.cpp +++ b/src/render/jobs/raycastingjob.cpp @@ -48,7 +48,6 @@ #include <Qt3DRender/private/pickboundingvolumeutils_p.h> #include <Qt3DRender/private/qray3d_p.h> #include <Qt3DRender/private/sphere_p.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/rendersettings_p.h> #include <Qt3DRender/private/trianglesvisitor_p.h> #include <Qt3DRender/private/entityvisitor_p.h> diff --git a/src/render/jobs/raycastingjob_p.h b/src/render/jobs/raycastingjob_p.h index 4b8b91ad5..0a8b7aa3a 100644 --- a/src/render/jobs/raycastingjob_p.h +++ b/src/render/jobs/raycastingjob_p.h @@ -55,6 +55,7 @@ #include <Qt3DRender/qpickevent.h> #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/private/qcollisionqueryresult_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> #include <QMouseEvent> #include <QKeyEvent> #include <QSharedPointer> @@ -70,7 +71,7 @@ typedef QVector<RayCasting::QCollisionQueryResult::Hit> HitList; class RayCastingJobPrivate; -class Q_AUTOTEST_EXPORT RayCastingJob : public AbstractPickingJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT RayCastingJob : public AbstractPickingJob { public: RayCastingJob(); diff --git a/src/render/jobs/updateskinningpalettejob_p.h b/src/render/jobs/updateskinningpalettejob_p.h index c52e0841c..f74cf6a73 100644 --- a/src/render/jobs/updateskinningpalettejob_p.h +++ b/src/render/jobs/updateskinningpalettejob_p.h @@ -53,6 +53,7 @@ #include <QtCore/qsharedpointer.h> #include <Qt3DRender/private/handle_types_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -61,7 +62,7 @@ namespace Render { class NodeManagers; -class UpdateSkinningPaletteJob : public Qt3DCore::QAspectJob +class Q_3DRENDERSHARED_PRIVATE_EXPORT UpdateSkinningPaletteJob : public Qt3DCore::QAspectJob { public: explicit UpdateSkinningPaletteJob(); diff --git a/src/render/jobs/updateworldtransformjob.cpp b/src/render/jobs/updateworldtransformjob.cpp index e3c8077f4..12582c297 100644 --- a/src/render/jobs/updateworldtransformjob.cpp +++ b/src/render/jobs/updateworldtransformjob.cpp @@ -42,7 +42,6 @@ #include <Qt3DCore/qtransform.h> #include <Qt3DCore/private/qtransform_p.h> #include <Qt3DCore/private/qaspectmanager_p.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/entity_p.h> #include <Qt3DRender/private/transform_p.h> #include <Qt3DRender/private/renderlogging_p.h> diff --git a/src/render/lights/environmentlight_p.h b/src/render/lights/environmentlight_p.h index 92f6ce100..7a631ed28 100644 --- a/src/render/lights/environmentlight_p.h +++ b/src/render/lights/environmentlight_p.h @@ -59,7 +59,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT EnvironmentLight : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT EnvironmentLight : public BackendNode { public: Qt3DCore::QNodeId shaderData() const; diff --git a/src/render/lights/light_p.h b/src/render/lights/light_p.h index 5f5f8140e..d1497fddd 100644 --- a/src/render/lights/light_p.h +++ b/src/render/lights/light_p.h @@ -61,7 +61,7 @@ namespace Render { class NodeManagers; -class Q_AUTOTEST_EXPORT Light : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Light : public BackendNode { public: Qt3DCore::QNodeId shaderData() const; diff --git a/src/render/lights/lightsource_p.h b/src/render/lights/lightsource_p.h index 9e56dc70e..bfa2b81f9 100644 --- a/src/render/lights/lightsource_p.h +++ b/src/render/lights/lightsource_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <Qt3DRender/qt3drender_global.h> +#include <Qt3DRender/private/qt3drender_global_p.h> #include <QVector> QT_BEGIN_NAMESPACE @@ -63,7 +63,7 @@ namespace Render { class Entity; class Light; -struct LightSource { +struct Q_3DRENDERSHARED_PRIVATE_EXPORT LightSource { LightSource(); LightSource(Entity *entity, const QVector<Light *> &lights); diff --git a/src/render/materialsystem/effect.cpp b/src/render/materialsystem/effect.cpp index 035cf4746..9b787b7e2 100644 --- a/src/render/materialsystem/effect.cpp +++ b/src/render/materialsystem/effect.cpp @@ -38,9 +38,9 @@ ****************************************************************************/ #include <Qt3DRender/private/effect_p.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/qeffect.h> #include <Qt3DRender/qparameter.h> +#include <Qt3DRender/qtechnique.h> #include <Qt3DRender/private/qeffect_p.h> #include <QVariant> diff --git a/src/render/materialsystem/effect_p.h b/src/render/materialsystem/effect_p.h index e81be2b8d..e8f79120b 100644 --- a/src/render/materialsystem/effect_p.h +++ b/src/render/materialsystem/effect_p.h @@ -63,7 +63,7 @@ class QTechnique; namespace Render { -class Q_AUTOTEST_EXPORT Effect : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Effect : public BackendNode { public: Effect(); diff --git a/src/render/materialsystem/filterkey_p.h b/src/render/materialsystem/filterkey_p.h index f4fb2c3d0..91d0ba1f0 100644 --- a/src/render/materialsystem/filterkey_p.h +++ b/src/render/materialsystem/filterkey_p.h @@ -62,7 +62,7 @@ class QFilterKey; namespace Render { -class Q_AUTOTEST_EXPORT FilterKey : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT FilterKey : public BackendNode { public: FilterKey(); diff --git a/src/render/materialsystem/material_p.h b/src/render/materialsystem/material_p.h index 7a02c6691..b13f49b81 100644 --- a/src/render/materialsystem/material_p.h +++ b/src/render/materialsystem/material_p.h @@ -54,7 +54,6 @@ #include <QVariant> #include <Qt3DRender/private/backendnode_p.h> -#include <Qt3DRender/private/shaderparameterpack_p.h> #include <Qt3DRender/private/parameterpack_p.h> QT_BEGIN_NAMESPACE @@ -72,7 +71,7 @@ class Technique; class Effect; class MaterialManager; -class Q_AUTOTEST_EXPORT Material : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Material : public BackendNode { public: Material(); diff --git a/src/render/materialsystem/parameter_p.h b/src/render/materialsystem/parameter_p.h index 258834ff3..8a30d6657 100644 --- a/src/render/materialsystem/parameter_p.h +++ b/src/render/materialsystem/parameter_p.h @@ -64,7 +64,7 @@ namespace Render { class ParameterManager; class ShaderDataManager; -class Q_AUTOTEST_EXPORT Parameter : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Parameter : public BackendNode { public: Parameter(); diff --git a/src/render/materialsystem/qshaderprogram_p.h b/src/render/materialsystem/qshaderprogram_p.h index d377ef039..8a14255a8 100644 --- a/src/render/materialsystem/qshaderprogram_p.h +++ b/src/render/materialsystem/qshaderprogram_p.h @@ -51,14 +51,15 @@ // We mean it. // -#include <private/qnode_p.h> +#include <Qt3DCore/private/qnode_p.h> #include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE namespace Qt3DRender { -class QShaderProgramPrivate : public Qt3DCore::QNodePrivate +class Q_3DRENDERSHARED_PRIVATE_EXPORT QShaderProgramPrivate : public Qt3DCore::QNodePrivate { public: QShaderProgramPrivate(); diff --git a/src/render/materialsystem/renderpass.cpp b/src/render/materialsystem/renderpass.cpp index 19e2a427e..a9e8c9b1d 100644 --- a/src/render/materialsystem/renderpass.cpp +++ b/src/render/materialsystem/renderpass.cpp @@ -46,7 +46,6 @@ #include <Qt3DRender/private/qrenderpass_p.h> #include <Qt3DRender/private/renderstates_p.h> -#include <Qt3DRender/private/renderstateset_p.h> #include <algorithm> diff --git a/src/render/materialsystem/renderpass_p.h b/src/render/materialsystem/renderpass_p.h index 314386ad1..03c5c5f19 100644 --- a/src/render/materialsystem/renderpass_p.h +++ b/src/render/materialsystem/renderpass_p.h @@ -71,7 +71,7 @@ namespace Render { class RenderPassManager; class RenderState; -class Q_AUTOTEST_EXPORT RenderPass : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderPass : public BackendNode { public: RenderPass(); diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index d0069bb4a..f3570f78d 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -46,7 +46,6 @@ #include <QMutexLocker> #include <qshaderprogram.h> #include <Qt3DRender/private/attachmentpack_p.h> -#include <Qt3DRender/private/graphicscontext_p.h> #include <Qt3DRender/private/qshaderprogram_p.h> #include <Qt3DRender/private/stringtoint_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index 23d57f25d..0814989ea 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -66,7 +66,7 @@ namespace Render { class ShaderManager; class AttachmentPack; -class Q_AUTOTEST_EXPORT Shader : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Shader : public BackendNode { public: static const int modelMatrixNameId; diff --git a/src/render/materialsystem/shaderdata.cpp b/src/render/materialsystem/shaderdata.cpp index 34d4641e9..67c8f35f7 100644 --- a/src/render/materialsystem/shaderdata.cpp +++ b/src/render/materialsystem/shaderdata.cpp @@ -44,12 +44,9 @@ #include <QMetaObject> #include <Qt3DCore/qdynamicpropertyupdatedchange.h> #include <Qt3DCore/qpropertyupdatedchange.h> -#include <private/graphicscontext_p.h> #include <private/qbackendnode_p.h> -#include <private/glbuffer_p.h> #include <private/managers_p.h> #include <private/nodemanagers_p.h> -#include <private/renderviewjobutils_p.h> QT_BEGIN_NAMESPACE @@ -164,11 +161,6 @@ ShaderData *ShaderData::lookupResource(QNodeId id) return ShaderData::lookupResource(m_managers, id); } -void ShaderData::cleanup(NodeManagers *managers) -{ - Q_UNUSED(managers) -} - // RenderCommand updater jobs QVariant ShaderData::getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix) { diff --git a/src/render/materialsystem/shaderdata_p.h b/src/render/materialsystem/shaderdata_p.h index c9cc22939..5c6352eba 100644 --- a/src/render/materialsystem/shaderdata_p.h +++ b/src/render/materialsystem/shaderdata_p.h @@ -52,7 +52,6 @@ // #include <Qt3DRender/private/backendnode_p.h> -#include <Qt3DRender/private/shadervariables_p.h> #include <Qt3DRender/qshaderdata.h> #include <QMutex> #include <Qt3DCore/private/matrix4x4_p.h> @@ -67,7 +66,7 @@ class GraphicsContext; class GLBuffer; class NodeManagers; -class Q_AUTOTEST_EXPORT ShaderData : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT ShaderData : public BackendNode { public: enum TransformType { @@ -95,13 +94,15 @@ public: // Unit tests purposes only TransformType propertyTransformType(const QString &name) const; - // Called by FrameCleanupJob - static void cleanup(NodeManagers *managers); - void setManagers(NodeManagers *managers); void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; +#ifdef Q_OS_WIN + // To get MSVC to compile even though we don't need any cleanup + void cleanup() {} +#endif + protected: PropertyReaderInterfacePtr m_propertyReader; diff --git a/src/render/materialsystem/technique.cpp b/src/render/materialsystem/technique.cpp index 10e9af990..440d7e49c 100644 --- a/src/render/materialsystem/technique.cpp +++ b/src/render/materialsystem/technique.cpp @@ -43,7 +43,6 @@ #include <Qt3DRender/qparameter.h> #include <Qt3DRender/qtechnique.h> #include <Qt3DRender/qgraphicsapifilter.h> -#include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/filterkey_p.h> #include <Qt3DRender/private/qtechnique_p.h> #include <Qt3DRender/private/shader_p.h> diff --git a/src/render/materialsystem/techniquemanager_p.h b/src/render/materialsystem/techniquemanager_p.h index 8108d5f5b..205dbc191 100644 --- a/src/render/materialsystem/techniquemanager_p.h +++ b/src/render/materialsystem/techniquemanager_p.h @@ -60,7 +60,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT TechniqueManager : public Qt3DCore::QResourceManager< +class Q_3DRENDERSHARED_PRIVATE_EXPORT TechniqueManager : public Qt3DCore::QResourceManager< Technique, Qt3DCore::QNodeId, Qt3DCore::NonLockingPolicy> diff --git a/src/render/picking/objectpicker_p.h b/src/render/picking/objectpicker_p.h index 49c8de770..d2ccf1c6a 100644 --- a/src/render/picking/objectpicker_p.h +++ b/src/render/picking/objectpicker_p.h @@ -62,7 +62,7 @@ typedef QSharedPointer<QPickEvent> QPickEventPtr; namespace Render { -class Q_AUTOTEST_EXPORT ObjectPicker : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT ObjectPicker : public BackendNode { public: ObjectPicker(); diff --git a/src/render/picking/pickeventfilter_p.h b/src/render/picking/pickeventfilter_p.h index dfd8c1b99..81ba6a9f4 100644 --- a/src/render/picking/pickeventfilter_p.h +++ b/src/render/picking/pickeventfilter_p.h @@ -55,6 +55,7 @@ #include <QMouseEvent> #include <QKeyEvent> #include <QtCore/qmutex.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -62,7 +63,7 @@ namespace Qt3DRender { namespace Render { -class PickEventFilter : public QObject +class Q_3DRENDERSHARED_PRIVATE_EXPORT PickEventFilter : public QObject { Q_OBJECT public: diff --git a/src/render/picking/raycaster_p.h b/src/render/picking/raycaster_p.h index 865d40365..e7d12af56 100644 --- a/src/render/picking/raycaster_p.h +++ b/src/render/picking/raycaster_p.h @@ -64,7 +64,7 @@ namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT RayCaster : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RayCaster : public BackendNode { public: RayCaster(); diff --git a/src/render/renderers/opengl/managers/glresourcemanagers.cpp b/src/render/qrendererplugin.cpp index 2b1b87925..eb54a0ead 100644 --- a/src/render/renderers/opengl/managers/glresourcemanagers.cpp +++ b/src/render/qrendererplugin.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. @@ -37,9 +37,7 @@ ** ****************************************************************************/ -#include "glresourcemanagers_p.h" -#include <Qt3DRender/private/glbuffer_p.h> -#include <QOpenGLVertexArrayObject> +#include "qrendererplugin_p.h" QT_BEGIN_NAMESPACE @@ -47,23 +45,20 @@ namespace Qt3DRender { namespace Render { +QRendererPlugin::QRendererPlugin(QObject *parent) + : QObject(parent) +{ +} -GLResourceManagers::GLResourceManagers() - : m_glBufferManager(new GLBufferManager()) - , m_glShaderManager(new GLShaderManager()) - , m_glTextureManager(new GLTextureManager()) - , m_glFenceManager(new GLFenceManager()) - , m_vaoManager(new VAOManager()) +QRendererPlugin::~QRendererPlugin() { } -GLResourceManagers::~GLResourceManagers() +AbstractRenderer *QRendererPlugin::create(const QString &key, QRenderAspect::RenderType renderMode) { - delete m_vaoManager; - delete m_glFenceManager; - delete m_glTextureManager; - delete m_glShaderManager; - delete m_glBufferManager; + Q_UNUSED(key) + Q_UNUSED(renderMode) + return nullptr; } } // Render diff --git a/src/render/renderers/opengl/graphicshelpers/glfence_p.h b/src/render/qrendererplugin_p.h index 366065048..d4daeeda2 100644 --- a/src/render/renderers/opengl/graphicshelpers/glfence_p.h +++ b/src/render/qrendererplugin_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef GLFENCE_P_H -#define GLFENCE_P_H +#ifndef QT3DRENDER_RENDER_QRENDERERPLUGIN_P_H +#define QT3DRENDER_RENDER_QRENDERERPLUGIN_P_H // // W A R N I N G @@ -51,7 +51,11 @@ // We mean it. // -#include <QtGlobal> +#include <QtCore/QObject> +#include <QtCore/QtPlugin> +#include <QtCore/QFactoryInterface> +#include <Qt3DRender/private/qt3drender_global_p.h> +#include <Qt3DRender/qrenderaspect.h> QT_BEGIN_NAMESPACE @@ -59,15 +63,24 @@ namespace Qt3DRender { namespace Render { -// GLsync is a pointer to a struct (unlike the rest of GL which used int ids) -// We cannot reference GLsync as it's only available since 3.2 We use FenceId -// to wrap that around and trust the GLHelpers will convert them accordingly. -using GLFence = void *; +#define QRendererPluginFactoryInterface_iid "org.qt-project.Qt3DRender.QRendererFactoryInterface 5.11" -} // namespace Render -} // namespace Qt3DRender +class AbstractRenderer; -QT_END_NAMESPACE +class Q_3DRENDERSHARED_PRIVATE_EXPORT QRendererPlugin : public QObject +{ + Q_OBJECT +public: + explicit QRendererPlugin(QObject *parent = nullptr); + ~QRendererPlugin(); + + virtual AbstractRenderer *create(const QString &key, QRenderAspect::RenderType renderMode); +}; + +} // Render +} // Qt3DRender + +QT_END_NAMESPACE -#endif // GLFENCE_P_H +#endif // QT3DRENDER_RENDER_QRENDERERPLUGIN_P_H diff --git a/src/render/qrendererpluginfactory.cpp b/src/render/qrendererpluginfactory.cpp new file mode 100644 index 000000000..3cd41daed --- /dev/null +++ b/src/render/qrendererpluginfactory.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrendererpluginfactory_p.h" + +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> + +#include <Qt3DRender/private/qrendererplugin_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QRendererPluginFactoryInterface_iid, QLatin1String("/renderers"), Qt::CaseInsensitive)) +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, (QRendererPluginFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList QRendererPluginFactory::keys(const QString &pluginPath) +{ + QStringList list; + if (!pluginPath.isEmpty()) { +#if QT_CONFIG(library) + QCoreApplication::addLibraryPath(pluginPath); + list = directLoader()->keyMap().values(); + if (!list.isEmpty()) { + const QString postFix = QLatin1String(" (from ") + + QDir::toNativeSeparators(pluginPath) + + QLatin1Char(')'); + const QStringList::iterator end = list.end(); + for (QStringList::iterator it = list.begin(); it != end; ++it) + (*it).append(postFix); + } +#else + qWarning() << QObject::tr("Cannot query QRendererPlugin plugins at %1. " + "Library loading is disabled.").arg(pluginPath); +#endif + } + list.append(loader()->keyMap().values()); + return list; +} + +AbstractRenderer *QRendererPluginFactory::create(const QString &name, QRenderAspect::RenderType renderMode, const QString &pluginPath) +{ + if (!pluginPath.isEmpty()) { +#if QT_CONFIG(library) + QCoreApplication::addLibraryPath(pluginPath); + if (AbstractRenderer *ret = qLoadPlugin<AbstractRenderer, QRendererPlugin>(directLoader(), name, renderMode)) + return ret; +#else + qWarning() << QObject::tr("Cannot load QRendererPlugin plugin from %1. " + "Library loading is disabled.").arg(pluginPath); +#endif + } + return qLoadPlugin<AbstractRenderer, QRendererPlugin>(loader(), name, renderMode); +} + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/managers/gl_handle_types_p.h b/src/render/qrendererpluginfactory_p.h index eb25bab7f..f73cc8929 100644 --- a/src/render/renderers/opengl/managers/gl_handle_types_p.h +++ b/src/render/qrendererpluginfactory_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QT3DRENDER_RENDER_OPENGL_HANDLE_TYPES_P_H -#define QT3DRENDER_RENDER_OPENGL_HANDLE_TYPES_P_H +#ifndef QT3DRENDER_RENDER_QRENDERERPLUGINFACTORY_P_H +#define QT3DRENDER_RENDER_QRENDERERPLUGINFACTORY_P_H // // W A R N I N G @@ -51,7 +51,9 @@ // We mean it. // -#include <Qt3DCore/private/qhandle_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> +#include <Qt3DRender/qrenderaspect.h> +#include <QtCore/QStringList> QT_BEGIN_NAMESPACE @@ -59,18 +61,19 @@ namespace Qt3DRender { namespace Render { -class GLBuffer; -class GLTexture; -class OpenGLVertexArrayObject; +class AbstractRenderer; -typedef Qt3DCore::QHandle<GLBuffer> HGLBuffer; -typedef Qt3DCore::QHandle<OpenGLVertexArrayObject> HVao; -typedef Qt3DCore::QHandle<GLTexture> HGLTexture; +class Q_3DRENDERSHARED_PRIVATE_EXPORT QRendererPluginFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static AbstractRenderer *create(const QString &name, QRenderAspect::RenderType renderMode, const QString &pluginPath = QString()); +}; -} // namespace Render +} // Render -} // namespace Qt3DRender +} // Qt3DRender QT_END_NAMESPACE -#endif // QT3DRENDER_RENDER_OPENGL_HANDLE_TYPES_P_H +#endif // QT3DRENDER_RENDER_QRENDERERPLUGINFACTORY_P_H diff --git a/src/render/render.pro b/src/render/render.pro index f8d44151f..bf7ef072f 100644 --- a/src/render/render.pro +++ b/src/render/render.pro @@ -1,8 +1,7 @@ TARGET = Qt3DRender MODULE = 3drender -QT = core-private gui-private 3dcore-private -QT_PRIVATE = openglextensions +QT = core-private 3dcore-private QT_FOR_PRIVATE = concurrent DEFINES += BUILD_QT3D_MODULE @@ -19,7 +18,6 @@ include (picking/picking.pri) include (raycasting/raycasting.pri) include (services/services.pri) include (texture/texture.pri) -include (renderers/renderers.pri) gcov { QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage @@ -40,14 +38,19 @@ HEADERS += \ renderlogging_p.h \ qt3drender_global.h \ qt3drender_global_p.h \ - aligned_malloc_p.h + aligned_malloc_p.h \ + qrendererplugin_p.h \ + qrendererpluginfactory_p.h SOURCES += \ - renderlogging.cpp + renderlogging.cpp \ + qrendererplugin.cpp \ + qrendererpluginfactory.cpp MODULE_PLUGIN_TYPES = \ sceneparsers \ geometryloaders \ - renderplugins + renderplugins \ + renderers load(qt_module) diff --git a/src/render/renderers/opengl/debug/debug.pri b/src/render/renderers/opengl/debug/debug.pri deleted file mode 100644 index c5153bbf7..000000000 --- a/src/render/renderers/opengl/debug/debug.pri +++ /dev/null @@ -1,10 +0,0 @@ -INCLUDEPATH += $$PWD - -include($$QT3D_ROOT/src/3rdparty/imgui/imgui.pri) - -HEADERS += \ - $$PWD/imguirenderer_p.h \ - $$PWD/imconfig.h - -SOURCES += \ - $$PWD/imguirenderer.cpp diff --git a/src/render/renderers/opengl/debug/imguirenderer.cpp b/src/render/renderers/opengl/debug/imguirenderer.cpp deleted file mode 100644 index 8abe1b8c0..000000000 --- a/src/render/renderers/opengl/debug/imguirenderer.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - * Based on https://github.com/seanchas116/qtimgui/ - * - * MIT License https://github.com/seanchas116/qtimgui/blob/master/LICENSE - * - */ - -#include "imguirenderer_p.h" -#include <Qt3DRender/private/renderview_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/geometryrenderermanager_p.h> -#include <Qt3DRender/private/submissioncontext_p.h> - -#include <QDateTime> -#include <QGuiApplication> -#include <QMouseEvent> -#include <QClipboard> -#include <QCursor> -#include <QOpenGLExtraFunctions> - -#include "imgui.h" - -#ifndef GL_VERTEX_ARRAY_BINDING -// just for building on some platforms, won't run anyway as this requires GL/ES > 2 -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#endif - -QT_BEGIN_NAMESPACE - -using namespace Qt3DRender; -using namespace Render; -using namespace Render::Debug; - -namespace { - - const QHash<int, ImGuiKey> keyMap = { - { Qt::Key_Tab, ImGuiKey_Tab }, - { Qt::Key_Left, ImGuiKey_LeftArrow }, - { Qt::Key_Right, ImGuiKey_RightArrow }, - { Qt::Key_Up, ImGuiKey_UpArrow }, - { Qt::Key_Down, ImGuiKey_DownArrow }, - { Qt::Key_PageUp, ImGuiKey_PageUp }, - { Qt::Key_PageDown, ImGuiKey_PageDown }, - { Qt::Key_Home, ImGuiKey_Home }, - { Qt::Key_End, ImGuiKey_End }, - { Qt::Key_Delete, ImGuiKey_Delete }, - { Qt::Key_Backspace, ImGuiKey_Backspace }, - { Qt::Key_Enter, ImGuiKey_Enter }, - { Qt::Key_Escape, ImGuiKey_Escape }, - { Qt::Key_A, ImGuiKey_A }, - { Qt::Key_C, ImGuiKey_C }, - { Qt::Key_V, ImGuiKey_V }, - { Qt::Key_X, ImGuiKey_X }, - { Qt::Key_Y, ImGuiKey_Y }, - { Qt::Key_Z, ImGuiKey_Z }, - }; - - QByteArray g_currentClipboardText; - - // doesn't handle primitive restart when using indexes - int vertexToPrimitiveCount(Qt3DRender::QGeometryRenderer::PrimitiveType primitiveType, int numVertices) { - int nPrimitives = 0; - switch (primitiveType) { - case QGeometryRenderer::Points: - case QGeometryRenderer::LineLoop: nPrimitives += numVertices; break; - case QGeometryRenderer::Triangles: nPrimitives += numVertices / 3; break; - case QGeometryRenderer::Lines: nPrimitives += numVertices / 2; break; - case QGeometryRenderer::TriangleFan: - case QGeometryRenderer::TriangleStrip: - case QGeometryRenderer::LineStrip: nPrimitives += numVertices - 1; break; - case QGeometryRenderer::TrianglesAdjacency: nPrimitives += numVertices / 6; break; - case QGeometryRenderer::TriangleStripAdjacency: - case QGeometryRenderer::LineStripAdjacency: nPrimitives += numVertices / 2 - 1; break; - case QGeometryRenderer::LinesAdjacency: nPrimitives += numVertices / 4; break; - case QGeometryRenderer::Patches: nPrimitives += 1; - } - return nPrimitives; - } - - const char *primitiveTypeName(Qt3DRender::QGeometryRenderer::PrimitiveType primitiveType) { - switch (primitiveType) { - case QGeometryRenderer::Points: return "Points"; - case QGeometryRenderer::LineLoop: return "LineLoop"; - case QGeometryRenderer::Triangles: return "Triangles"; - case QGeometryRenderer::TrianglesAdjacency: return "TriangleAdjacency"; - case QGeometryRenderer::TriangleFan: return "TriangleFan"; - case QGeometryRenderer::TriangleStrip: return "TriangleStrip"; - case QGeometryRenderer::TriangleStripAdjacency: return "TriangleStringAdjacency"; - case QGeometryRenderer::LineStrip: return "LineStrip"; - case QGeometryRenderer::LineStripAdjacency: return "LineStripAdjacency"; - case QGeometryRenderer::Lines: return "Lines"; - case QGeometryRenderer::LinesAdjacency: return "LinesAdjacency"; - case QGeometryRenderer::Patches: return "Patches"; - } - return ""; - } -} - -ImGuiRenderer::ImGuiRenderer(Renderer *renderer) - : m_renderer(renderer) -{ - ImGui::CreateContext(); - - ImGuiIO &io = ImGui::GetIO(); - for (ImGuiKey key : keyMap.values()) - io.KeyMap[key] = key; - -#ifndef QT_NO_CLIPBOARD - io.SetClipboardTextFn = [](void *user_data, const char *text) { - Q_UNUSED(user_data) - QGuiApplication::clipboard()->setText(QString::fromLatin1(text)); - }; - io.GetClipboardTextFn = [](void *user_data) { - Q_UNUSED(user_data) - g_currentClipboardText = QGuiApplication::clipboard()->text().toUtf8(); - return static_cast<const char *>(g_currentClipboardText.data()); - }; -#endif - - std::fill(std::begin(m_fpsLog), std::end(m_fpsLog), 0.f); - std::fill(std::begin(m_jobsLog), std::end(m_jobsLog), 0.f); - m_fpsRange.first = m_fpsRange.second = 0.f; - m_jobsRange.first = m_jobsRange.second = 0.f; -} - -void ImGuiRenderer::renderDebugOverlay(const QVector<RenderView *> &renderViews, const RenderView *renderView, int jobsInLastFrame) -{ - if (!newFrame(renderView)) - return; - - const int renderViewsCount = renderViews.size(); - - int logIndex = qMin(IMGUI_PERF_LOG_SIZE - 1, ImGui::GetFrameCount()); - if (logIndex == IMGUI_PERF_LOG_SIZE - 1) { - std::rotate(std::begin(m_fpsLog), std::begin(m_fpsLog) + 1, std::end(m_fpsLog)); - std::rotate(std::begin(m_jobsLog), std::begin(m_jobsLog) + 1, std::end(m_jobsLog)); - } - m_fpsLog[logIndex] = ImGui::GetIO().Framerate; - m_fpsRange.first = m_fpsRange.second = 0.f; - for (float v: m_fpsLog) { - m_fpsRange.first = qMin(m_fpsRange.first, qMax(v - 5.f, 0.f)); - m_fpsRange.second = qMax(m_fpsRange.second, v + 2.f); - } - m_jobsLog[logIndex] = jobsInLastFrame; - m_jobsRange.first = m_jobsRange.second = 0.f; - for (float v: m_jobsLog) { - m_jobsRange.first = qMin(m_jobsRange.first, qMax(v - 5.f, 0.f)); - m_jobsRange.second = qMax(m_jobsRange.second, v + 2.f); - } - - { - bool pj = m_renderer->services()->systemInformation()->isTraceEnabled(); - bool pg = m_renderer->services()->systemInformation()->isGraphicsTraceEnabled(); - - ImGui::Begin("Qt3D Profiling"); - char caption[50]; - sprintf(caption, "Avg %.3f ms/frame (%.1f FPS)", static_cast<double>(1000.0f / ImGui::GetIO().Framerate), static_cast<double>(ImGui::GetIO().Framerate)); - ImGui::PlotLines("FPS", m_fpsLog, logIndex + 1, 0, caption, m_fpsRange.first, m_fpsRange.second, ImVec2(0, 80)); - ImGui::PlotHistogram("Jobs", m_jobsLog, logIndex + 1, 0, nullptr, m_jobsRange.first, m_jobsRange.second, ImVec2(0, 80)); - ImGui::Text("Profiling: "); - ImGui::SameLine(); - if (ImGui::Checkbox("Jobs", &pj)) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "setTraceEnabled", Qt::QueuedConnection, Q_ARG(bool, pj)); - ImGui::SameLine(); - if (ImGui::Checkbox("GL", &pg)) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "setGraphicsTraceEnabled", Qt::QueuedConnection, Q_ARG(bool, pg)); - ImGui::SameLine(); - if (ImGui::Button("Reveal")) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "revealLogFolder", Qt::QueuedConnection); - - int nCommands = 0; - int nVertices = 0; - int nPrimitives = 0; - QSet<HGeometryRenderer> inUseGeometries; - QSet<Qt3DCore::QNodeId> inUseTextures; - for (int j=0; j<renderViewsCount; j++) { - const auto &commands = renderViews.at(j)->commands(); - nCommands += commands.size(); - for (int k=0; k<commands.size(); k++) { - const RenderCommand &command = commands.at(k); - if (command.m_type != RenderCommand::Draw) - continue; - nVertices += command.m_primitiveCount; - nPrimitives += vertexToPrimitiveCount(command.m_primitiveType, command.m_primitiveCount); - inUseGeometries.insert(command.m_geometryRenderer); - const auto &textures = command.m_parameterPack.textures(); - for (const auto &ns: textures) - inUseTextures.insert(ns.nodeId); - } - } - - auto columnNumber = [](int i) { - if (i == 0) - ImGui::Text("--"); - else - ImGui::Text(" %d", i); - ImGui::NextColumn(); - }; - auto column2Numbers = [](int i, int of) { - if (of == 0) - ImGui::Text("--"); - else - ImGui::Text(" %d of %d", i, of); - ImGui::NextColumn(); - }; - - ImGui::Columns(5); - ImGui::Separator(); - for (auto s: {"Jobs", "RV", "Cmds", "Verts", "Prims"}) { - ImGui::Text("#%s", s); - ImGui::NextColumn(); - } - for (auto s: {jobsInLastFrame, renderViewsCount, nCommands, nVertices, nPrimitives}) - columnNumber(s); - - ImGui::Columns(3); - ImGui::Separator(); - for (auto s: {"Entities", "Geometries", "Textures"}) { - ImGui::Text("#%s", s); - ImGui::NextColumn(); - } - columnNumber(m_renderer->nodeManagers()->renderNodesManager()->count()); - column2Numbers(inUseGeometries.size(), m_renderer->nodeManagers()->geometryRendererManager()->count()); - column2Numbers(inUseTextures.size(), m_renderer->nodeManagers()->textureManager()->count()); - - ImGui::Columns(1); - ImGui::Separator(); - - ImGui::AlignTextToFramePadding(); - ImGui::Text("Show:"); - ImGui::SameLine(); - if (ImGui::Button("GL Info")) - m_showGLInfoWindow = !m_showGLInfoWindow; - ImGui::SameLine(); - if (ImGui::Button("Render Views")) - m_showRenderDetailsWindow = !m_showRenderDetailsWindow; - - ImGui::AlignTextToFramePadding(); - ImGui::Text("Dump:"); - ImGui::SameLine(); - if (ImGui::Button("SceneGraph##1")) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand", - Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render scenegraph"))); - ImGui::SameLine(); - if (ImGui::Button("FrameGraph##1")) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand", - Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render framegraph"))); - ImGui::SameLine(); - if (ImGui::Button("FrameGraph Paths##1")) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand", - Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render framepaths"))); - - ImGui::End(); - - if (m_showGLInfoWindow) - showGLInfo(); - if (m_showRenderDetailsWindow) - showRenderDetails(renderViews); - } - - ImGui::Render(); - renderDrawList(ImGui::GetDrawData()); -} - -void ImGuiRenderer::setCapabilities(const QString &capabilities) -{ - m_capabilities = capabilities.toLatin1(); -} - -void ImGuiRenderer::showGLInfo() -{ - ImGui::Begin("Open GL Details", &m_showGLInfoWindow); - ImGui::Text("%s", m_capabilities.data()); - ImGui::End(); -} - -void ImGuiRenderer::showRenderDetails(const QVector<RenderView *> &renderViews) -{ - ImGui::Begin("Render Views", &m_showRenderDetailsWindow); - - int i = 1; - for (const RenderView *view: renderViews) { - QString label(QLatin1String("View ") + QString::number(i++)); - if (ImGui::TreeNode(label.toLatin1().data())) { - ImGui::Text("Viewport: (%.1f, %.1f, %.1f, %.1f)", view->viewport().x(), view->viewport().y(), - view->viewport().width(), view->viewport().height()); - ImGui::Text("Surface Size: (%d, %d)", view->surfaceSize().width(), view->surfaceSize().height()); - ImGui::Text("Pixel Ratio: %.1f", view->devicePixelRatio()); - ImGui::Text("No Draw: %s", view->noDraw() ? "TRUE" : "FALSE"); - ImGui::Text("Frustum Culling: %s", view->frustumCulling() ? "TRUE" : "FALSE"); - ImGui::Text("Compute: %s", view->isCompute() ? "TRUE" : "FALSE"); - ImGui::Text("Clear Depth Value: %f", static_cast<double>(view->clearDepthValue())); - ImGui::Text("Clear Stencil Value: %d", view->clearStencilValue()); - int j = 1; - const auto commands = view->commands(); - for (const RenderCommand &command: commands) { - QString label(QLatin1String("Command ") + QString::number(j++)); - if (ImGui::TreeNode(label.toLatin1().data())) { - ImGui::Text("Primitive Type: %s %s", primitiveTypeName(command.m_primitiveType), - command.m_drawIndexed ? "(indexed)" : ""); - ImGui::Text("# Vertices: %d", command.m_primitiveCount); - ImGui::Text("# Primitives: %d", vertexToPrimitiveCount(command.m_primitiveType, command.m_primitiveCount)); - ImGui::Text("# Instances: %d", command.m_instanceCount); - ImGui::TreePop(); - } - } - ImGui::TreePop(); - ImGui::Separator(); - } - } - - if (ImGui::Button("Dump")) - QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand", - Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render rendercommands"))); - ImGui::End(); -} - -void ImGuiRenderer::renderDrawList(ImDrawData *draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = int(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = int(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // Backup GL state - GLint last_active_texture; m_funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); - m_funcs->glActiveTexture(GL_TEXTURE0); - GLint last_program; m_funcs->glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; m_funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_array_buffer; m_funcs->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - GLint last_element_array_buffer; m_funcs->glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); - GLint last_vertex_array; m_funcs->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src_rgb; m_funcs->glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); - GLint last_blend_dst_rgb; m_funcs->glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); - GLint last_blend_src_alpha; m_funcs->glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); - GLint last_blend_dst_alpha; m_funcs->glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); - GLint last_blend_equation_rgb; m_funcs->glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); - GLint last_blend_equation_alpha; m_funcs->glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); - GLint last_viewport[4]; m_funcs->glGetIntegerv(GL_VIEWPORT, last_viewport); - GLint last_scissor_box[4]; m_funcs->glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); - GLboolean last_enable_blend = m_funcs->glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = m_funcs->glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = m_funcs->glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = m_funcs->glIsEnabled(GL_SCISSOR_TEST); - - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - m_funcs->glEnable(GL_BLEND); - m_funcs->glBlendEquation(GL_FUNC_ADD); - m_funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - m_funcs->glDisable(GL_CULL_FACE); - m_funcs->glDisable(GL_DEPTH_TEST); - m_funcs->glEnable(GL_SCISSOR_TEST); - - // Setup viewport, orthographic projection matrix - m_funcs->glViewport(0, 0, static_cast<GLsizei>(fb_width), static_cast<GLsizei>(fb_height)); - const float ortho_projection[4][4] = { - { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, - { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - {-1.0f, 1.0f, 0.0f, 1.0f }, - }; - m_funcs->glUseProgram(m_shaderHandle); - m_funcs->glUniform1i(m_attribLocationTex, 0); - m_funcs->glUniformMatrix4fv(m_attribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - m_funcs->glBindVertexArray(m_vaoHandle); - - for (int n = 0; n < draw_data->CmdListsCount; n++) { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const ImDrawIdx* idx_buffer_offset = nullptr; - - m_funcs->glBindBuffer(GL_ARRAY_BUFFER, m_vboHandle); - m_funcs->glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(cmd_list->VtxBuffer.Size) * sizeof(ImDrawVert), static_cast<const GLvoid*>(cmd_list->VtxBuffer.Data), GL_STREAM_DRAW); - - m_funcs->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsHandle); - m_funcs->glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLsizeiptr>(cmd_list->IdxBuffer.Size) * sizeof(ImDrawIdx), static_cast<const GLvoid*>(cmd_list->IdxBuffer.Data), GL_STREAM_DRAW); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) { - pcmd->UserCallback(cmd_list, pcmd); - } else { - m_funcs->glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - m_funcs->glScissor(static_cast<int>(pcmd->ClipRect.x), static_cast<int>(fb_height - pcmd->ClipRect.w), - static_cast<int>(pcmd->ClipRect.z - pcmd->ClipRect.x), static_cast<int>(pcmd->ClipRect.w - pcmd->ClipRect.y)); - m_funcs->glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(pcmd->ElemCount), sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); - } - idx_buffer_offset += pcmd->ElemCount; - } - } - - // Restore modified GL state - m_funcs->glUseProgram(last_program); - m_funcs->glBindTexture(GL_TEXTURE_2D, last_texture); - m_funcs->glActiveTexture(last_active_texture); - m_funcs->glBindVertexArray(last_vertex_array); - m_funcs->glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - m_funcs->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); - m_funcs->glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - m_funcs->glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); - if (last_enable_blend) - m_funcs->glEnable(GL_BLEND); else m_funcs->glDisable(GL_BLEND); - if (last_enable_cull_face) - m_funcs->glEnable(GL_CULL_FACE); else m_funcs->glDisable(GL_CULL_FACE); - if (last_enable_depth_test) - m_funcs->glEnable(GL_DEPTH_TEST); else m_funcs->glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) - m_funcs->glEnable(GL_SCISSOR_TEST); else m_funcs->glDisable(GL_SCISSOR_TEST); - m_funcs->glViewport(last_viewport[0], last_viewport[1], static_cast<GLsizei>(last_viewport[2]), static_cast<GLsizei>(last_viewport[3])); - m_funcs->glScissor(last_scissor_box[0], last_scissor_box[1], static_cast<GLsizei>(last_scissor_box[2]), static_cast<GLsizei>(last_scissor_box[3])); -} - -bool ImGuiRenderer::createFontsTexture() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. - - // Upload texture to graphics system - GLint last_texture; - m_funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - m_funcs->glGenTextures(1, &m_fontTexture); - m_funcs->glBindTexture(GL_TEXTURE_2D, m_fontTexture); - m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)m_fontTexture; - - // Restore state - m_funcs->glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -bool ImGuiRenderer::createDeviceObjects() -{ - auto *glContext = m_renderer->submissionContext()->openGLContext(); - if (glContext->format().majorVersion() < 3) { - qWarning() << "Qt3D Profiling overlay requires GL or GL ES >= 3"; - return false; - } - - // Backup GL state - GLint last_texture, last_array_buffer, last_vertex_array; - m_funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - m_funcs->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - m_funcs->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - - const GLchar *vertex_shader = - "#version 330\n" - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 UV;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - - const GLchar* fragment_shader = - "#version 330\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "out vec4 Out_Color;\n" - "void main()\n" - "{\n" - " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" - "}\n"; - - const GLchar *vertex_shader_es3 = - "#version 110\n" - "uniform mat4 ProjMtx;\n" - "in vec2 Position;\n" - "in vec2 UV;\n" - "in vec4 Color;\n" - "out vec2 Frag_UV;\n" - "out vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " Frag_UV = UV;\n" - " Frag_Color = Color;\n" - " gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n" - "}\n"; - - const GLchar* fragment_shader_es3 = - "#version 110\n" - "uniform sampler2D Texture;\n" - "in vec2 Frag_UV;\n" - "in vec4 Frag_Color;\n" - "void main()\n" - "{\n" - " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" - "}\n"; - -// m_shaderHandle = m_funcs->glCreateProgram(); -// m_vertHandle = m_funcs->glCreateShader(GL_VERTEX_SHADER); -// m_fragHandle = m_funcs->glCreateShader(GL_FRAGMENT_SHADER); -// auto *glContext = m_renderer->submissionContext()->openGLContext(); -// m_funcs->glShaderSource(m_vertHandle, 1, &vertex_shader, nullptr); -// m_funcs->glShaderSource(m_fragHandle, 1, &fragment_shader, nullptr); -// m_funcs->glCompileShader(m_vertHandle); -// m_funcs->glCompileShader(m_fragHandle); -// m_funcs->glAttachShader(m_shaderHandle, m_vertHandle); -// m_funcs->glAttachShader(m_shaderHandle, m_fragHandle); -// m_funcs->glLinkProgram(m_shaderHandle); - - QString logs; - m_shader = new QOpenGLShaderProgram(this); - if (glContext->isOpenGLES()) { - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader_es3)) - logs += m_shader->log(); - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader_es3)) - logs += m_shader->log(); - } else { - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader)) - logs += m_shader->log(); - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader)) - logs += m_shader->log(); - } - m_shader->link(); - logs += m_shader->log(); - if (!logs.isEmpty()) - qWarning() << logs; - m_shaderHandle = m_shader->programId(); - - m_attribLocationTex = m_funcs->glGetUniformLocation(m_shaderHandle, "Texture"); - m_attribLocationProjMtx = m_funcs->glGetUniformLocation(m_shaderHandle, "ProjMtx"); - m_attribLocationPosition = m_funcs->glGetAttribLocation(m_shaderHandle, "Position"); - m_attribLocationUV = m_funcs->glGetAttribLocation(m_shaderHandle, "UV"); - m_attribLocationColor = m_funcs->glGetAttribLocation(m_shaderHandle, "Color"); - - m_funcs->glGenBuffers(1, &m_vboHandle); - m_funcs->glGenBuffers(1, &m_elementsHandle); - - m_funcs->glGenVertexArrays(1, &m_vaoHandle); - m_funcs->glBindVertexArray(m_vaoHandle); - m_funcs->glBindBuffer(GL_ARRAY_BUFFER, m_vboHandle); - m_funcs->glEnableVertexAttribArray(m_attribLocationPosition); - m_funcs->glEnableVertexAttribArray(m_attribLocationUV); - m_funcs->glEnableVertexAttribArray(m_attribLocationColor); - -#define OFFSETOF(TYPE, ELEMENT) (reinterpret_cast<size_t>(&((static_cast<TYPE *>(nullptr))->ELEMENT))) - m_funcs->glVertexAttribPointer(m_attribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), reinterpret_cast<GLvoid*>(OFFSETOF(ImDrawVert, pos))); - m_funcs->glVertexAttribPointer(m_attribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), reinterpret_cast<GLvoid*>(OFFSETOF(ImDrawVert, uv))); - m_funcs->glVertexAttribPointer(m_attribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), reinterpret_cast<GLvoid*>(OFFSETOF(ImDrawVert, col))); -#undef OFFSETOF - - createFontsTexture(); - - // Restore modified GL state - m_funcs->glBindTexture(GL_TEXTURE_2D, last_texture); - m_funcs->glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - m_funcs->glBindVertexArray(last_vertex_array); - - return true; -} - -bool ImGuiRenderer::newFrame(const RenderView *renderView) -{ - if (!m_funcs) - m_funcs = m_renderer->submissionContext()->openGLContext()->extraFunctions(); - if (!m_fontTexture) - createDeviceObjects(); - if (!m_shader) - return false; - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - io.DisplaySize = ImVec2(renderView->surfaceSize().width() / renderView->devicePixelRatio(), renderView->surfaceSize().height() / renderView->devicePixelRatio()); - io.DisplayFramebufferScale = ImVec2(renderView->devicePixelRatio(), renderView->devicePixelRatio()); - - // Setup time step - double current_time = QDateTime::currentMSecsSinceEpoch() / 1000.; - io.DeltaTime = m_time > 0.0 ? static_cast<float>(current_time - m_time) : 1.0f / 60.0f; - if (io.DeltaTime == 0.f) - io.DeltaTime = 1.0f / 60.0f; - m_time = current_time; - - // Setup inputs - for (int i = 0; i < 3; i++) - io.MouseDown[i] = m_mousePressed[i]; - - io.MouseWheelH = m_mouseWheelH; - io.MouseWheel = m_mouseWheel; - m_mouseWheelH = 0; - m_mouseWheel = 0; - - // Start the frame - ImGui::NewFrame(); - return true; -} - -void ImGuiRenderer::onMouseChange(QMouseEvent *event) -{ - ImGuiIO& io = ImGui::GetIO(); - io.MousePos = ImVec2(event->pos().x(), event->pos().y()); - m_mousePressed[0] = event->buttons() & Qt::LeftButton; - m_mousePressed[1] = event->buttons() & Qt::RightButton; - m_mousePressed[2] = event->buttons() & Qt::MiddleButton; -} - -void ImGuiRenderer::onWheel(QWheelEvent *event) -{ - // 5 lines per unit - m_mouseWheelH += event->pixelDelta().x() / (ImGui::GetTextLineHeight()); - m_mouseWheel += event->pixelDelta().y() / (5.f * ImGui::GetTextLineHeight()); -} - -void ImGuiRenderer::onKeyPressRelease(QKeyEvent *event) -{ - ImGuiIO& io = ImGui::GetIO(); - if (keyMap.contains(event->key())) - io.KeysDown[keyMap[event->key()]] = event->type() == QEvent::KeyPress; - - if (event->type() == QEvent::KeyPress) { - QString text = event->text(); - if (text.size() == 1) - io.AddInputCharacter(static_cast<ImWchar>(text.at(0).unicode())); - } - -#ifdef Q_OS_DARWIN - io.KeyCtrl = event->modifiers() & Qt::MetaModifier; - io.KeyShift = event->modifiers() & Qt::ShiftModifier; - io.KeyAlt = event->modifiers() & Qt::AltModifier; - io.KeySuper = event->modifiers() & Qt::ControlModifier; // Command key -#else - io.KeyCtrl = event->modifiers() & Qt::ControlModifier; - io.KeyShift = event->modifiers() & Qt::ShiftModifier; - io.KeyAlt = event->modifiers() & Qt::AltModifier; - io.KeySuper = event->modifiers() & Qt::MetaModifier; -#endif -} - -void ImGuiRenderer::processEvent(QEvent *event) -{ - switch (event->type()) { - case QEvent::MouseMove: - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - this->onMouseChange(static_cast<QMouseEvent *>(event)); - break; - case QEvent::Wheel: - this->onWheel(static_cast<QWheelEvent *>(event)); - break; - case QEvent::KeyPress: - case QEvent::KeyRelease: - this->onKeyPressRelease(static_cast<QKeyEvent *>(event)); - break; - default: - break; - } -} - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/debug/imguirenderer_p.h b/src/render/renderers/opengl/debug/imguirenderer_p.h deleted file mode 100644 index e574574be..000000000 --- a/src/render/renderers/opengl/debug/imguirenderer_p.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3D_RENDER_GL_IMGUIRENDER_H_ -#define QT3D_RENDER_GL_IMGUIRENDER_H_ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QObject> -#include <QOpenGLFunctions> -#include <QPoint> -#include <memory> - -struct ImDrawData; - -QT_BEGIN_NAMESPACE - -class QMouseEvent; -class QWheelEvent; -class QKeyEvent; -class QOpenGLExtraFunctions; -class QOpenGLShaderProgram; - -namespace Qt3DCore { -class QServiceLocator; -} - -namespace Qt3DRender { -namespace Render { - -class RenderView; -class Renderer; - -namespace Debug { - -#define IMGUI_PERF_LOG_SIZE 30 - -class ImGuiRenderer : public QObject { - Q_OBJECT -public: - ImGuiRenderer(Qt3DRender::Render::Renderer *renderer); - - void processEvent(QEvent *event); - void renderDebugOverlay(const QVector<Render::RenderView *> &renderViews, const Render::RenderView *renderView, int jobsInLastFrame); - - void setCapabilities(const QString &capabilities); - -private: - bool newFrame(const RenderView *renderView); - void renderDrawList(ImDrawData *draw_data); - void onMouseChange(QMouseEvent *event); - void onWheel(QWheelEvent *event); - void onKeyPressRelease(QKeyEvent *event); - void showGLInfo(); - void showRenderDetails(const QVector<Render::RenderView *> &renderViews); - - bool createFontsTexture(); - bool createDeviceObjects(); - - double m_time = 0.; - bool m_mousePressed[3] = { false, false, false }; - float m_mouseWheel; - float m_mouseWheelH; - GLuint m_fontTexture = 0; - GLuint m_shaderHandle = 0, m_vertHandle = 0, m_fragHandle = 0; - int m_attribLocationTex = 0, m_attribLocationProjMtx = 0; - int m_attribLocationPosition = 0, m_attribLocationUV = 0, m_attribLocationColor = 0; - unsigned int m_vboHandle = 0, m_vaoHandle = 0, m_elementsHandle = 0; - - Renderer *m_renderer; - QOpenGLExtraFunctions *m_funcs = nullptr; - QOpenGLShaderProgram *m_shader = nullptr; - - bool m_showGLInfoWindow = false; - bool m_showRenderDetailsWindow = false; - - float m_fpsLog[IMGUI_PERF_LOG_SIZE]; - float m_jobsLog[IMGUI_PERF_LOG_SIZE]; - std::pair<float, float> m_fpsRange; - std::pair<float, float> m_jobsRange; - - QByteArray m_capabilities; -}; - -} // namespace Debug -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3D_RENDER_GL_IMGUIRENDER_H_ diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp b/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp deleted file mode 100644 index 25543bb19..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicscontext.cpp +++ /dev/null @@ -1,1026 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicscontext_p.h" - -#include <Qt3DRender/qgraphicsapifilter.h> -#include <Qt3DRender/qparameter.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/shader_p.h> -#include <Qt3DRender/private/material_p.h> -#include <Qt3DRender/private/gltexture_p.h> -#include <Qt3DRender/private/buffer_p.h> -#include <Qt3DRender/private/attribute_p.h> -#include <Qt3DRender/private/rendercommand_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/rendertarget_p.h> -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/buffermanager_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/glresourcemanagers_p.h> -#include <Qt3DRender/private/attachmentpack_p.h> -#include <Qt3DRender/private/qbuffer_p.h> -#include <Qt3DRender/private/renderbuffer_p.h> -#include <Qt3DRender/private/glshader_p.h> -#include <QOpenGLShaderProgram> - -#if !defined(QT_OPENGL_ES_2) -#include <QOpenGLFunctions_2_0> -#include <QOpenGLFunctions_3_2_Core> -#include <QOpenGLFunctions_3_3_Core> -#include <QOpenGLFunctions_4_3_Core> -#include <Qt3DRender/private/graphicshelpergl2_p.h> -#include <Qt3DRender/private/graphicshelpergl3_2_p.h> -#include <Qt3DRender/private/graphicshelpergl3_3_p.h> -#include <Qt3DRender/private/graphicshelpergl4_p.h> -#endif -#include <Qt3DRender/private/graphicshelperes2_p.h> -#include <Qt3DRender/private/graphicshelperes3_p.h> -#include <Qt3DRender/private/graphicshelperes3_1_p.h> -#include <Qt3DRender/private/graphicshelperes3_2_p.h> - -#include <QSurface> -#include <QWindow> -#include <QOpenGLTexture> -#include <QOpenGLDebugLogger> - -QT_BEGIN_NAMESPACE - -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif - -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -#ifndef GL_MAX_IMAGE_UNITS -#define GL_MAX_IMAGE_UNITS 0x8F38 -#endif - -namespace { - -QOpenGLShader::ShaderType shaderType(Qt3DRender::QShaderProgram::ShaderType type) -{ - switch (type) { - case Qt3DRender::QShaderProgram::Vertex: return QOpenGLShader::Vertex; - case Qt3DRender::QShaderProgram::TessellationControl: return QOpenGLShader::TessellationControl; - case Qt3DRender::QShaderProgram::TessellationEvaluation: return QOpenGLShader::TessellationEvaluation; - case Qt3DRender::QShaderProgram::Geometry: return QOpenGLShader::Geometry; - case Qt3DRender::QShaderProgram::Fragment: return QOpenGLShader::Fragment; - case Qt3DRender::QShaderProgram::Compute: return QOpenGLShader::Compute; - default: Q_UNREACHABLE(); - } -} - -} // anonymous namespace - -namespace Qt3DRender { -namespace Render { - -namespace { - -void logOpenGLDebugMessage(const QOpenGLDebugMessage &debugMessage) -{ - qDebug() << "OpenGL debug message:" << debugMessage; -} - -} // anonymous - -GraphicsContext::GraphicsContext() - : m_initialized(false) - , m_supportsVAO(false) - , m_maxTextureUnits(0) - , m_maxImageUnits(0) - , m_defaultFBO(0) - , m_gl(nullptr) - , m_glHelper(nullptr) - , m_debugLogger(nullptr) - , m_currentVAO(nullptr) -{ -} - -GraphicsContext::~GraphicsContext() -{ -} - -void GraphicsContext::setOpenGLContext(QOpenGLContext* ctx) -{ - Q_ASSERT(ctx); - m_gl = ctx; -} - -void GraphicsContext::initialize() -{ - m_initialized = true; - - Q_ASSERT(m_gl); - - m_gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_maxTextureUnits); - qCDebug(Backend) << "context supports" << m_maxTextureUnits << "texture units"; - m_gl->functions()->glGetIntegerv(GL_MAX_IMAGE_UNITS, &m_maxImageUnits); - qCDebug(Backend) << "context supports" << m_maxImageUnits << "image units"; - - if (m_gl->format().majorVersion() >= 3) { - m_supportsVAO = true; - } else { - QSet<QByteArray> extensions = m_gl->extensions(); - m_supportsVAO = extensions.contains(QByteArrayLiteral("GL_OES_vertex_array_object")) - || extensions.contains(QByteArrayLiteral("GL_ARB_vertex_array_object")) - || extensions.contains(QByteArrayLiteral("GL_APPLE_vertex_array_object")); - } - - m_defaultFBO = m_gl->defaultFramebufferObject(); - qCDebug(Backend) << "VAO support = " << m_supportsVAO; -} - -void GraphicsContext::clearBackBuffer(QClearBuffers::BufferTypeFlags buffers) -{ - if (buffers != QClearBuffers::None) { - GLbitfield mask = 0; - - if (buffers & QClearBuffers::ColorBuffer) - mask |= GL_COLOR_BUFFER_BIT; - if (buffers & QClearBuffers::DepthBuffer) - mask |= GL_DEPTH_BUFFER_BIT; - if (buffers & QClearBuffers::StencilBuffer) - mask |= GL_STENCIL_BUFFER_BIT; - - m_gl->functions()->glClear(mask); - } -} - -bool GraphicsContext::hasValidGLHelper() const -{ - return m_glHelper != nullptr; -} - -bool GraphicsContext::isInitialized() const -{ - return m_initialized; -} - -bool GraphicsContext::makeCurrent(QSurface *surface) -{ - Q_ASSERT(m_gl); - if (!m_gl->makeCurrent(surface)) { - qCWarning(Backend) << Q_FUNC_INFO << "makeCurrent failed"; - return false; - } - - initializeHelpers(surface); - - return true; -} - -void GraphicsContext::initializeHelpers(QSurface *surface) -{ - // Set the correct GL Helper depending on the surface - // If no helper exists, create one - m_glHelper = m_glHelpers.value(surface); - if (!m_glHelper) { - m_glHelper = resolveHighestOpenGLFunctions(); - m_glHelpers.insert(surface, m_glHelper); - } -} - -void GraphicsContext::doneCurrent() -{ - Q_ASSERT(m_gl); - m_gl->doneCurrent(); - m_glHelper = nullptr; -} - -// Called by GL Command Thread -GraphicsContext::ShaderCreationInfo GraphicsContext::createShaderProgram(GLShader *shader) -{ - QOpenGLShaderProgram *shaderProgram = shader->shaderProgram(); - - // Compile shaders - const auto shaderCode = shader->shaderCode(); - - QString logs; - for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) { - const QShaderProgram::ShaderType type = static_cast<QShaderProgram::ShaderType>(i); - if (!shaderCode.at(i).isEmpty()) { - // Note: logs only return the error but not all the shader code - // we could append it - if (!shaderProgram->addCacheableShaderFromSourceCode(shaderType(type), shaderCode.at(i))) - logs += shaderProgram->log(); - } - } - - // Call glBindFragDataLocation and link the program - // Since we are sharing shaders in the backend, we assume that if using custom - // fragOutputs, they should all be the same for a given shader - bindFragOutputs(shaderProgram->programId(), shader->fragOutputs()); - - const bool linkSucceeded = shaderProgram->link(); - logs += shaderProgram->log(); - - // Perform shader introspection - introspectShaderInterface(shader); - - ShaderCreationInfo info; - info.linkSucceeded = linkSucceeded; - info.logs = logs; - - return info; -} - -// That assumes that the shaderProgram in Shader stays the same -void GraphicsContext::introspectShaderInterface(GLShader *shader) -{ - QOpenGLShaderProgram *shaderProgram = shader->shaderProgram(); - GraphicsHelperInterface *glHelper = resolveHighestOpenGLFunctions(); - shader->initializeUniforms(glHelper->programUniformsAndLocations(shaderProgram->programId())); - shader->initializeAttributes(glHelper->programAttributesAndLocations(shaderProgram->programId())); - if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject)) - shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(shaderProgram->programId())); - if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject)) - shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(shaderProgram->programId())); -} - - -// Called by Renderer::updateGLResources -void GraphicsContext::loadShader(Shader *shaderNode, - ShaderManager *shaderManager, - GLShaderManager *glShaderManager) -{ - const Qt3DCore::QNodeId shaderId = shaderNode->peerId(); - GLShader *glShader = glShaderManager->lookupResource(shaderId); - - // We already have a shader associated with the node - if (glShader != nullptr) { - // We need to abandon it - glShaderManager->abandon(glShader, shaderNode); - } - - // We create or adopt an already created glShader - glShader = glShaderManager->createOrAdoptExisting(shaderNode); - - const QVector<Qt3DCore::QNodeId> sharedShaderIds = glShaderManager->shaderIdsForProgram(glShader); - if (sharedShaderIds.size() == 1) { - // Shader in the cache hasn't been loaded yet - glShader->setGraphicsContext(this); - glShader->setShaderCode(shaderNode->shaderCode()); - const ShaderCreationInfo loadResult = createShaderProgram(glShader); - shaderNode->setStatus(loadResult.linkSucceeded ? QShaderProgram::Ready : QShaderProgram::Error); - shaderNode->setLog(loadResult.logs); - // Loaded in the sense we tried to load it (and maybe it failed) - glShader->setLoaded(true); - } else { - // Find an already loaded shader that shares the same QOpenGLShaderProgram - for (const Qt3DCore::QNodeId sharedShaderId : sharedShaderIds) { - if (sharedShaderId != shaderNode->peerId()) { - Shader *refShader = shaderManager->lookupResource(sharedShaderId); - // We only introspect once per actual OpenGL shader program - // rather than once per ShaderNode. - shaderNode->initializeFromReference(*refShader); - break; - } - } - } - shaderNode->unsetDirty(); - // Ensure we will rebuilt material caches - shaderNode->markDirty(AbstractRenderer::AllDirty); -} - -void GraphicsContext::activateDrawBuffers(const AttachmentPack &attachments) -{ - const QVector<int> activeDrawBuffers = attachments.getGlDrawBuffers(); - - if (m_glHelper->checkFrameBufferComplete()) { - if (activeDrawBuffers.size() > 1) {// We need MRT - if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT)) { - // Set up MRT, glDrawBuffers... - m_glHelper->drawBuffers(activeDrawBuffers.size(), activeDrawBuffers.data()); - } - } - } else { - qWarning() << "FBO incomplete"; - } -} - -void GraphicsContext::rasterMode(GLenum faceMode, GLenum rasterMode) -{ - m_glHelper->rasterMode(faceMode, rasterMode); -} - -/*! - * \internal - * Finds the highest supported opengl version and internally use the most optimized - * helper for a given version. - */ -GraphicsHelperInterface *GraphicsContext::resolveHighestOpenGLFunctions() -{ - Q_ASSERT(m_gl); - GraphicsHelperInterface *glHelper = nullptr; - - if (m_gl->isOpenGLES()) { - if (m_gl->format().majorVersion() >= 3) { - if (m_gl->format().minorVersion() >= 2) { - glHelper = new GraphicsHelperES3_2; - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.2 Helper"; - } else if (m_gl->format().minorVersion() >= 1) { - glHelper = new GraphicsHelperES3_1; - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.1 Helper"; - } else { - glHelper = new GraphicsHelperES3(); - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES 3.0 Helper"; - } - } else { - glHelper = new GraphicsHelperES2(); - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL ES2 Helper"; - } - glHelper->initializeHelper(m_gl, nullptr); - } -#ifndef QT_OPENGL_ES_2 - else { - QAbstractOpenGLFunctions *glFunctions = nullptr; - if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_4_3_Core>()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 4.3"; - glHelper = new GraphicsHelperGL4(); - } else if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_3_3_Core>()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.3"; - glHelper = new GraphicsHelperGL3_3(); - } else if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_3_2_Core>()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 3.2"; - glHelper = new GraphicsHelperGL3_2(); - } else if ((glFunctions = m_gl->versionFunctions<QOpenGLFunctions_2_0>()) != nullptr) { - qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 2 Helper"; - glHelper = new GraphicsHelperGL2(); - } - Q_ASSERT_X(glHelper, "GraphicsContext::resolveHighestOpenGLFunctions", "unable to create valid helper for available OpenGL version"); - glHelper->initializeHelper(m_gl, glFunctions); - } -#endif - - // Note: at this point we are certain the context (m_gl) is current with a surface - const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING"); - const bool enableDebugLogging = !debugLoggingMode.isEmpty(); - - if (enableDebugLogging && !m_debugLogger) { - if (m_gl->hasExtension("GL_KHR_debug")) { - qCDebug(Backend) << "Qt3D: Enabling OpenGL debug logging"; - m_debugLogger.reset(new QOpenGLDebugLogger); - if (m_debugLogger->initialize()) { - QObject::connect(m_debugLogger.data(), &QOpenGLDebugLogger::messageLogged, &logOpenGLDebugMessage); - const QString mode = QString::fromLocal8Bit(debugLoggingMode); - m_debugLogger->startLogging(mode.startsWith(QLatin1String("sync"), Qt::CaseInsensitive) - ? QOpenGLDebugLogger::SynchronousLogging - : QOpenGLDebugLogger::AsynchronousLogging); - - const auto msgs = m_debugLogger->loggedMessages(); - for (const QOpenGLDebugMessage &msg : msgs) - logOpenGLDebugMessage(msg); - } - } else { - qCDebug(Backend) << "Qt3D: OpenGL debug logging requested but GL_KHR_debug not supported"; - } - } - - - // Set Vendor and Extensions of reference GraphicsApiFilter - // TO DO: would that vary like the glHelper ? - - QStringList extensions; - const auto exts = m_gl->extensions(); - for (const QByteArray &ext : exts) - extensions << QString::fromUtf8(ext); - m_contextInfo.m_major = m_gl->format().version().first; - m_contextInfo.m_minor = m_gl->format().version().second; - m_contextInfo.m_api = m_gl->isOpenGLES() ? QGraphicsApiFilter::OpenGLES : QGraphicsApiFilter::OpenGL; - m_contextInfo.m_profile = static_cast<QGraphicsApiFilter::OpenGLProfile>(m_gl->format().profile()); - m_contextInfo.m_extensions = extensions; - m_contextInfo.m_vendor = QString::fromUtf8(reinterpret_cast<const char *>(m_gl->functions()->glGetString(GL_VENDOR))); - - return glHelper; -} - -const GraphicsApiFilterData *GraphicsContext::contextInfo() const -{ - return &m_contextInfo; -} - -bool GraphicsContext::supportsDrawBuffersBlend() const -{ - return m_glHelper->supportsFeature(GraphicsHelperInterface::DrawBuffersBlend); -} - -/*! - * \internal - * Wraps an OpenGL call to glDrawElementsInstanced. - * If the call is not supported by the system's OpenGL version, - * it is simulated with a loop. - */ -void GraphicsContext::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - m_glHelper->drawElementsInstancedBaseVertexBaseInstance(primitiveType, - primitiveCount, - indexType, - indices, - instances, - baseVertex, - baseInstance); -} - -/*! - * \internal - * Wraps an OpenGL call to glDrawArraysInstanced. - */ -void GraphicsContext::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) -{ - m_glHelper->drawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsContext::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseinstance) -{ - m_glHelper->drawArraysInstancedBaseInstance(primitiveType, - first, - count, - instances, - baseinstance); -} - -/*! - * \internal - * Wraps an OpenGL call to glDrawElements. - */ -void GraphicsContext::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) -{ - m_glHelper->drawElements(primitiveType, - primitiveCount, - indexType, - indices, - baseVertex); -} - -void GraphicsContext::drawElementsIndirect(GLenum mode, - GLenum type, - void *indirect) -{ - m_glHelper->drawElementsIndirect(mode, type, indirect); -} - -/*! - * \internal - * Wraps an OpenGL call to glDrawArrays. - */ -void GraphicsContext::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) -{ - m_glHelper->drawArrays(primitiveType, - first, - count); -} - -void GraphicsContext::drawArraysIndirect(GLenum mode, void *indirect) -{ - m_glHelper->drawArraysIndirect(mode, indirect); -} - -void GraphicsContext::setVerticesPerPatch(GLint verticesPerPatch) -{ - m_glHelper->setVerticesPerPatch(verticesPerPatch); -} - -void GraphicsContext::blendEquation(GLenum mode) -{ - m_glHelper->blendEquation(mode); -} - -void GraphicsContext::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) -{ - m_glHelper->blendFunci(buf, sfactor, dfactor); -} - -void GraphicsContext::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) -{ - m_glHelper->blendFuncSeparatei(buf, sRGB, dRGB, sAlpha, dAlpha); -} - -void GraphicsContext::alphaTest(GLenum mode1, GLenum mode2) -{ - m_glHelper->alphaTest(mode1, mode2); -} - -void GraphicsContext::bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode) -{ - m_glHelper->bindFrameBufferObject(fbo, mode); -} - -void GraphicsContext::depthRange(GLdouble nearValue, GLdouble farValue) -{ - m_glHelper->depthRange(nearValue, farValue); -} - -void GraphicsContext::depthTest(GLenum mode) -{ - m_glHelper->depthTest(mode); -} - -void GraphicsContext::depthMask(GLenum mode) -{ - m_glHelper->depthMask(mode); -} - -void GraphicsContext::frontFace(GLenum mode) -{ - m_glHelper->frontFace(mode); -} - -void GraphicsContext::bindFragOutputs(GLuint shader, const QHash<QString, int> &outputs) -{ - if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT) && - m_glHelper->supportsFeature(GraphicsHelperInterface::BindableFragmentOutputs)) - m_glHelper->bindFragDataLocation(shader, outputs); -} - -void GraphicsContext::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - m_glHelper->bindImageTexture(imageUnit, - texture, - mipLevel, - layered, - layer, - access, - format); -} - -void GraphicsContext::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - m_glHelper->bindUniformBlock(programId, uniformBlockIndex, uniformBlockBinding); -} - -void GraphicsContext::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) -{ - m_glHelper->bindShaderStorageBlock(programId, shaderStorageBlockIndex, shaderStorageBlockBinding); -} - -void GraphicsContext::bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer) -{ - m_glHelper->bindBufferBase(target, bindingIndex, buffer); -} - -void GraphicsContext::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - m_glHelper->buildUniformBuffer(v, description, buffer); -} - -void GraphicsContext::setMSAAEnabled(bool enabled) -{ - m_glHelper->setMSAAEnabled(enabled); -} - -void GraphicsContext::setAlphaCoverageEnabled(bool enabled) -{ - m_glHelper->setAlphaCoverageEnabled(enabled); -} - -void GraphicsContext::clearBufferf(GLint drawbuffer, const QVector4D &values) -{ - m_glHelper->clearBufferf(drawbuffer, values); -} - -GLuint GraphicsContext::boundFrameBufferObject() -{ - return m_glHelper->boundFrameBufferObject(); -} - -void GraphicsContext::clearColor(const QColor &color) -{ - m_gl->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); -} - -void GraphicsContext::clearDepthValue(float depth) -{ - m_gl->functions()->glClearDepthf(depth); -} - -void GraphicsContext::clearStencilValue(int stencil) -{ - m_gl->functions()->glClearStencil(stencil); -} - -void GraphicsContext::enableClipPlane(int clipPlane) -{ - m_glHelper->enableClipPlane(clipPlane); -} - -void GraphicsContext::disableClipPlane(int clipPlane) -{ - m_glHelper->disableClipPlane(clipPlane); -} - -void GraphicsContext::setClipPlane(int clipPlane, const QVector3D &normal, float distance) -{ - m_glHelper->setClipPlane(clipPlane, normal, distance); -} - -GLint GraphicsContext::maxClipPlaneCount() -{ - return m_glHelper->maxClipPlaneCount(); -} - -GLint GraphicsContext::maxTextureUnitsCount() const -{ - return m_maxTextureUnits; -} - -GLint GraphicsContext::maxImageUnitsCount() const -{ - return m_maxImageUnits; -} - - -void GraphicsContext::enablePrimitiveRestart(int restartIndex) -{ - if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) - m_glHelper->enablePrimitiveRestart(restartIndex); -} - -void GraphicsContext::disablePrimitiveRestart() -{ - if (m_glHelper->supportsFeature(GraphicsHelperInterface::PrimitiveRestart)) - m_glHelper->disablePrimitiveRestart(); -} - -void GraphicsContext::pointSize(bool programmable, GLfloat value) -{ - m_glHelper->pointSize(programmable, value); -} - -void GraphicsContext::dispatchCompute(int x, int y, int z) -{ - if (m_glHelper->supportsFeature(GraphicsHelperInterface::Compute)) - m_glHelper->dispatchCompute(x, y, z); -} - -GLboolean GraphicsContext::unmapBuffer(GLenum target) -{ - return m_glHelper->unmapBuffer(target); -} - -char *GraphicsContext::mapBuffer(GLenum target, GLsizeiptr size) -{ - return m_glHelper->mapBuffer(target, size); -} - -void GraphicsContext::enablei(GLenum cap, GLuint index) -{ - m_glHelper->enablei(cap, index); -} - -void GraphicsContext::disablei(GLenum cap, GLuint index) -{ - m_glHelper->disablei(cap, index); -} - -void GraphicsContext::setSeamlessCubemap(bool enable) -{ - m_glHelper->setSeamlessCubemap(enable); -} - -void GraphicsContext::readBuffer(GLenum mode) -{ - m_glHelper->readBuffer(mode); -} - -void GraphicsContext::drawBuffer(GLenum mode) -{ - m_glHelper->drawBuffer(mode); -} - -void GraphicsContext::drawBuffers(GLsizei n, const int *bufs) -{ - m_glHelper->drawBuffers(n, bufs); -} - -void GraphicsContext::applyUniform(const ShaderUniform &description, const UniformValue &v) -{ - const UniformType type = m_glHelper->uniformTypeFromGLType(description.m_type); - - switch (type) { - case UniformType::Float: - // See QTBUG-57510 and uniform_p.h - if (v.storedType() == Int) { - float value = float(*v.constData<int>()); - UniformValue floatV(value); - applyUniformHelper<UniformType::Float>(description, floatV); - } else { - applyUniformHelper<UniformType::Float>(description, v); - } - break; - case UniformType::Vec2: - applyUniformHelper<UniformType::Vec2>(description, v); - break; - case UniformType::Vec3: - applyUniformHelper<UniformType::Vec3>(description, v); - break; - case UniformType::Vec4: - applyUniformHelper<UniformType::Vec4>(description, v); - break; - - case UniformType::Double: - applyUniformHelper<UniformType::Double>(description, v); - break; - case UniformType::DVec2: - applyUniformHelper<UniformType::DVec2>(description, v); - break; - case UniformType::DVec3: - applyUniformHelper<UniformType::DVec3>(description, v); - break; - case UniformType::DVec4: - applyUniformHelper<UniformType::DVec4>(description, v); - break; - - case UniformType::Sampler: - case UniformType::Image: - case UniformType::Int: - applyUniformHelper<UniformType::Int>(description, v); - break; - case UniformType::IVec2: - applyUniformHelper<UniformType::IVec2>(description, v); - break; - case UniformType::IVec3: - applyUniformHelper<UniformType::IVec3>(description, v); - break; - case UniformType::IVec4: - applyUniformHelper<UniformType::IVec4>(description, v); - break; - - case UniformType::UInt: - applyUniformHelper<UniformType::UInt>(description, v); - break; - case UniformType::UIVec2: - applyUniformHelper<UniformType::UIVec2>(description, v); - break; - case UniformType::UIVec3: - applyUniformHelper<UniformType::UIVec3>(description, v); - break; - case UniformType::UIVec4: - applyUniformHelper<UniformType::UIVec4>(description, v); - break; - - case UniformType::Bool: - applyUniformHelper<UniformType::Bool>(description, v); - break; - case UniformType::BVec2: - applyUniformHelper<UniformType::BVec2>(description, v); - break; - case UniformType::BVec3: - applyUniformHelper<UniformType::BVec3>(description, v); - break; - case UniformType::BVec4: - applyUniformHelper<UniformType::BVec4>(description, v); - break; - - case UniformType::Mat2: - applyUniformHelper<UniformType::Mat2>(description, v); - break; - case UniformType::Mat3: - applyUniformHelper<UniformType::Mat3>(description, v); - break; - case UniformType::Mat4: - applyUniformHelper<UniformType::Mat4>(description, v); - break; - case UniformType::Mat2x3: - applyUniformHelper<UniformType::Mat2x3>(description, v); - break; - case UniformType::Mat3x2: - applyUniformHelper<UniformType::Mat3x2>(description, v); - break; - case UniformType::Mat2x4: - applyUniformHelper<UniformType::Mat2x4>(description, v); - break; - case UniformType::Mat4x2: - applyUniformHelper<UniformType::Mat4x2>(description, v); - break; - case UniformType::Mat3x4: - applyUniformHelper<UniformType::Mat3x4>(description, v); - break; - case UniformType::Mat4x3: - applyUniformHelper<UniformType::Mat4x3>(description, v); - break; - - default: - break; - } -} - -void GraphicsContext::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - m_glHelper->memoryBarrier(barriers); -} - -GLint GraphicsContext::elementType(GLint type) -{ - switch (type) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - return GL_FLOAT; - -#ifndef QT_OPENGL_ES_2 // Otherwise compile error as Qt defines GL_DOUBLE as GL_FLOAT when using ES2 - case GL_DOUBLE: -#ifdef GL_DOUBLE_VEC3 // For compiling on pre GL 4.1 systems - case GL_DOUBLE_VEC2: - case GL_DOUBLE_VEC3: - case GL_DOUBLE_VEC4: -#endif - return GL_DOUBLE; -#endif - default: - qWarning() << Q_FUNC_INFO << "unsupported:" << QString::number(type, 16); - } - - return GL_INVALID_VALUE; -} - -GLint GraphicsContext::tupleSizeFromType(GLint type) -{ - switch (type) { - case GL_FLOAT: -#ifndef QT_OPENGL_ES_2 // Otherwise compile error as Qt defines GL_DOUBLE as GL_FLOAT when using ES2 - case GL_DOUBLE: -#endif - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_INT: - break; // fall through - - case GL_FLOAT_VEC2: -#ifdef GL_DOUBLE_VEC2 // For compiling on pre GL 4.1 systems. - case GL_DOUBLE_VEC2: -#endif - return 2; - - case GL_FLOAT_VEC3: -#ifdef GL_DOUBLE_VEC3 // For compiling on pre GL 4.1 systems. - case GL_DOUBLE_VEC3: -#endif - return 3; - - case GL_FLOAT_VEC4: -#ifdef GL_DOUBLE_VEC4 // For compiling on pre GL 4.1 systems. - case GL_DOUBLE_VEC4: -#endif - return 4; - - default: - qWarning() << Q_FUNC_INFO << "unsupported:" << QString::number(type, 16); - } - - return 1; -} - -GLuint GraphicsContext::byteSizeFromType(GLint type) -{ - switch (type) { - case GL_FLOAT: return sizeof(float); -#ifndef QT_OPENGL_ES_2 // Otherwise compile error as Qt defines GL_DOUBLE as GL_FLOAT when using ES2 - case GL_DOUBLE: return sizeof(double); -#endif - case GL_UNSIGNED_BYTE: return sizeof(unsigned char); - case GL_UNSIGNED_INT: return sizeof(GLuint); - - case GL_FLOAT_VEC2: return sizeof(float) * 2; - case GL_FLOAT_VEC3: return sizeof(float) * 3; - case GL_FLOAT_VEC4: return sizeof(float) * 4; -#ifdef GL_DOUBLE_VEC3 // Required to compile on pre GL 4.1 systems - case GL_DOUBLE_VEC2: return sizeof(double) * 2; - case GL_DOUBLE_VEC3: return sizeof(double) * 3; - case GL_DOUBLE_VEC4: return sizeof(double) * 4; -#endif - default: - qWarning() << Q_FUNC_INFO << "unsupported:" << QString::number(type, 16); - } - - return 0; -} - -GLint GraphicsContext::glDataTypeFromAttributeDataType(QAttribute::VertexBaseType dataType) -{ - switch (dataType) { - case QAttribute::Byte: - return GL_BYTE; - case QAttribute::UnsignedByte: - return GL_UNSIGNED_BYTE; - case QAttribute::Short: - return GL_SHORT; - case QAttribute::UnsignedShort: - return GL_UNSIGNED_SHORT; - case QAttribute::Int: - return GL_INT; - case QAttribute::UnsignedInt: - return GL_UNSIGNED_INT; - case QAttribute::HalfFloat: -#ifdef GL_HALF_FLOAT - return GL_HALF_FLOAT; -#endif -#ifndef QT_OPENGL_ES_2 // Otherwise compile error as Qt defines GL_DOUBLE as GL_FLOAT when using ES2 - case QAttribute::Double: - return GL_DOUBLE; -#endif - case QAttribute::Float: - break; - default: - qWarning() << Q_FUNC_INFO << "unsupported dataType:" << dataType; - } - return GL_FLOAT; -} - -QT3D_UNIFORM_TYPE_IMPL(UniformType::Float, float, glUniform1fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Vec2, float, glUniform2fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Vec3, float, glUniform3fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Vec4, float, glUniform4fv) - -// OpenGL expects int* as values for booleans -QT3D_UNIFORM_TYPE_IMPL(UniformType::Bool, int, glUniform1iv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::BVec2, int, glUniform2iv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::BVec3, int, glUniform3iv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::BVec4, int, glUniform4iv) - -QT3D_UNIFORM_TYPE_IMPL(UniformType::Int, int, glUniform1iv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::IVec2, int, glUniform2iv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::IVec3, int, glUniform3iv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::IVec4, int, glUniform4iv) - -QT3D_UNIFORM_TYPE_IMPL(UniformType::UInt, uint, glUniform1uiv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::UIVec2, uint, glUniform2uiv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::UIVec3, uint, glUniform3uiv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::UIVec4, uint, glUniform4uiv) - -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat2, float, glUniformMatrix2fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat3, float, glUniformMatrix3fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat4, float, glUniformMatrix4fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat2x3, float, glUniformMatrix2x3fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat3x2, float, glUniformMatrix3x2fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat2x4, float, glUniformMatrix2x4fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat4x2, float, glUniformMatrix4x2fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat3x4, float, glUniformMatrix3x4fv) -QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat4x3, float, glUniformMatrix4x3fv) - -} // namespace Render -} // namespace Qt3DRender of namespace - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h b/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h deleted file mode 100644 index d3f3615d5..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicscontext_p.h +++ /dev/null @@ -1,264 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSCONTEXT_H -#define QT3DRENDER_RENDER_GRAPHICSCONTEXT_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QOpenGLContext> -#include <QOpenGLFunctions> -#include <QOpenGLVertexArrayObject> -#include <QHash> -#include <QColor> -#include <QMatrix4x4> -#include <QBitArray> -#include <QImage> -#include <Qt3DRender/private/shaderparameterpack_p.h> -#include <Qt3DRender/qclearbuffers.h> -#include <Qt3DRender/private/shader_p.h> -#include <Qt3DRender/private/glbuffer_p.h> -#include <Qt3DRender/qattribute.h> -#include <Qt3DRender/qmemorybarrier.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/qgraphicsapifilter_p.h> -#include <Qt3DRender/private/uniform_p.h> -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <Qt3DRender/private/qblitframebuffer_p.h> -#include <Qt3DRender/private/gl_handle_types_p.h> -#include <qmath.h> - -QT_BEGIN_NAMESPACE - -class QOpenGLShaderProgram; -class QAbstractOpenGLFunctions; -class QOpenGLDebugLogger; - -namespace Qt3DRender { - -namespace Render { - -class GraphicsHelperInterface; -class RenderTarget; -class AttachmentPack; -class ShaderManager; -class GLShader; -class GLShaderManager; - -typedef QPair<QString, int> NamedUniformLocation; - -class Q_AUTOTEST_EXPORT GraphicsContext -{ -public: - GraphicsContext(); - ~GraphicsContext(); - - void setOpenGLContext(QOpenGLContext* ctx); - QOpenGLContext *openGLContext() { return m_gl; } - bool makeCurrent(QSurface *surface); - void doneCurrent(); - bool hasValidGLHelper() const; - bool isInitialized() const; - - // Shaders - struct ShaderCreationInfo - { - bool linkSucceeded = false; - QString logs; - }; - - ShaderCreationInfo createShaderProgram(GLShader *shaderNode); - void introspectShaderInterface(GLShader *shader); - void loadShader(Shader* shader, ShaderManager *shaderManager, GLShaderManager *glShaderManager); - - GLuint defaultFBO() const { return m_defaultFBO; } - - const GraphicsApiFilterData *contextInfo() const; - - // Wrapper methods - void clearBackBuffer(QClearBuffers::BufferTypeFlags buffers); - void alphaTest(GLenum mode1, GLenum mode2); - void bindFramebuffer(GLuint fbo, GraphicsHelperInterface::FBOBindMode mode); - void bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer); - void bindFragOutputs(GLuint shader, const QHash<QString, int> &outputs); - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format); - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding); - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding); - void blendEquation(GLenum mode); - void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor); - void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha); - GLuint boundFrameBufferObject(); - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer); - void clearBufferf(GLint drawbuffer, const QVector4D &values); - void clearColor(const QColor &color); - void clearDepthValue(float depth); - void clearStencilValue(int stencil); - void depthRange(GLdouble nearValue, GLdouble farValue); - void depthMask(GLenum mode); - void depthTest(GLenum mode); - void disableClipPlane(int clipPlane); - void disablei(GLenum cap, GLuint index); - void disablePrimitiveRestart(); - void dispatchCompute(int x, int y, int z); - char * mapBuffer(GLenum target, GLsizeiptr size); - GLboolean unmapBuffer(GLenum target); - void drawArrays(GLenum primitiveType, GLint first, GLsizei count); - void drawArraysIndirect(GLenum mode,void *indirect); - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances); - void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseinstance); - void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void * indices, GLint baseVertex); - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect); - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void * indices, GLsizei instances, GLint baseVertex, GLint baseInstance); - void enableClipPlane(int clipPlane); - void enablei(GLenum cap, GLuint index); - void enablePrimitiveRestart(int restartIndex); - void frontFace(GLenum mode); - GLint maxClipPlaneCount(); - GLint maxTextureUnitsCount() const; - GLint maxImageUnitsCount() const; - void pointSize(bool programmable, GLfloat value); - void readBuffer(GLenum mode); - void drawBuffer(GLenum mode); - void drawBuffers(GLsizei n, const int *bufs); - void setMSAAEnabled(bool enabled); - void setAlphaCoverageEnabled(bool enabled); - void setClipPlane(int clipPlane, const QVector3D &normal, float distance); - void setSeamlessCubemap(bool enable); - void setVerticesPerPatch(GLint verticesPerPatch); - void memoryBarrier(QMemoryBarrier::Operations barriers); - void activateDrawBuffers(const AttachmentPack &attachments); - void rasterMode(GLenum faceMode, GLenum rasterMode); - - // Helper methods - static GLint elementType(GLint type); - static GLint tupleSizeFromType(GLint type); - static GLuint byteSizeFromType(GLint type); - static GLint glDataTypeFromAttributeDataType(QAttribute::VertexBaseType dataType); - - bool supportsDrawBuffersBlend() const; - bool supportsVAO() const { return m_supportsVAO; } - - void initialize(); - void initializeHelpers(QSurface *surface); - GraphicsHelperInterface *resolveHighestOpenGLFunctions(); - - bool m_initialized; - bool m_supportsVAO; - GLint m_maxTextureUnits; - GLint m_maxImageUnits; - GLuint m_defaultFBO; - QOpenGLContext *m_gl; - GraphicsHelperInterface *m_glHelper; - - QHash<QSurface *, GraphicsHelperInterface*> m_glHelpers; - GraphicsApiFilterData m_contextInfo; - QScopedPointer<QOpenGLDebugLogger> m_debugLogger; - - friend class OpenGLVertexArrayObject; - OpenGLVertexArrayObject *m_currentVAO; - - void applyUniform(const ShaderUniform &description, const UniformValue &v); - - template<UniformType> - void applyUniformHelper(const ShaderUniform &, const UniformValue &) const - { - Q_ASSERT_X(false, Q_FUNC_INFO, "Uniform: Didn't provide specialized apply() implementation"); - } -}; - -#define QT3D_UNIFORM_TYPE_PROTO(UniformTypeEnum, BaseType, Func) \ -template<> \ -void GraphicsContext::applyUniformHelper<UniformTypeEnum>(const ShaderUniform &description, const UniformValue &value) const; - -#define QT3D_UNIFORM_TYPE_IMPL(UniformTypeEnum, BaseType, Func) \ - template<> \ - void GraphicsContext::applyUniformHelper<UniformTypeEnum>(const ShaderUniform &description, const UniformValue &value) const \ -{ \ - const int count = qMin(description.m_size, int(value.byteSize() / description.m_rawByteSize)); \ - m_glHelper->Func(description.m_location, count, value.constData<BaseType>()); \ -} - - -QT3D_UNIFORM_TYPE_PROTO(UniformType::Float, float, glUniform1fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec2, float, glUniform2fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec3, float, glUniform3fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec4, float, glUniform4fv) - -// OpenGL expects int* as values for booleans -QT3D_UNIFORM_TYPE_PROTO(UniformType::Bool, int, glUniform1iv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec2, int, glUniform2iv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec3, int, glUniform3iv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec4, int, glUniform4iv) - -QT3D_UNIFORM_TYPE_PROTO(UniformType::Int, int, glUniform1iv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec2, int, glUniform2iv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec3, int, glUniform3iv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec4, int, glUniform4iv) - -QT3D_UNIFORM_TYPE_PROTO(UniformType::UInt, uint, glUniform1uiv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec2, uint, glUniform2uiv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec3, uint, glUniform3uiv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec4, uint, glUniform4uiv) - -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2, float, glUniformMatrix2fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3, float, glUniformMatrix3fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4, float, glUniformMatrix4fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x3, float, glUniformMatrix2x3fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x2, float, glUniformMatrix3x2fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x4, float, glUniformMatrix2x4fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x2, float, glUniformMatrix4x2fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x4, float, glUniformMatrix3x4fv) -QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x3, float, glUniformMatrix4x3fv) - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GRAPHICSCONTEXT_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp deleted file mode 100644 index 5f77dd376..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2.cpp +++ /dev/null @@ -1,1034 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelperes2_p.h" -#include <Qt3DRender/private/renderlogging_p.h> -#include <private/attachmentpack_p.h> -#include <private/qgraphicsutils_p.h> -#include <private/renderbuffer_p.h> -#include <QtGui/private/qopenglextensions_p.h> - -QT_BEGIN_NAMESPACE - -// ES 3.0+ -#ifndef GL_SAMPLER_3D -#define GL_SAMPLER_3D 0x8B5F -#endif -#ifndef GL_SAMPLER_2D_SHADOW -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#endif -#ifndef GL_SAMPLER_CUBE_SHADOW -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#endif -#ifndef GL_SAMPLER_2D_ARRAY -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#endif -#ifndef GL_SAMPLER_2D_ARRAY_SHADOW -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#endif - -namespace Qt3DRender { -namespace Render { - -GraphicsHelperES2::GraphicsHelperES2() - : m_funcs(0) - , m_supportFramebufferBlit(false) -{ -} - -GraphicsHelperES2::~GraphicsHelperES2() -{ -} - -void GraphicsHelperES2::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *) -{ - Q_ASSERT(context); - m_funcs = context->functions(); - Q_ASSERT(m_funcs); - m_ext.reset(new QOpenGLExtensions(context)); - if (m_ext->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) - m_supportFramebufferBlit = true; -} - -void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; - - if (baseVertex != 0) - qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2"; - - for (GLint i = 0; i < instances; i++) - drawElements(primitiveType, - primitiveCount, - indexType, - indices); -} - -void GraphicsHelperES2::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) -{ - for (GLint i = 0; i < instances; i++) - drawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperES2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL ES 2"; - for (GLint i = 0; i < instances; i++) - drawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperES2::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) -{ - if (baseVertex != 0) - qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL ES 2"; - QOpenGLExtensions *xfuncs = static_cast<QOpenGLExtensions *>(m_funcs); - if (indexType == GL_UNSIGNED_INT && !xfuncs->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint)) { - static bool warnShown = false; - if (!warnShown) { - warnShown = true; - qWarning("GL_UNSIGNED_INT index type not supported on this system, skipping draw call."); - } - return; - } - m_funcs->glDrawElements(primitiveType, - primitiveCount, - indexType, - indices); -} - -void GraphicsHelperES2::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) -{ - m_funcs->glDrawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperES2::drawElementsIndirect(GLenum, GLenum, void *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "Indirect Drawing is not supported with OpenGL ES 2"; -} - -void GraphicsHelperES2::drawArraysIndirect(GLenum , void *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "Indirect Drawing is not supported with OpenGL ES 2"; -} - -void GraphicsHelperES2::setVerticesPerPatch(GLint verticesPerPatch) -{ - Q_UNUSED(verticesPerPatch); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "Tessellation not supported with OpenGL ES 2"; -} - -void GraphicsHelperES2::useProgram(GLuint programId) -{ - m_funcs->glUseProgram(programId); -} - -QVector<ShaderUniform> GraphicsHelperES2::programUniformsAndLocations(GLuint programId) -{ - QVector<ShaderUniform> uniforms; - - GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms); - uniforms.reserve(nbrActiveUniforms); - char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; i++) { - ShaderUniform uniform; - GLsizei uniformNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength, - &uniform.m_size, &uniform.m_type, uniformName); - uniformName[sizeof(uniformName) - 1] = '\0'; - uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); - uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); - // Work around for uniform array names that aren't returned with [0] by some drivers - if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]"))) - uniform.m_name.append(QLatin1String("[0]")); - uniform.m_rawByteSize = uniformByteSize(uniform); - uniforms.append(uniform); - } - return uniforms; -} - -QVector<ShaderAttribute> GraphicsHelperES2::programAttributesAndLocations(GLuint programId) -{ - QVector<ShaderAttribute> attributes; - GLint nbrActiveAttributes = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes); - attributes.reserve(nbrActiveAttributes); - char attributeName[256]; - for (GLint i = 0; i < nbrActiveAttributes; i++) { - ShaderAttribute attribute; - GLsizei attributeNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength, - &attribute.m_size, &attribute.m_type, attributeName); - attributeName[sizeof(attributeName) - 1] = '\0'; - attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName); - attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength); - attributes.append(attribute); - } - return attributes; -} - -QVector<ShaderUniformBlock> GraphicsHelperES2::programUniformBlocks(GLuint programId) -{ - Q_UNUSED(programId); - QVector<ShaderUniformBlock> blocks; - static bool showWarning = true; - if (!showWarning) - return blocks; - showWarning = false; - qWarning() << "UBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; - return blocks; -} - -QVector<ShaderStorageBlock> GraphicsHelperES2::programShaderStorageBlocks(GLuint programId) -{ - Q_UNUSED(programId); - QVector<ShaderStorageBlock> blocks; - static bool showWarning = true; - if (!showWarning) - return blocks; - showWarning = false; - qWarning() << "SSBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.1)"; - return blocks; -} - -void GraphicsHelperES2::vertexAttribDivisor(GLuint index, GLuint divisor) -{ - Q_UNUSED(index); - Q_UNUSED(divisor); -} - -void GraphicsHelperES2::vertexAttributePointer(GLenum shaderDataType, - GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer) -{ - switch (shaderDataType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: - m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); - break; - - default: - qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type"; - Q_UNREACHABLE(); - } -} - -void GraphicsHelperES2::readBuffer(GLenum mode) -{ - Q_UNUSED(mode) - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glReadBuffer not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; -} - -void GraphicsHelperES2::drawBuffer(GLenum mode) -{ - Q_UNUSED(mode); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glDrawBuffer is not supported with OpenGL ES 2"; -} - -void *GraphicsHelperES2::fenceSync() -{ - qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; - return nullptr; -} - -void GraphicsHelperES2::clientWaitSync(void *, GLuint64 ) -{ - qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; -} - -void GraphicsHelperES2::waitSync(void *) -{ - qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; -} - -bool GraphicsHelperES2::wasSyncSignaled(void *) -{ - qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; - return false; -} - -void GraphicsHelperES2::deleteSync(void *) -{ - qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; -} - -void GraphicsHelperES2::rasterMode(GLenum faceMode, GLenum rasterMode) -{ - Q_UNUSED(faceMode); - Q_UNUSED(rasterMode); - qWarning() << "glPolyonMode is not supported with OpenGL ES"; -} - -void GraphicsHelperES2::blendEquation(GLenum mode) -{ - m_funcs->glBlendEquation(mode); -} - -void GraphicsHelperES2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) -{ - Q_UNUSED(buf); - Q_UNUSED(sfactor); - Q_UNUSED(dfactor); - - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glBlendFunci() not supported by OpenGL ES 2.0"; -} - -void GraphicsHelperES2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) -{ - Q_UNUSED(buf); - Q_UNUSED(sRGB); - Q_UNUSED(dRGB); - Q_UNUSED(sAlpha); - Q_UNUSED(dAlpha); - - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glBlendFuncSeparatei() not supported by OpenGL ES 2.0"; -} - -void GraphicsHelperES2::alphaTest(GLenum, GLenum) -{ - qCWarning(Render::Rendering) << Q_FUNC_INFO << "AlphaTest not available with OpenGL ES 2.0"; -} - -void GraphicsHelperES2::depthTest(GLenum mode) -{ - m_funcs->glEnable(GL_DEPTH_TEST); - m_funcs->glDepthFunc(mode); -} - -void GraphicsHelperES2::depthMask(GLenum mode) -{ - m_funcs->glDepthMask(mode); -} - -void GraphicsHelperES2::depthRange(GLdouble nearValue, GLdouble farValue) -{ - m_funcs->glDepthRangef(static_cast<float>(nearValue), static_cast<float>(farValue)); -} - -void GraphicsHelperES2::frontFace(GLenum mode) -{ - m_funcs->glFrontFace(mode); -} - -void GraphicsHelperES2::setMSAAEnabled(bool enabled) -{ - Q_UNUSED(enabled); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "MSAA not available with OpenGL ES 2.0"; -} - -void GraphicsHelperES2::setAlphaCoverageEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) - : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); -} - -GLuint GraphicsHelperES2::createFrameBufferObject() -{ - GLuint id; - m_funcs->glGenFramebuffers(1, &id); - return id; -} - -void GraphicsHelperES2::releaseFrameBufferObject(GLuint frameBufferId) -{ - m_funcs->glDeleteFramebuffers(1, &frameBufferId); -} - -void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) -{ - Q_UNUSED(mode) - // For ES2 the spec states for target: The symbolic constant must be GL_FRAMEBUFFER - // so mode is ignored and is always set to GL_FRAMEBUFFER - m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); -} - -void GraphicsHelperES2::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - Q_UNUSED(imageUnit) - Q_UNUSED(texture) - Q_UNUSED(mipLevel) - Q_UNUSED(layered) - Q_UNUSED(layer) - Q_UNUSED(access) - Q_UNUSED(format) - qWarning() << "Shader Images are not supported by ES 2.0 (since ES 3.1)"; - -} - -GLuint GraphicsHelperES2::boundFrameBufferObject() -{ - GLint id = 0; - m_funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &id); - return id; -} - -bool GraphicsHelperES2::checkFrameBufferComplete() -{ - return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); -} - -bool GraphicsHelperES2::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - // Use a renderbuffer for depth or stencil attachments since this is - // problematic before GLES 3.2. Keep using textures for everything else. - // For ES2 individual Depth and Stencil buffers need to be an option because - // DepthStencil is an extension. - return attachment.m_point == QRenderTargetOutput::DepthStencil || - attachment.m_point == QRenderTargetOutput::Depth || - attachment.m_point == QRenderTargetOutput::Stencil; -} - -void GraphicsHelperES2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - GLenum attr = GL_COLOR_ATTACHMENT0; - - if (attachment.m_point == QRenderTargetOutput::Color0) - attr = GL_COLOR_ATTACHMENT0; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - else - qCritical() << "Unsupported FBO attachment OpenGL ES 2.0"; - - const QOpenGLTexture::Target target = texture->target(); - - if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) { - qWarning() << "OpenGL ES 2.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO"; - return; - } - - texture->bind(); - if (target == QOpenGLTexture::Target2D) - m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel); - else if (target == QOpenGLTexture::TargetCubeMap) - m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else - qCritical() << "Unsupported Texture FBO attachment format"; - texture->release(); -} - -void GraphicsHelperES2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) -{ - if (attachment.m_point != QRenderTargetOutput::DepthStencil && - attachment.m_point != QRenderTargetOutput::Depth && - attachment.m_point != QRenderTargetOutput::Stencil) { - qCritical() << "Renderbuffers only supported for combined depth-stencil, depth, or stencil, but got attachment point" - << attachment.m_point; - return; - } - - renderBuffer->bind(); - if (attachment.m_point == QRenderTargetOutput::DepthStencil || - attachment.m_point == QRenderTargetOutput::Depth) - m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId()); - if (attachment.m_point == QRenderTargetOutput::DepthStencil || - attachment.m_point == QRenderTargetOutput::Stencil) - m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId()); - renderBuffer->release(); -} - -bool GraphicsHelperES2::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case RenderBufferDimensionRetrieval: - return true; - case BlitFramebuffer: - return m_supportFramebufferBlit; - default: - return false; - } -} - -void GraphicsHelperES2::drawBuffers(GLsizei, const int *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "drawBuffers is not supported by ES 2.0"; -} - -void GraphicsHelperES2::bindFragDataLocation(GLuint , const QHash<QString, int> &) -{ - qCritical() << "bindFragDataLocation is not supported by ES 2.0"; -} - -void GraphicsHelperES2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - Q_UNUSED(programId); - Q_UNUSED(uniformBlockIndex); - Q_UNUSED(uniformBlockBinding); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)"; -} - -void GraphicsHelperES2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) -{ - Q_UNUSED(programId); - Q_UNUSED(shaderStorageBlockIndex); - Q_UNUSED(shaderStorageBlockBinding); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "SSBO are not supported by ES 2.0 (since ES 3.1)"; -} - -void GraphicsHelperES2::bindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - Q_UNUSED(target); - Q_UNUSED(index); - Q_UNUSED(buffer); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "bindBufferBase is not supported by ES 2.0 (since ES 3.0)"; -} - -void GraphicsHelperES2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - Q_UNUSED(v); - Q_UNUSED(description); - Q_UNUSED(buffer); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)"; -} - -uint GraphicsHelperES2::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - int arrayStride = qMax(description.m_arrayStride, 0); - int matrixStride = qMax(description.m_matrixStride, 0); - - switch (description.m_type) { - - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - rawByteSize = 8; - break; - - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - rawByteSize = 12; - break; - - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - rawByteSize = 16; - break; - - case GL_FLOAT_MAT2: - rawByteSize = matrixStride ? 2 * matrixStride : 16; - break; - - case GL_FLOAT_MAT3: - rawByteSize = matrixStride ? 3 * matrixStride : 36; - break; - - case GL_FLOAT_MAT4: - rawByteSize = matrixStride ? 4 * matrixStride : 64; - break; - - case GL_BOOL: - rawByteSize = 1; - break; - - case GL_BOOL_VEC2: - rawByteSize = 2; - break; - - case GL_BOOL_VEC3: - rawByteSize = 3; - break; - - case GL_BOOL_VEC4: - rawByteSize = 4; - break; - - case GL_INT: - case GL_FLOAT: - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - rawByteSize = 4; - break; - } - - return arrayStride ? rawByteSize * arrayStride : rawByteSize; -} - -void GraphicsHelperES2::enableClipPlane(int) -{ -} - -void GraphicsHelperES2::disableClipPlane(int) -{ -} - -void GraphicsHelperES2::setClipPlane(int, const QVector3D &, float) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "Clip planes not supported by OpenGL ES 2.0"; -} - -GLint GraphicsHelperES2::maxClipPlaneCount() -{ - return 0; -} - -void GraphicsHelperES2::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - Q_UNUSED(barriers); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "memory barrier is not supported by OpenGL ES 2.0 (since 4.3)"; -} - -void GraphicsHelperES2::enablePrimitiveRestart(int) -{ -} - -void GraphicsHelperES2::enableVertexAttributeArray(int location) -{ - m_funcs->glEnableVertexAttribArray(location); -} - -void GraphicsHelperES2::disablePrimitiveRestart() -{ -} - -void GraphicsHelperES2::clearBufferf(GLint drawbuffer, const QVector4D &values) -{ - Q_UNUSED(drawbuffer); - Q_UNUSED(values); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glClearBuffer*() not supported by OpenGL ES 2.0"; -} - -void GraphicsHelperES2::pointSize(bool programmable, GLfloat value) -{ - // If this is not a reset to default values, print a warning - if (programmable || !qFuzzyCompare(value, 1.0f)) { - static bool warned = false; - if (!warned) { - qWarning() << "glPointSize() and GL_PROGRAM_POINT_SIZE are not supported by ES 2.0"; - warned = true; - } - } -} - -void GraphicsHelperES2::enablei(GLenum cap, GLuint index) -{ - Q_UNUSED(cap); - Q_UNUSED(index); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glEnablei() not supported by OpenGL ES 2.0"; -} - -void GraphicsHelperES2::disablei(GLenum cap, GLuint index) -{ - Q_UNUSED(cap); - Q_UNUSED(index); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glDisablei() not supported by OpenGL ES 2.0"; -} - -void GraphicsHelperES2::setSeamlessCubemap(bool enable) -{ - Q_UNUSED(enable); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "GL_TEXTURE_CUBE_MAP_SEAMLESS not supported by OpenGL ES 2.0"; -} - -QSize GraphicsHelperES2::getRenderBufferDimensions(GLuint renderBufferId) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0); - - return QSize(width, height); -} - -QSize GraphicsHelperES2::getTextureDimensions(GLuint textureId, GLenum target, uint level) -{ - Q_UNUSED(textureId); - Q_UNUSED(target); - Q_UNUSED(level); - qCritical() << "getTextureDimensions is not supported by ES 2.0"; - return QSize(0, 0); -} - -void GraphicsHelperES2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) -{ - Q_UNUSED(wx); - Q_UNUSED(wy); - Q_UNUSED(wz); - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "Compute Shaders are not supported by ES 2.0 (since ES 3.1)"; -} - -char *GraphicsHelperES2::mapBuffer(GLenum target, GLsizeiptr size) -{ - Q_UNUSED(target); - Q_UNUSED(size); - static bool showWarning = true; - if (!showWarning) - return nullptr; - showWarning = false; - qWarning() << "Map buffer is not a core requirement for ES 2.0"; - return nullptr; -} - -GLboolean GraphicsHelperES2::unmapBuffer(GLenum target) -{ - Q_UNUSED(target); - static bool showWarning = true; - if (!showWarning) - return false; - showWarning = false; - qWarning() << "unMap buffer is not a core requirement for ES 2.0"; - return false; -} - -void GraphicsHelperES2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform1fv(location, count, values); -} - -void GraphicsHelperES2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform2fv(location, count, values); -} - -void GraphicsHelperES2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform3fv(location, count, values); -} - -void GraphicsHelperES2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform4fv(location, count, values); -} - -void GraphicsHelperES2::glUniform1iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform1iv(location, count, values); -} - -void GraphicsHelperES2::glUniform2iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform2iv(location, count, values); -} - -void GraphicsHelperES2::glUniform3iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform3iv(location, count, values); -} - -void GraphicsHelperES2::glUniform4iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform4iv(location, count, values); -} - -void GraphicsHelperES2::glUniform1uiv(GLint , GLsizei , const GLuint *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniform1uiv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniform2uiv(GLint , GLsizei , const GLuint *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniform2uiv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniform3uiv(GLint , GLsizei , const GLuint *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniform3uiv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniform4uiv(GLint , GLsizei , const GLuint *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniform4uiv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2fv(location, count, false, values); -} - -void GraphicsHelperES2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3fv(location, count, false, values); -} - -void GraphicsHelperES2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4fv(location, count, false, values); -} - -void GraphicsHelperES2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniformMatrix2x3fv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniformMatrix3x2fv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniformMatrix2x4fv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniformMatrix4x2fv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniformMatrix3x4fv not supported by ES 2"; -} - -void GraphicsHelperES2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *) -{ - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "glUniformMatrix4x3fv not supported by ES 2"; -} - -UniformType GraphicsHelperES2::uniformTypeFromGLType(GLenum type) -{ - switch (type) { - case GL_FLOAT: - return UniformType::Float; - case GL_FLOAT_VEC2: - return UniformType::Vec2; - case GL_FLOAT_VEC3: - return UniformType::Vec3; - case GL_FLOAT_VEC4: - return UniformType::Vec4; - case GL_FLOAT_MAT2: - return UniformType::Mat2; - case GL_FLOAT_MAT3: - return UniformType::Mat3; - case GL_FLOAT_MAT4: - return UniformType::Mat4; - case GL_INT: - return UniformType::Int; - case GL_INT_VEC2: - return UniformType::IVec2; - case GL_INT_VEC3: - return UniformType::IVec3; - case GL_INT_VEC4: - return UniformType::IVec4; - case GL_BOOL: - return UniformType::Bool; - case GL_BOOL_VEC2: - return UniformType::BVec2; - case GL_BOOL_VEC3: - return UniformType::BVec3; - case GL_BOOL_VEC4: - return UniformType::BVec4; - - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - return UniformType::Sampler; - default: - Q_UNREACHABLE(); - return UniformType::Float; - } -} - -void GraphicsHelperES2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - if (!m_supportFramebufferBlit) { - static bool showWarning = true; - if (!showWarning) - return; - showWarning = false; - qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)"; - } else - m_ext->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h deleted file mode 100644 index 882931ad9..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes2_p.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERES2_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERES2_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <QOpenGLContext> -#include <QOpenGLFunctions> - -QT_BEGIN_NAMESPACE - -class QOpenGLExtensions; - -namespace Qt3DRender { -namespace Render { - -class GraphicsHelperES2 : public GraphicsHelperInterface -{ -public: - GraphicsHelperES2(); - virtual ~GraphicsHelperES2(); - - // QGraphicHelperInterface interface - void alphaTest(GLenum mode1, GLenum mode2) override; - void bindBufferBase(GLenum target, GLuint index, GLuint buffer) override; - void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; - void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - void blendEquation(GLenum mode) override; - void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) override; - void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) override; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override; - GLuint boundFrameBufferObject() override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; - bool checkFrameBufferComplete() override; - void clearBufferf(GLint drawbuffer, const QVector4D &values) override; - GLuint createFrameBufferObject() override; - void depthMask(GLenum mode) override; - void depthRange(GLdouble nearValue, GLdouble farValue) override; - void depthTest(GLenum mode) override; - void disableClipPlane(int clipPlane) override; - void disablei(GLenum cap, GLuint index) override; - void disablePrimitiveRestart() override; - void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; - char *mapBuffer(GLenum target, GLsizeiptr size) override; - GLboolean unmapBuffer(GLenum target) override; - void drawArrays(GLenum primitiveType, GLint first, GLsizei count) override; - void drawArraysIndirect(GLenum mode,void *indirect) override; - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override; - void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) override; - void drawBuffers(GLsizei n, const int *bufs) override; - void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLint baseVertex = 0) override; - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - void enableClipPlane(int clipPlane) override; - void enablei(GLenum cap, GLuint index) override; - void enablePrimitiveRestart(int primitiveRestartIndex) override; - void enableVertexAttributeArray(int location) override; - void frontFace(GLenum mode) override; - QSize getRenderBufferDimensions(GLuint renderBufferId) override; - QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) override; - void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) override; - void pointSize(bool programmable, GLfloat value) override; - GLint maxClipPlaneCount() override; - void memoryBarrier(QMemoryBarrier::Operations barriers) override; - QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) override; - QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) override; - QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) override; - QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override; - void releaseFrameBufferObject(GLuint frameBufferId) override; - void setMSAAEnabled(bool enable) override; - void setAlphaCoverageEnabled(bool enable) override; - void setClipPlane(int clipPlane, const QVector3D &normal, float distance) override; - void setSeamlessCubemap(bool enable) override; - void setVerticesPerPatch(GLint verticesPerPatch) override; - bool supportsFeature(Feature feature) const override; - uint uniformByteSize(const ShaderUniform &description) override; - void useProgram(GLuint programId) override; - void vertexAttribDivisor(GLuint index, GLuint divisor) override; - void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; - void readBuffer(GLenum mode) override; - void drawBuffer(GLenum mode) override; - void rasterMode(GLenum faceMode, GLenum rasterMode) override; - - void *fenceSync() override; - void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; - void waitSync(void *sync) override; - bool wasSyncSignaled(void *sync) override; - void deleteSync(void *sync) override; - - void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) override; - - void glUniform1iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform2iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform3iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform4iv(GLint location, GLsizei count, const GLint *value) override; - - void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) override; - - void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) override; - - UniformType uniformTypeFromGLType(GLenum glType) override; - -protected: - QOpenGLFunctions *m_funcs; - bool m_supportFramebufferBlit; - QScopedPointer<QOpenGLExtensions> m_ext; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERES2_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp deleted file mode 100644 index 5e5d2e001..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3.cpp +++ /dev/null @@ -1,768 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 Svenn-Arne Dragly. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelperes3_p.h" -#include <private/attachmentpack_p.h> -#include <private/qgraphicsutils_p.h> -#include <private/renderlogging_p.h> -#include <QOpenGLExtraFunctions> - -QT_BEGIN_NAMESPACE - -// ES 3.0+ -#ifndef GL_SAMPLER_3D -#define GL_SAMPLER_3D 0x8B5F -#endif -#ifndef GL_SAMPLER_2D_SHADOW -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#endif -#ifndef GL_SAMPLER_CUBE_SHADOW -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#endif -#ifndef GL_SAMPLER_2D_ARRAY -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#endif -#ifndef GL_SAMPLER_2D_ARRAY_SHADOW -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#endif -#ifndef GL_FLOAT_MAT2x3 -#define GL_FLOAT_MAT2x3 0x8B65 -#endif -#ifndef GL_FLOAT_MAT2x4 -#define GL_FLOAT_MAT2x4 0x8B66 -#endif -#ifndef GL_FLOAT_MAT3x2 -#define GL_FLOAT_MAT3x2 0x8B67 -#endif -#ifndef GL_FLOAT_MAT3x4 -#define GL_FLOAT_MAT3x4 0x8B68 -#endif -#ifndef GL_FLOAT_MAT4x2 -#define GL_FLOAT_MAT4x2 0x8B69 -#endif -#ifndef GL_FLOAT_MAT4x3 -#define GL_FLOAT_MAT4x3 0x8B6A -#endif -#ifndef GL_UNSIGNED_INT_VEC2 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#endif -#ifndef GL_UNSIGNED_INT_VEC3 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#endif -#ifndef GL_UNSIGNED_INT_VEC4 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#endif -#ifndef GL_INT_SAMPLER_2D -#define GL_INT_SAMPLER_2D 0x8DCA -#endif -#ifndef GL_INT_SAMPLER_3D -#define GL_INT_SAMPLER_3D 0x8DCB -#endif -#ifndef GL_INT_SAMPLER_CUBE -#define GL_INT_SAMPLER_CUBE 0x8DCC -#endif -#ifndef GL_INT_SAMPLER_2D_ARRAY -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#endif -#ifndef GL_UNSIGNED_INT_SAMPLER_2D -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#endif -#ifndef GL_UNSIGNED_INT_SAMPLER_3D -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#endif -#ifndef GL_UNSIGNED_INT_SAMPLER_CUBE -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#endif -#ifndef GL_UNSIGNED_INT_SAMPLER_2D_ARRAY -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#endif - -#ifndef GL_ACTIVE_UNIFORM_BLOCKS -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#endif -#ifndef GL_UNIFORM_BLOCK_INDEX -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#endif -#ifndef GL_UNIFORM_OFFSET -#define GL_UNIFORM_OFFSET 0x8A3B -#endif -#ifndef GL_UNIFORM_ARRAY_STRIDE -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#endif -#ifndef GL_UNIFORM_MATRIX_STRIDE -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#endif -#ifndef GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#endif -#ifndef GL_UNIFORM_BLOCK_BINDING -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#endif -#ifndef GL_UNIFORM_BLOCK_DATA_SIZE -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#endif - -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif - -#ifndef GL_SIGNALED -#define GL_SIGNALED 0x9119 -#endif - -#ifndef GL_SYNC_STATUS -#define GL_SYNC_STATUS 0x9114 -#endif - -#ifndef GL_TIMEOUT_IGNORED -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull -#endif - -#ifndef GL_SYNC_GPU_COMMANDS_COMPLETE -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#endif - -#ifndef GL_SYNC_FLUSH_COMMANDS_BIT -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#endif - -namespace Qt3DRender { -namespace Render { - -GraphicsHelperES3::GraphicsHelperES3() -{ -} - -GraphicsHelperES3::~GraphicsHelperES3() -{ -} - -void GraphicsHelperES3::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) -{ - GraphicsHelperES2::initializeHelper(context, functions); - m_extraFuncs = context->extraFunctions(); - Q_ASSERT(m_extraFuncs); -} - -void GraphicsHelperES3::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 3"; - - if (baseVertex != 0) - qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 3"; - - m_extraFuncs->glDrawElementsInstanced(primitiveType, - primitiveCount, - indexType, - indices, - instances); -} - -void GraphicsHelperES3::vertexAttribDivisor(GLuint index, GLuint divisor) -{ - m_extraFuncs->glVertexAttribDivisor(index, divisor); -} - -void GraphicsHelperES3::vertexAttributePointer(GLenum shaderDataType, - GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer) -{ - switch (shaderDataType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_MAT4: - m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); - break; - - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_VEC2: - case GL_UNSIGNED_INT_VEC3: - case GL_UNSIGNED_INT_VEC4: - m_extraFuncs->glVertexAttribIPointer(index, size, type, stride, pointer); - break; - - default: - qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type"; - Q_UNREACHABLE(); - } -} - -void GraphicsHelperES3::drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) -{ - m_extraFuncs->glDrawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsHelperES3::readBuffer(GLenum mode) -{ - m_extraFuncs->glReadBuffer(mode); -} - -void GraphicsHelperES3::drawBuffer(GLenum mode) -{ - Q_UNUSED(mode); - qWarning() << "glDrawBuffer is not supported with OpenGL ES 3"; -} - -void GraphicsHelperES3::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - GLenum attr = GL_COLOR_ATTACHMENT0; - - if (attachment.m_point <= QRenderTargetOutput::Color15) - attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - else - qCritical() << "Unsupported FBO attachment OpenGL ES 3.0"; - - const QOpenGLTexture::Target target = texture->target(); - - if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) { - qWarning() << "OpenGL ES 3.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO"; - return; - } - - texture->bind(); - if (target == QOpenGLTexture::Target2D) - m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel); - else if (target == QOpenGLTexture::TargetCubeMap) - m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else - qCritical() << "Unsupported Texture FBO attachment format"; - texture->release(); -} - -void GraphicsHelperES3::bindFrameBufferObject(GLuint frameBufferId, GraphicsHelperInterface::FBOBindMode mode) -{ - switch (mode) { - case FBODraw: - m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId); - return; - case FBORead: - m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId); - return; - case FBOReadAndDraw: - default: - m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); - return; - } -} - -bool GraphicsHelperES3::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case RenderBufferDimensionRetrieval: - case MRT: - case BlitFramebuffer: - case UniformBufferObject: - case MapBuffer: - case Fences: - return true; - default: - return false; - } -} - -void GraphicsHelperES3::drawBuffers(GLsizei n, const int *bufs) -{ - QVarLengthArray<GLenum, 16> drawBufs(n); - - for (int i = 0; i < n; i++) - drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i]; - m_extraFuncs->glDrawBuffers(n, drawBufs.constData()); -} - -UniformType GraphicsHelperES3::uniformTypeFromGLType(GLenum glType) -{ - switch (glType) { - case GL_SAMPLER_3D: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - return UniformType::Sampler; - default: - return GraphicsHelperES2::uniformTypeFromGLType(glType); - } -} - -uint GraphicsHelperES3::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - int arrayStride = qMax(description.m_arrayStride, 0); - int matrixStride = qMax(description.m_matrixStride, 0); - - switch (description.m_type) { - - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_UNSIGNED_INT_VEC2: - rawByteSize = 8; - break; - - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_UNSIGNED_INT_VEC3: - rawByteSize = 12; - break; - - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_UNSIGNED_INT_VEC4: - rawByteSize = 16; - break; - - case GL_FLOAT_MAT2: - rawByteSize = matrixStride ? 2 * matrixStride : 16; - break; - - case GL_FLOAT_MAT2x4: - rawByteSize = matrixStride ? 2 * matrixStride : 32; - break; - - case GL_FLOAT_MAT4x2: - rawByteSize = matrixStride ? 4 * matrixStride : 32; - break; - - case GL_FLOAT_MAT3: - rawByteSize = matrixStride ? 3 * matrixStride : 36; - break; - - case GL_FLOAT_MAT2x3: - rawByteSize = matrixStride ? 2 * matrixStride : 24; - break; - - case GL_FLOAT_MAT3x2: - rawByteSize = matrixStride ? 3 * matrixStride : 24; - break; - - case GL_FLOAT_MAT4: - rawByteSize = matrixStride ? 4 * matrixStride : 64; - break; - - case GL_FLOAT_MAT4x3: - rawByteSize = matrixStride ? 4 * matrixStride : 48; - break; - - case GL_FLOAT_MAT3x4: - rawByteSize = matrixStride ? 3 * matrixStride : 48; - break; - - case GL_BOOL: - rawByteSize = 1; - break; - - case GL_BOOL_VEC2: - rawByteSize = 2; - break; - - case GL_BOOL_VEC3: - rawByteSize = 3; - break; - - case GL_BOOL_VEC4: - rawByteSize = 4; - break; - - case GL_INT: - case GL_FLOAT: - case GL_UNSIGNED_INT: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - rawByteSize = 4; - break; - } - - return arrayStride ? rawByteSize * arrayStride : rawByteSize; -} - -void *GraphicsHelperES3::fenceSync() -{ - return m_extraFuncs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -} - -void GraphicsHelperES3::clientWaitSync(void *sync, GLuint64 nanoSecTimeout) -{ - m_extraFuncs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout); -} - -void GraphicsHelperES3::waitSync(void *sync) -{ - m_extraFuncs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED); -} - -bool GraphicsHelperES3::wasSyncSignaled(void *sync) -{ - GLint v; - m_extraFuncs->glGetSynciv(static_cast<GLsync>(sync), - GL_SYNC_STATUS, - sizeof(v), - nullptr, - &v); - return v == GL_SIGNALED; -} - -void GraphicsHelperES3::deleteSync(void *sync) -{ - m_extraFuncs->glDeleteSync(static_cast<GLsync>(sync)); -} - -void GraphicsHelperES3::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - m_extraFuncs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -void GraphicsHelperES3::bindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - m_extraFuncs->glBindBufferBase(target, index, buffer); -} - -bool GraphicsHelperES3::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - // Use a renderbuffer for combined depth+stencil attachments since this is - // problematic before GLES 3.2. Keep using textures for everything else. - return attachment.m_point == QRenderTargetOutput::DepthStencil; -} - -void GraphicsHelperES3::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - m_extraFuncs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); -} - -void GraphicsHelperES3::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - char *bufferData = buffer.data(); - - switch (description.m_type) { - - case GL_FLOAT: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_FLOAT_VEC2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_FLOAT_VEC3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_FLOAT_VEC4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_FLOAT_MAT2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2); - break; - } - - case GL_FLOAT_MAT2x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3); - break; - } - - case GL_FLOAT_MAT2x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4); - break; - } - - case GL_FLOAT_MAT3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3); - break; - } - - case GL_FLOAT_MAT3x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2); - break; - } - - case GL_FLOAT_MAT3x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4); - break; - } - - case GL_FLOAT_MAT4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4); - break; - } - - case GL_FLOAT_MAT4x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2); - break; - } - - case GL_FLOAT_MAT4x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3); - break; - } - - case GL_INT: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_INT_VEC2: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_INT_VEC3: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_INT_VEC4: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_UNSIGNED_INT: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_UNSIGNED_INT_VEC2: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_UNSIGNED_INT_VEC3: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_UNSIGNED_INT_VEC4: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_BOOL: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_BOOL_VEC2: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_BOOL_VEC3: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_BOOL_VEC4: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - // note: only GLES 3.0 supported types, not the same as OpenGL proper - // (also, no MS samplers before ES 3.1) - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - { - Q_ASSERT(description.m_size == 1); - int value = v.toInt(); - QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - -char *GraphicsHelperES3::mapBuffer(GLenum target, GLsizeiptr size) -{ - return static_cast<char*>(m_extraFuncs->glMapBufferRange(target, 0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); -} - -GLboolean GraphicsHelperES3::unmapBuffer(GLenum target) -{ - return m_extraFuncs->glUnmapBuffer(target); -} - -QVector<ShaderUniform> GraphicsHelperES3::programUniformsAndLocations(GLuint programId) -{ - QVector<ShaderUniform> uniforms; - - GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms); - uniforms.reserve(nbrActiveUniforms); - char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; i++) { - ShaderUniform uniform; - GLsizei uniformNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength, - &uniform.m_size, &uniform.m_type, uniformName); - uniformName[sizeof(uniformName) - 1] = '\0'; - uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); - uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); - m_extraFuncs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex); - m_extraFuncs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset); - m_extraFuncs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride); - m_extraFuncs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride); - uniform.m_rawByteSize = uniformByteSize(uniform); - uniforms.append(uniform); - qCDebug(Render::Rendering) << uniform.m_name << "size" << uniform.m_size - << " offset" << uniform.m_offset - << " rawSize" << uniform.m_rawByteSize; - } - - return uniforms; -} - -QVector<ShaderUniformBlock> GraphicsHelperES3::programUniformBlocks(GLuint programId) -{ - QVector<ShaderUniformBlock> blocks; - GLint nbrActiveUniformsBlocks = 0; - m_extraFuncs->glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCKS, &nbrActiveUniformsBlocks); - blocks.reserve(nbrActiveUniformsBlocks); - for (GLint i = 0; i < nbrActiveUniformsBlocks; i++) { - QByteArray uniformBlockName(256, '\0'); - GLsizei length = 0; - ShaderUniformBlock uniformBlock; - m_extraFuncs->glGetActiveUniformBlockName(programId, i, 256, &length, uniformBlockName.data()); - uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length)); - uniformBlock.m_index = i; - m_extraFuncs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformBlock.m_activeUniformsCount); - m_extraFuncs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_BINDING, &uniformBlock.m_binding); - m_extraFuncs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlock.m_size); - blocks.append(uniformBlock); - } - return blocks; -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp deleted file mode 100644 index 9c424d962..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelperes3_1_p.h" -#include <private/qgraphicsutils_p.h> -#include <QOpenGLExtraFunctions> - -QT_BEGIN_NAMESPACE - -// ES 3.1+ -#ifndef GL_SAMPLER_2D_MULTISAMPLE -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#endif -#ifndef GL_INT_SAMPLER_2D_MULTISAMPLE -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#endif -#ifndef GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#endif -#ifndef GL_ACTIVE_RESOURCES -#define GL_ACTIVE_RESOURCES 0x92F5 -#endif -#ifndef GL_BUFFER_BINDING -#define GL_BUFFER_BINDING 0x9302 -#endif -#ifndef GL_BUFFER_DATA_SIZE -#define GL_BUFFER_DATA_SIZE 0x9303 -#endif -#ifndef GL_NUM_ACTIVE_VARIABLES -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#endif -#ifndef GL_SHADER_STORAGE_BLOCK -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#endif -#ifndef GL_ALL_BARRIER_BITS -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#endif -#ifndef GL_ELEMENT_ARRAY_BARRIER_BIT -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#endif -#ifndef GL_UNIFORM_BARRIER_BIT -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#endif -#ifndef GL_TEXTURE_FETCH_BARRIER_BIT -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#endif -#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#endif -#ifndef GL_COMMAND_BARRIER_BIT -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#endif -#ifndef GL_PIXEL_BUFFER_BARRIER_BIT -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#endif -#ifndef GL_TEXTURE_UPDATE_BARRIER_BIT -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#endif -#ifndef GL_BUFFER_UPDATE_BARRIER_BIT -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#endif -#ifndef GL_FRAMEBUFFER_BARRIER_BIT -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#endif -#ifndef GL_TRANSFORM_FEEDBACK_BARRIER_BIT -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#endif -#ifndef GL_ATOMIC_COUNTER_BARRIER_BIT -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#endif -#ifndef GL_SHADER_STORAGE_BARRIER_BIT -#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -#endif -#ifndef GL_IMAGE_2D -#define GL_IMAGE_2D 0x904D -#endif -#ifndef GL_IMAGE_3D -#define GL_IMAGE_3D 0x904E -#endif -#ifndef GL_IMAGE_CUBE -#define GL_IMAGE_CUBE 0x9050 -#endif -#ifndef GL_IMAGE_2D_ARRAY -#define GL_IMAGE_2D_ARRAY 0x9053 -#endif -#ifndef GL_INT_IMAGE_2D -#define GL_INT_IMAGE_2D 0x9058 -#endif -#ifndef GL_INT_IMAGE_3D -#define GL_INT_IMAGE_3D 0x9059 -#endif -#ifndef GL_INT_IMAGE_CUBE -#define GL_INT_IMAGE_CUBE 0x905B -#endif -#ifndef GL_INT_IMAGE_2D_ARRAY -#define GL_INT_IMAGE_2D_ARRAY 0x905E -#endif -#ifndef GL_UNSIGNED_INT_IMAGE_2D -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#endif -#ifndef GL_UNSIGNED_INT_IMAGE_3D -#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -#endif -#ifndef GL_UNSIGNED_INT_IMAGE_CUBE -#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -#endif -#ifndef GL_UNSIGNED_INT_IMAGE_2D_ARRAY -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -#endif - - -namespace Qt3DRender { -namespace Render { - -namespace { - -GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers) -{ - GLbitfield bits = 0; - - if (barriers.testFlag(QMemoryBarrier::All)) { - bits |= GL_ALL_BARRIER_BITS; - return bits; - } - - if (barriers.testFlag(QMemoryBarrier::VertexAttributeArray)) - bits |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ElementArray)) - bits |= GL_ELEMENT_ARRAY_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::Uniform)) - bits |= GL_UNIFORM_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TextureFetch)) - bits |= GL_TEXTURE_FETCH_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ShaderImageAccess)) - bits |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::Command)) - bits |= GL_COMMAND_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::PixelBuffer)) - bits |= GL_PIXEL_BUFFER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TextureUpdate)) - bits |= GL_TEXTURE_UPDATE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::BufferUpdate)) - bits |= GL_BUFFER_UPDATE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::FrameBuffer)) - bits |= GL_FRAMEBUFFER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TransformFeedback)) - bits |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::AtomicCounter)) - bits |= GL_ATOMIC_COUNTER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ShaderStorage)) - bits |= GL_SHADER_STORAGE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::QueryBuffer)) - qWarning() << "QueryBuffer barrier not supported by ES 3.1"; - - return bits; -} - -} // anonymous - - -GraphicsHelperES3_1::GraphicsHelperES3_1() -{ -} - -GraphicsHelperES3_1::~GraphicsHelperES3_1() -{ -} - -bool GraphicsHelperES3_1::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case GraphicsHelperInterface::Compute: - case GraphicsHelperInterface::ShaderStorageObject: - case GraphicsHelperInterface::IndirectDrawing: - case GraphicsHelperInterface::ShaderImage: - return true; - default: - break; - } - return GraphicsHelperES3::supportsFeature(feature); -} - -void GraphicsHelperES3_1::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - m_extraFuncs->glBindImageTexture(imageUnit, - texture, - mipLevel, - layered, - layer, - access, - format); -} - -void GraphicsHelperES3_1::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) -{ - m_extraFuncs->glDispatchCompute(wx, wy, wz); -} - -void GraphicsHelperES3_1::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - m_extraFuncs->glMemoryBarrier(memoryBarrierGLBitfield(barriers)); -} - -void GraphicsHelperES3_1::drawArraysIndirect(GLenum mode, void *indirect) -{ - m_extraFuncs->glDrawArraysIndirect(mode, indirect); -} - -void GraphicsHelperES3_1::drawElementsIndirect(GLenum mode, GLenum type, void *indirect) -{ - m_extraFuncs->glDrawElementsIndirect(mode, type, indirect); -} - -void GraphicsHelperES3_1::bindShaderStorageBlock(GLuint , GLuint , GLuint ) -{ - // ES 3.1 has no API for that, bindings have to be specified directly in the shader - // with layout(std430, binding = 3) - qWarning() << "ES 3.1 has no bindShaderStorageBlock API, it uses binding declaration from the shader storage block"; -} - -QVector<ShaderStorageBlock> GraphicsHelperES3_1::programShaderStorageBlocks(GLuint programId) -{ - QVector<ShaderStorageBlock> blocks; - GLint nbrActiveShaderStorageBlocks = 0; - m_extraFuncs->glGetProgramInterfaceiv(programId, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveShaderStorageBlocks); - blocks.reserve(nbrActiveShaderStorageBlocks); - for (GLint i = 0; i < nbrActiveShaderStorageBlocks; ++i) { - QByteArray storageBlockName(256, '\0'); - GLsizei length = 0; - ShaderStorageBlock storageBlock; - m_extraFuncs->glGetProgramResourceName(programId, GL_SHADER_STORAGE_BLOCK, i, 256, &length, storageBlockName.data()); - storageBlock.m_index = i; - storageBlock.m_name = QString::fromUtf8(storageBlockName.left(length)); - GLenum prop = GL_BUFFER_BINDING; - m_extraFuncs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_binding); - prop = GL_BUFFER_DATA_SIZE; - m_extraFuncs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_size); - prop = GL_NUM_ACTIVE_VARIABLES; - m_extraFuncs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_activeVariablesCount); - blocks.push_back(storageBlock); - } - return blocks; -} - -UniformType GraphicsHelperES3_1::uniformTypeFromGLType(GLenum glType) -{ - switch (glType) { - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - return UniformType::Sampler; - case GL_IMAGE_2D: - case GL_IMAGE_3D: - case GL_IMAGE_CUBE: - case GL_IMAGE_2D_ARRAY: - case GL_INT_IMAGE_2D: - case GL_INT_IMAGE_3D: - case GL_INT_IMAGE_CUBE: - case GL_INT_IMAGE_2D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D: - case GL_UNSIGNED_INT_IMAGE_3D: - case GL_UNSIGNED_INT_IMAGE_CUBE: - case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: - return UniformType::Image; - - default: - return GraphicsHelperES3::uniformTypeFromGLType(glType); - } -} - -uint GraphicsHelperES3_1::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - - switch (description.m_type) { - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_IMAGE_2D: - case GL_IMAGE_3D: - case GL_IMAGE_CUBE: - case GL_IMAGE_2D_ARRAY: - case GL_INT_IMAGE_2D: - case GL_INT_IMAGE_3D: - case GL_INT_IMAGE_CUBE: - case GL_INT_IMAGE_2D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D: - case GL_UNSIGNED_INT_IMAGE_3D: - case GL_UNSIGNED_INT_IMAGE_CUBE: - case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: - rawByteSize = 4; - break; - - default: - rawByteSize = GraphicsHelperES3::uniformByteSize(description); - break; - } - - return rawByteSize; -} - -void GraphicsHelperES3_1::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - char *bufferData = buffer.data(); - - switch (description.m_type) { - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - { - Q_ASSERT(description.m_size == 1); - int value = v.toInt(); - QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1); - break; - } - - default: - GraphicsHelperES3::buildUniformBuffer(v, description, buffer); - break; - } -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h deleted file mode 100644 index 43d9ae7dd..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_1_p.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERES3_1_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERES3_1_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperes3_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class GraphicsHelperES3_1 : public GraphicsHelperES3 -{ -public: - GraphicsHelperES3_1(); - ~GraphicsHelperES3_1(); - - bool supportsFeature(Feature feature) const override; - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; - void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; - void memoryBarrier(QMemoryBarrier::Operations barriers) override; - void drawArraysIndirect(GLenum mode,void *indirect) override; - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override; - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; - QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override; - - // QGraphicHelperInterface interface - UniformType uniformTypeFromGLType(GLenum glType) override; - uint uniformByteSize(const ShaderUniform &description) override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERES3_1_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp deleted file mode 100644 index 9d0988410..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelperes3_2_p.h" -#include <QOpenGLExtraFunctions> -#include <Qt3DRender/qrendertargetoutput.h> -#include <private/attachmentpack_p.h> - -QT_BEGIN_NAMESPACE - -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -#ifndef GL_DEPTH_STENCIL_ATTACHMENT -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#endif - -#ifndef GL_PATCH_VERTICES -#define GL_PATCH_VERTICES 36466 -#endif - -#ifndef GL_IMAGE_BUFFER -#define GL_IMAGE_BUFFER 0x9051 -#endif -#ifndef GL_IMAGE_CUBE_MAP_ARRAY -#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 -#endif -#ifndef GL_INT_IMAGE_BUFFER -#define GL_INT_IMAGE_BUFFER 0x905C -#endif -#ifndef GL_INT_IMAGE_CUBE_MAP_ARRAY -#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F -#endif -#ifndef GL_UNSIGNED_INT_IMAGE_BUFFER -#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 -#endif -#ifndef GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A -#endif - -namespace Qt3DRender { -namespace Render { - -GraphicsHelperES3_2::GraphicsHelperES3_2() -{ -} - -GraphicsHelperES3_2::~GraphicsHelperES3_2() -{ -} - -bool GraphicsHelperES3_2::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case GraphicsHelperInterface::Tessellation: - return true; - default: - break; - } - return GraphicsHelperES3_1::supportsFeature(feature); -} - -bool GraphicsHelperES3_2::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - Q_UNUSED(attachment); - // This is first ES version where we have glFramebufferTexture, so - // attaching a D24S8 texture to the combined depth-stencil attachment point - // should work. - return false; -} - -void GraphicsHelperES3_2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - GLenum attr = GL_COLOR_ATTACHMENT0; - - if (attachment.m_point <= QRenderTargetOutput::Color15) - attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::DepthStencil) - attr = GL_DEPTH_STENCIL_ATTACHMENT; - else - qCritical() << "Unsupported FBO attachment OpenGL ES 3.2"; - - const QOpenGLTexture::Target target = texture->target(); - - texture->bind(); - if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces) - m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else - m_extraFuncs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel); - texture->release(); -} - -void GraphicsHelperES3_2::setVerticesPerPatch(GLint verticesPerPatch) -{ - m_extraFuncs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch); -} - -void GraphicsHelperES3_2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex, GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; - - m_extraFuncs->glDrawElementsInstancedBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - instances, - baseVertex); -} - -UniformType GraphicsHelperES3_2::uniformTypeFromGLType(GLenum glType) -{ - switch (glType) { - case GL_IMAGE_BUFFER: - case GL_IMAGE_CUBE_MAP_ARRAY: - case GL_INT_IMAGE_BUFFER: - case GL_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: - return UniformType::Image; - - default: - return GraphicsHelperES3_1::uniformTypeFromGLType(glType); - } -} - -uint GraphicsHelperES3_2::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - - switch (description.m_type) { - case GL_IMAGE_BUFFER: - case GL_IMAGE_CUBE_MAP_ARRAY: - case GL_INT_IMAGE_BUFFER: - case GL_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: - rawByteSize = 4; - break; - - default: - rawByteSize = GraphicsHelperES3_1::uniformByteSize(description); - break; - } - - return rawByteSize; -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h deleted file mode 100644 index 6b1a893d4..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_2_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERES3_2_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERES3_2_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperes3_1_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class GraphicsHelperES3_2 : public GraphicsHelperES3_1 -{ -public: - GraphicsHelperES3_2(); - ~GraphicsHelperES3_2(); - - bool supportsFeature(Feature feature) const override; - - // QGraphicHelperInterface interface - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void setVerticesPerPatch(GLint verticesPerPatch) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - UniformType uniformTypeFromGLType(GLenum glType) override; - uint uniformByteSize(const ShaderUniform &description) override; - -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERES3_2_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h deleted file mode 100644 index dc5cef10c..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperes3_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 Svenn-Arne Dragly. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERES3_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERES3_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperes2_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class GraphicsHelperES3 : public GraphicsHelperES2 -{ -public: - GraphicsHelperES3(); - ~GraphicsHelperES3(); - - // QGraphicHelperInterface interface - void bindBufferBase(GLenum target, GLuint index, GLuint buffer) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; - void drawBuffers(GLsizei n, const int *bufs) override; - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - void readBuffer(GLenum mode) override; - void drawBuffer(GLenum mode) override; - void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) override; - char *mapBuffer(GLenum target, GLsizeiptr size) override; - QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) override; - QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) override; - bool supportsFeature(Feature feature) const override; - GLboolean unmapBuffer(GLenum target) override; - void vertexAttribDivisor(GLuint index, GLuint divisor) override; - void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; - - UniformType uniformTypeFromGLType(GLenum glType) override; - uint uniformByteSize(const ShaderUniform &description) override; - - void *fenceSync() override; - void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; - void waitSync(void *sync) override; - bool wasSyncSignaled(void *sync) override; - void deleteSync(void *sync) override; - -protected: - QOpenGLExtraFunctions *m_extraFuncs = nullptr; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERES3_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp deleted file mode 100644 index b9ee16acb..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2.cpp +++ /dev/null @@ -1,935 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelpergl2_p.h" -#ifndef QT_OPENGL_ES_2 -#include <QOpenGLFunctions_2_0> -#include <private/attachmentpack_p.h> -#include <QtOpenGLExtensions/QOpenGLExtensions> -#include <private/qgraphicsutils_p.h> -#include <Qt3DRender/private/renderlogging_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -GraphicsHelperGL2::GraphicsHelperGL2() - : m_funcs(nullptr) - , m_fboFuncs(nullptr) -{ - -} - -void GraphicsHelperGL2::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) -{ - Q_UNUSED(context); - m_funcs = static_cast<QOpenGLFunctions_2_0*>(functions); - const bool ok = m_funcs->initializeOpenGLFunctions(); - Q_ASSERT(ok); - Q_UNUSED(ok); - if (context->hasExtension(QByteArrayLiteral("GL_ARB_framebuffer_object"))) { - m_fboFuncs = new QOpenGLExtension_ARB_framebuffer_object(); - const bool extensionOk = m_fboFuncs->initializeOpenGLFunctions(); - Q_ASSERT(extensionOk); - Q_UNUSED(extensionOk); - } -} - -void GraphicsHelperGL2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; - - if (baseVertex != 0) - qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2"; - - for (GLint i = 0; i < instances; i++) - drawElements(primitiveType, - primitiveCount, - indexType, - indices); -} - -void GraphicsHelperGL2::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) -{ - for (GLint i = 0; i < instances; i++) - drawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperGL2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL 2"; - for (GLint i = 0; i < instances; i++) - drawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperGL2::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) -{ - if (baseVertex != 0) - qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL 2"; - - m_funcs->glDrawElements(primitiveType, - primitiveCount, - indexType, - indices); -} - -void GraphicsHelperGL2::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) -{ - m_funcs->glDrawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperGL2::drawElementsIndirect(GLenum, GLenum, void *) -{ - qWarning() << "Indirect Drawing is not supported with OpenGL 2"; -} - -void GraphicsHelperGL2::drawArraysIndirect(GLenum , void *) -{ - qWarning() << "Indirect Drawing is not supported with OpenGL 2"; -} - -void GraphicsHelperGL2::setVerticesPerPatch(GLint verticesPerPatch) -{ - Q_UNUSED(verticesPerPatch); - qWarning() << "Tessellation not supported with OpenGL 2"; -} - -void GraphicsHelperGL2::useProgram(GLuint programId) -{ - m_funcs->glUseProgram(programId); -} - -QVector<ShaderUniform> GraphicsHelperGL2::programUniformsAndLocations(GLuint programId) -{ - QVector<ShaderUniform> uniforms; - - GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms); - uniforms.reserve(nbrActiveUniforms); - char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; i++) { - ShaderUniform uniform; - GLsizei uniformNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength, - &uniform.m_size, &uniform.m_type, uniformName); - uniformName[sizeof(uniformName) - 1] = '\0'; - uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); - uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); - // Work around for uniform array names that aren't returned with [0] by some drivers - if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]"))) - uniform.m_name.append(QLatin1String("[0]")); - uniform.m_rawByteSize = uniformByteSize(uniform); - uniforms.append(uniform); - } - return uniforms; -} - -QVector<ShaderAttribute> GraphicsHelperGL2::programAttributesAndLocations(GLuint programId) -{ - QVector<ShaderAttribute> attributes; - GLint nbrActiveAttributes = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes); - attributes.reserve(nbrActiveAttributes); - char attributeName[256]; - for (GLint i = 0; i < nbrActiveAttributes; i++) { - ShaderAttribute attribute; - GLsizei attributeNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength, - &attribute.m_size, &attribute.m_type, attributeName); - attributeName[sizeof(attributeName) - 1] = '\0'; - attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName); - attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength); - attributes.append(attribute); - } - return attributes; -} - -QVector<ShaderUniformBlock> GraphicsHelperGL2::programUniformBlocks(GLuint programId) -{ - Q_UNUSED(programId); - QVector<ShaderUniformBlock> blocks; - qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)"; - return blocks; -} - -QVector<ShaderStorageBlock> GraphicsHelperGL2::programShaderStorageBlocks(GLuint programId) -{ - Q_UNUSED(programId); - qWarning() << "SSBO are not supported by OpenGL 2.0 (since OpenGL 4.3)"; - return QVector<ShaderStorageBlock>(); -} - -void GraphicsHelperGL2::vertexAttribDivisor(GLuint index, - GLuint divisor) -{ - Q_UNUSED(index); - Q_UNUSED(divisor); -} - -void GraphicsHelperGL2::vertexAttributePointer(GLenum shaderDataType, - GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer) -{ - switch (shaderDataType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_MAT4: - m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); - break; - - default: - qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type"; - Q_UNREACHABLE(); - } -} - -void GraphicsHelperGL2::readBuffer(GLenum mode) -{ - m_funcs->glReadBuffer(mode); -} - -void GraphicsHelperGL2::drawBuffer(GLenum mode) -{ - m_funcs->glDrawBuffer(mode); -} - -void *GraphicsHelperGL2::fenceSync() -{ - qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)"; - return nullptr; -} - -void GraphicsHelperGL2::clientWaitSync(void *, GLuint64 ) -{ - qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)"; -} - -void GraphicsHelperGL2::waitSync(void *) -{ - qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)"; -} - -bool GraphicsHelperGL2::wasSyncSignaled(void *) -{ - qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)"; - return false; -} - -void GraphicsHelperGL2::deleteSync(void *) -{ - qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)"; -} - -void GraphicsHelperGL2::rasterMode(GLenum faceMode, GLenum rasterMode) -{ - m_funcs->glPolygonMode(faceMode, rasterMode); -} - -void GraphicsHelperGL2::blendEquation(GLenum mode) -{ - m_funcs->glBlendEquation(mode); -} - -void GraphicsHelperGL2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) -{ - Q_UNUSED(buf); - Q_UNUSED(sfactor); - Q_UNUSED(dfactor); - - qWarning() << "glBlendFunci() not supported by OpenGL 2.0 (since OpenGL 4.0)"; -} - -void GraphicsHelperGL2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) -{ - Q_UNUSED(buf); - Q_UNUSED(sRGB); - Q_UNUSED(dRGB); - Q_UNUSED(sAlpha); - Q_UNUSED(dAlpha); - - qWarning() << "glBlendFuncSeparatei() not supported by OpenGL 2.0 (since OpenGL 4.0)"; -} - -void GraphicsHelperGL2::alphaTest(GLenum mode1, GLenum mode2) -{ - m_funcs->glEnable(GL_ALPHA_TEST); - m_funcs->glAlphaFunc(mode1, mode2); -} - -void GraphicsHelperGL2::depthTest(GLenum mode) -{ - m_funcs->glEnable(GL_DEPTH_TEST); - m_funcs->glDepthFunc(mode); -} - -void GraphicsHelperGL2::depthMask(GLenum mode) -{ - m_funcs->glDepthMask(mode); -} - -void GraphicsHelperGL2::depthRange(GLdouble nearValue, GLdouble farValue) -{ - m_funcs->glDepthRange(nearValue, farValue); -} - -void GraphicsHelperGL2::frontFace(GLenum mode) -{ - m_funcs->glFrontFace(mode); -} - -void GraphicsHelperGL2::setMSAAEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_MULTISAMPLE) - : m_funcs->glDisable(GL_MULTISAMPLE); -} - -void GraphicsHelperGL2::setAlphaCoverageEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) - : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); -} - -GLuint GraphicsHelperGL2::createFrameBufferObject() -{ - if (m_fboFuncs != nullptr) { - GLuint id; - m_fboFuncs->glGenFramebuffers(1, &id); - return id; - } - qWarning() << "FBO not supported by your OpenGL hardware"; - return 0; -} - -void GraphicsHelperGL2::releaseFrameBufferObject(GLuint frameBufferId) -{ - if (m_fboFuncs != nullptr) - m_fboFuncs->glDeleteFramebuffers(1, &frameBufferId); - else - qWarning() << "FBO not supported by your OpenGL hardware"; -} - -bool GraphicsHelperGL2::checkFrameBufferComplete() -{ - if (m_fboFuncs != nullptr) - return (m_fboFuncs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); - return false; -} - -bool GraphicsHelperGL2::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - Q_UNUSED(attachment); - return false; -} - -void GraphicsHelperGL2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - if (m_fboFuncs != nullptr) { - GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT; - - if (attachment.m_point <= QRenderTargetOutput::Color15) - attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - else - qCritical() << "DepthStencil Attachment not supported on OpenGL 2.0"; - - const QOpenGLTexture::Target target = texture->target(); - - if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) { - qWarning() << "OpenGL 2.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO"; - return; - } - - texture->bind(); - if (target == QOpenGLTexture::Target3D) - m_fboFuncs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMap) - m_fboFuncs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else if (target == QOpenGLTexture::Target1D) - m_fboFuncs->glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel); - else if (target == QOpenGLTexture::Target2D || target == QOpenGLTexture::TargetRectangle) - m_fboFuncs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel); - else - qCritical() << "Texture format not supported for Attachment on OpenGL 2.0"; - texture->release(); - } -} - -void GraphicsHelperGL2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) -{ - Q_UNUSED(renderBuffer); - Q_UNUSED(attachment); - Q_UNREACHABLE(); -} - -bool GraphicsHelperGL2::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case MRT: - return (m_fboFuncs != nullptr); - case TextureDimensionRetrieval: - case MapBuffer: - return true; - default: - return false; - } -} - -void GraphicsHelperGL2::drawBuffers(GLsizei n, const int *bufs) -{ - QVarLengthArray<GLenum, 16> drawBufs(n); - - for (int i = 0; i < n; i++) - drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i]; - m_funcs->glDrawBuffers(n, drawBufs.constData()); -} - -void GraphicsHelperGL2::bindFragDataLocation(GLuint, const QHash<QString, int> &) -{ - qCritical() << "bindFragDataLocation is not supported by GL 2.0"; -} - -void GraphicsHelperGL2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) -{ - if (m_fboFuncs != nullptr) { - switch (mode) { - case FBODraw: - m_fboFuncs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId); - return; - case FBORead: - m_fboFuncs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId); - return; - case FBOReadAndDraw: - default: - m_fboFuncs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); - return; - } - } else { - qWarning() << "FBO not supported by your OpenGL hardware"; - } -} - -void GraphicsHelperGL2::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - Q_UNUSED(imageUnit) - Q_UNUSED(texture) - Q_UNUSED(mipLevel) - Q_UNUSED(layered) - Q_UNUSED(layer) - Q_UNUSED(access) - Q_UNUSED(format) - qWarning() << "Shader Images are not supported by OpenGL 2.0 (since OpenGL 4.2)"; - -} - -GLuint GraphicsHelperGL2::boundFrameBufferObject() -{ - GLint id = 0; - m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id); - return id; -} - -void GraphicsHelperGL2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - Q_UNUSED(programId); - Q_UNUSED(uniformBlockIndex); - Q_UNUSED(uniformBlockBinding); - qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)"; -} - -void GraphicsHelperGL2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) -{ - Q_UNUSED(programId); - Q_UNUSED(shaderStorageBlockIndex); - Q_UNUSED(shaderStorageBlockBinding); - qWarning() << "SSBO are not supported by OpenGL 2.0 (since OpenGL 4.3)"; -} - -void GraphicsHelperGL2::bindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - Q_UNUSED(target); - Q_UNUSED(index); - Q_UNUSED(buffer); - qWarning() << "bindBufferBase is not supported by OpenGL 2.0 (since OpenGL 3.0)"; -} - -void GraphicsHelperGL2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - Q_UNUSED(v); - Q_UNUSED(description); - Q_UNUSED(buffer); - qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)"; -} - -uint GraphicsHelperGL2::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - int arrayStride = qMax(description.m_arrayStride, 0); - int matrixStride = qMax(description.m_matrixStride, 0); - - switch (description.m_type) { - - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - rawByteSize = 8; - break; - - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - rawByteSize = 12; - break; - - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - rawByteSize = 16; - break; - - case GL_FLOAT_MAT2: - rawByteSize = matrixStride ? 2 * matrixStride : 16; - break; - - case GL_FLOAT_MAT2x4: - rawByteSize = matrixStride ? 2 * matrixStride : 32; - break; - - case GL_FLOAT_MAT4x2: - rawByteSize = matrixStride ? 4 * matrixStride : 32; - break; - - case GL_FLOAT_MAT3: - rawByteSize = matrixStride ? 3 * matrixStride : 36; - break; - - case GL_FLOAT_MAT2x3: - rawByteSize = matrixStride ? 2 * matrixStride : 24; - break; - - case GL_FLOAT_MAT3x2: - rawByteSize = matrixStride ? 3 * matrixStride : 24; - break; - - case GL_FLOAT_MAT4: - rawByteSize = matrixStride ? 4 * matrixStride : 64; - break; - - case GL_FLOAT_MAT4x3: - rawByteSize = matrixStride ? 4 * matrixStride : 48; - break; - - case GL_FLOAT_MAT3x4: - rawByteSize = matrixStride ? 3 * matrixStride : 48; - break; - - case GL_BOOL: - rawByteSize = 1; - break; - - case GL_BOOL_VEC2: - rawByteSize = 2; - break; - - case GL_BOOL_VEC3: - rawByteSize = 3; - break; - - case GL_BOOL_VEC4: - rawByteSize = 4; - break; - - case GL_INT: - case GL_FLOAT: - case GL_SAMPLER_1D: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - rawByteSize = 4; - break; - - default: - Q_UNREACHABLE(); - } - - return arrayStride ? rawByteSize * arrayStride : rawByteSize; -} - -void GraphicsHelperGL2::enableClipPlane(int clipPlane) -{ - m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL2::disableClipPlane(int clipPlane) -{ - m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL2::setClipPlane(int clipPlane, const QVector3D &normal, float distance) -{ - double plane[4]; - plane[0] = normal.x(); - plane[1] = normal.y(); - plane[2] = normal.z(); - plane[3] = distance; - - m_funcs->glClipPlane(GL_CLIP_PLANE0 + clipPlane, plane); -} - -GLint GraphicsHelperGL2::maxClipPlaneCount() -{ - GLint max = 0; - m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max); - return max; -} - -void GraphicsHelperGL2::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - Q_UNUSED(barriers); - qWarning() << "memory barrier is not supported by OpenGL 2.0 (since 4.3)"; -} - -void GraphicsHelperGL2::enablePrimitiveRestart(int) -{ -} - -void GraphicsHelperGL2::enableVertexAttributeArray(int location) -{ - m_funcs->glEnableVertexAttribArray(location); -} - -void GraphicsHelperGL2::disablePrimitiveRestart() -{ -} - -void GraphicsHelperGL2::clearBufferf(GLint drawbuffer, const QVector4D &values) -{ - Q_UNUSED(drawbuffer); - Q_UNUSED(values); - qWarning() << "glClearBuffer*() not supported by OpenGL 2.0"; -} - -void GraphicsHelperGL2::pointSize(bool programmable, GLfloat value) -{ - m_funcs->glEnable(GL_POINT_SPRITE); - if (programmable) - m_funcs->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - else - m_funcs->glPointSize(value); -} - -void GraphicsHelperGL2::enablei(GLenum cap, GLuint index) -{ - Q_UNUSED(cap); - Q_UNUSED(index); - qWarning() << "glEnablei() not supported by OpenGL 2.0 (since 3.0)"; -} - -void GraphicsHelperGL2::disablei(GLenum cap, GLuint index) -{ - Q_UNUSED(cap); - Q_UNUSED(index); - qWarning() << "glDisablei() not supported by OpenGL 2.0 (since 3.0)"; -} - -void GraphicsHelperGL2::setSeamlessCubemap(bool enable) -{ - Q_UNUSED(enable); - qWarning() << "GL_TEXTURE_CUBE_MAP_SEAMLESS not supported by OpenGL 2.0 (since 3.2)"; -} - -QSize GraphicsHelperGL2::getRenderBufferDimensions(GLuint renderBufferId) -{ - Q_UNUSED(renderBufferId); - qCritical() << "RenderBuffer dimensions retrival not supported on OpenGL 2.0"; - return QSize(0,0); -} - -QSize GraphicsHelperGL2::getTextureDimensions(GLuint textureId, GLenum target, uint level) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindTexture(target, textureId); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - m_funcs->glBindTexture(target, 0); - - return QSize(width, height); -} - -void GraphicsHelperGL2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) -{ - Q_UNUSED(wx); - Q_UNUSED(wy); - Q_UNUSED(wz); - qWarning() << "Compute Shaders are not supported by OpenGL 2.0 (since OpenGL 4.3)"; -} - -char *GraphicsHelperGL2::mapBuffer(GLenum target, GLsizeiptr size) -{ - Q_UNUSED(size); - return static_cast<char*>(m_funcs->glMapBuffer(target, GL_READ_WRITE)); -} - -GLboolean GraphicsHelperGL2::unmapBuffer(GLenum target) -{ - return m_funcs->glUnmapBuffer(target); -} - -void GraphicsHelperGL2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform1fv(location, count, values); -} - -void GraphicsHelperGL2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform2fv(location, count, values); -} - -void GraphicsHelperGL2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform3fv(location, count, values); -} - -void GraphicsHelperGL2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform4fv(location, count, values); -} - -void GraphicsHelperGL2::glUniform1iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform1iv(location, count, values); -} - -void GraphicsHelperGL2::glUniform2iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform2iv(location, count, values); -} - -void GraphicsHelperGL2::glUniform3iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform3iv(location, count, values); -} - -void GraphicsHelperGL2::glUniform4iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform4iv(location, count, values); -} - -void GraphicsHelperGL2::glUniform1uiv(GLint , GLsizei , const GLuint *) -{ - qWarning() << "glUniform1uiv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniform2uiv(GLint , GLsizei , const GLuint *) -{ - qWarning() << "glUniform2uiv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniform3uiv(GLint , GLsizei , const GLuint *) -{ - qWarning() << "glUniform3uiv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniform4uiv(GLint , GLsizei , const GLuint *) -{ - qWarning() << "glUniform4uiv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2fv(location, count, false, values); -} - -void GraphicsHelperGL2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3fv(location, count, false, values); -} - -void GraphicsHelperGL2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4fv(location, count, false, values); -} - -void GraphicsHelperGL2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *) -{ - qWarning() << "glUniformMatrix2x3fv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *) -{ - qWarning() << "glUniformMatrix3x2fv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *) -{ - qWarning() << "glUniformMatrix2x4fv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *) -{ - qWarning() << "glUniformMatrix4x2fv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *) -{ - qWarning() << "glUniformMatrix3x4fv not supported by GL 2"; -} - -void GraphicsHelperGL2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *) -{ - qWarning() << "glUniformMatrix4x3fv not supported by GL 2"; -} - -UniformType GraphicsHelperGL2::uniformTypeFromGLType(GLenum type) -{ - switch (type) { - case GL_FLOAT: - return UniformType::Float; - case GL_FLOAT_VEC2: - return UniformType::Vec2; - case GL_FLOAT_VEC3: - return UniformType::Vec3; - case GL_FLOAT_VEC4: - return UniformType::Vec4; - case GL_FLOAT_MAT2: - return UniformType::Mat2; - case GL_FLOAT_MAT3: - return UniformType::Mat3; - case GL_FLOAT_MAT4: - return UniformType::Mat4; - case GL_INT: - return UniformType::Int; - case GL_INT_VEC2: - return UniformType::IVec2; - case GL_INT_VEC3: - return UniformType::IVec3; - case GL_INT_VEC4: - return UniformType::IVec4; - case GL_BOOL: - return UniformType::Bool; - case GL_BOOL_VEC2: - return UniformType::BVec2; - case GL_BOOL_VEC3: - return UniformType::BVec3; - case GL_BOOL_VEC4: - return UniformType::BVec4; - - case GL_SAMPLER_1D: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_3D: - return UniformType::Sampler; - - default: - Q_UNREACHABLE(); - return UniformType::Float; - } -} - -void GraphicsHelperGL2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - Q_UNUSED(srcX0); - Q_UNUSED(srcX1); - Q_UNUSED(srcY0); - Q_UNUSED(srcY1); - Q_UNUSED(dstX0); - Q_UNUSED(dstX1); - Q_UNUSED(dstY0); - Q_UNUSED(dstY1); - Q_UNUSED(mask); - Q_UNUSED(filter); - qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)"; -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h deleted file mode 100644 index eb85b8537..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl2_p.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERGL2_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERGL2_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperinterface_p.h> - -#ifndef QT_OPENGL_ES_2 - -QT_BEGIN_NAMESPACE - -class QOpenGLFunctions_2_0; -class QOpenGLExtension_ARB_framebuffer_object; - -namespace Qt3DRender { -namespace Render { - -class Q_AUTOTEST_EXPORT GraphicsHelperGL2 : public GraphicsHelperInterface -{ -public: - GraphicsHelperGL2(); - - // QGraphicHelperInterface interface - void alphaTest(GLenum mode1, GLenum mode2) override; - void bindBufferBase(GLenum target, GLuint index, GLuint buffer) override; - void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; - void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - void blendEquation(GLenum mode) override; - void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) override; - void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) override; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override; - GLuint boundFrameBufferObject() override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; - bool checkFrameBufferComplete() override; - void clearBufferf(GLint drawbuffer, const QVector4D &values) override; - GLuint createFrameBufferObject() override; - void depthMask(GLenum mode) override; - void depthRange(GLdouble nearValue, GLdouble farValue) override; - void depthTest(GLenum mode) override; - void disableClipPlane(int clipPlane) override; - void disablei(GLenum cap, GLuint index) override; - void disablePrimitiveRestart() override; - void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; - char *mapBuffer(GLenum target, GLsizeiptr size) override; - GLboolean unmapBuffer(GLenum target) override; - void drawArrays(GLenum primitiveType, GLint first, GLsizei count) override; - void drawArraysIndirect(GLenum mode,void *indirect) override; - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override; - void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) override; - void drawBuffers(GLsizei n, const int *bufs) override; - void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLint baseVertex = 0) override; - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - void enableClipPlane(int clipPlane) override; - void enablei(GLenum cap, GLuint index) override; - void enablePrimitiveRestart(int primitiveRestartIndex) override; - void enableVertexAttributeArray(int location) override; - void frontFace(GLenum mode) override; - QSize getRenderBufferDimensions(GLuint renderBufferId) override; - QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) override; - void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) override; - void pointSize(bool programmable, GLfloat value) override; - GLint maxClipPlaneCount() override; - void memoryBarrier(QMemoryBarrier::Operations barriers) override; - QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) override; - QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) override; - QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) override; - QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override; - void releaseFrameBufferObject(GLuint frameBufferId) override; - void setMSAAEnabled(bool enable) override; - void setAlphaCoverageEnabled(bool enable) override; - void setClipPlane(int clipPlane, const QVector3D &normal, float distance) override; - void setSeamlessCubemap(bool enable) override; - void setVerticesPerPatch(GLint verticesPerPatch) override; - bool supportsFeature(Feature feature) const override; - uint uniformByteSize(const ShaderUniform &description) override; - void useProgram(GLuint programId) override; - void vertexAttribDivisor(GLuint index, GLuint divisor) override; - void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; - void readBuffer(GLenum mode) override; - void drawBuffer(GLenum mode) override; - void rasterMode(GLenum faceMode, GLenum rasterMode) override; - - void *fenceSync() override; - void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; - void waitSync(void *sync) override; - bool wasSyncSignaled(void *sync) override; - void deleteSync(void *sync) override; - - void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) override; - - void glUniform1iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform2iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform3iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform4iv(GLint location, GLsizei count, const GLint *value) override; - - void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) override; - - void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) override; - - UniformType uniformTypeFromGLType(GLenum glType) override; - -private: - QOpenGLFunctions_2_0 *m_funcs; - QOpenGLExtension_ARB_framebuffer_object *m_fboFuncs; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERGL2_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp deleted file mode 100644 index f20491358..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2.cpp +++ /dev/null @@ -1,1245 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelpergl3_2_p.h" - -#ifndef QT_OPENGL_ES_2 -#include <QOpenGLFunctions_3_2_Core> -#include <QOpenGLFunctions_3_3_Core> -#include <QtOpenGLExtensions/qopenglextensions.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <private/attachmentpack_p.h> -#include <private/qgraphicsutils_p.h> - -QT_BEGIN_NAMESPACE - -# ifndef QT_OPENGL_3 -# define GL_PATCH_VERTICES 36466 -# define GL_ACTIVE_RESOURCES 0x92F5 -# define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -# define GL_BUFFER_BINDING 0x9302 -# define GL_BUFFER_DATA_SIZE 0x9303 -# define GL_NUM_ACTIVE_VARIABLES 0x9304 -# define GL_SHADER_STORAGE_BLOCK 0x92E6 -# define GL_UNIFORM 0x92E1 -# define GL_UNIFORM_BLOCK 0x92E2 -# define GL_UNIFORM_BLOCK_INDEX 0x8A3A -# define GL_UNIFORM_OFFSET 0x8A3B -# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -# define GL_UNIFORM_BLOCK_BINDING 0x8A3F -# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -# endif - -namespace Qt3DRender { -namespace Render { - -GraphicsHelperGL3_2::GraphicsHelperGL3_2() - : m_funcs(nullptr) - , m_tessFuncs() -{ -} - -GraphicsHelperGL3_2::~GraphicsHelperGL3_2() -{ -} - -void GraphicsHelperGL3_2::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) -{ - m_funcs = static_cast<QOpenGLFunctions_3_2_Core*>(functions); - const bool ok = m_funcs->initializeOpenGLFunctions(); - Q_ASSERT(ok); - Q_UNUSED(ok); - - if (context->hasExtension(QByteArrayLiteral("GL_ARB_tessellation_shader"))) { - m_tessFuncs.reset(new QOpenGLExtension_ARB_tessellation_shader); - m_tessFuncs->initializeOpenGLFunctions(); - } -} - -void GraphicsHelperGL3_2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; - - // glDrawElements OpenGL 3.1 or greater - m_funcs->glDrawElementsInstancedBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - instances, - baseVertex); -} - -void GraphicsHelperGL3_2::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) -{ - // glDrawArraysInstanced OpenGL 3.1 or greater - m_funcs->glDrawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsHelperGL3_2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL 3"; - m_funcs->glDrawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsHelperGL3_2::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) -{ - m_funcs->glDrawElementsBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - baseVertex); -} - -void GraphicsHelperGL3_2::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) -{ - m_funcs->glDrawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperGL3_2::drawElementsIndirect(GLenum, GLenum, void *) -{ - qWarning() << "Indirect Drawing is not supported with OpenGL 3.2"; -} - -void GraphicsHelperGL3_2::drawArraysIndirect(GLenum , void *) -{ - qWarning() << "Indirect Drawing is not supported with OpenGL 3.2"; -} - -void GraphicsHelperGL3_2::setVerticesPerPatch(GLint verticesPerPatch) -{ -#if defined(QT_OPENGL_4) - if (!m_tessFuncs) { - qWarning() << "Tessellation not supported with OpenGL 3 without GL_ARB_tessellation_shader"; - return; - } - - m_tessFuncs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch); -#else - Q_UNUSED(verticesPerPatch); - qWarning() << "Tessellation not supported"; -#endif -} - -void GraphicsHelperGL3_2::useProgram(GLuint programId) -{ - m_funcs->glUseProgram(programId); -} - -QVector<ShaderUniform> GraphicsHelperGL3_2::programUniformsAndLocations(GLuint programId) -{ - QVector<ShaderUniform> uniforms; - - GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms); - uniforms.reserve(nbrActiveUniforms); - char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; i++) { - ShaderUniform uniform; - GLsizei uniformNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength, - &uniform.m_size, &uniform.m_type, uniformName); - uniformName[sizeof(uniformName) - 1] = '\0'; - uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); - uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); - // Work around for uniform array names that aren't returned with [0] by some drivers - if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]"))) - uniform.m_name.append(QLatin1String("[0]")); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride); - uniform.m_rawByteSize = uniformByteSize(uniform); - uniforms.append(uniform); - qCDebug(Render::Rendering) << uniform.m_name << "size" << uniform.m_size - << " offset" << uniform.m_offset - << " rawSize" << uniform.m_rawByteSize; - } - - return uniforms; -} - -QVector<ShaderAttribute> GraphicsHelperGL3_2::programAttributesAndLocations(GLuint programId) -{ - QVector<ShaderAttribute> attributes; - GLint nbrActiveAttributes = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes); - attributes.reserve(nbrActiveAttributes); - char attributeName[256]; - for (GLint i = 0; i < nbrActiveAttributes; i++) { - ShaderAttribute attribute; - GLsizei attributeNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength, - &attribute.m_size, &attribute.m_type, attributeName); - attributeName[sizeof(attributeName) - 1] = '\0'; - attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName); - attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength); - attributes.append(attribute); - } - return attributes; -} - -QVector<ShaderUniformBlock> GraphicsHelperGL3_2::programUniformBlocks(GLuint programId) -{ - QVector<ShaderUniformBlock> blocks; - GLint nbrActiveUniformsBlocks = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCKS, &nbrActiveUniformsBlocks); - blocks.reserve(nbrActiveUniformsBlocks); - for (GLint i = 0; i < nbrActiveUniformsBlocks; i++) { - QByteArray uniformBlockName(256, '\0'); - GLsizei length = 0; - ShaderUniformBlock uniformBlock; - m_funcs->glGetActiveUniformBlockName(programId, i, 256, &length, uniformBlockName.data()); - uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length)); - uniformBlock.m_index = i; - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformBlock.m_activeUniformsCount); - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_BINDING, &uniformBlock.m_binding); - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlock.m_size); - blocks.append(uniformBlock); - } - return blocks; -} - -QVector<ShaderStorageBlock> GraphicsHelperGL3_2::programShaderStorageBlocks(GLuint programId) -{ - Q_UNUSED(programId); - QVector<ShaderStorageBlock> blocks; - qWarning() << "SSBO are not supported by OpenGL 3.2 (since OpenGL 4.3)"; - return blocks; -} - -void GraphicsHelperGL3_2::vertexAttribDivisor(GLuint index, GLuint divisor) -{ - Q_UNUSED(index); - Q_UNUSED(divisor); - qCWarning(Render::Rendering) << "Vertex attribute divisor not available with OpenGL 3.2 core"; -} - -void GraphicsHelperGL3_2::vertexAttributePointer(GLenum shaderDataType, - GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer) -{ - switch (shaderDataType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_MAT4: - m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); - break; - - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_VEC2: - case GL_UNSIGNED_INT_VEC3: - case GL_UNSIGNED_INT_VEC4: - m_funcs->glVertexAttribIPointer(index, size, type, stride, pointer); - break; - - default: - qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type"; - Q_UNREACHABLE(); - } -} - -void GraphicsHelperGL3_2::readBuffer(GLenum mode) -{ - m_funcs->glReadBuffer(mode); -} - -void GraphicsHelperGL3_2::drawBuffer(GLenum mode) -{ - m_funcs->glDrawBuffer(mode); -} - -void *GraphicsHelperGL3_2::fenceSync() -{ - return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -} - -void GraphicsHelperGL3_2::clientWaitSync(void *sync, GLuint64 nanoSecTimeout) -{ - m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout); -} - -void GraphicsHelperGL3_2::waitSync(void *sync) -{ - m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED); -} - -bool GraphicsHelperGL3_2::wasSyncSignaled(void *sync) -{ - GLint v; - m_funcs->glGetSynciv(static_cast<GLsync>(sync), - GL_SYNC_STATUS, - sizeof(v), - nullptr, - &v); - return v == GL_SIGNALED; -} - -void GraphicsHelperGL3_2::deleteSync(void *sync) -{ - m_funcs->glDeleteSync(static_cast<GLsync>(sync)); -} - -void GraphicsHelperGL3_2::rasterMode(GLenum faceMode, GLenum rasterMode) -{ - m_funcs->glPolygonMode(faceMode, rasterMode); -} - -void GraphicsHelperGL3_2::blendEquation(GLenum mode) -{ - m_funcs->glBlendEquation(mode); -} - -void GraphicsHelperGL3_2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) -{ - Q_UNUSED(buf); - Q_UNUSED(sfactor); - Q_UNUSED(dfactor); - - qWarning() << "glBlendFunci() not supported by OpenGL 3.0 (since OpenGL 4.0)"; -} - -void GraphicsHelperGL3_2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) -{ - Q_UNUSED(buf); - Q_UNUSED(sRGB); - Q_UNUSED(dRGB); - Q_UNUSED(sAlpha); - Q_UNUSED(dAlpha); - - qWarning() << "glBlendFuncSeparatei() not supported by OpenGL 3.0 (since OpenGL 4.0)"; -} - -void GraphicsHelperGL3_2::alphaTest(GLenum, GLenum) -{ - qCWarning(Render::Rendering) << "AlphaTest not available with OpenGL 3.2 core"; -} - -void GraphicsHelperGL3_2::depthTest(GLenum mode) -{ - m_funcs->glEnable(GL_DEPTH_TEST); - m_funcs->glDepthFunc(mode); -} - -void GraphicsHelperGL3_2::depthMask(GLenum mode) -{ - m_funcs->glDepthMask(mode); -} - -void GraphicsHelperGL3_2::depthRange(GLdouble nearValue, GLdouble farValue) -{ - m_funcs->glDepthRange(nearValue, farValue); -} - -void GraphicsHelperGL3_2::frontFace(GLenum mode) -{ - m_funcs->glFrontFace(mode); - -} - -void GraphicsHelperGL3_2::setMSAAEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_MULTISAMPLE) - : m_funcs->glDisable(GL_MULTISAMPLE); -} - -void GraphicsHelperGL3_2::setAlphaCoverageEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) - : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); -} - -GLuint GraphicsHelperGL3_2::createFrameBufferObject() -{ - GLuint id; - m_funcs->glGenFramebuffers(1, &id); - return id; -} - -void GraphicsHelperGL3_2::releaseFrameBufferObject(GLuint frameBufferId) -{ - m_funcs->glDeleteFramebuffers(1, &frameBufferId); -} - -void GraphicsHelperGL3_2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) -{ - switch (mode) { - case FBODraw: - m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId); - return; - case FBORead: - m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId); - return; - case FBOReadAndDraw: - default: - m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); - return; - } -} - -void GraphicsHelperGL3_2::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - Q_UNUSED(imageUnit) - Q_UNUSED(texture) - Q_UNUSED(mipLevel) - Q_UNUSED(layered) - Q_UNUSED(layer) - Q_UNUSED(access) - Q_UNUSED(format) - qWarning() << "Shader Images are not supported by OpenGL 3.2 (since OpenGL 4.2)"; - -} - -GLuint GraphicsHelperGL3_2::boundFrameBufferObject() -{ - GLint id = 0; - m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id); - return id; -} - -bool GraphicsHelperGL3_2::checkFrameBufferComplete() -{ - return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); -} - -bool GraphicsHelperGL3_2::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - Q_UNUSED(attachment); - return false; -} - -void GraphicsHelperGL3_2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT; - - if (attachment.m_point <= QRenderTargetOutput::Color15) - attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - - texture->bind(); - QOpenGLTexture::Target target = texture->target(); - if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray || - target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D) - m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMapArray) - m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMap) - m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else - m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel); - texture->release(); -} - -void GraphicsHelperGL3_2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) -{ - Q_UNUSED(renderBuffer); - Q_UNUSED(attachment); - Q_UNREACHABLE(); -} - -bool GraphicsHelperGL3_2::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case MRT: - case UniformBufferObject: - case PrimitiveRestart: - case RenderBufferDimensionRetrieval: - case TextureDimensionRetrieval: - case BindableFragmentOutputs: - case BlitFramebuffer: - case Fences: - return true; - case Tessellation: - return !m_tessFuncs.isNull(); - default: - return false; - } -} - -void GraphicsHelperGL3_2::drawBuffers(GLsizei n, const int *bufs) -{ - // Use QVarLengthArray here - QVarLengthArray<GLenum, 16> drawBufs(n); - - for (int i = 0; i < n; i++) - drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i]; - m_funcs->glDrawBuffers(n, drawBufs.constData()); -} - -void GraphicsHelperGL3_2::bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) -{ - for (auto it = outputs.begin(), end = outputs.end(); it != end; ++it) - m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str()); -} - -void GraphicsHelperGL3_2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); -} - -void GraphicsHelperGL3_2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) -{ - Q_UNUSED(programId); - Q_UNUSED(shaderStorageBlockIndex); - Q_UNUSED(shaderStorageBlockBinding); - qWarning() << "SSBO are not supported by OpenGL 3.0 (since OpenGL 4.3)"; -} - -void GraphicsHelperGL3_2::bindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - m_funcs->glBindBufferBase(target, index, buffer); -} - -void GraphicsHelperGL3_2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - char *bufferData = buffer.data(); - - switch (description.m_type) { - - case GL_FLOAT: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_FLOAT_VEC2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_FLOAT_VEC3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_FLOAT_VEC4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_FLOAT_MAT2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2); - break; - } - - case GL_FLOAT_MAT2x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3); - break; - } - - case GL_FLOAT_MAT2x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4); - break; - } - - case GL_FLOAT_MAT3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3); - break; - } - - case GL_FLOAT_MAT3x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2); - break; - } - - case GL_FLOAT_MAT3x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4); - break; - } - - case GL_FLOAT_MAT4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4); - break; - } - - case GL_FLOAT_MAT4x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2); - break; - } - - case GL_FLOAT_MAT4x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3); - break; - } - - case GL_INT: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_INT_VEC2: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_INT_VEC3: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_INT_VEC4: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_UNSIGNED_INT: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_UNSIGNED_INT_VEC2: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_UNSIGNED_INT_VEC3: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_UNSIGNED_INT_VEC4: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_BOOL: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_BOOL_VEC2: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_BOOL_VEC3: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_BOOL_VEC4: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: { - Q_ASSERT(description.m_size == 1); - int value = v.toInt(); - QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - -uint GraphicsHelperGL3_2::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - int arrayStride = qMax(description.m_arrayStride, 0); - int matrixStride = qMax(description.m_matrixStride, 0); - - switch (description.m_type) { - - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_UNSIGNED_INT_VEC2: - rawByteSize = 8; - break; - - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_UNSIGNED_INT_VEC3: - rawByteSize = 12; - break; - - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_UNSIGNED_INT_VEC4: - rawByteSize = 16; - break; - - case GL_FLOAT_MAT2: - rawByteSize = matrixStride ? 2 * matrixStride : 16; - break; - - case GL_FLOAT_MAT2x4: - rawByteSize = matrixStride ? 2 * matrixStride : 32; - break; - - case GL_FLOAT_MAT4x2: - rawByteSize = matrixStride ? 4 * matrixStride : 32; - break; - - case GL_FLOAT_MAT3: - rawByteSize = matrixStride ? 3 * matrixStride : 36; - break; - - case GL_FLOAT_MAT2x3: - rawByteSize = matrixStride ? 2 * matrixStride : 24; - break; - - case GL_FLOAT_MAT3x2: - rawByteSize = matrixStride ? 3 * matrixStride : 24; - break; - - case GL_FLOAT_MAT4: - rawByteSize = matrixStride ? 4 * matrixStride : 64; - break; - - case GL_FLOAT_MAT4x3: - rawByteSize = matrixStride ? 4 * matrixStride : 48; - break; - - case GL_FLOAT_MAT3x4: - rawByteSize = matrixStride ? 3 * matrixStride : 48; - break; - - case GL_BOOL: - rawByteSize = 1; - break; - - case GL_BOOL_VEC2: - rawByteSize = 2; - break; - - case GL_BOOL_VEC3: - rawByteSize = 3; - break; - - case GL_BOOL_VEC4: - rawByteSize = 4; - break; - - case GL_INT: - case GL_FLOAT: - case GL_UNSIGNED_INT: - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - rawByteSize = 4; - break; - } - - return arrayStride ? rawByteSize * arrayStride : rawByteSize; -} - -void GraphicsHelperGL3_2::enableClipPlane(int clipPlane) -{ - m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL3_2::disableClipPlane(int clipPlane) -{ - m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL3_2::setClipPlane(int clipPlane, const QVector3D &normal, float distance) -{ - // deprecated - Q_UNUSED(clipPlane); - Q_UNUSED(normal); - Q_UNUSED(distance); -} - -GLint GraphicsHelperGL3_2::maxClipPlaneCount() -{ - GLint max = 0; - m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max); - return max; -} - -void GraphicsHelperGL3_2::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - Q_UNUSED(barriers); - qWarning() << "memory barrier is not supported by OpenGL 3.0 (since 4.3)"; -} - -void GraphicsHelperGL3_2::enablePrimitiveRestart(int primitiveRestartIndex) -{ - m_funcs->glPrimitiveRestartIndex(primitiveRestartIndex); - m_funcs->glEnable(GL_PRIMITIVE_RESTART); -} - -void GraphicsHelperGL3_2::enableVertexAttributeArray(int location) -{ - m_funcs->glEnableVertexAttribArray(location); -} - -void GraphicsHelperGL3_2::disablePrimitiveRestart() -{ - m_funcs->glDisable(GL_PRIMITIVE_RESTART); -} - -void GraphicsHelperGL3_2::clearBufferf(GLint drawbuffer, const QVector4D &values) -{ - GLfloat vec[4] = {values[0], values[1], values[2], values[3]}; - m_funcs->glClearBufferfv(GL_COLOR, drawbuffer, vec); -} - -void GraphicsHelperGL3_2::pointSize(bool programmable, GLfloat value) -{ - if (programmable) { - m_funcs->glEnable(GL_PROGRAM_POINT_SIZE); - } else { - m_funcs->glDisable(GL_PROGRAM_POINT_SIZE); - m_funcs->glPointSize(value); - } -} - -void GraphicsHelperGL3_2::enablei(GLenum cap, GLuint index) -{ - m_funcs->glEnablei(cap, index); -} - -void GraphicsHelperGL3_2::disablei(GLenum cap, GLuint index) -{ - m_funcs->glDisablei(cap, index); -} - -void GraphicsHelperGL3_2::setSeamlessCubemap(bool enable) -{ - if (enable) - m_funcs->glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - else - m_funcs->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); -} - -QSize GraphicsHelperGL3_2::getRenderBufferDimensions(GLuint renderBufferId) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0); - - return QSize(width, height); -} - -QSize GraphicsHelperGL3_2::getTextureDimensions(GLuint textureId, GLenum target, uint level) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindTexture(target, textureId); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - m_funcs->glBindTexture(target, 0); - - return QSize(width, height); -} - -void GraphicsHelperGL3_2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) -{ - Q_UNUSED(wx); - Q_UNUSED(wy); - Q_UNUSED(wz); - qWarning() << "Compute Shaders are not supported by OpenGL 3.2 (since OpenGL 4.3)"; -} - -char *GraphicsHelperGL3_2::mapBuffer(GLenum target, GLsizeiptr size) -{ - return static_cast<char*>(m_funcs->glMapBufferRange(target, 0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); -} - -GLboolean GraphicsHelperGL3_2::unmapBuffer(GLenum target) -{ - return m_funcs->glUnmapBuffer(target); -} - -void GraphicsHelperGL3_2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform1fv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform2fv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform3fv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform4fv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform1iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform1iv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform2iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform2iv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform3iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform3iv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform4iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform4iv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform1uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform1uiv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform2uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform2uiv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform3uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform3uiv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniform4uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform4uiv(location, count, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2x3fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3x2fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2x4fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4x2fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3x4fv(location, count, false, values); -} - -void GraphicsHelperGL3_2::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4x3fv(location, count, false, values); -} - -UniformType GraphicsHelperGL3_2::uniformTypeFromGLType(GLenum type) -{ - switch (type) { - case GL_FLOAT: - return UniformType::Float; - case GL_FLOAT_VEC2: - return UniformType::Vec2; - case GL_FLOAT_VEC3: - return UniformType::Vec3; - case GL_FLOAT_VEC4: - return UniformType::Vec4; - case GL_FLOAT_MAT2: - return UniformType::Mat2; - case GL_FLOAT_MAT3: - return UniformType::Mat3; - case GL_FLOAT_MAT4: - return UniformType::Mat4; - case GL_FLOAT_MAT2x3: - return UniformType::Mat2x3; - case GL_FLOAT_MAT3x2: - return UniformType::Mat3x2; - case GL_FLOAT_MAT2x4: - return UniformType::Mat2x4; - case GL_FLOAT_MAT4x2: - return UniformType::Mat4x2; - case GL_FLOAT_MAT3x4: - return UniformType::Mat3x4; - case GL_FLOAT_MAT4x3: - return UniformType::Mat4x3; - case GL_INT: - return UniformType::Int; - case GL_INT_VEC2: - return UniformType::IVec2; - case GL_INT_VEC3: - return UniformType::IVec3; - case GL_INT_VEC4: - return UniformType::IVec4; - case GL_UNSIGNED_INT: - return UniformType::UInt; - case GL_UNSIGNED_INT_VEC2: - return UniformType::UIVec2; - case GL_UNSIGNED_INT_VEC3: - return UniformType::UIVec3; - case GL_UNSIGNED_INT_VEC4: - return UniformType::UIVec4; - case GL_BOOL: - return UniformType::Bool; - case GL_BOOL_VEC2: - return UniformType::BVec2; - case GL_BOOL_VEC3: - return UniformType::BVec3; - case GL_BOOL_VEC4: - return UniformType::BVec4; - - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_1D: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_RECT: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_SAMPLER_3D: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - return UniformType::Sampler; - default: - Q_UNREACHABLE(); - return UniformType::Float; - } -} - -void GraphicsHelperGL3_2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - m_funcs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h deleted file mode 100644 index 914afc9ff..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_2_p.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERGL3_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERGL3_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <QtCore/qscopedpointer.h> - -#ifndef QT_OPENGL_ES_2 - -QT_BEGIN_NAMESPACE - -class QOpenGLFunctions_3_2_Core; -class QOpenGLExtension_ARB_tessellation_shader; - -namespace Qt3DRender { -namespace Render { - -class Q_AUTOTEST_EXPORT GraphicsHelperGL3_2 : public GraphicsHelperInterface -{ -public: - GraphicsHelperGL3_2(); - ~GraphicsHelperGL3_2(); - - // QGraphicHelperInterface interface - void alphaTest(GLenum mode1, GLenum mode2) override; - void bindBufferBase(GLenum target, GLuint index, GLuint buffer) override; - void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; - void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - void blendEquation(GLenum mode) override; - void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) override; - void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) override; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override; - GLuint boundFrameBufferObject() override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; - bool checkFrameBufferComplete() override; - void clearBufferf(GLint drawbuffer, const QVector4D &values) override; - GLuint createFrameBufferObject() override; - void depthMask(GLenum mode) override; - void depthRange(GLdouble nearValue, GLdouble farValue) override; - void depthTest(GLenum mode) override; - void disableClipPlane(int clipPlane) override; - void disablei(GLenum cap, GLuint index) override; - void disablePrimitiveRestart() override; - void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; - char *mapBuffer(GLenum target, GLsizeiptr size) override; - GLboolean unmapBuffer(GLenum target) override; - void drawArrays(GLenum primitiveType, GLint first, GLsizei count) override; - void drawArraysIndirect(GLenum mode,void *indirect) override; - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override; - void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) override; - void drawBuffers(GLsizei n, const int *bufs) override; - void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLint baseVertex = 0) override; - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - void enableClipPlane(int clipPlane) override; - void enablei(GLenum cap, GLuint index) override; - void enablePrimitiveRestart(int primitiveRestartIndex) override; - void enableVertexAttributeArray(int location) override; - void frontFace(GLenum mode) override; - QSize getRenderBufferDimensions(GLuint renderBufferId) override; - QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) override; - void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) override; - void pointSize(bool programmable, GLfloat value) override; - GLint maxClipPlaneCount() override; - void memoryBarrier(QMemoryBarrier::Operations barriers) override; - QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) override; - QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) override; - QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) override; - QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override; - void releaseFrameBufferObject(GLuint frameBufferId) override; - void setMSAAEnabled(bool enable) override; - void setAlphaCoverageEnabled(bool enable) override; - void setClipPlane(int clipPlane, const QVector3D &normal, float distance) override; - void setSeamlessCubemap(bool enable) override; - void setVerticesPerPatch(GLint verticesPerPatch) override; - bool supportsFeature(Feature feature) const override; - uint uniformByteSize(const ShaderUniform &description) override; - void useProgram(GLuint programId) override; - void vertexAttribDivisor(GLuint index, GLuint divisor) override; - void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; - void readBuffer(GLenum mode) override; - void drawBuffer(GLenum mode) override; - void rasterMode(GLenum faceMode, GLenum rasterMode) override; - - void *fenceSync() override; - void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; - void waitSync(void *sync) override; - bool wasSyncSignaled(void *sync) override; - void deleteSync(void *sync) override; - - void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) override; - - void glUniform1iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform2iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform3iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform4iv(GLint location, GLsizei count, const GLint *value) override; - - void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) override; - - void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) override; - - UniformType uniformTypeFromGLType(GLenum glType) override; - -private: - QOpenGLFunctions_3_2_Core *m_funcs; - QScopedPointer<QOpenGLExtension_ARB_tessellation_shader> m_tessFuncs; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERGL3_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp deleted file mode 100644 index ddffb38e2..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelpergl3_3_p.h" - -#ifndef QT_OPENGL_ES_2 -#include <QOpenGLFunctions_3_3_Core> -#include <QtOpenGLExtensions/qopenglextensions.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <private/attachmentpack_p.h> -#include <private/qgraphicsutils_p.h> - -# ifndef QT_OPENGL_3_2 -# define GL_PATCH_VERTICES 36466 -# define GL_ACTIVE_RESOURCES 0x92F5 -# define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -# define GL_BUFFER_BINDING 0x9302 -# define GL_BUFFER_DATA_SIZE 0x9303 -# define GL_NUM_ACTIVE_VARIABLES 0x9304 -# define GL_SHADER_STORAGE_BLOCK 0x92E6 -# define GL_UNIFORM 0x92E1 -# define GL_UNIFORM_BLOCK 0x92E2 -# define GL_UNIFORM_BLOCK_INDEX 0x8A3A -# define GL_UNIFORM_OFFSET 0x8A3B -# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -# define GL_UNIFORM_BLOCK_BINDING 0x8A3F -# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -# endif - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -GraphicsHelperGL3_3::GraphicsHelperGL3_3() - : m_funcs(nullptr) - , m_tessFuncs() -{ -} - -GraphicsHelperGL3_3::~GraphicsHelperGL3_3() -{ -} - -void GraphicsHelperGL3_3::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) -{ - m_funcs = static_cast<QOpenGLFunctions_3_3_Core*>(functions); - const bool ok = m_funcs->initializeOpenGLFunctions(); - Q_ASSERT(ok); - Q_UNUSED(ok); - - if (context->hasExtension(QByteArrayLiteral("GL_ARB_tessellation_shader"))) { - m_tessFuncs.reset(new QOpenGLExtension_ARB_tessellation_shader); - m_tessFuncs->initializeOpenGLFunctions(); - } -} - -void GraphicsHelperGL3_3::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL 3"; - - // glDrawElements OpenGL 3.1 or greater - m_funcs->glDrawElementsInstancedBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - instances, - baseVertex); -} - -void GraphicsHelperGL3_3::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) -{ - // glDrawArraysInstanced OpenGL 3.1 or greater - m_funcs->glDrawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsHelperGL3_3::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL 3"; - m_funcs->glDrawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsHelperGL3_3::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) -{ - m_funcs->glDrawElementsBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - baseVertex); -} - -void GraphicsHelperGL3_3::drawElementsIndirect(GLenum, GLenum, void *) -{ - qWarning() << "Indirect Drawing is not supported with OpenGL 3"; -} - -void GraphicsHelperGL3_3::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) -{ - m_funcs->glDrawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperGL3_3::drawArraysIndirect(GLenum , void *) -{ - qWarning() << "Indirect Drawing is not supported with OpenGL 3"; -} - -void GraphicsHelperGL3_3::setVerticesPerPatch(GLint verticesPerPatch) -{ -#if defined(QT_OPENGL_4) - if (!m_tessFuncs) { - qWarning() << "Tessellation not supported with OpenGL 3 without GL_ARB_tessellation_shader"; - return; - } - - m_tessFuncs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch); -#else - Q_UNUSED(verticesPerPatch); - qWarning() << "Tessellation not supported"; -#endif -} - -void GraphicsHelperGL3_3::useProgram(GLuint programId) -{ - m_funcs->glUseProgram(programId); -} - -QVector<ShaderUniform> GraphicsHelperGL3_3::programUniformsAndLocations(GLuint programId) -{ - QVector<ShaderUniform> uniforms; - - GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms); - uniforms.reserve(nbrActiveUniforms); - char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; i++) { - ShaderUniform uniform; - GLsizei uniformNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength, - &uniform.m_size, &uniform.m_type, uniformName); - uniformName[sizeof(uniformName) - 1] = '\0'; - uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); - uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); - // Work around for uniform array names that aren't returned with [0] by some drivers - if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]"))) - uniform.m_name.append(QLatin1String("[0]")); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride); - uniform.m_rawByteSize = uniformByteSize(uniform); - uniforms.append(uniform); - qCDebug(Render::Rendering) << uniform.m_name << "size" << uniform.m_size - << " offset" << uniform.m_offset - << " rawSize" << uniform.m_rawByteSize; - } - - return uniforms; -} - -QVector<ShaderAttribute> GraphicsHelperGL3_3::programAttributesAndLocations(GLuint programId) -{ - QVector<ShaderAttribute> attributes; - GLint nbrActiveAttributes = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes); - attributes.reserve(nbrActiveAttributes); - char attributeName[256]; - for (GLint i = 0; i < nbrActiveAttributes; i++) { - ShaderAttribute attribute; - GLsizei attributeNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength, - &attribute.m_size, &attribute.m_type, attributeName); - attributeName[sizeof(attributeName) - 1] = '\0'; - attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName); - attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength); - attributes.append(attribute); - } - return attributes; -} - -QVector<ShaderUniformBlock> GraphicsHelperGL3_3::programUniformBlocks(GLuint programId) -{ - QVector<ShaderUniformBlock> blocks; - GLint nbrActiveUniformsBlocks = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCKS, &nbrActiveUniformsBlocks); - blocks.reserve(nbrActiveUniformsBlocks); - for (GLint i = 0; i < nbrActiveUniformsBlocks; i++) { - QByteArray uniformBlockName(256, '\0'); - GLsizei length = 0; - ShaderUniformBlock uniformBlock; - m_funcs->glGetActiveUniformBlockName(programId, i, 256, &length, uniformBlockName.data()); - uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length)); - uniformBlock.m_index = i; - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformBlock.m_activeUniformsCount); - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_BINDING, &uniformBlock.m_binding); - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlock.m_size); - blocks.append(uniformBlock); - } - return blocks; -} - -QVector<ShaderStorageBlock> GraphicsHelperGL3_3::programShaderStorageBlocks(GLuint programId) -{ - Q_UNUSED(programId); - QVector<ShaderStorageBlock> blocks; - qWarning() << "SSBO are not supported by OpenGL 3.3 (since OpenGL 4.3)"; - return blocks; -} - -void GraphicsHelperGL3_3::vertexAttribDivisor(GLuint index, GLuint divisor) -{ - m_funcs->glVertexAttribDivisor(index, divisor); -} - -void GraphicsHelperGL3_3::vertexAttributePointer(GLenum shaderDataType, - GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer) -{ - switch (shaderDataType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_MAT4: - m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); - break; - - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_VEC2: - case GL_UNSIGNED_INT_VEC3: - case GL_UNSIGNED_INT_VEC4: - m_funcs->glVertexAttribIPointer(index, size, type, stride, pointer); - break; - - default: - qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type"; - } -} - -void GraphicsHelperGL3_3::readBuffer(GLenum mode) -{ - m_funcs->glReadBuffer(mode); -} - -void GraphicsHelperGL3_3::drawBuffer(GLenum mode) -{ - m_funcs->glDrawBuffer(mode); -} - -void *GraphicsHelperGL3_3::fenceSync() -{ - return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -} - -void GraphicsHelperGL3_3::clientWaitSync(void *sync, GLuint64 nanoSecTimeout) -{ - m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout); -} - -void GraphicsHelperGL3_3::waitSync(void *sync) -{ - m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED); -} - -bool GraphicsHelperGL3_3::wasSyncSignaled(void *sync) -{ - GLint v; - m_funcs->glGetSynciv(static_cast<GLsync>(sync), - GL_SYNC_STATUS, - sizeof(v), - nullptr, - &v); - return v == GL_SIGNALED; -} - -void GraphicsHelperGL3_3::deleteSync(void *sync) -{ - m_funcs->glDeleteSync(static_cast<GLsync>(sync)); -} - -void GraphicsHelperGL3_3::rasterMode(GLenum faceMode, GLenum rasterMode) -{ - m_funcs->glPolygonMode(faceMode, rasterMode); -} - -void GraphicsHelperGL3_3::blendEquation(GLenum mode) -{ - m_funcs->glBlendEquation(mode); -} - -void GraphicsHelperGL3_3::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) -{ - Q_UNUSED(buf); - Q_UNUSED(sfactor); - Q_UNUSED(dfactor); - - qWarning() << "glBlendFunci() not supported by OpenGL 3.3 (since OpenGL 4.0)"; -} - -void GraphicsHelperGL3_3::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) -{ - Q_UNUSED(buf); - Q_UNUSED(sRGB); - Q_UNUSED(dRGB); - Q_UNUSED(sAlpha); - Q_UNUSED(dAlpha); - - qWarning() << "glBlendFuncSeparatei() not supported by OpenGL 3.3 (since OpenGL 4.0)"; -} - -void GraphicsHelperGL3_3::alphaTest(GLenum, GLenum) -{ - qCWarning(Render::Rendering) << "AlphaTest not available with OpenGL 3.2 core"; -} - -void GraphicsHelperGL3_3::depthTest(GLenum mode) -{ - m_funcs->glEnable(GL_DEPTH_TEST); - m_funcs->glDepthFunc(mode); -} - -void GraphicsHelperGL3_3::depthMask(GLenum mode) -{ - m_funcs->glDepthMask(mode); -} - -void GraphicsHelperGL3_3::depthRange(GLdouble nearValue, GLdouble farValue) -{ - m_funcs->glDepthRange(nearValue, farValue); -} - -void GraphicsHelperGL3_3::frontFace(GLenum mode) -{ - m_funcs->glFrontFace(mode); - -} - -void GraphicsHelperGL3_3::setMSAAEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_MULTISAMPLE) - : m_funcs->glDisable(GL_MULTISAMPLE); -} - -void GraphicsHelperGL3_3::setAlphaCoverageEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) - : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); -} - -GLuint GraphicsHelperGL3_3::createFrameBufferObject() -{ - GLuint id; - m_funcs->glGenFramebuffers(1, &id); - return id; -} - -void GraphicsHelperGL3_3::releaseFrameBufferObject(GLuint frameBufferId) -{ - m_funcs->glDeleteFramebuffers(1, &frameBufferId); -} - -void GraphicsHelperGL3_3::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) -{ - switch (mode) { - case FBODraw: - m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId); - return; - case FBORead: - m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId); - return; - case FBOReadAndDraw: - default: - m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); - return; - } -} - -GLuint GraphicsHelperGL3_3::boundFrameBufferObject() -{ - GLint id = 0; - m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id); - return id; -} - -bool GraphicsHelperGL3_3::checkFrameBufferComplete() -{ - return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); -} - -bool GraphicsHelperGL3_3::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - Q_UNUSED(attachment); - return false; -} - -void GraphicsHelperGL3_3::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT; - - if (attachment.m_point <= QRenderTargetOutput::Color15) - attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - - texture->bind(); - QOpenGLTexture::Target target = texture->target(); - if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray || - target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D) - m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMapArray) - m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces) - m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else - m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel); - texture->release(); -} - -void GraphicsHelperGL3_3::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) -{ - Q_UNUSED(renderBuffer); - Q_UNUSED(attachment); - Q_UNREACHABLE(); -} - -bool GraphicsHelperGL3_3::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case MRT: - case UniformBufferObject: - case PrimitiveRestart: - case RenderBufferDimensionRetrieval: - case TextureDimensionRetrieval: - case BindableFragmentOutputs: - case BlitFramebuffer: - case Fences: - return true; - case Tessellation: - return !m_tessFuncs.isNull(); - default: - return false; - } -} - -void GraphicsHelperGL3_3::drawBuffers(GLsizei n, const int *bufs) -{ - // Use QVarLengthArray here - QVarLengthArray<GLenum, 16> drawBufs(n); - - for (int i = 0; i < n; i++) - drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i]; - m_funcs->glDrawBuffers(n, drawBufs.constData()); -} - -void GraphicsHelperGL3_3::bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) -{ - for (auto it = outputs.begin(), end = outputs.end(); it != end; ++it) - m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str()); -} - -void GraphicsHelperGL3_3::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); -} - -void GraphicsHelperGL3_3::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) -{ - Q_UNUSED(programId); - Q_UNUSED(shaderStorageBlockIndex); - Q_UNUSED(shaderStorageBlockBinding); - qWarning() << "SSBO are not supported by OpenGL 3.3 (since OpenGL 4.3)"; -} - -void GraphicsHelperGL3_3::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - Q_UNUSED(imageUnit) - Q_UNUSED(texture) - Q_UNUSED(mipLevel) - Q_UNUSED(layered) - Q_UNUSED(layer) - Q_UNUSED(access) - Q_UNUSED(format) - qWarning() << "Shader Images are not supported by OpenGL 3.3 (since OpenGL 4.2)"; -} - -void GraphicsHelperGL3_3::bindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - m_funcs->glBindBufferBase(target, index, buffer); -} - -void GraphicsHelperGL3_3::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - char *bufferData = buffer.data(); - - switch (description.m_type) { - - case GL_FLOAT: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_FLOAT_VEC2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_FLOAT_VEC3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_FLOAT_VEC4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_FLOAT_MAT2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2); - break; - } - - case GL_FLOAT_MAT2x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3); - break; - } - - case GL_FLOAT_MAT2x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4); - break; - } - - case GL_FLOAT_MAT3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3); - break; - } - - case GL_FLOAT_MAT3x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2); - break; - } - - case GL_FLOAT_MAT3x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4); - break; - } - - case GL_FLOAT_MAT4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4); - break; - } - - case GL_FLOAT_MAT4x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2); - break; - } - - case GL_FLOAT_MAT4x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3); - break; - } - - case GL_INT: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_INT_VEC2: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_INT_VEC3: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_INT_VEC4: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_UNSIGNED_INT: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_UNSIGNED_INT_VEC2: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_UNSIGNED_INT_VEC3: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_UNSIGNED_INT_VEC4: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_BOOL: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_BOOL_VEC2: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_BOOL_VEC3: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_BOOL_VEC4: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: { - Q_ASSERT(description.m_size == 1); - int value = v.toInt(); - QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - -uint GraphicsHelperGL3_3::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - int arrayStride = qMax(description.m_arrayStride, 0); - int matrixStride = qMax(description.m_matrixStride, 0); - - switch (description.m_type) { - - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_UNSIGNED_INT_VEC2: - rawByteSize = 8; - break; - - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_UNSIGNED_INT_VEC3: - rawByteSize = 12; - break; - - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_UNSIGNED_INT_VEC4: - rawByteSize = 16; - break; - - case GL_FLOAT_MAT2: - rawByteSize = matrixStride ? 2 * matrixStride : 16; - break; - - case GL_FLOAT_MAT2x4: - rawByteSize = matrixStride ? 2 * matrixStride : 32; - break; - - case GL_FLOAT_MAT4x2: - rawByteSize = matrixStride ? 4 * matrixStride : 32; - break; - - case GL_FLOAT_MAT3: - rawByteSize = matrixStride ? 3 * matrixStride : 36; - break; - - case GL_FLOAT_MAT2x3: - rawByteSize = matrixStride ? 2 * matrixStride : 24; - break; - - case GL_FLOAT_MAT3x2: - rawByteSize = matrixStride ? 3 * matrixStride : 24; - break; - - case GL_FLOAT_MAT4: - rawByteSize = matrixStride ? 4 * matrixStride : 64; - break; - - case GL_FLOAT_MAT4x3: - rawByteSize = matrixStride ? 4 * matrixStride : 48; - break; - - case GL_FLOAT_MAT3x4: - rawByteSize = matrixStride ? 3 * matrixStride : 48; - break; - - case GL_BOOL: - rawByteSize = 1; - break; - - case GL_BOOL_VEC2: - rawByteSize = 2; - break; - - case GL_BOOL_VEC3: - rawByteSize = 3; - break; - - case GL_BOOL_VEC4: - rawByteSize = 4; - break; - - case GL_INT: - case GL_FLOAT: - case GL_UNSIGNED_INT: - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - rawByteSize = 4; - break; - } - - return arrayStride ? rawByteSize * arrayStride : rawByteSize; -} - -void GraphicsHelperGL3_3::enableClipPlane(int clipPlane) -{ - m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL3_3::disableClipPlane(int clipPlane) -{ - m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL3_3::setClipPlane(int clipPlane, const QVector3D &normal, float distance) -{ - // deprecated - Q_UNUSED(clipPlane); - Q_UNUSED(normal); - Q_UNUSED(distance); -} - -GLint GraphicsHelperGL3_3::maxClipPlaneCount() -{ - GLint max = 0; - m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max); - return max; -} - -void GraphicsHelperGL3_3::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - Q_UNUSED(barriers); - qWarning() << "memory barrier is not supported by OpenGL 3.3 (since 4.3)"; -} - -void GraphicsHelperGL3_3::enablePrimitiveRestart(int primitiveRestartIndex) -{ - m_funcs->glPrimitiveRestartIndex(primitiveRestartIndex); - m_funcs->glEnable(GL_PRIMITIVE_RESTART); -} - -void GraphicsHelperGL3_3::enableVertexAttributeArray(int location) -{ - m_funcs->glEnableVertexAttribArray(location); -} - -void GraphicsHelperGL3_3::disablePrimitiveRestart() -{ - m_funcs->glDisable(GL_PRIMITIVE_RESTART); -} - -void GraphicsHelperGL3_3::clearBufferf(GLint drawbuffer, const QVector4D &values) -{ - GLfloat vec[4] = {values[0], values[1], values[2], values[3]}; - m_funcs->glClearBufferfv(GL_COLOR, drawbuffer, vec); -} - -void GraphicsHelperGL3_3::pointSize(bool programmable, GLfloat value) -{ - if (programmable) { - m_funcs->glEnable(GL_PROGRAM_POINT_SIZE); - } else { - m_funcs->glDisable(GL_PROGRAM_POINT_SIZE); - m_funcs->glPointSize(value); - } -} - -void GraphicsHelperGL3_3::enablei(GLenum cap, GLuint index) -{ - m_funcs->glEnablei(cap, index); -} - -void GraphicsHelperGL3_3::disablei(GLenum cap, GLuint index) -{ - m_funcs->glDisablei(cap, index); -} - -void GraphicsHelperGL3_3::setSeamlessCubemap(bool enable) -{ - if (enable) - m_funcs->glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - else - m_funcs->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); -} - -QSize GraphicsHelperGL3_3::getRenderBufferDimensions(GLuint renderBufferId) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0); - - return QSize(width, height); -} - -QSize GraphicsHelperGL3_3::getTextureDimensions(GLuint textureId, GLenum target, uint level) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindTexture(target, textureId); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - m_funcs->glBindTexture(target, 0); - - return QSize(width, height); -} - -void GraphicsHelperGL3_3::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) -{ - Q_UNUSED(wx); - Q_UNUSED(wy); - Q_UNUSED(wz); - qWarning() << "Compute Shaders are not supported by OpenGL 3.3 (since OpenGL 4.3)"; -} - -char *GraphicsHelperGL3_3::mapBuffer(GLenum target, GLsizeiptr size) -{ - return static_cast<char*>(m_funcs->glMapBufferRange(target, 0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); -} - -GLboolean GraphicsHelperGL3_3::unmapBuffer(GLenum target) -{ - return m_funcs->glUnmapBuffer(target); -} - -void GraphicsHelperGL3_3::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform1fv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform2fv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform3fv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform4fv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform1iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform1iv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform2iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform2iv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform3iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform3iv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform4iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform4iv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform1uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform1uiv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform2uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform2uiv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform3uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform3uiv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniform4uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform4uiv(location, count, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2x3fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3x2fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2x4fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4x2fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3x4fv(location, count, false, values); -} - -void GraphicsHelperGL3_3::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4x3fv(location, count, false, values); -} - -UniformType GraphicsHelperGL3_3::uniformTypeFromGLType(GLenum type) -{ - switch (type) { - case GL_FLOAT: - return UniformType::Float; - case GL_FLOAT_VEC2: - return UniformType::Vec2; - case GL_FLOAT_VEC3: - return UniformType::Vec3; - case GL_FLOAT_VEC4: - return UniformType::Vec4; - case GL_FLOAT_MAT2: - return UniformType::Mat2; - case GL_FLOAT_MAT3: - return UniformType::Mat3; - case GL_FLOAT_MAT4: - return UniformType::Mat4; - case GL_FLOAT_MAT2x3: - return UniformType::Mat2x3; - case GL_FLOAT_MAT3x2: - return UniformType::Mat3x2; - case GL_FLOAT_MAT2x4: - return UniformType::Mat2x4; - case GL_FLOAT_MAT4x2: - return UniformType::Mat4x2; - case GL_FLOAT_MAT3x4: - return UniformType::Mat3x4; - case GL_FLOAT_MAT4x3: - return UniformType::Mat4x3; - case GL_INT: - return UniformType::Int; - case GL_INT_VEC2: - return UniformType::IVec2; - case GL_INT_VEC3: - return UniformType::IVec3; - case GL_INT_VEC4: - return UniformType::IVec4; - case GL_UNSIGNED_INT: - return UniformType::UInt; - case GL_UNSIGNED_INT_VEC2: - return UniformType::UIVec2; - case GL_UNSIGNED_INT_VEC3: - return UniformType::UIVec3; - case GL_UNSIGNED_INT_VEC4: - return UniformType::UIVec4; - case GL_BOOL: - return UniformType::Bool; - case GL_BOOL_VEC2: - return UniformType::BVec2; - case GL_BOOL_VEC3: - return UniformType::BVec3; - case GL_BOOL_VEC4: - return UniformType::BVec4; - - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_1D: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_RECT: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_SAMPLER_3D: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - return UniformType::Sampler; - default: - Q_UNREACHABLE(); - return UniformType::Float; - } -} - -void GraphicsHelperGL3_3::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - m_funcs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h deleted file mode 100644 index 4dbf6fe7b..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl3_3_p.h +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERGL3_3_P_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERGL3_3_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <QtCore/qscopedpointer.h> - -#ifndef QT_OPENGL_ES_2 - -QT_BEGIN_NAMESPACE - -class QOpenGLFunctions_3_3_Core; -class QOpenGLExtension_ARB_tessellation_shader; - -namespace Qt3DRender { -namespace Render { - -class Q_AUTOTEST_EXPORT GraphicsHelperGL3_3 : public GraphicsHelperInterface -{ -public: - GraphicsHelperGL3_3(); - ~GraphicsHelperGL3_3(); - - // QGraphicHelperInterface interface - void alphaTest(GLenum mode1, GLenum mode2) override; - void bindBufferBase(GLenum target, GLuint index, GLuint buffer) override; - void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; - void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - void blendEquation(GLenum mode) override; - void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) override; - void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) override; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override; - GLuint boundFrameBufferObject() override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; - bool checkFrameBufferComplete() override; - void clearBufferf(GLint drawbuffer, const QVector4D &values) override; - GLuint createFrameBufferObject() override; - void depthMask(GLenum mode) override; - void depthRange(GLdouble nearValue, GLdouble farValue) override; - void depthTest(GLenum mode) override; - void disableClipPlane(int clipPlane) override; - void disablei(GLenum cap, GLuint index) override; - void disablePrimitiveRestart() override; - void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; - char *mapBuffer(GLenum target, GLsizeiptr size) override; - GLboolean unmapBuffer(GLenum target) override; - void drawArrays(GLenum primitiveType, GLint first, GLsizei count) override; - void drawArraysIndirect(GLenum mode,void *indirect) override; - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override; - void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) override; - void drawBuffers(GLsizei n, const int *bufs) override; - void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLint baseVertex = 0) override; - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - void enableClipPlane(int clipPlane) override; - void enablei(GLenum cap, GLuint index) override; - void enablePrimitiveRestart(int primitiveRestartIndex) override; - void enableVertexAttributeArray(int location) override; - void frontFace(GLenum mode) override; - QSize getRenderBufferDimensions(GLuint renderBufferId) override; - QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) override; - void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) override; - void pointSize(bool programmable, GLfloat value) override; - GLint maxClipPlaneCount() override; - void memoryBarrier(QMemoryBarrier::Operations barriers) override; - QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) override; - QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) override; - QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) override; - QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override; - void releaseFrameBufferObject(GLuint frameBufferId) override; - void setMSAAEnabled(bool enable) override; - void setAlphaCoverageEnabled(bool enable) override; - void setClipPlane(int clipPlane, const QVector3D &normal, float distance) override; - void setSeamlessCubemap(bool enable) override; - void setVerticesPerPatch(GLint verticesPerPatch) override; - bool supportsFeature(Feature feature) const override; - uint uniformByteSize(const ShaderUniform &description) override; - void useProgram(GLuint programId) override; - void vertexAttribDivisor(GLuint index, GLuint divisor) override; - void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; - void readBuffer(GLenum mode) override; - void drawBuffer(GLenum mode) override; - void rasterMode(GLenum faceMode, GLenum rasterMode) override; - - void *fenceSync() override; - void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; - void waitSync(void *sync) override; - bool wasSyncSignaled(void *sync) override; - void deleteSync(void *sync) override; - - void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) override; - - void glUniform1iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform2iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform3iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform4iv(GLint location, GLsizei count, const GLint *value) override; - - void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) override; - - void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) override; - - UniformType uniformTypeFromGLType(GLenum glType) override; - -private: - QOpenGLFunctions_3_3_Core *m_funcs; - QScopedPointer<QOpenGLExtension_ARB_tessellation_shader> m_tessFuncs; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERGL3_3_P_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp deleted file mode 100644 index 60caed273..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp +++ /dev/null @@ -1,1442 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicshelpergl4_p.h" - -#ifndef QT_OPENGL_ES_2 -#include <QOpenGLFunctions_4_3_Core> -#include <QtOpenGLExtensions/qopenglextensions.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <private/attachmentpack_p.h> -#include <private/qgraphicsutils_p.h> - -# ifndef QT_OPENGL_4_3 -# ifndef GL_PATCH_VERTICES -# define GL_PATCH_VERTICES 36466 -# endif -# define GL_ACTIVE_RESOURCES 0x92F5 -# define GL_BUFFER_BINDING 0x9302 -# define GL_BUFFER_DATA_SIZE 0x9303 -# define GL_NUM_ACTIVE_VARIABLES 0x9304 -# define GL_SHADER_STORAGE_BLOCK 0x92E6 -# define GL_UNIFORM 0x92E1 -# define GL_UNIFORM_BLOCK 0x92E2 -# define GL_UNIFORM_BLOCK_INDEX 0x8A3A -# define GL_UNIFORM_OFFSET 0x8A3B -# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -# define GL_UNIFORM_BLOCK_BINDING 0x8A3F -# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -# define GL_ALL_BARRIER_BITS 0xFFFFFFFF -# define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -# define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -# define GL_UNIFORM_BARRIER_BIT 0x00000004 -# define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -# define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -# define GL_COMMAND_BARRIER_BIT 0x00000040 -# define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -# define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -# define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -# define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -# define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -# define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -# define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -# define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 -# define GL_IMAGE_1D 0x904C -# define GL_IMAGE_2D 0x904D -# define GL_IMAGE_3D 0x904E -# define GL_IMAGE_2D_RECT 0x904F -# define GL_IMAGE_CUBE 0x9050 -# define GL_IMAGE_BUFFER 0x9051 -# define GL_IMAGE_1D_ARRAY 0x9052 -# define GL_IMAGE_2D_ARRAY 0x9053 -# define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 -# define GL_IMAGE_2D_MULTISAMPLE 0x9055 -# define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 -# define GL_INT_IMAGE_1D 0x9057 -# define GL_INT_IMAGE_2D 0x9058 -# define GL_INT_IMAGE_3D 0x9059 -# define GL_INT_IMAGE_2D_RECT 0x905A -# define GL_INT_IMAGE_CUBE 0x905B -# define GL_INT_IMAGE_BUFFER 0x905C -# define GL_INT_IMAGE_1D_ARRAY 0x905D -# define GL_INT_IMAGE_2D_ARRAY 0x905E -# define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F -# define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 -# define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 -# define GL_UNSIGNED_INT_IMAGE_1D 0x9062 -# define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -# define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -# define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 -# define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -# define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 -# define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 -# define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -# define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A -# define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B -# define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C -# endif - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -namespace { - -GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers) -{ - GLbitfield bits = 0; - - if (barriers.testFlag(QMemoryBarrier::All)) { - bits |= GL_ALL_BARRIER_BITS; - return bits; - } - - if (barriers.testFlag(QMemoryBarrier::VertexAttributeArray)) - bits |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ElementArray)) - bits |= GL_ELEMENT_ARRAY_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::Uniform)) - bits |= GL_UNIFORM_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TextureFetch)) - bits |= GL_TEXTURE_FETCH_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ShaderImageAccess)) - bits |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::Command)) - bits |= GL_COMMAND_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::PixelBuffer)) - bits |= GL_PIXEL_BUFFER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TextureUpdate)) - bits |= GL_TEXTURE_UPDATE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::BufferUpdate)) - bits |= GL_BUFFER_UPDATE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::FrameBuffer)) - bits |= GL_FRAMEBUFFER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::TransformFeedback)) - bits |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::AtomicCounter)) - bits |= GL_ATOMIC_COUNTER_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::ShaderStorage)) - bits |= GL_SHADER_STORAGE_BARRIER_BIT; - if (barriers.testFlag(QMemoryBarrier::QueryBuffer)) - bits |= GL_QUERY_BUFFER_BARRIER_BIT; - - return bits; -} - -} - -GraphicsHelperGL4::GraphicsHelperGL4() - : m_funcs(nullptr) -{ -} - -void GraphicsHelperGL4::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) -{ - Q_UNUSED(context); - m_funcs = static_cast<QOpenGLFunctions_4_3_Core*>(functions); - const bool ok = m_funcs->initializeOpenGLFunctions(); - Q_ASSERT(ok); - Q_UNUSED(ok); -} - -void GraphicsHelperGL4::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) -{ - if (baseInstance != 0) - qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; - - // glDrawElements OpenGL 3.1 or greater - m_funcs->glDrawElementsInstancedBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - instances, - baseVertex); -} - -void GraphicsHelperGL4::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) -{ - // glDrawArraysInstanced OpenGL 3.1 or greater - m_funcs->glDrawArraysInstanced(primitiveType, - first, - count, - instances); -} - -void GraphicsHelperGL4::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) -{ - m_funcs->glDrawArraysInstancedBaseInstance(primitiveType, - first, - count, - instances, - baseInstance); -} - -void GraphicsHelperGL4::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) -{ - m_funcs->glDrawElementsBaseVertex(primitiveType, - primitiveCount, - indexType, - indices, - baseVertex); -} - -void GraphicsHelperGL4::drawElementsIndirect(GLenum mode, - GLenum type, - void *indirect) -{ - m_funcs->glDrawElementsIndirect(mode, type, indirect); -} - -void GraphicsHelperGL4::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) -{ - m_funcs->glDrawArrays(primitiveType, - first, - count); -} - -void GraphicsHelperGL4::drawArraysIndirect(GLenum mode, void *indirect) -{ - m_funcs->glDrawArraysIndirect(mode, indirect); -} - -void GraphicsHelperGL4::setVerticesPerPatch(GLint verticesPerPatch) -{ - m_funcs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch); -} - -void GraphicsHelperGL4::useProgram(GLuint programId) -{ - m_funcs->glUseProgram(programId); -} - -QVector<ShaderUniform> GraphicsHelperGL4::programUniformsAndLocations(GLuint programId) -{ - QVector<ShaderUniform> uniforms; - - GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramInterfaceiv(programId, GL_UNIFORM, GL_ACTIVE_RESOURCES, &nbrActiveUniforms); - uniforms.reserve(nbrActiveUniforms); - char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; ++i) { - ShaderUniform uniform; - GLsizei uniformNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength, - &uniform.m_size, &uniform.m_type, uniformName); - uniformName[sizeof(uniformName) - 1] = '\0'; - uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName); - uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength); - // Work around for uniform array names that aren't returned with [0] by some drivers - if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]"))) - uniform.m_name.append(QLatin1String("[0]")); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride); - m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride); - uniform.m_rawByteSize = uniformByteSize(uniform); - uniforms.append(uniform); - qCDebug(Render::Rendering) << uniform.m_name << "size" << uniform.m_size - << " offset" << uniform.m_offset - << " rawSize" << uniform.m_rawByteSize; - } - - return uniforms; -} - -QVector<ShaderAttribute> GraphicsHelperGL4::programAttributesAndLocations(GLuint programId) -{ - QVector<ShaderAttribute> attributes; - GLint nbrActiveAttributes = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes); - attributes.reserve(nbrActiveAttributes); - char attributeName[256]; - for (GLint i = 0; i < nbrActiveAttributes; ++i) { - ShaderAttribute attribute; - GLsizei attributeNameLength = 0; - // Size is 1 for scalar and more for struct or arrays - // Type is the GL Type - m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength, - &attribute.m_size, &attribute.m_type, attributeName); - attributeName[sizeof(attributeName) - 1] = '\0'; - attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName); - attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength); - attributes.append(attribute); - } - return attributes; -} - -QVector<ShaderUniformBlock> GraphicsHelperGL4::programUniformBlocks(GLuint programId) -{ - QVector<ShaderUniformBlock> blocks; - GLint nbrActiveUniformsBlocks = 0; - m_funcs->glGetProgramInterfaceiv(programId, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveUniformsBlocks); - blocks.reserve(nbrActiveUniformsBlocks); - for (GLint i = 0; i < nbrActiveUniformsBlocks; ++i) { - QByteArray uniformBlockName(256, '\0'); - GLsizei length = 0; - ShaderUniformBlock uniformBlock; - m_funcs->glGetProgramResourceName(programId, GL_UNIFORM_BLOCK, i, 256, &length, uniformBlockName.data()); - uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length)); - uniformBlock.m_index = i; - GLenum prop = GL_BUFFER_BINDING; - m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_binding); - prop = GL_BUFFER_DATA_SIZE; - m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_size); - prop = GL_NUM_ACTIVE_VARIABLES; - m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_activeUniformsCount); - blocks.append(uniformBlock); - } - return blocks; -} - -QVector<ShaderStorageBlock> GraphicsHelperGL4::programShaderStorageBlocks(GLuint programId) -{ - QVector<ShaderStorageBlock> blocks; - GLint nbrActiveShaderStorageBlocks = 0; - m_funcs->glGetProgramInterfaceiv(programId, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveShaderStorageBlocks); - blocks.reserve(nbrActiveShaderStorageBlocks); - for (GLint i = 0; i < nbrActiveShaderStorageBlocks; ++i) { - QByteArray storageBlockName(256, '\0'); - GLsizei length = 0; - ShaderStorageBlock storageBlock; - m_funcs->glGetProgramResourceName(programId, GL_SHADER_STORAGE_BLOCK, i, 256, &length, storageBlockName.data()); - storageBlock.m_index = i; - storageBlock.m_name = QString::fromUtf8(storageBlockName.left(length)); - GLenum prop = GL_BUFFER_BINDING; - m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_binding); - prop = GL_BUFFER_DATA_SIZE; - m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_size); - prop = GL_NUM_ACTIVE_VARIABLES; - m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_activeVariablesCount); - blocks.push_back(storageBlock); - } - return blocks; -} - -void GraphicsHelperGL4::vertexAttribDivisor(GLuint index, GLuint divisor) -{ - m_funcs->glVertexAttribDivisor(index, divisor); -} - -void GraphicsHelperGL4::vertexAttributePointer(GLenum shaderDataType, - GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer) -{ - switch (shaderDataType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_MAT4: - m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); - break; - - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_VEC2: - case GL_UNSIGNED_INT_VEC3: - case GL_UNSIGNED_INT_VEC4: - m_funcs->glVertexAttribIPointer(index, size, type, stride, pointer); - break; - - case GL_DOUBLE: - case GL_DOUBLE_VEC2: - case GL_DOUBLE_VEC3: - case GL_DOUBLE_VEC4: - m_funcs->glVertexAttribLPointer(index, size, type, stride, pointer); - break; - - default: - qCWarning(Render::Rendering) << "vertexAttribPointer: Unhandled type"; - Q_UNREACHABLE(); - } -} - -void GraphicsHelperGL4::readBuffer(GLenum mode) -{ - m_funcs->glReadBuffer(mode); -} - -void GraphicsHelperGL4::drawBuffer(GLenum mode) -{ - m_funcs->glDrawBuffer(mode); -} - -void *GraphicsHelperGL4::fenceSync() -{ - return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -} - -void GraphicsHelperGL4::clientWaitSync(void *sync, GLuint64 nanoSecTimeout) -{ - qDebug() << Q_FUNC_INFO << sync << static_cast<GLsync>(sync); - GLenum e = m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout); - qDebug() << e; -} - -void GraphicsHelperGL4::waitSync(void *sync) -{ - m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED); -} - -bool GraphicsHelperGL4::wasSyncSignaled(void *sync) -{ - GLint v = 0; - m_funcs->glGetSynciv(static_cast<GLsync>(sync), - GL_SYNC_STATUS, - sizeof(v), - nullptr, - &v); - return v == GL_SIGNALED; -} - -void GraphicsHelperGL4::deleteSync(void *sync) -{ - m_funcs->glDeleteSync(static_cast<GLsync>(sync)); -} - -void GraphicsHelperGL4::rasterMode(GLenum faceMode, GLenum rasterMode) -{ - m_funcs->glPolygonMode(faceMode, rasterMode); -} - -void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform1fv(location, count, values); -} - -void GraphicsHelperGL4::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform2fv(location, count, values); -} - -void GraphicsHelperGL4::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform3fv(location, count, values); -} - -void GraphicsHelperGL4::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniform4fv(location, count, values); -} - -void GraphicsHelperGL4::glUniform1iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform1iv(location, count, values); -} - -void GraphicsHelperGL4::glUniform2iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform2iv(location, count, values); -} - -void GraphicsHelperGL4::glUniform3iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform3iv(location, count, values); -} - -void GraphicsHelperGL4::glUniform4iv(GLint location, GLsizei count, const GLint *values) -{ - m_funcs->glUniform4iv(location, count, values); -} - -void GraphicsHelperGL4::glUniform1uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform1uiv(location, count, values); -} - -void GraphicsHelperGL4::glUniform2uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform2uiv(location, count, values); -} - -void GraphicsHelperGL4::glUniform3uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform3uiv(location, count, values); -} - -void GraphicsHelperGL4::glUniform4uiv(GLint location, GLsizei count, const GLuint *values) -{ - m_funcs->glUniform4uiv(location, count, values); -} - -void GraphicsHelperGL4::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2x3fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3x2fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix2x4fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4x2fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix3x4fv(location, count, false, values); -} - -void GraphicsHelperGL4::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values) -{ - m_funcs->glUniformMatrix4x3fv(location, count, false, values); -} - -UniformType GraphicsHelperGL4::uniformTypeFromGLType(GLenum type) -{ - switch (type) { - case GL_FLOAT: - return UniformType::Float; - case GL_FLOAT_VEC2: - return UniformType::Vec2; - case GL_FLOAT_VEC3: - return UniformType::Vec3; - case GL_FLOAT_VEC4: - return UniformType::Vec4; - case GL_FLOAT_MAT2: - return UniformType::Mat2; - case GL_FLOAT_MAT3: - return UniformType::Mat3; - case GL_FLOAT_MAT4: - return UniformType::Mat4; - case GL_FLOAT_MAT2x3: - return UniformType::Mat2x3; - case GL_FLOAT_MAT3x2: - return UniformType::Mat3x2; - case GL_FLOAT_MAT2x4: - return UniformType::Mat2x4; - case GL_FLOAT_MAT4x2: - return UniformType::Mat4x2; - case GL_FLOAT_MAT3x4: - return UniformType::Mat3x4; - case GL_FLOAT_MAT4x3: - return UniformType::Mat4x3; - case GL_INT: - return UniformType::Int; - case GL_INT_VEC2: - return UniformType::IVec2; - case GL_INT_VEC3: - return UniformType::IVec3; - case GL_INT_VEC4: - return UniformType::IVec4; - case GL_UNSIGNED_INT: - return UniformType::UInt; - case GL_UNSIGNED_INT_VEC2: - return UniformType::UIVec2; - case GL_UNSIGNED_INT_VEC3: - return UniformType::UIVec3; - case GL_UNSIGNED_INT_VEC4: - return UniformType::UIVec4; - case GL_BOOL: - return UniformType::Bool; - case GL_BOOL_VEC2: - return UniformType::BVec2; - case GL_BOOL_VEC3: - return UniformType::BVec3; - case GL_BOOL_VEC4: - return UniformType::BVec4; - - case GL_SAMPLER_1D: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_RECT: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_CUBE_MAP_ARRAY: - case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_SAMPLER_3D: - case GL_SAMPLER_BUFFER: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_CUBE_MAP_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: - return UniformType::Sampler; - - case GL_IMAGE_1D: - case GL_IMAGE_2D: - case GL_IMAGE_3D: - case GL_IMAGE_2D_RECT: - case GL_IMAGE_CUBE: - case GL_IMAGE_BUFFER: - case GL_IMAGE_1D_ARRAY: - case GL_IMAGE_2D_ARRAY: - case GL_IMAGE_CUBE_MAP_ARRAY: - case GL_IMAGE_2D_MULTISAMPLE: - case GL_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_INT_IMAGE_1D: - case GL_INT_IMAGE_2D: - case GL_INT_IMAGE_3D: - case GL_INT_IMAGE_2D_RECT: - case GL_INT_IMAGE_CUBE: - case GL_INT_IMAGE_BUFFER: - case GL_INT_IMAGE_1D_ARRAY: - case GL_INT_IMAGE_2D_ARRAY: - case GL_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_INT_IMAGE_2D_MULTISAMPLE: - case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_IMAGE_1D: - case GL_UNSIGNED_INT_IMAGE_2D: - case GL_UNSIGNED_INT_IMAGE_3D: - case GL_UNSIGNED_INT_IMAGE_2D_RECT: - case GL_UNSIGNED_INT_IMAGE_CUBE: - case GL_UNSIGNED_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - return UniformType::Image; - - default: - // TO DO: Add support for Doubles and Images - Q_UNREACHABLE(); - return UniformType::Float; - } -} - -void GraphicsHelperGL4::blendEquation(GLenum mode) -{ - m_funcs->glBlendEquation(mode); -} - -void GraphicsHelperGL4::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) -{ - m_funcs->glBlendFunci(buf, sfactor, dfactor); -} - -void GraphicsHelperGL4::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) -{ - m_funcs->glBlendFuncSeparatei(buf, sRGB, dRGB, sAlpha, dAlpha); -} - -void GraphicsHelperGL4::alphaTest(GLenum, GLenum) -{ - qCWarning(Render::Rendering) << "AlphaTest not available with OpenGL 3.2 core"; -} - -void GraphicsHelperGL4::depthTest(GLenum mode) -{ - m_funcs->glEnable(GL_DEPTH_TEST); - m_funcs->glDepthFunc(mode); -} - -void GraphicsHelperGL4::depthMask(GLenum mode) -{ - m_funcs->glDepthMask(mode); -} - -void GraphicsHelperGL4::depthRange(GLdouble nearValue, GLdouble farValue) -{ - m_funcs->glDepthRange(nearValue, farValue); -} - -void GraphicsHelperGL4::frontFace(GLenum mode) -{ - m_funcs->glFrontFace(mode); - -} - -void GraphicsHelperGL4::setMSAAEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_MULTISAMPLE) - : m_funcs->glDisable(GL_MULTISAMPLE); -} - -void GraphicsHelperGL4::setAlphaCoverageEnabled(bool enabled) -{ - enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) - : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); -} - -GLuint GraphicsHelperGL4::createFrameBufferObject() -{ - GLuint id; - m_funcs->glGenFramebuffers(1, &id); - return id; -} - -void GraphicsHelperGL4::releaseFrameBufferObject(GLuint frameBufferId) -{ - m_funcs->glDeleteFramebuffers(1, &frameBufferId); -} - -void GraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) -{ - switch (mode) { - case FBODraw: - m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId); - return; - case FBORead: - m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId); - return; - case FBOReadAndDraw: - default: - m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId); - return; - } -} - -void GraphicsHelperGL4::bindImageTexture(GLuint imageUnit, GLuint texture, - GLint mipLevel, GLboolean layered, - GLint layer, GLenum access, GLenum format) -{ - m_funcs->glBindImageTexture(imageUnit, - texture, - mipLevel, - layered, - layer, - access, - format); -} - -GLuint GraphicsHelperGL4::boundFrameBufferObject() -{ - GLint id = 0; - m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id); - return id; -} - -bool GraphicsHelperGL4::checkFrameBufferComplete() -{ - return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); -} - -bool GraphicsHelperGL4::frameBufferNeedsRenderBuffer(const Attachment &attachment) -{ - Q_UNUSED(attachment); - return false; -} - -void GraphicsHelperGL4::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) -{ - GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT; - - if (attachment.m_point <= QRenderTargetOutput::Color15) - attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; - else if (attachment.m_point == QRenderTargetOutput::Depth) - attr = GL_DEPTH_ATTACHMENT; - else if (attachment.m_point == QRenderTargetOutput::Stencil) - attr = GL_STENCIL_ATTACHMENT; - - texture->bind(); - QOpenGLTexture::Target target = texture->target(); - if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray || - target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D) - m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMapArray) - m_funcs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel, attachment.m_layer); - else if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces) - m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel); - else - m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel); - texture->release(); -} - -void GraphicsHelperGL4::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) -{ - Q_UNUSED(renderBuffer); - Q_UNUSED(attachment); - Q_UNREACHABLE(); -} - -bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature) const -{ - switch (feature) { - case MRT: - case Tessellation: - case UniformBufferObject: - case BindableFragmentOutputs: - case PrimitiveRestart: - case RenderBufferDimensionRetrieval: - case TextureDimensionRetrieval: - case ShaderStorageObject: - case Compute: - case DrawBuffersBlend: - case BlitFramebuffer: - case IndirectDrawing: - case MapBuffer: - case Fences: - case ShaderImage: - return true; - default: - return false; - } -} - -void GraphicsHelperGL4::drawBuffers(GLsizei n, const int *bufs) -{ - // Use QVarLengthArray here - QVarLengthArray<GLenum, 16> drawBufs(n); - - for (int i = 0; i < n; i++) - drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i]; - m_funcs->glDrawBuffers(n, drawBufs.constData()); -} - -void GraphicsHelperGL4::bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) -{ - for (auto it = outputs.begin(), end = outputs.end(); it != end; ++it) - m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str()); -} - -void GraphicsHelperGL4::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); -} - -void GraphicsHelperGL4::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) -{ - m_funcs->glShaderStorageBlockBinding(programId, shaderStorageBlockIndex, shaderStorageBlockBinding); -} - -void GraphicsHelperGL4::bindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - m_funcs->glBindBufferBase(target, index, buffer); -} - -void GraphicsHelperGL4::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) -{ - char *bufferData = buffer.data(); - - switch (description.m_type) { - - case GL_FLOAT: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_FLOAT_VEC2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_FLOAT_VEC3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_FLOAT_VEC4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_FLOAT_MAT2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2); - break; - } - - case GL_FLOAT_MAT2x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3); - break; - } - - case GL_FLOAT_MAT2x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4); - break; - } - - case GL_FLOAT_MAT3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3); - break; - } - - case GL_FLOAT_MAT3x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2); - break; - } - - case GL_FLOAT_MAT3x4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4); - break; - } - - case GL_FLOAT_MAT4: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4); - break; - } - - case GL_FLOAT_MAT4x2: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2); - break; - } - - case GL_FLOAT_MAT4x3: { - const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12); - QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3); - break; - } - - case GL_INT: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_INT_VEC2: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_INT_VEC3: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_INT_VEC4: { - const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_UNSIGNED_INT: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_UNSIGNED_INT_VEC2: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_UNSIGNED_INT_VEC3: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_UNSIGNED_INT_VEC4: { - const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_BOOL: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1); - QGraphicsUtils::fillDataArray(bufferData, data, description, 1); - break; - } - - case GL_BOOL_VEC2: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2); - QGraphicsUtils::fillDataArray(bufferData, data, description, 2); - break; - } - - case GL_BOOL_VEC3: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3); - QGraphicsUtils::fillDataArray(bufferData, data, description, 3); - break; - } - - case GL_BOOL_VEC4: { - const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4); - QGraphicsUtils::fillDataArray(bufferData, data, description, 4); - break; - } - - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_IMAGE_1D: - case GL_IMAGE_2D: - case GL_IMAGE_3D: - case GL_IMAGE_2D_RECT: - case GL_IMAGE_CUBE: - case GL_IMAGE_BUFFER: - case GL_IMAGE_1D_ARRAY: - case GL_IMAGE_2D_ARRAY: - case GL_IMAGE_CUBE_MAP_ARRAY: - case GL_IMAGE_2D_MULTISAMPLE: - case GL_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_INT_IMAGE_1D: - case GL_INT_IMAGE_2D: - case GL_INT_IMAGE_3D: - case GL_INT_IMAGE_2D_RECT: - case GL_INT_IMAGE_CUBE: - case GL_INT_IMAGE_BUFFER: - case GL_INT_IMAGE_1D_ARRAY: - case GL_INT_IMAGE_2D_ARRAY: - case GL_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_INT_IMAGE_2D_MULTISAMPLE: - case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_IMAGE_1D: - case GL_UNSIGNED_INT_IMAGE_2D: - case GL_UNSIGNED_INT_IMAGE_3D: - case GL_UNSIGNED_INT_IMAGE_2D_RECT: - case GL_UNSIGNED_INT_IMAGE_CUBE: - case GL_UNSIGNED_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: { - Q_ASSERT(description.m_size == 1); - int value = v.toInt(); - QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - -uint GraphicsHelperGL4::uniformByteSize(const ShaderUniform &description) -{ - uint rawByteSize = 0; - int arrayStride = qMax(description.m_arrayStride, 0); - int matrixStride = qMax(description.m_matrixStride, 0); - - switch (description.m_type) { - - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_UNSIGNED_INT_VEC2: - rawByteSize = 8; - break; - - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_UNSIGNED_INT_VEC3: - rawByteSize = 12; - break; - - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_UNSIGNED_INT_VEC4: - rawByteSize = 16; - break; - - case GL_FLOAT_MAT2: - rawByteSize = matrixStride ? 2 * matrixStride : 16; - break; - - case GL_FLOAT_MAT2x4: - rawByteSize = matrixStride ? 2 * matrixStride : 32; - break; - - case GL_FLOAT_MAT4x2: - rawByteSize = matrixStride ? 4 * matrixStride : 32; - break; - - case GL_FLOAT_MAT3: - rawByteSize = matrixStride ? 3 * matrixStride : 36; - break; - - case GL_FLOAT_MAT2x3: - rawByteSize = matrixStride ? 2 * matrixStride : 24; - break; - - case GL_FLOAT_MAT3x2: - rawByteSize = matrixStride ? 3 * matrixStride : 24; - break; - - case GL_FLOAT_MAT4: - rawByteSize = matrixStride ? 4 * matrixStride : 64; - break; - - case GL_FLOAT_MAT4x3: - rawByteSize = matrixStride ? 4 * matrixStride : 48; - break; - - case GL_FLOAT_MAT3x4: - rawByteSize = matrixStride ? 3 * matrixStride : 48; - break; - - case GL_BOOL: - rawByteSize = 1; - break; - - case GL_BOOL_VEC2: - rawByteSize = 2; - break; - - case GL_BOOL_VEC3: - rawByteSize = 3; - break; - - case GL_BOOL_VEC4: - rawByteSize = 4; - break; - - case GL_INT: - case GL_FLOAT: - case GL_UNSIGNED_INT: - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_IMAGE_1D: - case GL_IMAGE_2D: - case GL_IMAGE_3D: - case GL_IMAGE_2D_RECT: - case GL_IMAGE_CUBE: - case GL_IMAGE_BUFFER: - case GL_IMAGE_1D_ARRAY: - case GL_IMAGE_2D_ARRAY: - case GL_IMAGE_CUBE_MAP_ARRAY: - case GL_IMAGE_2D_MULTISAMPLE: - case GL_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_INT_IMAGE_1D: - case GL_INT_IMAGE_2D: - case GL_INT_IMAGE_3D: - case GL_INT_IMAGE_2D_RECT: - case GL_INT_IMAGE_CUBE: - case GL_INT_IMAGE_BUFFER: - case GL_INT_IMAGE_1D_ARRAY: - case GL_INT_IMAGE_2D_ARRAY: - case GL_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_INT_IMAGE_2D_MULTISAMPLE: - case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_IMAGE_1D: - case GL_UNSIGNED_INT_IMAGE_2D: - case GL_UNSIGNED_INT_IMAGE_3D: - case GL_UNSIGNED_INT_IMAGE_2D_RECT: - case GL_UNSIGNED_INT_IMAGE_CUBE: - case GL_UNSIGNED_INT_IMAGE_BUFFER: - case GL_UNSIGNED_INT_IMAGE_1D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: - case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: - rawByteSize = 4; - break; - - default: { - qWarning() << Q_FUNC_INFO << "unable to deduce rawByteSize for uniform type:" << description.m_type << "for uniform" << description.m_name; - break; - } - - } - - return arrayStride ? rawByteSize * arrayStride : rawByteSize; -} - -void GraphicsHelperGL4::enableClipPlane(int clipPlane) -{ - m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL4::disableClipPlane(int clipPlane) -{ - m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane); -} - -void GraphicsHelperGL4::setClipPlane(int, const QVector3D &, float) -{ - // deprecated -} - -GLint GraphicsHelperGL4::maxClipPlaneCount() -{ - GLint max = 0; - m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max); - return max; -} - -void GraphicsHelperGL4::memoryBarrier(QMemoryBarrier::Operations barriers) -{ - m_funcs->glMemoryBarrier(memoryBarrierGLBitfield(barriers)); -} - -void GraphicsHelperGL4::enablePrimitiveRestart(int primitiveRestartIndex) -{ - m_funcs->glPrimitiveRestartIndex(primitiveRestartIndex); - m_funcs->glEnable(GL_PRIMITIVE_RESTART); -} - -void GraphicsHelperGL4::enableVertexAttributeArray(int location) -{ - m_funcs->glEnableVertexAttribArray(location); -} - -void GraphicsHelperGL4::disablePrimitiveRestart() -{ - m_funcs->glDisable(GL_PRIMITIVE_RESTART); -} - -void GraphicsHelperGL4::clearBufferf(GLint drawbuffer, const QVector4D &values) -{ - GLfloat vec[4] = {values[0], values[1], values[2], values[3]}; - m_funcs->glClearBufferfv(GL_COLOR, drawbuffer, vec); -} - -void GraphicsHelperGL4::pointSize(bool programmable, GLfloat value) -{ - if (programmable) { - m_funcs->glEnable(GL_PROGRAM_POINT_SIZE); - } else { - m_funcs->glDisable(GL_PROGRAM_POINT_SIZE); - m_funcs->glPointSize(value); - } -} - -void GraphicsHelperGL4::enablei(GLenum cap, GLuint index) -{ - m_funcs->glEnablei(cap, index); -} - -void GraphicsHelperGL4::disablei(GLenum cap, GLuint index) -{ - m_funcs->glDisablei(cap, index); -} - -void GraphicsHelperGL4::setSeamlessCubemap(bool enable) -{ - if (enable) - m_funcs->glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - else - m_funcs->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); -} - -QSize GraphicsHelperGL4::getRenderBufferDimensions(GLuint renderBufferId) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0); - - return QSize(width, height); -} - -QSize GraphicsHelperGL4::getTextureDimensions(GLuint textureId, GLenum target, uint level) -{ - GLint width = 0; - GLint height = 0; - - m_funcs->glBindTexture(target, textureId); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - m_funcs->glBindTexture(target, 0); - - return QSize(width, height); -} - -void GraphicsHelperGL4::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) -{ - m_funcs->glDispatchCompute(wx, wy, wz); -} - -char *GraphicsHelperGL4::mapBuffer(GLenum target, GLsizeiptr size) -{ - return static_cast<char*>(m_funcs->glMapBufferRange(target, 0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); -} - -GLboolean GraphicsHelperGL4::unmapBuffer(GLenum target) -{ - return m_funcs->glUnmapBuffer(target); -} - -void GraphicsHelperGL4::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - m_funcs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h deleted file mode 100644 index d3ce0d079..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpergl4_p.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERGL4_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERGL4_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <QtCore/qscopedpointer.h> - -#ifndef QT_OPENGL_ES_2 - -QT_BEGIN_NAMESPACE - -class QOpenGLFunctions_4_3_Core; - -namespace Qt3DRender { -namespace Render { - -class Q_AUTOTEST_EXPORT GraphicsHelperGL4 : public GraphicsHelperInterface -{ -public: - GraphicsHelperGL4(); - - // QGraphicHelperInterface interface - void alphaTest(GLenum mode1, GLenum mode2) override; - void bindBufferBase(GLenum target, GLuint index, GLuint buffer) override; - void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) override; - bool frameBufferNeedsRenderBuffer(const Attachment &attachment) override; - void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) override; - void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) override; - void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) override; - void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) override; - void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) override; - void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - void blendEquation(GLenum mode) override; - void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) override; - void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) override; - void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) override; - GLuint boundFrameBufferObject() override; - void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) override; - bool checkFrameBufferComplete() override; - void clearBufferf(GLint drawbuffer, const QVector4D &values) override; - GLuint createFrameBufferObject() override; - void depthMask(GLenum mode) override; - void depthRange(GLdouble nearValue, GLdouble farValue) override; - void depthTest(GLenum mode) override; - void disableClipPlane(int clipPlane) override; - void disablei(GLenum cap, GLuint index) override; - void disablePrimitiveRestart() override; - void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) override; - char *mapBuffer(GLenum target, GLsizeiptr size) override; - GLboolean unmapBuffer(GLenum target) override; - void drawArrays(GLenum primitiveType, GLint first, GLsizei count) override; - void drawArraysIndirect(GLenum mode,void *indirect) override; - void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) override; - void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) override; - void drawBuffers(GLsizei n, const int *bufs) override; - void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLint baseVertex = 0) override; - void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) override; - void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) override; - void enableClipPlane(int clipPlane) override; - void enablei(GLenum cap, GLuint index) override; - void enablePrimitiveRestart(int primitiveRestartIndex) override; - void enableVertexAttributeArray(int location) override; - void frontFace(GLenum mode) override; - QSize getRenderBufferDimensions(GLuint renderBufferId) override; - QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) override; - void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) override; - void pointSize(bool programmable, GLfloat value) override; - GLint maxClipPlaneCount() override; - void memoryBarrier(QMemoryBarrier::Operations barriers) override; - QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) override; - QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) override; - QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) override; - QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) override; - void releaseFrameBufferObject(GLuint frameBufferId) override; - void setMSAAEnabled(bool enable) override; - void setAlphaCoverageEnabled(bool enable) override; - void setClipPlane(int clipPlane, const QVector3D &normal, float distance) override; - void setSeamlessCubemap(bool enable) override; - void setVerticesPerPatch(GLint verticesPerPatch) override; - bool supportsFeature(Feature feature) const override; - uint uniformByteSize(const ShaderUniform &description) override; - void useProgram(GLuint programId) override; - void vertexAttribDivisor(GLuint index, GLuint divisor) override; - void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) override; - void readBuffer(GLenum mode) override; - void drawBuffer(GLenum mode) override; - void rasterMode(GLenum faceMode, GLenum rasterMode) override; - - void *fenceSync() override; - void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) override; - void waitSync(void *sync) override; - bool wasSyncSignaled(void *sync) override; - void deleteSync(void *sync) override; - - void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) override; - - void glUniform1iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform2iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform3iv(GLint location, GLsizei count, const GLint *value) override; - void glUniform4iv(GLint location, GLsizei count, const GLint *value) override; - - void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) override; - void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) override; - - void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) override; - void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) override; - - UniformType uniformTypeFromGLType(GLenum glType) override; - -private: - QOpenGLFunctions_4_3_Core *m_funcs; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // !QT_OPENGL_ES_2 - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERGL4_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h b/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h deleted file mode 100644 index 21146c32b..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelperinterface_p.h +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERINTERFACE_H -#define QT3DRENDER_RENDER_GRAPHICSHELPERINTERFACE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QOpenGLFunctions> -#include <QOpenGLTexture> -#include <QVector> -#include <Qt3DRender/private/shadervariables_p.h> -#include <Qt3DRender/private/uniform_p.h> -#include <Qt3DRender/qmemorybarrier.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -struct Attachment; -class RenderBuffer; - -class GraphicsHelperInterface -{ -public: - enum Feature { - MRT = 0, - Tessellation, - UniformBufferObject, - BindableFragmentOutputs, - PrimitiveRestart, - RenderBufferDimensionRetrieval, - TextureDimensionRetrieval, - ShaderStorageObject, - Compute, - DrawBuffersBlend, - BlitFramebuffer, - IndirectDrawing, - MapBuffer, - Fences, - ShaderImage - }; - - enum FBOBindMode { - FBODraw, - FBORead, - FBOReadAndDraw - }; - - virtual ~GraphicsHelperInterface() {} - virtual void alphaTest(GLenum mode1, GLenum mode2) = 0; - virtual void bindBufferBase(GLenum target, GLuint index, GLuint buffer) = 0; - virtual void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) = 0; - virtual bool frameBufferNeedsRenderBuffer(const Attachment &attachment) = 0; - virtual void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) = 0; - virtual void bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) = 0; - virtual void bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) = 0; - virtual void bindImageTexture(GLuint imageUnit, GLuint texture, GLint mipLevel, GLboolean layered, GLint layer, GLenum access, GLenum format) = 0; - virtual void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) = 0; - virtual void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; - virtual void blendEquation(GLenum mode) = 0; - virtual void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) = 0; - virtual void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) = 0; - virtual void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) = 0; - virtual GLuint boundFrameBufferObject() = 0; - virtual void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) = 0; - virtual bool checkFrameBufferComplete() = 0; - virtual void clearBufferf(GLint drawbuffer, const QVector4D &values) = 0; - virtual GLuint createFrameBufferObject() = 0; - virtual void depthRange(GLdouble nearValue, GLdouble farValue) = 0; - virtual void depthMask(GLenum mode) = 0; - virtual void depthTest(GLenum mode) = 0; - virtual void disableClipPlane(int clipPlane) = 0; - virtual void disablei(GLenum cap, GLuint index) = 0; - virtual void disablePrimitiveRestart() = 0; - virtual void dispatchCompute(GLuint wx, GLuint wy, GLuint wz) = 0; - virtual char *mapBuffer(GLenum target, GLsizeiptr size) = 0; - virtual GLboolean unmapBuffer(GLenum target) = 0; - virtual void drawArrays(GLenum primitiveType, GLint first, GLsizei count) = 0; - virtual void drawArraysIndirect(GLenum mode,void *indirect) = 0; - virtual void drawArraysInstanced(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances) = 0; - virtual void drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseinstance) = 0; - virtual void drawBuffers(GLsizei n, const int *bufs) = 0; - virtual void drawElements(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void * indices, GLint baseVertex) = 0; - virtual void drawElementsIndirect(GLenum mode, GLenum type, void *indirect) = 0; - virtual void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void * indices, GLsizei instances, GLint baseVertex, GLint baseInstance) = 0; - virtual void enableClipPlane(int clipPlane) = 0; - virtual void enablei(GLenum cap, GLuint index) = 0; - virtual void enablePrimitiveRestart(int primitiveRestartIndex) = 0; - virtual void enableVertexAttributeArray(int location) = 0; - virtual void frontFace(GLenum mode) = 0; - virtual QSize getRenderBufferDimensions(GLuint renderBufferId) = 0; - virtual QSize getTextureDimensions(GLuint textureId, GLenum target, uint level = 0) = 0; - virtual void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) = 0; - virtual GLint maxClipPlaneCount() = 0; - virtual void memoryBarrier(QMemoryBarrier::Operations barriers) = 0; - virtual void pointSize(bool programmable, GLfloat value) = 0; - virtual QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) = 0; - virtual QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) = 0; - virtual QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) = 0; - virtual QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) = 0; - virtual void releaseFrameBufferObject(GLuint frameBufferId) = 0; - virtual void setAlphaCoverageEnabled(bool enable) = 0; - virtual void setClipPlane(int clipPlane, const QVector3D &normal, float distance) = 0; - virtual void setMSAAEnabled(bool enable) = 0; - virtual void setSeamlessCubemap(bool enable) = 0; - virtual void setVerticesPerPatch(GLint verticesPerPatch) = 0; - virtual bool supportsFeature(Feature feature) const = 0; - virtual uint uniformByteSize(const ShaderUniform &description) = 0; - virtual void useProgram(GLuint programId) = 0; - virtual void vertexAttribDivisor(GLuint index, GLuint divisor) = 0; - virtual void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) = 0; - virtual void readBuffer(GLenum mode) = 0; - virtual void drawBuffer(GLenum mode) = 0; - virtual void rasterMode(GLenum faceMode, GLenum rasterMode) = 0; - - virtual void *fenceSync() = 0; - virtual void clientWaitSync(void *sync, GLuint64 nanoSecTimeout) = 0; - virtual void waitSync(void *sync) = 0; - virtual bool wasSyncSignaled(void *sync) = 0; - virtual void deleteSync(void *sync) = 0; - - virtual void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) = 0; - - virtual void glUniform1iv(GLint location, GLsizei count, const GLint *value) = 0; - virtual void glUniform2iv(GLint location, GLsizei count, const GLint *value) = 0; - virtual void glUniform3iv(GLint location, GLsizei count, const GLint *value) = 0; - virtual void glUniform4iv(GLint location, GLsizei count, const GLint *value) = 0; - - virtual void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) = 0; - virtual void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) = 0; - virtual void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) = 0; - virtual void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) = 0; - - virtual void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) = 0; - virtual void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) = 0; - - virtual UniformType uniformTypeFromGLType(GLenum glType) = 0; -}; - - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GRAPHICSHELPERINTERFACE_H diff --git a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri b/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri deleted file mode 100644 index f2f7274d7..000000000 --- a/src/render/renderers/opengl/graphicshelpers/graphicshelpers.pri +++ /dev/null @@ -1,33 +0,0 @@ -#DEFINES += QT3D_RENDER_ASPECT_OPENGL_DEBUG - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/glfence_p.h \ - $$PWD/graphicscontext_p.h \ - $$PWD/graphicshelperinterface_p.h \ - $$PWD/graphicshelperes2_p.h \ - $$PWD/graphicshelperes3_p.h \ - $$PWD/graphicshelperes3_1_p.h \ - $$PWD/graphicshelperes3_2_p.h \ - $$PWD/graphicshelpergl2_p.h \ - $$PWD/graphicshelpergl3_3_p.h \ - $$PWD/graphicshelpergl4_p.h \ - $$PWD/graphicshelpergl3_2_p.h \ - $$PWD/imagesubmissioncontext_p.h \ - $$PWD/submissioncontext_p.h \ - $$PWD/texturesubmissioncontext_p.h - -SOURCES += \ - $$PWD/graphicscontext.cpp \ - $$PWD/graphicshelperes2.cpp \ - $$PWD/graphicshelperes3.cpp \ - $$PWD/graphicshelperes3_1.cpp \ - $$PWD/graphicshelperes3_2.cpp \ - $$PWD/graphicshelpergl2.cpp \ - $$PWD/graphicshelpergl3_3.cpp \ - $$PWD/graphicshelpergl4.cpp \ - $$PWD/graphicshelpergl3_2.cpp \ - $$PWD/imagesubmissioncontext.cpp \ - $$PWD/submissioncontext.cpp \ - $$PWD/texturesubmissioncontext.cpp diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp deleted file mode 100644 index ca600f994..000000000 --- a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "imagesubmissioncontext_p.h" -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/gltexture_p.h> -#include <Qt3DRender/private/shaderimage_p.h> -#include <Qt3DRender/qshaderimage.h> - -QT_BEGIN_NAMESPACE - -// ES 3.1+ or GL 4.2+ -#ifndef GL_READ_ONLY -#define GL_READ_ONLY 0x88B8 -#endif -#ifndef GL_WRITE_ONLY -#define GL_WRITE_ONLY 0x88B9 -#endif -#ifndef GL_READ_WRITE -#define GL_READ_WRITE 0x88BA -#endif - -namespace Qt3DRender { -namespace Render { - -class GraphicsContext; -class GLTexture; - -namespace { - -GLenum glAccessEnumForShaderImageAccess(QShaderImage::Access access) -{ - switch (access) { - case QShaderImage::ReadOnly: - return GL_READ_ONLY; - case QShaderImage::WriteOnly: - return GL_WRITE_ONLY; - case QShaderImage::ReadWrite: - default: - break; - } - return GL_READ_WRITE; -} - -GLenum glImageFormatToGL(QShaderImage::ImageFormat format) -{ - // Right now we can abuse from the fact that the ImageFormat enum values - // have been assigned the same value as the GL enum - return GLenum(format); -} - -GLenum glImageFormatForShaderImageFormat(QShaderImage::ImageFormat format, - QAbstractTexture::TextureFormat textureFormat) -{ - Q_ASSERT_X(format != QShaderImage::NoFormat, Q_FUNC_INFO, "Valid image format or Automatic expected"); - - if (format != QShaderImage::Automatic) - return glImageFormatToGL(format); - - // Otherwise try to mind to best texture format - switch (textureFormat) { - case QAbstractTexture::R8_UNorm: - return glImageFormatToGL(QShaderImage::R8_UNorm); - case QAbstractTexture::RG8_UNorm: - return glImageFormatToGL(QShaderImage::RG8_UNorm); - case QAbstractTexture::RGBA8_UNorm: - return glImageFormatToGL(QShaderImage::RGBA8_UNorm); - - case QAbstractTexture::R16_UNorm: - return glImageFormatToGL(QShaderImage::R16_UNorm); - case QAbstractTexture::RG16_UNorm: - return glImageFormatToGL(QShaderImage::RG16_UNorm); - case QAbstractTexture::RGBA16_UNorm: - return glImageFormatToGL(QShaderImage::RGBA16_UNorm); - - case QAbstractTexture::R8_SNorm: - return glImageFormatToGL(QShaderImage::R8_SNorm); - case QAbstractTexture::RG8_SNorm: - return glImageFormatToGL(QShaderImage::RG8_SNorm); - case QAbstractTexture::RGBA8_SNorm: - return glImageFormatToGL(QShaderImage::RGBA8_SNorm); - - case QAbstractTexture::R16_SNorm: - return glImageFormatToGL(QShaderImage::R16_SNorm); - case QAbstractTexture::RG16_SNorm: - return glImageFormatToGL(QShaderImage::RG16_SNorm); - case QAbstractTexture::RGBA16_SNorm: - return glImageFormatToGL(QShaderImage::RGBA16_SNorm); - - case QAbstractTexture::R8U: - return glImageFormatToGL(QShaderImage::R8U); - case QAbstractTexture::RG8U: - return glImageFormatToGL(QShaderImage::RG8U); - case QAbstractTexture::RGBA8U: - return glImageFormatToGL(QShaderImage::RGBA8U); - - case QAbstractTexture::R16U: - return glImageFormatToGL(QShaderImage::R16U); - case QAbstractTexture::RG16U: - return glImageFormatToGL(QShaderImage::RG16U); - case QAbstractTexture::RGBA16U: - return glImageFormatToGL(QShaderImage::RGBA16U); - - case QAbstractTexture::R32U: - return glImageFormatToGL(QShaderImage::R32U); - case QAbstractTexture::RG32U: - return glImageFormatToGL(QShaderImage::RG32U); - case QAbstractTexture::RGBA32U: - return glImageFormatToGL(QShaderImage::RGBA32U); - - case QAbstractTexture::R8I: - return glImageFormatToGL(QShaderImage::R8I); - case QAbstractTexture::RG8I: - return glImageFormatToGL(QShaderImage::RG8I); - case QAbstractTexture::RGBA8I: - return glImageFormatToGL(QShaderImage::RGBA8I); - - case QAbstractTexture::R16I: - return glImageFormatToGL(QShaderImage::R16I); - case QAbstractTexture::RG16I: - return glImageFormatToGL(QShaderImage::RG16I); - case QAbstractTexture::RGBA16I: - return glImageFormatToGL(QShaderImage::RGBA16I); - - case QAbstractTexture::R32I: - return glImageFormatToGL(QShaderImage::R32I); - case QAbstractTexture::RG32I: - return glImageFormatToGL(QShaderImage::RG32I); - case QAbstractTexture::RGBA32I: - return glImageFormatToGL(QShaderImage::RGBA32I); - - case QAbstractTexture::R16F: - return glImageFormatToGL(QShaderImage::R16F); - case QAbstractTexture::RG16F: - return glImageFormatToGL(QShaderImage::RG16F); - case QAbstractTexture::RGBA16F: - return glImageFormatToGL(QShaderImage::RGBA16F); - - case QAbstractTexture::R32F: - return glImageFormatToGL(QShaderImage::R32F); - case QAbstractTexture::RG32F: - return glImageFormatToGL(QShaderImage::RG32F); - case QAbstractTexture::RGBA32F: - return glImageFormatToGL(QShaderImage::RGBA32F); - - case QAbstractTexture::RG11B10F: - return glImageFormatToGL(QShaderImage::RG11B10F); - case QAbstractTexture::RGB10A2: - return glImageFormatToGL(QShaderImage::RGB10A2); - case QAbstractTexture::RGB10A2U: - return glImageFormatToGL(QShaderImage::RGB10A2U); - - default: - qWarning() << "Cannot map Texture format" << textureFormat << "to a valid Image Format"; - Q_UNREACHABLE(); - return GL_NONE; - } -} - -} // anonymous - -ImageSubmissionContext::ImageSubmissionContext() - : m_ctx(nullptr) -{ -} - -void ImageSubmissionContext::initialize(GraphicsContext *context) -{ - m_ctx = context; - m_activeImages.resize(m_ctx->maxImageUnitsCount()); -} - -void ImageSubmissionContext::endDrawing() -{ - // Reduce score of all active Images - decayImageScores(); -} - -// Return Image Unit for Image -// If Image was used previously and recently, it will return the last used unit -// for that image. Otherwise it will try to return the image unit the least used. -int ImageSubmissionContext::activateImage(ShaderImage *image, GLTexture *tex) -{ - const int onUnit = assignUnitForImage(image->peerId()); - - if (onUnit < 0) { - qWarning() << "Unable to find available image unit"; - return -1; - } - - QOpenGLTexture *glTex = tex->getGLTexture(); - if (glTex == nullptr) { - qWarning() << "Unable to retrieve valid texture for Image"; - return -1; - } - - // Bind Image against Texture and resolve Image Format - m_ctx->bindImageTexture(onUnit, - glTex->textureId(), - image->mipLevel(), - image->layered(), - image->layer(), - glAccessEnumForShaderImageAccess(image->access()), - glImageFormatForShaderImageFormat(image->format(), - tex->properties().format)); - - // Store information about the Texture/Image on ActiveImage for given - // image unit - m_activeImages[onUnit].shaderImageId = image->peerId(); - m_activeImages[onUnit].texture = tex; - m_activeImages[onUnit].score = 200; - m_activeImages[onUnit].pinned = true; - - return onUnit; -} - -// Unset pinned Active Image and reduce their score -void ImageSubmissionContext::deactivateImages() -{ - for (int u = 0, m = m_activeImages.size(); u < m; ++u) { - if (m_activeImages[u].pinned) { - m_activeImages[u].pinned = false; - m_activeImages[u].score = qMax(m_activeImages[u].score - 1, 0); - return; - } - } -} - -// Reduce score of all active images (pinned or not) -void ImageSubmissionContext::decayImageScores() -{ - for (int u = 0, m = m_activeImages.size(); u < m; ++u) - m_activeImages[u].score = qMax(m_activeImages[u].score - 1, 0); -} - -int ImageSubmissionContext::assignUnitForImage(Qt3DCore::QNodeId shaderImageId) -{ - int lowestScoredUnit = -1; - int lowestScore = 0xfffffff; - - const int m = m_activeImages.size(); - for (int u = 0; u < m; ++u) { - if (m_activeImages[u].shaderImageId == shaderImageId) - return u; - } - - for (int u = 0; u < m; ++u) { - // No image is currently active on the image unit - // we save the image unit with the texture that has been on there - // the longest time while not being used - if (!m_activeImages[u].pinned) { - const int score = m_activeImages[u].score; - if (score < lowestScore) { - lowestScore = score; - lowestScoredUnit = u; - } - } - } - - if (lowestScoredUnit == -1) - qCWarning(Backend) << Q_FUNC_INFO << "No free image units!"; - - return lowestScoredUnit; -} - - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h deleted file mode 100644 index 6d39f469b..000000000 --- a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext_p.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H -#define QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/QNodeId> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class GraphicsContext; -class GLTexture; -class ShaderImage; - -class Q_AUTOTEST_EXPORT ImageSubmissionContext -{ -public: - ImageSubmissionContext(); - - void initialize(GraphicsContext *context); - void endDrawing(); - int activateImage(ShaderImage *image, GLTexture *tex); - void deactivateImages(); - -private: - void decayImageScores(); - int assignUnitForImage(Qt3DCore::QNodeId shaderImageId); - - struct ActiveImage - { - Qt3DCore::QNodeId shaderImageId; - GLTexture *texture = nullptr; - int score = 0; - bool pinned = false; - }; - QVector<ActiveImage> m_activeImages; - GraphicsContext *m_ctx; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_IMAGESUBMISSIONCONTEXT_P_H diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp deleted file mode 100644 index 8afec233d..000000000 --- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp +++ /dev/null @@ -1,1574 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "submissioncontext_p.h" - -#include <Qt3DRender/qgraphicsapifilter.h> -#include <Qt3DRender/qparameter.h> -#include <Qt3DRender/qcullface.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/shader_p.h> -#include <Qt3DRender/private/material_p.h> -#include <Qt3DRender/private/gltexture_p.h> -#include <Qt3DRender/private/buffer_p.h> -#include <Qt3DRender/private/attribute_p.h> -#include <Qt3DRender/private/rendercommand_p.h> -#include <Qt3DRender/private/renderstates_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/rendertarget_p.h> -#include <Qt3DRender/private/graphicshelperinterface_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/glresourcemanagers_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/buffermanager_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/attachmentpack_p.h> -#include <Qt3DRender/private/qbuffer_p.h> -#include <Qt3DRender/private/renderbuffer_p.h> -#include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DRender/private/glshader_p.h> -#include <Qt3DRender/private/openglvertexarrayobject_p.h> -#include <QOpenGLShaderProgram> - -#if !defined(QT_OPENGL_ES_2) -#include <QOpenGLFunctions_2_0> -#include <QOpenGLFunctions_3_2_Core> -#include <QOpenGLFunctions_3_3_Core> -#include <QOpenGLFunctions_4_3_Core> -#include <Qt3DRender/private/graphicshelpergl2_p.h> -#include <Qt3DRender/private/graphicshelpergl3_2_p.h> -#include <Qt3DRender/private/graphicshelpergl3_3_p.h> -#include <Qt3DRender/private/graphicshelpergl4_p.h> -#endif -#include <Qt3DRender/private/graphicshelperes2_p.h> -#include <Qt3DRender/private/graphicshelperes3_p.h> - -#include <private/qdebug_p.h> -#include <QSurface> -#include <QWindow> -#include <QOpenGLTexture> -#include <QOpenGLDebugLogger> - -QT_BEGIN_NAMESPACE - -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif - -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -namespace Qt3DRender { -namespace Render { - - -static QHash<unsigned int, SubmissionContext*> static_contexts; - -unsigned int nextFreeContextId() -{ - for (unsigned int i=0; i < 0xffff; ++i) { - if (!static_contexts.contains(i)) - return i; - } - - qFatal("Couldn't find free context ID"); - return 0; -} - -namespace { - -GLBuffer::Type attributeTypeToGLBufferType(QAttribute::AttributeType type) -{ - switch (type) { - case QAttribute::VertexAttribute: - return GLBuffer::ArrayBuffer; - case QAttribute::IndexAttribute: - return GLBuffer::IndexBuffer; - case QAttribute::DrawIndirectAttribute: - return GLBuffer::DrawIndirectBuffer; - default: - Q_UNREACHABLE(); - } -} - -void copyGLFramebufferDataToImage(QImage &img, const uchar *srcData, uint stride, uint width, uint height, QAbstractTexture::TextureFormat format) -{ - switch (format) { - case QAbstractTexture::RGBA32F: - { - uchar *srcScanline = (uchar *)srcData + stride * (height - 1); - for (uint i = 0; i < height; ++i) { - uchar *dstScanline = img.scanLine(i); - float *pSrc = (float*)srcScanline; - for (uint j = 0; j < width; j++) { - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+2], 1.0f)); - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+1], 1.0f)); - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+0], 1.0f)); - *dstScanline++ = (uchar)(255.0f * qBound(0.0f, pSrc[4*j+3], 1.0f)); - } - srcScanline -= stride; - } - } break; - default: - { - uchar* srcScanline = (uchar *)srcData + stride * (height - 1); - for (uint i = 0; i < height; ++i) { - memcpy(img.scanLine(i), srcScanline, stride); - srcScanline -= stride; - } - } break; - } -} - -// Render States Helpers -template<typename GenericState> -void applyStateHelper(const GenericState *state, SubmissionContext *gc) -{ - Q_UNUSED(state); - Q_UNUSED(gc); -} - -template<> -void applyStateHelper<AlphaFunc>(const AlphaFunc *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->alphaTest(std::get<0>(values), std::get<1>(values)); -} - -template<> -void applyStateHelper<BlendEquationArguments>(const BlendEquationArguments *state, SubmissionContext *gc) -{ - const auto values = state->values(); - // Un-indexed BlendEquationArguments -> Use normal GL1.0 functions - if (std::get<5>(values) < 0) { - if (std::get<4>(values)) { - gc->openGLContext()->functions()->glEnable(GL_BLEND); - gc->openGLContext()->functions()->glBlendFuncSeparate(std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values)); - } else { - gc->openGLContext()->functions()->glDisable(GL_BLEND); - } - } - // BlendEquationArguments for a particular Draw Buffer. Different behaviours for - // (1) 3.0-3.3: only enablei/disablei supported. - // (2) 4.0+: all operations supported. - // We just ignore blend func parameter for (1), so no warnings get - // printed. - else { - if (std::get<4>(values)) { - gc->enablei(GL_BLEND, std::get<5>(values)); - if (gc->supportsDrawBuffersBlend()) { - gc->blendFuncSeparatei(std::get<5>(values), std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values)); - } - } else { - gc->disablei(GL_BLEND, std::get<5>(values)); - } - } -} - -template<> -void applyStateHelper<BlendEquation>(const BlendEquation *state, SubmissionContext *gc) -{ - gc->blendEquation(std::get<0>(state->values())); -} - -template<> -void applyStateHelper<MSAAEnabled>(const MSAAEnabled *state, SubmissionContext *gc) -{ - gc->setMSAAEnabled(std::get<0>(state->values())); -} - -template<> -void applyStateHelper<DepthRange>(const DepthRange *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->depthRange(std::get<0>(values), std::get<1>(values)); -} - -template<> -void applyStateHelper<DepthTest>(const DepthTest *state, SubmissionContext *gc) -{ - gc->depthTest(std::get<0>(state->values())); -} - -template<> -void applyStateHelper<RasterMode>(const RasterMode *state, SubmissionContext *gc) -{ - gc->rasterMode(std::get<0>(state->values()), std::get<1>(state->values())); -} - -template<> -void applyStateHelper<NoDepthMask>(const NoDepthMask *state, SubmissionContext *gc) -{ - gc->depthMask(std::get<0>(state->values())); -} - -template<> -void applyStateHelper<CullFace>(const CullFace *state, SubmissionContext *gc) -{ - const auto values = state->values(); - if (std::get<0>(values) == QCullFace::NoCulling) { - gc->openGLContext()->functions()->glDisable(GL_CULL_FACE); - } else { - gc->openGLContext()->functions()->glEnable(GL_CULL_FACE); - gc->openGLContext()->functions()->glCullFace(std::get<0>(values)); - } -} - -template<> -void applyStateHelper<FrontFace>(const FrontFace *state, SubmissionContext *gc) -{ - gc->frontFace(std::get<0>(state->values())); -} - -template<> -void applyStateHelper<ScissorTest>(const ScissorTest *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->openGLContext()->functions()->glEnable(GL_SCISSOR_TEST); - gc->openGLContext()->functions()->glScissor(std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values)); -} - -template<> -void applyStateHelper<StencilTest>(const StencilTest *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->openGLContext()->functions()->glEnable(GL_STENCIL_TEST); - gc->openGLContext()->functions()->glStencilFuncSeparate(GL_FRONT, std::get<0>(values), std::get<1>(values), std::get<2>(values)); - gc->openGLContext()->functions()->glStencilFuncSeparate(GL_BACK, std::get<3>(values), std::get<4>(values), std::get<5>(values)); -} - -template<> -void applyStateHelper<AlphaCoverage>(const AlphaCoverage *, SubmissionContext *gc) -{ - gc->setAlphaCoverageEnabled(true); -} - -template<> -void applyStateHelper<PointSize>(const PointSize *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->pointSize(std::get<0>(values), std::get<1>(values)); -} - - -template<> -void applyStateHelper<PolygonOffset>(const PolygonOffset *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->openGLContext()->functions()->glEnable(GL_POLYGON_OFFSET_FILL); - gc->openGLContext()->functions()->glPolygonOffset(std::get<0>(values), std::get<1>(values)); -} - -template<> -void applyStateHelper<ColorMask>(const ColorMask *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->openGLContext()->functions()->glColorMask(std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values)); -} - -template<> -void applyStateHelper<ClipPlane>(const ClipPlane *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->enableClipPlane(std::get<0>(values)); - gc->setClipPlane(std::get<0>(values), std::get<1>(values), std::get<2>(values)); -} - -template<> -void applyStateHelper<SeamlessCubemap>(const SeamlessCubemap *, SubmissionContext *gc) -{ - gc->setSeamlessCubemap(true); -} - -template<> -void applyStateHelper<StencilOp>(const StencilOp *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->openGLContext()->functions()->glStencilOpSeparate(GL_FRONT, std::get<0>(values), std::get<1>(values), std::get<2>(values)); - gc->openGLContext()->functions()->glStencilOpSeparate(GL_BACK, std::get<3>(values), std::get<4>(values), std::get<5>(values)); -} - -template<> -void applyStateHelper<StencilMask>(const StencilMask *state, SubmissionContext *gc) -{ - const auto values = state->values(); - gc->openGLContext()->functions()->glStencilMaskSeparate(GL_FRONT, std::get<0>(values)); - gc->openGLContext()->functions()->glStencilMaskSeparate(GL_BACK, std::get<1>(values)); -} - -template<> -void applyStateHelper<Dithering>(const Dithering *, SubmissionContext *gc) -{ - gc->openGLContext()->functions()->glEnable(GL_DITHER); -} - -#ifndef GL_LINE_SMOOTH -#define GL_LINE_SMOOTH 0x0B20 -#endif - -template<> -void applyStateHelper<LineWidth>(const LineWidth *state, SubmissionContext *gc) -{ - const auto values = state->values(); - if (std::get<1>(values)) - gc->openGLContext()->functions()->glEnable(GL_LINE_SMOOTH); - else - gc->openGLContext()->functions()->glDisable(GL_LINE_SMOOTH); - - gc->openGLContext()->functions()->glLineWidth(std::get<0>(values)); -} - -} // anonymous - - -SubmissionContext::SubmissionContext() - : GraphicsContext() - , m_ownCurrent(true) - , m_id(nextFreeContextId()) - , m_surface(nullptr) - , m_activeShader(nullptr) - , m_renderTargetFormat(QAbstractTexture::NoFormat) - , m_currClearStencilValue(0) - , m_currClearDepthValue(1.f) - , m_currClearColorValue(0,0,0,0) - , m_material(nullptr) - , m_activeFBO(0) - , m_boundArrayBuffer(nullptr) - , m_stateSet(nullptr) - , m_renderer(nullptr) - , m_uboTempArray(QByteArray(1024, 0)) -{ - static_contexts[m_id] = this; -} - -SubmissionContext::~SubmissionContext() -{ - releaseOpenGL(); - - Q_ASSERT(static_contexts[m_id] == this); - static_contexts.remove(m_id); -} - -void SubmissionContext::initialize() -{ - GraphicsContext::initialize(); - m_textureContext.initialize(this); - m_imageContext.initialize(this); -} - -void SubmissionContext::resolveRenderTargetFormat() -{ - const QSurfaceFormat format = m_gl->format(); - const uint a = (format.alphaBufferSize() == -1) ? 0 : format.alphaBufferSize(); - const uint r = format.redBufferSize(); - const uint g = format.greenBufferSize(); - const uint b = format.blueBufferSize(); - -#define RGBA_BITS(r,g,b,a) (r | (g << 6) | (b << 12) | (a << 18)) - - const uint bits = RGBA_BITS(r,g,b,a); - switch (bits) { - case RGBA_BITS(8,8,8,8): - m_renderTargetFormat = QAbstractTexture::RGBA8_UNorm; - break; - case RGBA_BITS(8,8,8,0): - m_renderTargetFormat = QAbstractTexture::RGB8_UNorm; - break; - case RGBA_BITS(5,6,5,0): - m_renderTargetFormat = QAbstractTexture::R5G6B5; - break; - } -#undef RGBA_BITS -} - -bool SubmissionContext::beginDrawing(QSurface *surface) -{ - Q_ASSERT(surface); - Q_ASSERT(m_gl); - - m_surface = surface; - - // TO DO: Find a way to make to pause work if the window is not exposed - // if (m_surface && m_surface->surfaceClass() == QSurface::Window) { - // qDebug() << Q_FUNC_INFO << 1; - // if (!static_cast<QWindow *>(m_surface)->isExposed()) - // return false; - // qDebug() << Q_FUNC_INFO << 2; - // } - - // Makes the surface current on the OpenGLContext - // and sets the right glHelper - m_ownCurrent = !(m_gl->surface() == m_surface); - if (m_ownCurrent && !makeCurrent(m_surface)) - return false; - - // TODO: cache surface format somewhere rather than doing this every time render surface changes - resolveRenderTargetFormat(); - -#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG) - GLint err = m_gl->functions()->glGetError(); - if (err != 0) { - qCWarning(Backend) << Q_FUNC_INFO << "glGetError:" << err; - } -#endif - - if (!isInitialized()) - initialize(); - initializeHelpers(m_surface); - - // need to reset these values every frame, may get overwritten elsewhere - m_gl->functions()->glClearColor(m_currClearColorValue.redF(), m_currClearColorValue.greenF(), m_currClearColorValue.blueF(), m_currClearColorValue.alphaF()); - m_gl->functions()->glClearDepthf(m_currClearDepthValue); - m_gl->functions()->glClearStencil(m_currClearStencilValue); - - if (m_activeShader) { - m_activeShader = nullptr; - } - - m_boundArrayBuffer = nullptr; - return true; -} - -void SubmissionContext::endDrawing(bool swapBuffers) -{ - if (swapBuffers) - m_gl->swapBuffers(m_surface); - if (m_ownCurrent) - m_gl->doneCurrent(); - m_textureContext.endDrawing(); - m_imageContext.endDrawing(); -} - -void SubmissionContext::activateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, GLuint defaultFboId) -{ - GLuint fboId = defaultFboId; // Default FBO - if (renderTargetNodeId) { - // New RenderTarget - if (!m_renderTargets.contains(renderTargetNodeId)) { - if (m_defaultFBO && fboId == m_defaultFBO) { - // this is the default fbo that some platforms create (iOS), we just register it - // Insert FBO into hash - m_renderTargets.insert(renderTargetNodeId, fboId); - } else { - fboId = createRenderTarget(renderTargetNodeId, attachments); - } - } else { - fboId = updateRenderTarget(renderTargetNodeId, attachments, true); - } - } - m_activeFBO = fboId; - m_glHelper->bindFrameBufferObject(m_activeFBO, GraphicsHelperInterface::FBODraw); - // Set active drawBuffers - activateDrawBuffers(attachments); -} - -GLuint SubmissionContext::createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments) -{ - const GLuint fboId = m_glHelper->createFrameBufferObject(); - if (fboId) { - // The FBO is created and its attachments are set once - // Insert FBO into hash - m_renderTargets.insert(renderTargetNodeId, fboId); - // Bind FBO - m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); - bindFrameBufferAttachmentHelper(fboId, attachments); - } else { - qCritical("Failed to create FBO"); - } - return fboId; -} - -GLuint SubmissionContext::updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget) -{ - const GLuint fboId = m_renderTargets.value(renderTargetNodeId); - - // We need to check if one of the attachment was resized - bool needsResize = !m_renderTargetsSize.contains(fboId); // not even initialized yet? - if (!needsResize) { - // render target exists, has attachment been resized? - GLTextureManager *glTextureManager = m_renderer->glResourceManagers()->glTextureManager(); - const QSize s = m_renderTargetsSize[fboId]; - const auto attachments_ = attachments.attachments(); - for (const Attachment &attachment : attachments_) { - GLTexture *rTex = glTextureManager->lookupResource(attachment.m_textureUuid); - // ### TODO QTBUG-64757 this check is insufficient since the - // texture may have changed to another one with the same size. That - // case is not handled atm. - if (rTex) { - needsResize |= rTex->size() != s; - if (isActiveRenderTarget && attachment.m_point == QRenderTargetOutput::Color0) - m_renderTargetFormat = rTex->properties().format; - } - } - } - - if (needsResize) { - m_glHelper->bindFrameBufferObject(fboId, GraphicsHelperInterface::FBODraw); - bindFrameBufferAttachmentHelper(fboId, attachments); - } - - return fboId; -} - -QSize SubmissionContext::renderTargetSize(const QSize &surfaceSize) const -{ - QSize renderTargetSize; - if (m_activeFBO != m_defaultFBO) { - // For external FBOs we may not have a m_renderTargets entry. - if (m_renderTargetsSize.contains(m_activeFBO)) { - renderTargetSize = m_renderTargetsSize[m_activeFBO]; - } else if (surfaceSize.isValid()) { - renderTargetSize = surfaceSize; - } else { - // External FBO (when used with QtQuick2 Scene3D) - - // Query FBO color attachment 0 size - GLint attachmentObjectType = GL_NONE; - GLint attachment0Name = 0; - m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, - &attachmentObjectType); - m_gl->functions()->glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, - &attachment0Name); - - if (attachmentObjectType == GL_RENDERBUFFER && m_glHelper->supportsFeature(GraphicsHelperInterface::RenderBufferDimensionRetrieval)) - renderTargetSize = m_glHelper->getRenderBufferDimensions(attachment0Name); - else if (attachmentObjectType == GL_TEXTURE && m_glHelper->supportsFeature(GraphicsHelperInterface::TextureDimensionRetrieval)) - // Assumes texture level 0 and GL_TEXTURE_2D target - renderTargetSize = m_glHelper->getTextureDimensions(attachment0Name, GL_TEXTURE_2D); - else - return renderTargetSize; - } - } else { - renderTargetSize = m_surface->size(); - if (m_surface->surfaceClass() == QSurface::Window) { - const float dpr = static_cast<QWindow *>(m_surface)->devicePixelRatio(); - renderTargetSize *= dpr; - } - } - return renderTargetSize; -} - -QImage SubmissionContext::readFramebuffer(const QRect &rect) -{ - QImage img; - const unsigned int area = rect.width() * rect.height(); - unsigned int bytes; - GLenum format, type; - QImage::Format imageFormat; - uint stride; - - /* format value should match GL internalFormat */ - GLenum internalFormat = m_renderTargetFormat; - - switch (m_renderTargetFormat) { - case QAbstractTexture::RGBAFormat: - case QAbstractTexture::RGBA8_SNorm: - case QAbstractTexture::RGBA8_UNorm: - case QAbstractTexture::RGBA8U: - case QAbstractTexture::SRGB8_Alpha8: -#ifdef QT_OPENGL_ES_2 - format = GL_RGBA; - imageFormat = QImage::Format_RGBA8888_Premultiplied; -#else - format = GL_BGRA; - imageFormat = QImage::Format_ARGB32_Premultiplied; - internalFormat = GL_RGBA8; -#endif - type = GL_UNSIGNED_BYTE; - bytes = area * 4; - stride = rect.width() * 4; - break; - case QAbstractTexture::SRGB8: - case QAbstractTexture::RGBFormat: - case QAbstractTexture::RGB8U: - case QAbstractTexture::RGB8_UNorm: -#ifdef QT_OPENGL_ES_2 - format = GL_RGBA; - imageFormat = QImage::Format_RGBX8888; -#else - format = GL_BGRA; - imageFormat = QImage::Format_RGB32; - internalFormat = GL_RGB8; -#endif - type = GL_UNSIGNED_BYTE; - bytes = area * 4; - stride = rect.width() * 4; - break; -#ifndef QT_OPENGL_ES_2 - case QAbstractTexture::RG11B10F: - bytes = area * 4; - format = GL_RGB; - type = GL_UNSIGNED_INT_10F_11F_11F_REV; - imageFormat = QImage::Format_RGB30; - stride = rect.width() * 4; - break; - case QAbstractTexture::RGB10A2: - bytes = area * 4; - format = GL_RGBA; - type = GL_UNSIGNED_INT_2_10_10_10_REV; - imageFormat = QImage::Format_A2BGR30_Premultiplied; - stride = rect.width() * 4; - break; - case QAbstractTexture::R5G6B5: - bytes = area * 2; - format = GL_RGB; - type = GL_UNSIGNED_SHORT; - internalFormat = GL_UNSIGNED_SHORT_5_6_5_REV; - imageFormat = QImage::Format_RGB16; - stride = rect.width() * 2; - break; - case QAbstractTexture::RGBA16F: - case QAbstractTexture::RGBA16U: - case QAbstractTexture::RGBA32F: - case QAbstractTexture::RGBA32U: - bytes = area * 16; - format = GL_RGBA; - type = GL_FLOAT; - imageFormat = QImage::Format_ARGB32_Premultiplied; - stride = rect.width() * 16; - break; -#endif - default: - auto warning = qWarning(); - warning << "Unable to convert"; - QtDebugUtils::formatQEnum(warning, m_renderTargetFormat); - warning << "render target texture format to QImage."; - return img; - } - - GLint samples = 0; - m_gl->functions()->glGetIntegerv(GL_SAMPLES, &samples); - if (samples > 0 && !m_glHelper->supportsFeature(GraphicsHelperInterface::BlitFramebuffer)) { - qCWarning(Backend) << Q_FUNC_INFO << "Unable to capture multisampled framebuffer; " - "Required feature BlitFramebuffer is missing."; - return img; - } - - img = QImage(rect.width(), rect.height(), imageFormat); - - QScopedArrayPointer<uchar> data(new uchar [bytes]); - - if (samples > 0) { - // resolve multisample-framebuffer to renderbuffer and read pixels from it - GLuint fbo, rb; - QOpenGLFunctions *gl = m_gl->functions(); - gl->glGenFramebuffers(1, &fbo); - gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); - gl->glGenRenderbuffers(1, &rb); - gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); - gl->glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, rect.width(), rect.height()); - gl->glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb); - - const GLenum status = gl->glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - gl->glDeleteRenderbuffers(1, &rb); - gl->glDeleteFramebuffers(1, &fbo); - qCWarning(Backend) << Q_FUNC_INFO << "Copy-framebuffer not complete: " << status; - return img; - } - - m_glHelper->blitFramebuffer(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), - 0, 0, rect.width(), rect.height(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); - gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); - gl->glReadPixels(0,0,rect.width(), rect.height(), format, type, data.data()); - - copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); - - gl->glBindRenderbuffer(GL_RENDERBUFFER, rb); - gl->glDeleteRenderbuffers(1, &rb); - gl->glBindFramebuffer(GL_FRAMEBUFFER, m_activeFBO); - gl->glDeleteFramebuffers(1, &fbo); - } else { - // read pixels directly from framebuffer - m_gl->functions()->glReadPixels(rect.x(), rect.y(), rect.width(), rect.height(), format, type, data.data()); - copyGLFramebufferDataToImage(img, data.data(), stride, rect.width(), rect.height(), m_renderTargetFormat); - } - - return img; -} - -void SubmissionContext::setViewport(const QRectF &viewport, const QSize &surfaceSize) -{ - // // save for later use; this has nothing to do with the viewport but it is - // // here that we get to know the surfaceSize from the RenderView. - m_surfaceSize = surfaceSize; - - m_viewport = viewport; - QSize size = renderTargetSize(surfaceSize); - - // Check that the returned size is before calling glViewport - if (size.isEmpty()) - return; - - // Qt3D 0------------------> 1 OpenGL 1^ - // | | - // | | - // | | - // V | - // 1 0---------------------> 1 - // The Viewport is defined between 0 and 1 which allows us to automatically - // scale to the size of the provided window surface - m_gl->functions()->glViewport(m_viewport.x() * size.width(), - (1.0 - m_viewport.y() - m_viewport.height()) * size.height(), - m_viewport.width() * size.width(), - m_viewport.height() * size.height()); -} - -void SubmissionContext::releaseOpenGL() -{ - m_renderBufferHash.clear(); - - // Stop and destroy the OpenGL logger - if (m_debugLogger) { - m_debugLogger->stopLogging(); - m_debugLogger.reset(nullptr); - } -} - -// The OpenGLContext is not current on any surface at this point -void SubmissionContext::setOpenGLContext(QOpenGLContext* ctx) -{ - Q_ASSERT(ctx); - - releaseOpenGL(); - m_gl = ctx; -} - -// Called only from RenderThread -bool SubmissionContext::activateShader(GLShader *shader) -{ - if (shader->shaderProgram() != m_activeShader) { - // Ensure material uniforms are re-applied - m_material = nullptr; - - m_activeShader = shader->shaderProgram(); - if (Q_LIKELY(m_activeShader != nullptr)) { - m_activeShader->bind(); - } else { - m_glHelper->useProgram(0); - qWarning() << "No shader program found"; - return false; - } - } - return true; -} - -void SubmissionContext::bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments) -{ - // Set FBO attachments. These are normally textures, except that on Open GL - // ES <= 3.1 we must use a renderbuffer if a combined depth+stencil is - // desired since this cannot be achieved neither with a single texture (not - // before GLES 3.2) nor with separate textures (no suitable format for - // stencil before 3.1 with the appropriate extension). - - QSize fboSize; - GLTextureManager *glTextureManager = m_renderer->glResourceManagers()->glTextureManager(); - const auto attachments_ = attachments.attachments(); - for (const Attachment &attachment : attachments_) { - GLTexture *rTex = glTextureManager->lookupResource(attachment.m_textureUuid); - if (!m_glHelper->frameBufferNeedsRenderBuffer(attachment)) { - QOpenGLTexture *glTex = rTex ? rTex->getGLTexture() : nullptr; - if (glTex != nullptr) { - // The texture can not be rendered simultaniously by another renderer - Q_ASSERT(!rTex->isExternalRenderingEnabled()); - if (fboSize.isEmpty()) - fboSize = QSize(glTex->width(), glTex->height()); - else - fboSize = QSize(qMin(fboSize.width(), glTex->width()), qMin(fboSize.height(), glTex->height())); - m_glHelper->bindFrameBufferAttachment(glTex, attachment); - } - } else { - RenderBuffer *renderBuffer = rTex ? rTex->getOrCreateRenderBuffer() : nullptr; - if (renderBuffer) { - if (fboSize.isEmpty()) - fboSize = QSize(renderBuffer->width(), renderBuffer->height()); - else - fboSize = QSize(qMin(fboSize.width(), renderBuffer->width()), qMin(fboSize.height(), renderBuffer->height())); - m_glHelper->bindFrameBufferAttachment(renderBuffer, attachment); - } - } - } - m_renderTargetsSize.insert(fboId, fboSize); -} - -void SubmissionContext::activateDrawBuffers(const AttachmentPack &attachments) -{ - const QVector<int> activeDrawBuffers = attachments.getGlDrawBuffers(); - - if (m_glHelper->checkFrameBufferComplete()) { - if (activeDrawBuffers.size() > 1) {// We need MRT - if (m_glHelper->supportsFeature(GraphicsHelperInterface::MRT)) { - // Set up MRT, glDrawBuffers... - m_glHelper->drawBuffers(activeDrawBuffers.size(), activeDrawBuffers.data()); - } - } - } else { - qCWarning(Backend) << "FBO incomplete"; - } -} - - -void SubmissionContext::setActiveMaterial(Material *rmat) -{ - if (m_material == rmat) - return; - - m_textureContext.deactivateTexturesWithScope(TextureSubmissionContext::TextureScopeMaterial); - m_imageContext.deactivateImages(); - m_material = rmat; -} - -void SubmissionContext::setCurrentStateSet(RenderStateSet *ss) -{ - if (ss == m_stateSet) - return; - if (ss) - applyStateSet(ss); - m_stateSet = ss; -} - -RenderStateSet *SubmissionContext::currentStateSet() const -{ - return m_stateSet; -} - -void SubmissionContext::applyState(const StateVariant &stateVariant) -{ - switch (stateVariant.type) { - - case AlphaCoverageStateMask: { - applyStateHelper<AlphaCoverage>(static_cast<const AlphaCoverage *>(stateVariant.constState()), this); - break; - } - case AlphaTestMask: { - applyStateHelper<AlphaFunc>(static_cast<const AlphaFunc *>(stateVariant.constState()), this); - break; - } - case BlendStateMask: { - applyStateHelper<BlendEquation>(static_cast<const BlendEquation *>(stateVariant.constState()), this); - break; - } - case BlendEquationArgumentsMask: { - applyStateHelper<BlendEquationArguments>(static_cast<const BlendEquationArguments *>(stateVariant.constState()), this); - break; - } - case MSAAEnabledStateMask: { - applyStateHelper<MSAAEnabled>(static_cast<const MSAAEnabled *>(stateVariant.constState()), this); - break; - } - - case CullFaceStateMask: { - applyStateHelper<CullFace>(static_cast<const CullFace *>(stateVariant.constState()), this); - break; - } - - case DepthWriteStateMask: { - applyStateHelper<NoDepthMask>(static_cast<const NoDepthMask *>(stateVariant.constState()), this); - break; - } - - case DepthTestStateMask: { - applyStateHelper<DepthTest>(static_cast<const DepthTest *>(stateVariant.constState()), this); - break; - } - - case DepthRangeMask: { - applyStateHelper<DepthRange>(static_cast<const DepthRange *>(stateVariant.constState()), this); - break; - } - - case RasterModeMask: { - applyStateHelper<RasterMode>(static_cast<const RasterMode *>(stateVariant.constState()), this); - break; - } - - case FrontFaceStateMask: { - applyStateHelper<FrontFace>(static_cast<const FrontFace *>(stateVariant.constState()), this); - break; - } - - case ScissorStateMask: { - applyStateHelper<ScissorTest>(static_cast<const ScissorTest *>(stateVariant.constState()), this); - break; - } - - case StencilTestStateMask: { - applyStateHelper<StencilTest>(static_cast<const StencilTest *>(stateVariant.constState()), this); - break; - } - - case PointSizeMask: { - applyStateHelper<PointSize>(static_cast<const PointSize *>(stateVariant.constState()), this); - break; - } - - case PolygonOffsetStateMask: { - applyStateHelper<PolygonOffset>(static_cast<const PolygonOffset *>(stateVariant.constState()), this); - break; - } - - case ColorStateMask: { - applyStateHelper<ColorMask>(static_cast<const ColorMask *>(stateVariant.constState()), this); - break; - } - - case ClipPlaneMask: { - applyStateHelper<ClipPlane>(static_cast<const ClipPlane *>(stateVariant.constState()), this); - break; - } - - case SeamlessCubemapMask: { - applyStateHelper<SeamlessCubemap>(static_cast<const SeamlessCubemap *>(stateVariant.constState()), this); - break; - } - - case StencilOpMask: { - applyStateHelper<StencilOp>(static_cast<const StencilOp *>(stateVariant.constState()), this); - break; - } - - case StencilWriteStateMask: { - applyStateHelper<StencilMask>(static_cast<const StencilMask *>(stateVariant.constState()), this); - break; - } - - case DitheringStateMask: { - applyStateHelper<Dithering>(static_cast<const Dithering *>(stateVariant.constState()), this); - break; - } - - case LineWidthMask: { - applyStateHelper<LineWidth>(static_cast<const LineWidth *>(stateVariant.constState()), this); - break; - } - default: - Q_UNREACHABLE(); - } -} - -void SubmissionContext::resetMasked(qint64 maskOfStatesToReset) -{ - // TO DO -> Call gcHelper methods instead of raw GL - // QOpenGLFunctions shouldn't be used here directly - QOpenGLFunctions *funcs = m_gl->functions(); - - if (maskOfStatesToReset & ScissorStateMask) - funcs->glDisable(GL_SCISSOR_TEST); - - if (maskOfStatesToReset & BlendStateMask) - funcs->glDisable(GL_BLEND); - - if (maskOfStatesToReset & StencilWriteStateMask) - funcs->glStencilMask(0); - - if (maskOfStatesToReset & StencilTestStateMask) - funcs->glDisable(GL_STENCIL_TEST); - - if (maskOfStatesToReset & DepthRangeMask) - depthRange(0.0f, 1.0f); - - if (maskOfStatesToReset & DepthTestStateMask) - funcs->glDisable(GL_DEPTH_TEST); - - if (maskOfStatesToReset & DepthWriteStateMask) - funcs->glDepthMask(GL_TRUE); // reset to default - - if (maskOfStatesToReset & FrontFaceStateMask) - funcs->glFrontFace(GL_CCW); // reset to default - - if (maskOfStatesToReset & CullFaceStateMask) - funcs->glDisable(GL_CULL_FACE); - - if (maskOfStatesToReset & DitheringStateMask) - funcs->glDisable(GL_DITHER); - - if (maskOfStatesToReset & AlphaCoverageStateMask) - setAlphaCoverageEnabled(false); - - if (maskOfStatesToReset & PointSizeMask) - pointSize(false, 1.0f); // reset to default - - if (maskOfStatesToReset & PolygonOffsetStateMask) - funcs->glDisable(GL_POLYGON_OFFSET_FILL); - - if (maskOfStatesToReset & ColorStateMask) - funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - if (maskOfStatesToReset & ClipPlaneMask) { - GLint max = maxClipPlaneCount(); - for (GLint i = 0; i < max; ++i) - disableClipPlane(i); - } - - if (maskOfStatesToReset & SeamlessCubemapMask) - setSeamlessCubemap(false); - - if (maskOfStatesToReset & StencilOpMask) - funcs->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - if (maskOfStatesToReset & LineWidthMask) - funcs->glLineWidth(1.0f); - -#ifndef QT_OPENGL_ES_2 - if (maskOfStatesToReset & RasterModeMask) - m_glHelper->rasterMode(GL_FRONT_AND_BACK, GL_FILL); -#endif -} - -void SubmissionContext::applyStateSet(RenderStateSet *ss) -{ - RenderStateSet* previousStates = currentStateSet(); - - const StateMaskSet invOurState = ~ss->stateMask(); - // generate a mask for each set bit in previous, where we do not have - // the corresponding bit set. - - StateMaskSet stateToReset = 0; - if (previousStates) { - stateToReset = previousStates->stateMask() & invOurState; - qCDebug(RenderStates) << "previous states " << QString::number(previousStates->stateMask(), 2); - } - qCDebug(RenderStates) << " current states " << QString::number(ss->stateMask(), 2) << "inverse " << QString::number(invOurState, 2) << " -> states to change: " << QString::number(stateToReset, 2); - - // Reset states that aren't active in the current state set - resetMasked(stateToReset); - - // Apply states that weren't in the previous state or that have - // different values - const QVector<StateVariant> statesToSet = ss->states(); - for (const StateVariant &ds : statesToSet) { - if (previousStates && previousStates->contains(ds)) - continue; - applyState(ds); - } -} - -void SubmissionContext::clearColor(const QColor &color) -{ - if (m_currClearColorValue != color) { - m_currClearColorValue = color; - m_gl->functions()->glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); - } -} - -void SubmissionContext::clearDepthValue(float depth) -{ - if (m_currClearDepthValue != depth) { - m_currClearDepthValue = depth; - m_gl->functions()->glClearDepthf(depth); - } -} - -void SubmissionContext::clearStencilValue(int stencil) -{ - if (m_currClearStencilValue != stencil) { - m_currClearStencilValue = stencil; - m_gl->functions()->glClearStencil(stencil); - } -} - -GLFence SubmissionContext::fenceSync() -{ - return m_glHelper->fenceSync(); -} - -void SubmissionContext::clientWaitSync(GLFence sync, GLuint64 nanoSecTimeout) -{ - qDebug() << Q_FUNC_INFO << sync; - m_glHelper->clientWaitSync(sync, nanoSecTimeout); -} - -void SubmissionContext::waitSync(GLFence sync) -{ - qDebug() << Q_FUNC_INFO << sync; - m_glHelper->waitSync(sync); -} - -bool SubmissionContext::wasSyncSignaled(GLFence sync) -{ - return m_glHelper->wasSyncSignaled(sync); -} - -void SubmissionContext::deleteSync(GLFence sync) -{ - m_glHelper->deleteSync(sync); -} - -// It will be easier if the QGraphicContext applies the QUniformPack -// than the other way around -bool SubmissionContext::setParameters(ShaderParameterPack ¶meterPack) -{ - static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight.irradiance")); - static const int specularId = StringToInt::lookupId(QLatin1String("envLight.specular")); - // Activate textures and update TextureUniform in the pack - // with the correct textureUnit - - // Set the pinned texture of the previous material texture - // to pinable so that we should easily find an available texture unit - m_textureContext.deactivateTexturesWithScope(TextureSubmissionContext::TextureScopeMaterial); - // Update the uniforms with the correct texture unit id's - PackUniformHash &uniformValues = parameterPack.uniforms(); - - // Fill Texture Uniform Value with proper texture units - // so that they can be applied as regular uniforms in a second step - for (int i = 0; i < parameterPack.textures().size(); ++i) { - const ShaderParameterPack::NamedResource &namedTex = parameterPack.textures().at(i); - // Given a Texture QNodeId, we retrieve the associated shared GLTexture - if (uniformValues.contains(namedTex.glslNameId)) { - GLTexture *t = m_renderer->glResourceManagers()->glTextureManager()->lookupResource(namedTex.nodeId); - if (t != nullptr) { - UniformValue &texUniform = uniformValues.value(namedTex.glslNameId); - if (texUniform.valueType() == UniformValue::TextureValue) { - const int texUnit = m_textureContext.activateTexture(TextureSubmissionContext::TextureScopeMaterial, m_gl, t); - texUniform.data<int>()[namedTex.uniformArrayIndex] = texUnit; - if (texUnit == -1) { - if (namedTex.glslNameId != irradianceId && - namedTex.glslNameId != specularId) { - // Only return false if we are not dealing with env light textures - qCWarning(Backend) << "Unable to find suitable Texture Unit"; - return false; - } - } - } - } - } - } - - // Fill Image Uniform Value with proper image units - // so that they can be applied as regular uniforms in a second step - for (int i = 0; i < parameterPack.images().size(); ++i) { - const ShaderParameterPack::NamedResource &namedTex = parameterPack.images().at(i); - // Given a Texture QNodeId, we retrieve the associated shared GLTexture - if (uniformValues.contains(namedTex.glslNameId)) { - ShaderImage *img = m_renderer->nodeManagers()->shaderImageManager()->lookupResource(namedTex.nodeId); - if (img != nullptr) { - GLTexture *t = m_renderer->glResourceManagers()->glTextureManager()->lookupResource(img->textureId()); - if (t == nullptr) { - qCWarning(Backend) << "Shader Image referencing invalid texture"; - continue; - } else { - UniformValue &imgUniform = uniformValues.value(namedTex.glslNameId); - if (imgUniform.valueType() == UniformValue::ShaderImageValue) { - const int imgUnit = m_imageContext.activateImage(img, t); - imgUniform.data<int>()[namedTex.uniformArrayIndex] = imgUnit; - if (imgUnit == -1) { - qCWarning(Backend) << "Unable to bind Image to Texture"; - return false; - } - } - } - } - } - } - - QOpenGLShaderProgram *shader = activeShader(); - - // TO DO: We could cache the binding points somehow and only do the binding when necessary - // for SSBO and UBO - - // Bind Shader Storage block to SSBO and update SSBO - const QVector<BlockToSSBO> blockToSSBOs = parameterPack.shaderStorageBuffers(); - for (const BlockToSSBO b : blockToSSBOs) { - Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); - GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer); - // bindShaderStorageBlock - // This is currently not required as we are introspecting the bindingIndex - // value from the shaders and not replacing them, making such a call useless - // bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex); - bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex); - // Needed to avoid conflict where the buffer would already - // be bound as a VertexArray - bindGLBuffer(ssbo, GLBuffer::ShaderStorageBuffer); - ssbo->bindBufferBase(this, b.m_bindingIndex, GLBuffer::ShaderStorageBuffer); - // TO DO: Make sure that there's enough binding points - } - - // Bind UniformBlocks to UBO and update UBO from Buffer - // TO DO: Convert ShaderData to Buffer so that we can use that generic process - const QVector<BlockToUBO> blockToUBOs = parameterPack.uniformBuffers(); - int uboIndex = 0; - for (const BlockToUBO &b : blockToUBOs) { - Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID); - GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer); - bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex); - // Needed to avoid conflict where the buffer would already - // be bound as a VertexArray - bindGLBuffer(ubo, GLBuffer::UniformBuffer); - ubo->bindBufferBase(this, uboIndex++, GLBuffer::UniformBuffer); - // TO DO: Make sure that there's enough binding points - } - - // Update uniforms in the Default Uniform Block - const PackUniformHash values = parameterPack.uniforms(); - const QVector<ShaderUniform> activeUniforms = parameterPack.submissionUniforms(); - - for (const ShaderUniform &uniform : activeUniforms) { - // We can use [] as we are sure the the uniform wouldn't - // be un activeUniforms if there wasn't a matching value - const UniformValue &v = values.value(uniform.m_nameId); - - // skip invalid textures/images - if ((v.valueType() == UniformValue::TextureValue || - v.valueType() == UniformValue::ShaderImageValue) && - *v.constData<int>() == -1) - continue; - - applyUniform(uniform, v); - } - // if not all data is valid, the next frame will be rendered immediately - return true; -} - -void SubmissionContext::enableAttribute(const VAOVertexAttribute &attr) -{ - // Bind buffer within the current VAO - GLBuffer *buf = m_renderer->glResourceManagers()->glBufferManager()->data(attr.bufferHandle); - Q_ASSERT(buf); - bindGLBuffer(buf, attr.attributeType); - - // Don't use QOpenGLShaderProgram::setAttributeBuffer() because of QTBUG-43199. - // Use the introspection data and set the attribute explicitly - m_glHelper->enableVertexAttributeArray(attr.location); - m_glHelper->vertexAttributePointer(attr.shaderDataType, - attr.location, - attr.vertexSize, - attr.dataType, - GL_TRUE, // TODO: Support normalization property on QAttribute - attr.byteStride, - reinterpret_cast<const void *>(qintptr(attr.byteOffset))); - - - // Done by the helper if it supports it - if (attr.divisor != 0) - m_glHelper->vertexAttribDivisor(attr.location, attr.divisor); -} - -void SubmissionContext::disableAttribute(const SubmissionContext::VAOVertexAttribute &attr) -{ - QOpenGLShaderProgram *prog = activeShader(); - prog->disableAttributeArray(attr.location); -} - -// Note: needs to be called while VAO is bound -void SubmissionContext::specifyAttribute(const Attribute *attribute, - Buffer *buffer, - const ShaderAttribute *attributeDescription) -{ - const int location = attributeDescription->m_location; - if (location < 0) { - qCWarning(Backend) << "failed to resolve location for attribute:" << attribute->name(); - return; - } - - const GLint attributeDataType = glDataTypeFromAttributeDataType(attribute->vertexBaseType()); - const HGLBuffer glBufferHandle = m_renderer->glResourceManagers()->glBufferManager()->lookupHandle(buffer->peerId()); - Q_ASSERT(!glBufferHandle.isNull()); - const GLBuffer::Type attributeType = attributeTypeToGLBufferType(attribute->attributeType()); - - int typeSize = 0; - int attrCount = 0; - - if (attribute->vertexSize() >= 1 && attribute->vertexSize() <= 4) { - attrCount = 1; - } else if (attribute->vertexSize() == 9) { - typeSize = byteSizeFromType(attributeDataType); - attrCount = 3; - } else if (attribute->vertexSize() == 16) { - typeSize = byteSizeFromType(attributeDataType); - attrCount = 4; - } else { - Q_UNREACHABLE(); - } - - Q_ASSERT(!glBufferHandle.isNull()); - VAOVertexAttribute attr; - attr.bufferHandle = glBufferHandle; - attr.attributeType = attributeType; - attr.dataType = attributeDataType; - attr.divisor = attribute->divisor(); - attr.vertexSize = attribute->vertexSize() / attrCount; - attr.byteStride = (attribute->byteStride() != 0) ? attribute->byteStride() : (attrCount * attrCount * typeSize); - attr.shaderDataType = attributeDescription->m_type; - - for (int i = 0; i < attrCount; i++) { - attr.location = location + i; - attr.byteOffset = attribute->byteOffset() + (i * attrCount * typeSize); - - enableAttribute(attr); - - // Save this in the current emulated VAO - if (m_currentVAO) - m_currentVAO->saveVertexAttribute(attr); - } -} - -void SubmissionContext::specifyIndices(Buffer *buffer) -{ - GLBuffer *buf = glBufferForRenderBuffer(buffer); - if (!bindGLBuffer(buf, GLBuffer::IndexBuffer)) - qCWarning(Backend) << Q_FUNC_INFO << "binding index buffer failed"; - - // bound within the current VAO - // Save this in the current emulated VAO - if (m_currentVAO) - m_currentVAO->saveIndexAttribute(m_renderer->glResourceManagers()->glBufferManager()->lookupHandle(buffer->peerId())); -} - -void SubmissionContext::updateBuffer(Buffer *buffer) -{ - const QHash<Qt3DCore::QNodeId, HGLBuffer>::iterator it = m_renderBufferHash.find(buffer->peerId()); - if (it != m_renderBufferHash.end()) - uploadDataToGLBuffer(buffer, m_renderer->glResourceManagers()->glBufferManager()->data(it.value())); -} - -QByteArray SubmissionContext::downloadBufferContent(Buffer *buffer) -{ - const QHash<Qt3DCore::QNodeId, HGLBuffer>::iterator it = m_renderBufferHash.find(buffer->peerId()); - if (it != m_renderBufferHash.end()) - return downloadDataFromGLBuffer(buffer, m_renderer->glResourceManagers()->glBufferManager()->data(it.value())); - return QByteArray(); -} - -void SubmissionContext::releaseBuffer(Qt3DCore::QNodeId bufferId) -{ - auto it = m_renderBufferHash.find(bufferId); - if (it != m_renderBufferHash.end()) { - HGLBuffer glBuffHandle = it.value(); - GLBuffer *glBuff = m_renderer->glResourceManagers()->glBufferManager()->data(glBuffHandle); - - Q_ASSERT(glBuff); - // Destroy the GPU resource - glBuff->destroy(this); - // Destroy the GLBuffer instance - m_renderer->glResourceManagers()->glBufferManager()->releaseResource(bufferId); - // Remove Id - HGLBuffer entry - m_renderBufferHash.erase(it); - } -} - -bool SubmissionContext::hasGLBufferForBuffer(Buffer *buffer) -{ - const QHash<Qt3DCore::QNodeId, HGLBuffer>::iterator it = m_renderBufferHash.find(buffer->peerId()); - return (it != m_renderBufferHash.end()); -} - -GLBuffer *SubmissionContext::glBufferForRenderBuffer(Buffer *buf) -{ - if (!m_renderBufferHash.contains(buf->peerId())) - m_renderBufferHash.insert(buf->peerId(), createGLBufferFor(buf)); - return m_renderer->glResourceManagers()->glBufferManager()->data(m_renderBufferHash.value(buf->peerId())); -} - -HGLBuffer SubmissionContext::createGLBufferFor(Buffer *buffer) -{ - GLBuffer *b = m_renderer->glResourceManagers()->glBufferManager()->getOrCreateResource(buffer->peerId()); - // b.setUsagePattern(static_cast<QOpenGLBuffer::UsagePattern>(buffer->usage())); - Q_ASSERT(b); - if (!b->create(this)) - qCWarning(Render::Io) << Q_FUNC_INFO << "buffer creation failed"; - - return m_renderer->glResourceManagers()->glBufferManager()->lookupHandle(buffer->peerId()); -} - -bool SubmissionContext::bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type) -{ - if (type == GLBuffer::ArrayBuffer && buffer == m_boundArrayBuffer) - return true; - - if (buffer->bind(this, type)) { - if (type == GLBuffer::ArrayBuffer) - m_boundArrayBuffer = buffer; - return true; - } - return false; -} - -void SubmissionContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer) -{ - if (!bindGLBuffer(b, GLBuffer::ArrayBuffer)) // We're uploading, the type doesn't matter here - qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed"; - // If the buffer is dirty (hence being called here) - // there are two possible cases - // * setData was called changing the whole data or functor (or the usage pattern) - // * partial buffer updates where received - - // TO DO: Handle usage pattern - QVector<Qt3DRender::QBufferUpdate> updates = std::move(buffer->pendingBufferUpdates()); - for (auto it = updates.begin(); it != updates.end(); ++it) { - auto update = it; - // We have a partial update - if (update->offset >= 0) { - //accumulate sequential updates as single one - int bufferSize = update->data.size(); - auto it2 = it + 1; - while ((it2 != updates.end()) - && (it2->offset - update->offset == bufferSize)) { - bufferSize += it2->data.size(); - ++it2; - } - update->data.resize(bufferSize); - while (it + 1 != it2) { - ++it; - update->data.replace(it->offset - update->offset, it->data.size(), it->data); - it->data.clear(); - } - // TO DO: based on the number of updates .., it might make sense to - // sometime use glMapBuffer rather than glBufferSubData - b->update(this, update->data.constData(), update->data.size(), update->offset); - } else { - // We have an update that was done by calling QBuffer::setData - // which is used to resize or entirely clear the buffer - // Note: we use the buffer data directly in that case - const int bufferSize = buffer->data().size(); - b->allocate(this, bufferSize, false); // orphan the buffer - b->allocate(this, buffer->data().constData(), bufferSize, false); - } - } - - if (releaseBuffer) { - b->release(this); - m_boundArrayBuffer = nullptr; - } - qCDebug(Render::Io) << "uploaded buffer size=" << buffer->data().size(); -} - -QByteArray SubmissionContext::downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b) -{ - if (!bindGLBuffer(b, GLBuffer::ArrayBuffer)) // We're downloading, the type doesn't matter here - qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed"; - - QByteArray data = b->download(this, buffer->data().size()); - return data; -} - -void SubmissionContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, - Qt3DCore::QNodeId outputRenderTargetId, - QRect inputRect, QRect outputRect, - uint defaultFboId, - QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, - QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, - QBlitFramebuffer::InterpolationMethod interpolationMethod) -{ - GLuint inputFboId = defaultFboId; - bool inputBufferIsDefault = true; - if (!inputRenderTargetId.isNull()) { - RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(inputRenderTargetId); - if (renderTarget) { - AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); - if (m_renderTargets.contains(inputRenderTargetId)) - inputFboId = updateRenderTarget(inputRenderTargetId, attachments, false); - else - inputFboId = createRenderTarget(inputRenderTargetId, attachments); - } - inputBufferIsDefault = false; - } - - GLuint outputFboId = defaultFboId; - bool outputBufferIsDefault = true; - if (!outputRenderTargetId.isNull()) { - RenderTarget *renderTarget = m_renderer->nodeManagers()->renderTargetManager()->lookupResource(outputRenderTargetId); - if (renderTarget) { - AttachmentPack attachments(renderTarget, m_renderer->nodeManagers()->attachmentManager()); - if (m_renderTargets.contains(outputRenderTargetId)) - outputFboId = updateRenderTarget(outputRenderTargetId, attachments, false); - else - outputFboId = createRenderTarget(outputRenderTargetId, attachments); - } - outputBufferIsDefault = false; - } - - // Up until this point the input and output rects are normal Qt rectangles. - // Convert them to GL rectangles (Y at bottom). - const int inputFboHeight = inputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[inputFboId].height(); - const GLint srcX0 = inputRect.left(); - const GLint srcY0 = inputFboHeight - (inputRect.top() + inputRect.height()); - const GLint srcX1 = srcX0 + inputRect.width(); - const GLint srcY1 = srcY0 + inputRect.height(); - - const int outputFboHeight = outputFboId == defaultFboId ? m_surfaceSize.height() : m_renderTargetsSize[outputFboId].height(); - const GLint dstX0 = outputRect.left(); - const GLint dstY0 = outputFboHeight - (outputRect.top() + outputRect.height()); - const GLint dstX1 = dstX0 + outputRect.width(); - const GLint dstY1 = dstY0 + outputRect.height(); - - //Get the last bounded framebuffers - const GLuint lastDrawFboId = boundFrameBufferObject(); - - // Activate input framebuffer for reading - bindFramebuffer(inputFboId, GraphicsHelperInterface::FBORead); - - // Activate output framebuffer for writing - bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); - - //Bind texture - if (!inputBufferIsDefault) - readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); - - if (!outputBufferIsDefault) { - // Note that we use glDrawBuffers, not glDrawBuffer. The - // latter is not available with GLES. - const int buf = outputAttachmentPoint; - drawBuffers(1, &buf); - } - - // Blit framebuffer - const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; - m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, - mode); - - // Reset draw buffer - bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); - if (outputAttachmentPoint != QRenderTargetOutput::Color0) { - const int buf = QRenderTargetOutput::Color0; - drawBuffers(1, &buf); - } -} - -} // namespace Render -} // namespace Qt3DRender of namespace - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h deleted file mode 100644 index e7a31e6ce..000000000 --- a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_SUBMISSIONCONTEXT_H -#define QT3DRENDER_RENDER_SUBMISSIONCONTEXT_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - - -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/texturesubmissioncontext_p.h> -#include <Qt3DRender/private/imagesubmissioncontext_p.h> -#include <Qt3DRender/qclearbuffers.h> -#include <Qt3DRender/private/glbuffer_p.h> -#include <Qt3DRender/qattribute.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/glfence_p.h> - -QT_BEGIN_NAMESPACE - -class QAbstractOpenGLFunctions; - -namespace Qt3DRender { - -namespace Render { - -class Renderer; -class GraphicsHelperInterface; -class RenderStateSet; -class Material; -class GLTexture; -class RenderCommand; -class RenderTarget; -class AttachmentPack; -class Attribute; -class Buffer; -class ShaderManager; -struct StateVariant; - -typedef QPair<QString, int> NamedUniformLocation; - -class Q_AUTOTEST_EXPORT SubmissionContext : public GraphicsContext -{ -public: - SubmissionContext(); - ~SubmissionContext(); - - int id() const; // unique, small integer ID of this context - void setRenderer(Renderer *renderer) { m_renderer = renderer; } - - bool beginDrawing(QSurface *surface); - void endDrawing(bool swapBuffers); - void releaseOpenGL(); - void setOpenGLContext(QOpenGLContext* ctx); - - // Viewport - void setViewport(const QRectF &viewport, const QSize &surfaceSize); - QRectF viewport() const { return m_viewport; } - - // Shaders - bool activateShader(GLShader *shader); - QOpenGLShaderProgram *activeShader() const { return m_activeShader; } - - // FBO - GLuint activeFBO() const { return m_activeFBO; } - void activateRenderTarget(const Qt3DCore::QNodeId id, const AttachmentPack &attachments, GLuint defaultFboId); - QSize renderTargetSize(const QSize &surfaceSize) const; - QImage readFramebuffer(const QRect &rect); - void blitFramebuffer(Qt3DCore::QNodeId outputRenderTargetId, Qt3DCore::QNodeId inputRenderTargetId, - QRect inputRect, - QRect outputRect, uint defaultFboId, - QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, - QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, - QBlitFramebuffer::InterpolationMethod interpolationMethod); - - // Attributes - void specifyAttribute(const Attribute *attribute, - Buffer *buffer, - const ShaderAttribute *attributeDescription); - void specifyIndices(Buffer *buffer); - - // Buffer - void updateBuffer(Buffer *buffer); - QByteArray downloadBufferContent(Buffer *buffer); - void releaseBuffer(Qt3DCore::QNodeId bufferId); - bool hasGLBufferForBuffer(Buffer *buffer); - GLBuffer *glBufferForRenderBuffer(Buffer *buf); - - // Parameters - bool setParameters(ShaderParameterPack ¶meterPack); - - // RenderState - void setCurrentStateSet(RenderStateSet* ss); - RenderStateSet *currentStateSet() const; - void applyState(const StateVariant &state); - - void resetMasked(qint64 maskOfStatesToReset); - void applyStateSet(RenderStateSet *ss); - - // Wrappers - void clearColor(const QColor &color); - void clearDepthValue(float depth); - void clearStencilValue(int stencil); - - - // Fences - GLFence fenceSync(); - void clientWaitSync(GLFence sync, GLuint64 nanoSecTimeout); - void waitSync(GLFence sync); - bool wasSyncSignaled(GLFence sync); - void deleteSync(GLFence sync); - -private: - void initialize(); - - // Material - Material* activeMaterial() const { return m_material; } - void setActiveMaterial(Material* rmat); - - // FBO - void bindFrameBufferAttachmentHelper(GLuint fboId, const AttachmentPack &attachments); - void activateDrawBuffers(const AttachmentPack &attachments); - void resolveRenderTargetFormat(); - GLuint createRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments); - GLuint updateRenderTarget(Qt3DCore::QNodeId renderTargetNodeId, const AttachmentPack &attachments, bool isActiveRenderTarget); - - // Buffers - HGLBuffer createGLBufferFor(Buffer *buffer); - void uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool releaseBuffer = false); - QByteArray downloadDataFromGLBuffer(Buffer *buffer, GLBuffer *b); - bool bindGLBuffer(GLBuffer *buffer, GLBuffer::Type type); - - bool m_ownCurrent; - const unsigned int m_id; - QSurface *m_surface; - QSize m_surfaceSize; - - QOpenGLShaderProgram *m_activeShader; - - QHash<Qt3DCore::QNodeId, HGLBuffer> m_renderBufferHash; - QHash<Qt3DCore::QNodeId, GLuint> m_renderTargets; - QHash<GLuint, QSize> m_renderTargetsSize; - QAbstractTexture::TextureFormat m_renderTargetFormat; - - // cache some current state, to make sure we don't issue unnecessary GL calls - int m_currClearStencilValue; - float m_currClearDepthValue; - QColor m_currClearColorValue; - - Material* m_material; - QRectF m_viewport; - GLuint m_activeFBO; - - GLBuffer *m_boundArrayBuffer; - RenderStateSet* m_stateSet; - Renderer *m_renderer; - QByteArray m_uboTempArray; - - TextureSubmissionContext m_textureContext; - ImageSubmissionContext m_imageContext; - - // Attributes - friend class OpenGLVertexArrayObject; - - struct VAOVertexAttribute - { - HGLBuffer bufferHandle; - GLBuffer::Type attributeType; - int location; - GLint dataType; - uint byteOffset; - uint vertexSize; - uint byteStride; - uint divisor; - GLenum shaderDataType; - }; - - using VAOIndexAttribute = HGLBuffer; - void enableAttribute(const VAOVertexAttribute &attr); - void disableAttribute(const VAOVertexAttribute &attr); -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_SUBMISSIONCONTEXT_H diff --git a/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp deleted file mode 100644 index 67d0f9976..000000000 --- a/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "texturesubmissioncontext_p.h" - -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/gltexture_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class TextureExtRendererLocker -{ -public: - static void lock(GLTexture *tex) - { - if (!tex->isExternalRenderingEnabled()) - return; - if (s_lockHash.keys().contains(tex)) { - ++s_lockHash[tex]; - } else { - tex->externalRenderingLock()->lock(); - s_lockHash[tex] = 1; - } - } - static void unlock(GLTexture *tex) - { - if (!tex->isExternalRenderingEnabled()) - return; - if (!s_lockHash.keys().contains(tex)) - return; - - --s_lockHash[tex]; - if (s_lockHash[tex] == 0) { - s_lockHash.remove(tex); - tex->externalRenderingLock()->unlock(); - } - } -private: - static QHash<GLTexture*, int> s_lockHash; -}; - -QHash<GLTexture*, int> TextureExtRendererLocker::s_lockHash = QHash<GLTexture*, int>(); - - -TextureSubmissionContext::TextureSubmissionContext() -{ - -} - -TextureSubmissionContext::~TextureSubmissionContext() -{ - -} - -void TextureSubmissionContext::initialize(GraphicsContext *context) -{ - m_activeTextures.resize(context->maxTextureUnitsCount()); -} - -void TextureSubmissionContext::endDrawing() -{ - decayTextureScores(); - for (int i = 0; i < m_activeTextures.size(); ++i) - if (m_activeTextures[i].texture) - TextureExtRendererLocker::unlock(m_activeTextures[i].texture); -} - -int TextureSubmissionContext::activateTexture(TextureSubmissionContext::TextureScope scope, - QOpenGLContext *m_gl, - GLTexture *tex) -{ - // Returns the texture unit to use for the texture - // This always return a valid unit, unless there are more textures than - // texture unit available for the current material - const int onUnit = assignUnitForTexture(tex); - - // check we didn't overflow the available units - if (onUnit == -1) - return -1; - - const int sharedTextureId = tex->sharedTextureId(); - // We have a valid texture id provided by a shared context - if (sharedTextureId > 0) { - m_gl->functions()->glActiveTexture(GL_TEXTURE0 + onUnit); - const QAbstractTexture::Target target = tex->properties().target; - // For now we know that target values correspond to the GL values - m_gl->functions()->glBindTexture(target, tex->sharedTextureId()); - } else { - // Texture must have been created and updated at this point - QOpenGLTexture *glTex = tex->getGLTexture(); - if (glTex == nullptr) - return -1; - glTex->bind(uint(onUnit)); - } - if (m_activeTextures[onUnit].texture != tex) { - if (m_activeTextures[onUnit].texture) - TextureExtRendererLocker::unlock(m_activeTextures[onUnit].texture); - m_activeTextures[onUnit].texture = tex; - TextureExtRendererLocker::lock(tex); - } - -#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG) - int err = m_gl->functions()->glGetError(); - if (err) - qCWarning(Backend) << "GL error after activating texture" << QString::number(err, 16) - << tex->getGLTexture()->textureId() << "on unit" << onUnit; -#endif - - m_activeTextures[onUnit].score = 200; - m_activeTextures[onUnit].pinned = true; - m_activeTextures[onUnit].scope = scope; - - return onUnit; -} - -void TextureSubmissionContext::deactivateTexturesWithScope(TextureSubmissionContext::TextureScope ts) -{ - for (int u=0; u<m_activeTextures.size(); ++u) { - if (!m_activeTextures[u].pinned) - continue; // inactive, ignore - - if (m_activeTextures[u].scope == ts) { - m_activeTextures[u].pinned = false; - m_activeTextures[u].score = qMax(m_activeTextures[u].score, 1) - 1; - } - } // of units iteration -} - -void TextureSubmissionContext::deactivateTexture(GLTexture* tex) -{ - for (int u=0; u<m_activeTextures.size(); ++u) { - if (m_activeTextures[u].texture == tex) { - Q_ASSERT(m_activeTextures[u].pinned); - m_activeTextures[u].pinned = false; - return; - } - } // of units iteration - - qCWarning(Backend) << Q_FUNC_INFO << "texture not active:" << tex; -} - -/*! - \internal - Returns a texture unit for a texture, -1 if all texture units are assigned. - Tries to use the texture unit with the texture that hasn't been used for the longest time - if the texture happens not to be already pinned on a texture unit. - */ -int TextureSubmissionContext::assignUnitForTexture(GLTexture *tex) -{ - int lowestScoredUnit = -1; - int lowestScore = 0xfffffff; - - for (int u=0; u<m_activeTextures.size(); ++u) { - if (m_activeTextures[u].texture == tex) - return u; - } - - for (int u=0; u<m_activeTextures.size(); ++u) { - // No texture is currently active on the texture unit - // we save the texture unit with the texture that has been on there - // the longest time while not being used - if (!m_activeTextures[u].pinned) { - int score = m_activeTextures[u].score; - if (score < lowestScore) { - lowestScore = score; - lowestScoredUnit = u; - } - } - } // of units iteration - - if (lowestScoredUnit == -1) - qCWarning(Backend) << Q_FUNC_INFO << "No free texture units!"; - - return lowestScoredUnit; -} - -void TextureSubmissionContext::decayTextureScores() -{ - for (int u = 0; u < m_activeTextures.size(); u++) - m_activeTextures[u].score = qMax(m_activeTextures[u].score - 1, 0); -} - -} // namespace Render -} // namespace Qt3DRender of namespace - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h deleted file mode 100644 index 3c84fe558..000000000 --- a/src/render/renderers/opengl/graphicshelpers/texturesubmissioncontext_p.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_TEXTURESUBMISSIONCONTEXT_H -#define QT3DRENDER_RENDER_TEXTURESUBMISSIONCONTEXT_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - - -#include <qglobal.h> -#include <QVector> - -QT_BEGIN_NAMESPACE - -class QOpenGLContext; - -namespace Qt3DRender { -namespace Render { - -class GraphicsContext; -class GLTexture; - -class Q_AUTOTEST_EXPORT TextureSubmissionContext -{ -public: - enum TextureScope - { - TextureScopeMaterial = 0, - TextureScopeTechnique - // per-pass for deferred rendering? - }; - - TextureSubmissionContext(); - ~TextureSubmissionContext(); - - void initialize(GraphicsContext *context); - void endDrawing(); - int activateTexture(TextureScope scope, QOpenGLContext *gl, GLTexture* tex); - void deactivateTexture(GLTexture *tex); - void deactivateTexturesWithScope(TextureScope ts); - -private: - void decayTextureScores(); - int assignUnitForTexture(GLTexture* tex); - - // active textures, indexed by texture unit - struct ActiveTexture { - GLTexture *texture = nullptr; - int score = 0; - TextureScope scope = TextureScopeMaterial; - bool pinned = false; - }; - QVector<ActiveTexture> m_activeTextures; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_TEXTURESUBMISSIONCONTEXT_H diff --git a/src/render/renderers/opengl/io/glbuffer.cpp b/src/render/renderers/opengl/io/glbuffer.cpp deleted file mode 100644 index f1b860f03..000000000 --- a/src/render/renderers/opengl/io/glbuffer.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glbuffer_p.h" -#include <private/graphicscontext_p.h> - -#if !defined(GL_UNIFORM_BUFFER) -#define GL_UNIFORM_BUFFER 0x8A11 -#endif -#if !defined(GL_ARRAY_BUFFER) -#define GL_ARRAY_BUFFER 0x8892 -#endif -#if !defined(GL_ELEMENT_ARRAY_BUFFER) -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#endif -#if !defined(GL_SHADER_STORAGE_BUFFER) -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#endif -#if !defined(GL_PIXEL_PACK_BUFFER) -#define GL_PIXEL_PACK_BUFFER 0x88EB -#endif -#if !defined(GL_PIXEL_UNPACK_BUFFER) -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#endif -#if !defined(GL_DRAW_INDIRECT_BUFFER) -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#endif - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -// A UBO is created for each ShaderData Shader Pair -// That means a UBO is unique to a shader/shaderdata - -namespace { - -GLenum glBufferTypes[] = { - GL_ARRAY_BUFFER, - GL_UNIFORM_BUFFER, - GL_ELEMENT_ARRAY_BUFFER, - GL_SHADER_STORAGE_BUFFER, - GL_PIXEL_PACK_BUFFER, - GL_PIXEL_UNPACK_BUFFER, - GL_DRAW_INDIRECT_BUFFER -}; - -} // anonymous - -GLBuffer::GLBuffer() - : m_bufferId(0) - , m_isCreated(false) - , m_bound(false) - , m_lastTarget(GL_ARRAY_BUFFER) -{ -} - -bool GLBuffer::bind(GraphicsContext *ctx, Type t) -{ - if (m_bufferId == 0) - return false; - m_lastTarget = glBufferTypes[t]; - ctx->openGLContext()->functions()->glBindBuffer(m_lastTarget, m_bufferId); - m_bound = true; - return true; -} - -bool GLBuffer::release(GraphicsContext *ctx) -{ - m_bound = false; - ctx->openGLContext()->functions()->glBindBuffer(m_lastTarget, 0); - return true; -} - -bool GLBuffer::create(GraphicsContext *ctx) -{ - ctx->openGLContext()->functions()->glGenBuffers(1, &m_bufferId); - m_isCreated = true; - return m_bufferId != 0; -} - -void GLBuffer::destroy(GraphicsContext *ctx) -{ - ctx->openGLContext()->functions()->glDeleteBuffers(1, &m_bufferId); - m_isCreated = false; -} - -void GLBuffer::allocate(GraphicsContext *ctx, uint size, bool dynamic) -{ - // Either GL_STATIC_DRAW OR GL_DYNAMIC_DRAW depending on the use case - // TO DO: find a way to know how a buffer/QShaderData will be used to use the right usage - ctx->openGLContext()->functions()->glBufferData(m_lastTarget, size, NULL, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); -} - -void GLBuffer::allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic) -{ - ctx->openGLContext()->functions()->glBufferData(m_lastTarget, size, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); -} - -void GLBuffer::update(GraphicsContext *ctx, const void *data, uint size, int offset) -{ - ctx->openGLContext()->functions()->glBufferSubData(m_lastTarget, offset, size, data); -} - -QByteArray GLBuffer::download(GraphicsContext *ctx, uint size) -{ - char *gpu_ptr = ctx->mapBuffer(m_lastTarget, size); - QByteArray data; - if (gpu_ptr != nullptr) { - data.resize(size); - std::copy(gpu_ptr, gpu_ptr+size, data.data()); - } - ctx->unmapBuffer(m_lastTarget); - return data; -} - -void GLBuffer::bindBufferBase(GraphicsContext *ctx, int bindingPoint, GLBuffer::Type t) -{ - ctx->bindBufferBase(glBufferTypes[t], bindingPoint, m_bufferId); -} - -void GLBuffer::bindBufferBase(GraphicsContext *ctx, int bindingPoint) -{ - ctx->bindBufferBase(m_lastTarget, bindingPoint, m_bufferId); -} - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/io/glbuffer_p.h b/src/render/renderers/opengl/io/glbuffer_p.h deleted file mode 100644 index 676fb00d9..000000000 --- a/src/render/renderers/opengl/io/glbuffer_p.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GLBUFFER_P_H -#define QT3DRENDER_RENDER_GLBUFFER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QOpenGLContext> -#include <Qt3DCore/qnodeid.h> -#include <qbytearray.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class GraphicsContext; - -class GLBuffer -{ -public: - GLBuffer(); - - enum Type - { - ArrayBuffer = 0, - UniformBuffer, - IndexBuffer, - ShaderStorageBuffer, - PixelPackBuffer, - PixelUnpackBuffer, - DrawIndirectBuffer - }; - - bool bind(GraphicsContext *ctx, Type t); - bool release(GraphicsContext *ctx); - bool create(GraphicsContext *ctx); - void destroy(GraphicsContext *ctx); - void allocate(GraphicsContext *ctx, uint size, bool dynamic = true); - void allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic = true); - void update(GraphicsContext *ctx, const void *data, uint size, int offset = 0); - QByteArray download(GraphicsContext *ctx, uint size); - void bindBufferBase(GraphicsContext *ctx, int bindingPoint, Type t); - void bindBufferBase(GraphicsContext *ctx, int bindingPoint); - - inline GLuint bufferId() const { return m_bufferId; } - inline bool isCreated() const { return m_isCreated; } - inline bool isBound() const { return m_bound; } - -#ifdef Q_OS_WIN - // To get MSVC to compile even though we don't need any cleanup - void cleanup() {} -#endif - -private: - GLuint m_bufferId; - bool m_isCreated; - bool m_bound; - GLenum m_lastTarget; -}; - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GLBUFFER_P_H diff --git a/src/render/renderers/opengl/io/io.pri b/src/render/renderers/opengl/io/io.pri deleted file mode 100644 index 462978c4d..000000000 --- a/src/render/renderers/opengl/io/io.pri +++ /dev/null @@ -1,8 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/glbuffer.cpp - -HEADERS += \ - $$PWD/glbuffer_p.h - diff --git a/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp b/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp deleted file mode 100644 index d2a01eef4..000000000 --- a/src/render/renderers/opengl/jobs/filtercompatibletechniquejob.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "filtercompatibletechniquejob_p.h" -#include <Qt3DRender/private/techniquemanager_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/job_common_p.h> -#include <Qt3DRender/private/submissioncontext_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -FilterCompatibleTechniqueJob::FilterCompatibleTechniqueJob() - : m_manager(nullptr) - , m_renderer(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::FilterCompatibleTechniques, 0) -} - -void FilterCompatibleTechniqueJob::setManager(TechniqueManager *manager) -{ - m_manager = manager; -} - -TechniqueManager *FilterCompatibleTechniqueJob::manager() const -{ - return m_manager; -} - -void FilterCompatibleTechniqueJob::setRenderer(Renderer *renderer) -{ - m_renderer = renderer; -} - -Renderer *FilterCompatibleTechniqueJob::renderer() const -{ - return m_renderer; -} - -void FilterCompatibleTechniqueJob::run() -{ - Q_ASSERT(m_manager != nullptr && m_renderer != nullptr); - Q_ASSERT(m_renderer->isRunning() && m_renderer->submissionContext()->isInitialized()); - - const QVector<Qt3DCore::QNodeId> dirtyTechniqueIds = m_manager->takeDirtyTechniques(); - for (const Qt3DCore::QNodeId techniqueId : dirtyTechniqueIds) { - Technique *technique = m_manager->lookupResource(techniqueId); - if (Q_LIKELY(technique != nullptr)) - technique->setCompatibleWithRenderer((*m_renderer->contextInfo() == *technique->graphicsApiFilter())); - } -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/jobs/filtercompatibletechniquejob_p.h b/src/render/renderers/opengl/jobs/filtercompatibletechniquejob_p.h deleted file mode 100644 index 27b3d4ed2..000000000 --- a/src/render/renderers/opengl/jobs/filtercompatibletechniquejob_p.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_FILTERCOMPATIBLETECHNIQUEJOB_H -#define QT3DRENDER_RENDER_FILTERCOMPATIBLETECHNIQUEJOB_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/qt3drender_global_p.h> - -#include <QSharedPointer> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class TechniqueManager; -class Renderer; - -class Q_3DRENDERSHARED_PRIVATE_EXPORT FilterCompatibleTechniqueJob : public Qt3DCore::QAspectJob -{ -public: - FilterCompatibleTechniqueJob(); - - void setManager(TechniqueManager *managers); - TechniqueManager *manager() const; - - void setRenderer(Renderer *renderer); - Renderer *renderer() const; - - void run() override; - -private: - TechniqueManager *m_manager; - Renderer *m_renderer; -}; - -typedef QSharedPointer<FilterCompatibleTechniqueJob> FilterCompatibleTechniqueJobPtr; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_FILTERCOMPATIBLETECHNIQUEJOB_H diff --git a/src/render/renderers/opengl/jobs/jobs.pri b/src/render/renderers/opengl/jobs/jobs.pri deleted file mode 100644 index d80b8bfd9..000000000 --- a/src/render/renderers/opengl/jobs/jobs.pri +++ /dev/null @@ -1,17 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/filtercompatibletechniquejob.cpp \ - $$PWD/materialparametergathererjob.cpp \ - $$PWD/renderviewcommandbuilderjob.cpp \ - $$PWD/renderviewcommandupdaterjob.cpp \ - $$PWD/renderviewinitializerjob.cpp \ - $$PWD/renderviewjobutils.cpp - -HEADERS += \ - $$PWD/filtercompatibletechniquejob_p.h \ - $$PWD/materialparametergathererjob_p.h \ - $$PWD/renderviewcommandbuilderjob_p.h \ - $$PWD/renderviewcommandupdaterjob_p.h \ - $$PWD/renderviewinitializerjob_p.h \ - $$PWD/renderviewjobutils_p.h diff --git a/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp b/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp deleted file mode 100644 index e1f8aa403..000000000 --- a/src/render/renderers/opengl/jobs/materialparametergathererjob.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "materialparametergathererjob_p.h" -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/renderpassfilternode_p.h> -#include <Qt3DRender/private/techniquefilternode_p.h> -#include <Qt3DRender/private/job_common_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace { - -int materialParameterGathererCounter = 0; -const int likelyNumberOfParameters = 24; - -} // anonymous - -MaterialParameterGathererJob::MaterialParameterGathererJob() - : Qt3DCore::QAspectJob() - , m_manager(nullptr) - , m_techniqueFilter(nullptr) - , m_renderPassFilter(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::MaterialParameterGathering, materialParameterGathererCounter++) -} - -// TechniqueFilter / RenderPassFilter - -// Parameters from Material/Effect/Technique - -// Note: we could maybe improve that by having a smart update when we detect -// that a parameter value has changed. That might require way more book keeping -// which might make this solution a bit too complex - -// The fact that this can now be performed in parallel should already provide a big -// improvement -void MaterialParameterGathererJob::run() -{ - for (const HMaterial &materialHandle : qAsConst(m_handles)) { - Material *material = m_manager->materialManager()->data(materialHandle); - - if (Q_UNLIKELY(!material->isEnabled())) - continue; - - Effect *effect = m_manager->effectManager()->lookupResource(material->effect()); - Technique *technique = findTechniqueForEffect(m_manager, m_techniqueFilter, effect); - - if (Q_LIKELY(technique != nullptr)) { - RenderPassList passes = findRenderPassesForTechnique(m_manager, m_renderPassFilter, technique); - if (Q_LIKELY(passes.size() > 0)) { - // Order set: - // 1 Pass Filter - // 2 Technique Filter - // 3 Material - // 4 Effect - // 5 Technique - // 6 RenderPass - - // Add Parameters define in techniqueFilter and passFilter - // passFilter have priority over techniqueFilter - - ParameterInfoList parameters; - // Doing the reserve allows a gain of 0.5ms on some of the demo examples - parameters.reserve(likelyNumberOfParameters); - - if (m_renderPassFilter) - parametersFromParametersProvider(¶meters, m_manager->parameterManager(), - m_renderPassFilter); - if (m_techniqueFilter) - parametersFromParametersProvider(¶meters, m_manager->parameterManager(), - m_techniqueFilter); - // Get the parameters for our selected rendering setup (override what was defined in the technique/pass filter) - parametersFromMaterialEffectTechnique(¶meters, m_manager->parameterManager(), material, effect, technique); - - for (RenderPass *renderPass : passes) { - ParameterInfoList globalParameters = parameters; - parametersFromParametersProvider(&globalParameters, m_manager->parameterManager(), renderPass); - m_parameters[material->peerId()].push_back({renderPass, globalParameters}); - } - } - } - } -} - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/jobs/materialparametergathererjob_p.h b/src/render/renderers/opengl/jobs/materialparametergathererjob_p.h deleted file mode 100644 index 6ba060841..000000000 --- a/src/render/renderers/opengl/jobs/materialparametergathererjob_p.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_MATERIALPARAMETERGATHERERJOB_P_H -#define QT3DRENDER_RENDER_MATERIALPARAMETERGATHERERJOB_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DCore/qnodeid.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/renderviewjobutils_p.h> -#include <Qt3DRender/private/qt3drender_global_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class NodeManagers; -class TechniqueFilter; -class RenderPassFilter; -class Renderer; - -// TO be executed for each FrameGraph branch with a given RenderPassFilter/TechniqueFilter - -class Q_3DRENDERSHARED_PRIVATE_EXPORT MaterialParameterGathererJob : public Qt3DCore::QAspectJob -{ -public: - MaterialParameterGathererJob(); - - inline void setNodeManagers(NodeManagers *manager) Q_DECL_NOTHROW { m_manager = manager; } - inline void setTechniqueFilter(TechniqueFilter *techniqueFilter) Q_DECL_NOTHROW { m_techniqueFilter = techniqueFilter; } - inline void setRenderPassFilter(RenderPassFilter *renderPassFilter) Q_DECL_NOTHROW { m_renderPassFilter = renderPassFilter; } - inline const QHash<Qt3DCore::QNodeId, QVector<RenderPassParameterData>> &materialToPassAndParameter() Q_DECL_NOTHROW { return m_parameters; } - inline void setHandles(const QVector<HMaterial> &handles) Q_DECL_NOTHROW { m_handles = handles; } - - inline TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_techniqueFilter; } - inline RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_renderPassFilter; } - - void run() final; - -private: - NodeManagers *m_manager; - TechniqueFilter *m_techniqueFilter; - RenderPassFilter *m_renderPassFilter; - - // Material id to array of RenderPasse with parameters - MaterialParameterGathererData m_parameters; - QVector<HMaterial> m_handles; -}; - -typedef QSharedPointer<MaterialParameterGathererJob> MaterialParameterGathererJobPtr; - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_MATERIALPARAMETERGATHERERJOB_P_H diff --git a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp deleted file mode 100644 index 091d49ef5..000000000 --- a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewcommandbuilderjob_p.h" -#include <Qt3DRender/private/job_common_p.h> -#include <Qt3DRender/private/renderview_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace { -int renderViewInstanceCounter = 0; -} // anonymous - -RenderViewCommandBuilderJob::RenderViewCommandBuilderJob() - : Qt3DCore::QAspectJob() - , m_offset(0) - , m_count(0) - , m_renderView(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewCommandBuilder, renderViewInstanceCounter++) -} - -void RenderViewCommandBuilderJob::run() -{ - if (!m_renderView->noDraw()) { - if (m_count == 0) - return; - - const bool isDraw = !m_renderView->isCompute(); - if (isDraw) - m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count); - else - m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count); - } -} - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h deleted file mode 100644 index 556c7f241..000000000 --- a/src/render/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H -#define QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/rendercommand_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class Q_AUTOTEST_EXPORT RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob -{ -public: - RenderViewCommandBuilderJob(); - - inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } - inline void setEntities(const QVector<Entity *> &entities, int offset, int count) - { - m_offset = offset; - m_count = count; - m_entities = entities; - } - inline EntityRenderCommandData &commandData() { return m_commandData; } - - void run() final; - -private: - int m_offset; - int m_count; - RenderView *m_renderView; - QVector<Entity *> m_entities; - EntityRenderCommandData m_commandData; -}; - -typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr; - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp deleted file mode 100644 index 6772279d7..000000000 --- a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewcommandupdaterjob_p.h" -#include <Qt3DRender/private/job_common_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/renderview_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace { -int renderViewInstanceCounter = 0; -} // anonymous - -RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob() - : Qt3DCore::QAspectJob() - , m_offset(0) - , m_count(0) - , m_renderView(nullptr) - , m_renderer(nullptr) - , m_renderables() -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++) -} - -void RenderViewCommandUpdaterJob::run() -{ - // Build RenderCommand should perform the culling as we have no way to determine - // if a child has a mesh in the view frustum while its parent isn't contained in it. - if (!m_renderView->noDraw()) { - if (m_count == 0) - return; - // Update Render Commands (Uniform Change, Depth Change) - m_renderView->updateRenderCommand(m_renderables.data(), m_offset, m_count); - } -} - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h b/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h deleted file mode 100644 index d7f424966..000000000 --- a/src/render/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H -#define QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/rendercommand_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class RenderView; -class Renderer; - -class Q_AUTOTEST_EXPORT RenderViewCommandUpdaterJob : public Qt3DCore::QAspectJob -{ -public: - RenderViewCommandUpdaterJob(); - - inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } - inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; } - inline void setRenderables(const EntityRenderCommandDataPtr &renderables, int offset, int count) Q_DECL_NOTHROW - { - m_offset = offset; - m_count = count; - m_renderables = renderables; - } - EntityRenderCommandDataPtr renderables() const { return m_renderables; } - - QVector<RenderCommand> &commands() Q_DECL_NOTHROW { return m_commands; } - - void run() final; - -private: - int m_offset; - int m_count; - RenderView *m_renderView; - Renderer *m_renderer; - EntityRenderCommandDataPtr m_renderables; - QVector<RenderCommand> m_commands; -}; - -typedef QSharedPointer<RenderViewCommandUpdaterJob> RenderViewCommandUpdaterJobPtr; - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H diff --git a/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp b/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp deleted file mode 100644 index f0f72803c..000000000 --- a/src/render/renderers/opengl/jobs/renderviewinitializerjob.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 Paul Lemire -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewinitializerjob_p.h" - -#include <Qt3DRender/private/renderview_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/renderviewjobutils_p.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/job_common_p.h> - -#include <QElapsedTimer> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -namespace { -// only accessed in ctor and dtor of RenderViewJob -// which are always being called in a non concurrent manner -int renderViewInstanceCounter = 0; -} // anonymous - -RenderViewInitializerJob::RenderViewInitializerJob() - : m_renderer(nullptr) - , m_fgLeaf(nullptr) - , m_index(0) - , m_renderView(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, renderViewInstanceCounter++) -} - -RenderViewInitializerJob::~RenderViewInitializerJob() -{ - renderViewInstanceCounter--; -} - -void RenderViewInitializerJob::run() -{ - qCDebug(Jobs) << Q_FUNC_INFO << m_index; -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) - QElapsedTimer timer; - timer.start(); - qint64 gatherLightsTime; - qint64 buildCommandsTime; -#endif - - // Create a RenderView object - // The RenderView are created from a QFrameAllocator stored in the current Thread local storage - m_renderView = new RenderView; - - // RenderView should allocate heap resources using only the currentFrameAllocator - m_renderView->setRenderer(m_renderer); - - // Populate the renderview's configuration from the framegraph - setRenderViewConfigFromFrameGraphLeafNode(m_renderView, m_fgLeaf); -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) - qint64 gatherStateTime = timer.nsecsElapsed(); - timer.restart(); -#endif -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/jobs/renderviewinitializerjob_p.h b/src/render/renderers/opengl/jobs/renderviewinitializerjob_p.h deleted file mode 100644 index fb4e2c67c..000000000 --- a/src/render/renderers/opengl/jobs/renderviewinitializerjob_p.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERVIEWINITIALIZERJOB_H -#define QT3DRENDER_RENDER_RENDERVIEWINITIALIZERJOB_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DCore/private/qframeallocator_p.h> -#include <QSize> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class Renderer; -class FrameGraphNode; -class RenderView; - -class Q_AUTOTEST_EXPORT RenderViewInitializerJob : public Qt3DCore::QAspectJob -{ -public: - RenderViewInitializerJob(); - ~RenderViewInitializerJob(); - - inline void setRenderer(Renderer *renderer) { m_renderer = renderer; } - inline RenderView *renderView() const Q_DECL_NOTHROW { return m_renderView; } - - inline void setFrameGraphLeafNode(FrameGraphNode *fgLeaf) - { - m_fgLeaf = fgLeaf; - } - - // Sets the position in the queue of RenderViews that the - // RenderView generated by this job should be inserted. This is - // used to ensure that for example a RenderView for creating - // a shadow map texture is submitted before the RenderView that - // contains commands making use of the shadow map - inline void setSubmitOrderIndex(int index) { m_index = index; } - inline int submitOrderIndex() const { return m_index; } - - void run() override; - -private: - Renderer *m_renderer; - FrameGraphNode *m_fgLeaf; - int m_index; - RenderView *m_renderView; -}; - -typedef QSharedPointer<RenderViewInitializerJob> RenderViewInitializerJobPtr; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERVIEWINITIALIZERJOB_H diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp deleted file mode 100644 index 16d449d4a..000000000 --- a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewjobutils_p.h" -#include "renderlogging_p.h" - -#include <Qt3DRender/qgraphicsapifilter.h> -#include <Qt3DRender/private/sphere_p.h> -#include <Qt3DRender/qshaderdata.h> - -#include <Qt3DRender/private/cameraselectornode_p.h> -#include <Qt3DRender/private/clearbuffers_p.h> -#include <Qt3DRender/private/layerfilternode_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/effect_p.h> -#include <Qt3DRender/private/renderpassfilternode_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/rendertargetselectornode_p.h> -#include <Qt3DRender/private/renderview_p.h> -#include <Qt3DRender/private/sortpolicy_p.h> -#include <Qt3DRender/private/techniquefilternode_p.h> -#include <Qt3DRender/private/viewportnode_p.h> -#include <Qt3DRender/private/shadervariables_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/shaderdata_p.h> -#include <Qt3DRender/private/statesetnode_p.h> -#include <Qt3DRender/private/dispatchcompute_p.h> -#include <Qt3DRender/private/rendersurfaceselector_p.h> -#include <Qt3DRender/private/rendercapture_p.h> -#include <Qt3DRender/private/buffercapture_p.h> -#include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DRender/private/techniquemanager_p.h> -#include <Qt3DRender/private/memorybarrier_p.h> -#include <Qt3DRender/private/blitframebuffer_p.h> -#include <Qt3DRender/private/waitfence_p.h> - -QT_BEGIN_NAMESPACE - -using namespace Qt3DCore; - -namespace Qt3DRender { -namespace Render { - -/*! - \internal - Walks up the framegraph tree from \a fgLeaf and builds up as much state - as possible and populates \a rv. For cases where we can't get the specific state - (e.g. because it depends upon more than just the framegraph) we store the data from - the framegraph that will be needed to later when the rest of the data becomes available -*/ -void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphNode *fgLeaf) -{ - // The specific RenderPass to be used is also dependent upon the Effect and TechniqueFilter - // which is referenced by the Material which is referenced by the RenderMesh. So we can - // only store the filter info in the RenderView structure and use it to do the resolving - // when we build the RenderCommand list. - const NodeManagers *manager = rv->nodeManagers(); - const FrameGraphNode *node = fgLeaf; - - while (node) { - FrameGraphNode::FrameGraphNodeType type = node->nodeType(); - if (node->isEnabled()) - switch (type) { - case FrameGraphNode::InvalidNodeType: - // A base FrameGraphNode, can be used for grouping purposes - break; - case FrameGraphNode::CameraSelector: - // Can be set only once and we take camera nearest to the leaf node - if (!rv->renderCameraLens()) { - const CameraSelector *cameraSelector = static_cast<const CameraSelector *>(node); - Entity *camNode = manager->renderNodesManager()->lookupResource(cameraSelector->cameraUuid()); - if (camNode) { - CameraLens *lens = camNode->renderComponent<CameraLens>(); - rv->setRenderCameraEntity(camNode); - if (lens && lens->isEnabled()) { - rv->setRenderCameraLens(lens); - // ViewMatrix and ProjectionMatrix are computed - // later in updateMatrices() - // since at this point the transformation matrices - // may not yet have been updated - } - } - } - break; - - case FrameGraphNode::LayerFilter: // Can be set multiple times in the tree - rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId()); - break; - - case FrameGraphNode::ProximityFilter: // Can be set multiple times in the tree - rv->appendProximityFilterId(node->peerId()); - break; - - case FrameGraphNode::RenderPassFilter: - // Can be set once - // TODO: Amalgamate all render pass filters from leaf to root - if (!rv->renderPassFilter()) - rv->setRenderPassFilter(static_cast<const RenderPassFilter *>(node)); - break; - - case FrameGraphNode::RenderTarget: { - // Can be set once and we take render target nearest to the leaf node - const RenderTargetSelector *targetSelector = static_cast<const RenderTargetSelector *>(node); - QNodeId renderTargetUid = targetSelector->renderTargetUuid(); - HTarget renderTargetHandle = manager->renderTargetManager()->lookupHandle(renderTargetUid); - - // Add renderTarget Handle and build renderCommand AttachmentPack - if (!rv->renderTargetId()) { - rv->setRenderTargetId(renderTargetUid); - - RenderTarget *renderTarget = manager->renderTargetManager()->data(renderTargetHandle); - if (renderTarget) - rv->setAttachmentPack(AttachmentPack(renderTarget, manager->attachmentManager(), targetSelector->outputs())); - } - break; - } - - case FrameGraphNode::ClearBuffers: { - const ClearBuffers *cbNode = static_cast<const ClearBuffers *>(node); - rv->addClearBuffers(cbNode); - break; - } - - case FrameGraphNode::TechniqueFilter: - // Can be set once - // TODO Amalgamate all technique filters from leaf to root - if (!rv->techniqueFilter()) - rv->setTechniqueFilter(static_cast<const TechniqueFilter *>(node)); - break; - - case FrameGraphNode::Viewport: { - // If the Viewport has already been set in a lower node - // Make it so that the new viewport is actually - // a subregion relative to that of the parent viewport - const ViewportNode *vpNode = static_cast<const ViewportNode *>(node); - rv->setViewport(ViewportNode::computeViewport(rv->viewport(), vpNode)); - rv->setGamma(vpNode->gamma()); - break; - } - - case FrameGraphNode::SortMethod: { - const Render::SortPolicy *sortPolicy = static_cast<const Render::SortPolicy *>(node); - rv->addSortType(sortPolicy->sortTypes()); - break; - } - - case FrameGraphNode::SubtreeEnabler: - // Has no meaning here. SubtreeEnabler was used - // in a prior step to filter the list of RenderViewJobs - break; - - case FrameGraphNode::StateSet: { - const Render::StateSetNode *rStateSet = static_cast<const Render::StateSetNode *>(node); - // Create global RenderStateSet for renderView if no stateSet was set before - RenderStateSet *stateSet = rv->stateSet(); - if (stateSet == nullptr && rStateSet->hasRenderStates()) { - stateSet = new RenderStateSet(); - rv->setStateSet(stateSet); - } - - // Add states from new stateSet we might be missing - // but don' t override existing states (lower StateSetNode always has priority) - if (rStateSet->hasRenderStates()) - addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); - break; - } - - case FrameGraphNode::NoDraw: { - rv->setNoDraw(true); - break; - } - - case FrameGraphNode::FrustumCulling: { - rv->setFrustumCulling(true); - break; - } - - case FrameGraphNode::ComputeDispatch: { - const Render::DispatchCompute *dispatchCompute = static_cast<const Render::DispatchCompute *>(node); - rv->setCompute(true); - rv->setComputeWorkgroups(dispatchCompute->x(), - dispatchCompute->y(), - dispatchCompute->z()); - break; - } - - case FrameGraphNode::Lighting: { - // TODO - break; - } - - case FrameGraphNode::Surface: { - // Use the surface closest to leaf node - if (rv->surface() == nullptr) { - const Render::RenderSurfaceSelector *surfaceSelector - = static_cast<const Render::RenderSurfaceSelector *>(node); - rv->setSurface(surfaceSelector->surface()); - rv->setSurfaceSize(surfaceSelector->renderTargetSize() * surfaceSelector->devicePixelRatio()); - rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio()); - } - break; - } - - case FrameGraphNode::DebugOverlay: - rv->setShowDebugOverlay(true); - break; - - case FrameGraphNode::RenderCapture: { - auto *renderCapture = const_cast<Render::RenderCapture *>( - static_cast<const Render::RenderCapture *>(node)); - if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { - rv->setRenderCaptureNodeId(renderCapture->peerId()); - rv->setRenderCaptureRequest(renderCapture->takeCaptureRequest()); - } - break; - } - - case FrameGraphNode::MemoryBarrier: { - const Render::MemoryBarrier *barrier = static_cast<const Render::MemoryBarrier *>(node); - rv->setMemoryBarrier(barrier->waitOperations()|rv->memoryBarrier()); - break; - } - - case FrameGraphNode::BufferCapture: { - auto *bufferCapture = const_cast<Render::BufferCapture *>( - static_cast<const Render::BufferCapture *>(node)); - if (bufferCapture != nullptr) - rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); - break; - } - - case FrameGraphNode::BlitFramebuffer: { - const Render::BlitFramebuffer *blitFramebufferNode = - static_cast<const Render::BlitFramebuffer *>(node); - rv->setHasBlitFramebufferInfo(true); - BlitFramebufferInfo bfbInfo; - bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); - bfbInfo.destinationRenderTargetId = blitFramebufferNode->destinationRenderTargetId(); - bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); - bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); - bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); - bfbInfo.destinationAttachmentPoint = blitFramebufferNode->destinationAttachmentPoint(); - bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); - rv->setBlitFrameBufferInfo(bfbInfo); - break; - } - - case FrameGraphNode::WaitFence: { - const Render::WaitFence *waitFence = static_cast<const Render::WaitFence *>(node); - rv->appendWaitFence(waitFence->data()); - break; - } - - case FrameGraphNode::SetFence: { - rv->appendInsertFenceId(node->peerId()); - break; - } - - case FrameGraphNode::NoPicking: - // Nothing to do RenderView wise for NoPicking - break; - - default: - // Should never get here - qCWarning(Backend) << "Unhandled FrameGraphNode type"; - } - - node = node->parent(); - } -} - -/*! - \internal - Searches the best matching Technique from \a effect specified. -*/ -Technique *findTechniqueForEffect(NodeManagers *manager, - const TechniqueFilter *techniqueFilter, - Effect *effect) -{ - if (!effect) - return nullptr; - - QVector<Technique*> matchingTechniques; - const bool hasInvalidTechniqueFilter = (techniqueFilter == nullptr || techniqueFilter->filters().isEmpty()); - - // Iterate through the techniques in the effect - const auto techniqueIds = effect->techniques(); - for (const QNodeId techniqueId : techniqueIds) { - Technique *technique = manager->techniqueManager()->lookupResource(techniqueId); - - // Should be valid, if not there likely a problem with node addition/destruction changes - Q_ASSERT(technique); - - // Check if the technique is compatible with the rendering API - // If no techniqueFilter is present, we return the technique as it satisfies OpenGL version - if (technique->isCompatibleWithRenderer() && (hasInvalidTechniqueFilter || technique->isCompatibleWithFilters(techniqueFilter->filters()))) - matchingTechniques.append(technique); - } - - if (matchingTechniques.size() == 0) // We failed to find a suitable technique to use :( - return nullptr; - - if (matchingTechniques.size() == 1) - return matchingTechniques.first(); - - // Several compatible techniques, return technique with highest major and minor version - Technique* highest = matchingTechniques.first(); - GraphicsApiFilterData filter = *highest->graphicsApiFilter(); - for (auto it = matchingTechniques.cbegin() + 1; it < matchingTechniques.cend(); ++it) { - if (filter < *(*it)->graphicsApiFilter()) { - filter = *(*it)->graphicsApiFilter(); - highest = *it; - } - } - return highest; -} - - -RenderPassList findRenderPassesForTechnique(NodeManagers *manager, - const RenderPassFilter *passFilter, - Technique *technique) -{ - Q_ASSERT(manager); - Q_ASSERT(technique); - - RenderPassList passes; - const auto passIds = technique->renderPasses(); - for (const QNodeId passId : passIds) { - RenderPass *renderPass = manager->renderPassManager()->lookupResource(passId); - - if (renderPass && renderPass->isEnabled()) { - bool foundMatch = (!passFilter || passFilter->filters().size() == 0); - - // A pass filter is present so we need to check for matching criteria - if (!foundMatch && renderPass->filterKeys().size() >= passFilter->filters().size()) { - - // Iterate through the filter criteria and look for render passes with criteria that satisfy them - const auto filterKeyIds = passFilter->filters(); - for (const QNodeId filterKeyId : filterKeyIds) { - foundMatch = false; - FilterKey *filterFilterKey = manager->filterKeyManager()->lookupResource(filterKeyId); - - const auto passFilterKeyIds = renderPass->filterKeys(); - for (const QNodeId passFilterKeyId : passFilterKeyIds) { - FilterKey *passFilterKey = manager->filterKeyManager()->lookupResource(passFilterKeyId); - if ((foundMatch = (*passFilterKey == *filterFilterKey))) - break; - } - - if (!foundMatch) { - // No match for criterion in any of the render pass' criteria - break; - } - } - } - - if (foundMatch) { - // Found a renderpass that satisfies our needs. Add it in order - passes << renderPass; - } - } - } - - return passes; -} - - -ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *params, const int nameId) -{ - const ParameterInfoList::const_iterator end = params->cend(); - ParameterInfoList::const_iterator it = std::lower_bound(params->cbegin(), end, nameId); - if (it != end && it->nameId != nameId) - return end; - return it; -} - -void addParametersForIds(ParameterInfoList *params, ParameterManager *manager, - const Qt3DCore::QNodeIdVector ¶meterIds) -{ - for (const QNodeId paramId : parameterIds) { - const HParameter parameterHandle = manager->lookupHandle(paramId); - const Parameter *param = manager->data(parameterHandle); - ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->nameId()); - if (it == params->end() || it->nameId != param->nameId()) - params->insert(it, ParameterInfo(param->nameId(), parameterHandle)); - } -} - -void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, - ParameterManager *manager, - Material *material, - Effect *effect, - Technique *technique) -{ - // The parameters are taken in the following priority order: - // - // 1) Material - // 2) Effect - // 3) Technique - // - // That way a user can override defaults in Effect's and Techniques on a - // object manner and a Technique can override global defaults from the Effect. - parametersFromParametersProvider(infoList, manager, material); - parametersFromParametersProvider(infoList, manager, effect); - parametersFromParametersProvider(infoList, manager, technique); -} - -// Only add states with types we don't already have -void addStatesToRenderStateSet(RenderStateSet *stateSet, - const QVector<Qt3DCore::QNodeId> stateIds, - RenderStateManager *manager) -{ - for (const Qt3DCore::QNodeId &stateId : stateIds) { - RenderStateNode *node = manager->lookupResource(stateId); - if (node->isEnabled() && stateSet->canAddStateOfType(node->type())) { - stateSet->addState(node->impl()); - } - } -} - -namespace { - -const QString blockArray = QStringLiteral("[%1]"); -const int qNodeIdTypeId = qMetaTypeId<QNodeId>(); - -} - -UniformBlockValueBuilder::UniformBlockValueBuilder() - : updatedPropertiesOnly(false) - , shaderDataManager(nullptr) - , textureManager(nullptr) -{ -} - -UniformBlockValueBuilder::~UniformBlockValueBuilder() -{ -} - -void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData, const QString &blockName, const QString &qmlPropertyName, const QVariant &value) -{ - // In the end, values are either scalar or a scalar array - // Composed elements (structs, structs array) are simplified into simple scalars - if (value.userType() == QMetaType::QVariantList) { // Array - QVariantList list = value.value<QVariantList>(); - if (list.at(0).userType() == qNodeIdTypeId) { // Array of struct qmlPropertyName[i].structMember - for (int i = 0; i < list.size(); ++i) { - const QVariant variantElement = list.at(i); - if (list.at(i).userType() == qNodeIdTypeId) { - const auto nodeId = variantElement.value<QNodeId>(); - ShaderData *subShaderData = shaderDataManager->lookupResource(nodeId); - if (subShaderData) { - buildActiveUniformNameValueMapStructHelper(subShaderData, - blockName + QLatin1Char('.') + qmlPropertyName + blockArray.arg(i), - QLatin1String("")); - } - // Note: we only handle ShaderData as nested container nodes here - } - } - } else { // Array of scalar/vec qmlPropertyName[0] - QString varName; - varName.reserve(blockName.length() + 1 + qmlPropertyName.length() + 3); - varName.append(blockName); - varName.append(QLatin1String(".")); - varName.append(qmlPropertyName); - varName.append(QLatin1String("[0]")); - if (uniforms.contains(varName)) { - qCDebug(Shaders) << "UBO array member " << varName << " set for update"; - activeUniformNamesToValue.insert(StringToInt::lookupId(varName), value); - } - } - } else if (value.userType() == qNodeIdTypeId) { // Struct qmlPropertyName.structMember - const auto nodeId = value.value<QNodeId>(); - ShaderData *rSubShaderData = shaderDataManager->lookupResource(nodeId); - if (rSubShaderData) { - buildActiveUniformNameValueMapStructHelper(rSubShaderData, - blockName, - qmlPropertyName); - } else if (textureManager->contains(nodeId)) { - const auto varId = StringToInt::lookupId(blockName + QLatin1Char('.') + qmlPropertyName); - activeUniformNamesToValue.insert(varId, value); - } - } else { // Scalar / Vec - QString varName; - varName.reserve(blockName.length() + 1 + qmlPropertyName.length()); - varName.append(blockName); - varName.append(QLatin1String(".")); - varName.append(qmlPropertyName); - if (uniforms.contains(varName)) { - qCDebug(Shaders) << "UBO scalar member " << varName << " set for update"; - - // If the property needs to be transformed, we transform it here as - // the shaderdata cannot hold transformed properties for multiple - // thread contexts at once - activeUniformNamesToValue.insert(StringToInt::lookupId(varName), - currentShaderData->getTransformedProperty(qmlPropertyName, viewMatrix)); - } - } -} - -void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(ShaderData *rShaderData, const QString &blockName, const QString &qmlPropertyName) -{ - const QHash<QString, ShaderData::PropertyValue> &properties = rShaderData->properties(); - auto it = properties.begin(); - const auto end = properties.end(); - - while (it != end) { - QString fullBlockName; - fullBlockName.reserve(blockName.length() + 1 + qmlPropertyName.length()); - fullBlockName.append(blockName); - if (!qmlPropertyName.isEmpty()) { - fullBlockName.append(QLatin1String(".")); - fullBlockName.append(qmlPropertyName); - } - buildActiveUniformNameValueMapHelper(rShaderData, fullBlockName, - it.key(), it.value().value); - ++it; - } -} - -ParameterInfo::ParameterInfo(const int nameId, const HParameter &handle) - : nameId(nameId) - , handle(handle) -{} - -bool ParameterInfo::operator<(const ParameterInfo &other) const Q_DECL_NOEXCEPT -{ - return nameId < other.nameId; -} - -bool ParameterInfo::operator<(const int otherNameId) const Q_DECL_NOEXCEPT -{ - return nameId < otherNameId; -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils_p.h b/src/render/renderers/opengl/jobs/renderviewjobutils_p.h deleted file mode 100644 index b2fa59785..000000000 --- a/src/render/renderers/opengl/jobs/renderviewjobutils_p.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDERVIEWJOBUTILS_P_H -#define QT3DRENDER_RENDERVIEWJOBUTILS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qt3drender_global.h> -#include <Qt3DCore/qnodeid.h> -#include <QtCore/qhash.h> -#include <QtCore/qvariant.h> -#include <QMatrix4x4> -#include <Qt3DRender/private/uniform_p.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/aligned_malloc_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DCore { -class QFrameAllocator; -} - -namespace Qt3DRender { -namespace Render { - -class FrameGraphNode; -class ParameterManager; -class Effect; -class Entity; -class Material; -class RenderPass; -class RenderStateSet; -class Technique; -class RenderView; -class TechniqueFilter; -class RenderPassFilter; -class Renderer; -class NodeManagers; -class ShaderDataManager; -struct ShaderUniform; -class ShaderData; -class TextureManager; -class RenderStateManager; -class RenderStateCollection; - -Q_AUTOTEST_EXPORT void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, - const FrameGraphNode *fgLeaf); - -Q_AUTOTEST_EXPORT Technique *findTechniqueForEffect(NodeManagers *manager, - const TechniqueFilter *techniqueFilter, - Effect *effect); - -typedef QVarLengthArray<RenderPass*, 4> RenderPassList; -Q_AUTOTEST_EXPORT RenderPassList findRenderPassesForTechnique(NodeManagers *manager, - const RenderPassFilter *passFilter, - Technique *technique); - -// Extracts the type T from a QVariant v without using QVariant::value which is slow -// Note: Assumes you are 100% sure about the type you requested -template<typename T> -inline T variant_value(const QVariant &v) -{ - return *reinterpret_cast<const T *>(v.data()); -} - -struct ParameterInfo -{ - explicit ParameterInfo(const int nameId = -1, const HParameter &handle = HParameter()); - - int nameId; - HParameter handle; - - bool operator<(const int otherNameId) const Q_DECL_NOEXCEPT; - bool operator<(const ParameterInfo &other) const Q_DECL_NOEXCEPT; -}; -typedef QVector<ParameterInfo> ParameterInfoList; - -struct RenderPassParameterData -{ - RenderPass *pass; - ParameterInfoList parameterInfo; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, RenderPassParameterData, Q_MOVABLE_TYPE) - -using MaterialParameterGathererData = QHash<Qt3DCore::QNodeId, QVector<RenderPassParameterData>>; - -Q_AUTOTEST_EXPORT void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, - ParameterManager *manager, - Material *material, - Effect *effect, - Technique *technique); - -Q_AUTOTEST_EXPORT void addParametersForIds(ParameterInfoList *params, ParameterManager *manager, - const QVector<Qt3DCore::QNodeId> ¶meterIds); - -template<class T> -void parametersFromParametersProvider(ParameterInfoList *infoList, - ParameterManager *manager, - T *provider) -{ - addParametersForIds(infoList, manager, provider->parameters()); -} - -Q_AUTOTEST_EXPORT ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *infoList, - const int nameId); - -Q_AUTOTEST_EXPORT void addStatesToRenderStateSet(RenderStateSet *stateSet, - const QVector<Qt3DCore::QNodeId> stateIds, - RenderStateManager *manager); - -typedef QHash<int, QVariant> UniformBlockValueBuilderHash; - -struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder -{ - UniformBlockValueBuilder(); - ~UniformBlockValueBuilder(); - - QT3D_ALIGNED_MALLOC_AND_FREE() - - void buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData, - const QString &blockName, - const QString &qmlPropertyName, - const QVariant &value); - void buildActiveUniformNameValueMapStructHelper(ShaderData *rShaderData, - const QString &blockName, - const QString &qmlPropertyName = QString()); - - bool updatedPropertiesOnly; - QHash<QString, ShaderUniform> uniforms; - UniformBlockValueBuilderHash activeUniformNamesToValue; - ShaderDataManager *shaderDataManager; - TextureManager *textureManager; - Matrix4x4 viewMatrix; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDERVIEWJOBUTILS_P_H diff --git a/src/render/renderers/opengl/managers/glresourcemanagers_p.h b/src/render/renderers/opengl/managers/glresourcemanagers_p.h deleted file mode 100644 index 8c4c46bca..000000000 --- a/src/render/renderers/opengl/managers/glresourcemanagers_p.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GLRESOURCEMANAGERS_P_H -#define QT3DRENDER_RENDER_GLRESOURCEMANAGERS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/private/qt3drender_global_p.h> -#include <Qt3DCore/private/qresourcemanager_p.h> -#include <Qt3DRender/private/gltexture_p.h> -#include <Qt3DRender/private/glbuffer_p.h> -#include <Qt3DRender/private/glfence_p.h> -#include <Qt3DRender/private/openglvertexarrayobject_p.h> -#include <Qt3DRender/private/glshader_p.h> -#include <Qt3DRender/private/apishadermanager_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class Q_AUTOTEST_EXPORT GLFenceManager : public QHash<Qt3DCore::QNodeId, GLFence> -{ -}; - -class Q_AUTOTEST_EXPORT VAOManager : public Qt3DCore::QResourceManager< - OpenGLVertexArrayObject, - VAOIdentifier, - Qt3DCore::NonLockingPolicy> -{ -public: - VAOManager() {} -}; - -class Q_AUTOTEST_EXPORT GLBufferManager : public Qt3DCore::QResourceManager< - GLBuffer, - Qt3DCore::QNodeId, - Qt3DCore::NonLockingPolicy> -{ -}; - -class Q_AUTOTEST_EXPORT GLTextureManager : public Qt3DCore::QResourceManager< - GLTexture, - Qt3DCore::QNodeId, - Qt3DCore::NonLockingPolicy> -{ -public: - QHash<GLTexture *, Qt3DCore::QNodeId> texNodeIdForGLTexture; -}; - -class Q_AUTOTEST_EXPORT GLShaderManager : public APIShaderManager<GLShader> -{ -public: - explicit GLShaderManager() - : APIShaderManager<GLShader>() - {} -}; - - -class Q_AUTOTEST_EXPORT GLResourceManagers -{ -public: - GLResourceManagers(); - ~GLResourceManagers(); - - inline VAOManager *vaoManager() const noexcept { return m_vaoManager; } - inline GLShaderManager *glShaderManager() const noexcept { return m_glShaderManager; } - inline GLTextureManager *glTextureManager() const noexcept { return m_glTextureManager; } - inline GLBufferManager *glBufferManager() const noexcept { return m_glBufferManager; } - inline GLFenceManager *glFenceManager() const noexcept { return m_glFenceManager; } - -private: - GLBufferManager *m_glBufferManager; - GLShaderManager *m_glShaderManager; - GLTextureManager *m_glTextureManager; - GLFenceManager *m_glFenceManager; - VAOManager *m_vaoManager; -}; - -} // Render - -} // Qt3DRender - -Q_DECLARE_RESOURCE_INFO(Qt3DRender::Render::OpenGLVertexArrayObject, Q_REQUIRES_CLEANUP) - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GLRESOURCEMANAGERS_P_H diff --git a/src/render/renderers/opengl/managers/managers.pri b/src/render/renderers/opengl/managers/managers.pri deleted file mode 100644 index 56a0732b1..000000000 --- a/src/render/renderers/opengl/managers/managers.pri +++ /dev/null @@ -1,9 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/gl_handle_types_p.h \ - $$PWD/glresourcemanagers_p.h - $$PWD/glshadermanager_p.h \ - -SOURCES += \ - $$PWD/glresourcemanagers.cpp diff --git a/src/render/renderers/opengl/opengl.pri b/src/render/renderers/opengl/opengl.pri deleted file mode 100644 index ad9d5c79a..000000000 --- a/src/render/renderers/opengl/opengl.pri +++ /dev/null @@ -1,15 +0,0 @@ - -include (renderer/renderer.pri) -include (jobs/jobs.pri) -include (io/io.pri) -include (textures/textures.pri) -include (graphicshelpers/graphicshelpers.pri) -include (renderstates/renderstates.pri) -include (managers/managers.pri) - -!integrity: include (debug/debug.pri) - -gcov { - QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage - QMAKE_LFLAGS += -fprofile-arcs -ftest-coverage -} diff --git a/src/render/renderers/opengl/renderer/glshader.cpp b/src/render/renderers/opengl/renderer/glshader.cpp deleted file mode 100644 index a6f118d65..000000000 --- a/src/render/renderers/opengl/renderer/glshader.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glshader_p.h" -#include <QMutexLocker> -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/stringtoint_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -GLShader::GLShader() - : m_isLoaded(false) - , m_graphicsContext(nullptr) -{ - m_shaderCode.resize(static_cast<int>(QShaderProgram::Compute) + 1); -} - -void GLShader::setGraphicsContext(GraphicsContext *context) -{ - QMutexLocker lock(&m_mutex); - m_graphicsContext = context; - if (m_graphicsContext) { - m_contextConnection = QObject::connect(m_graphicsContext->openGLContext(), - &QOpenGLContext::aboutToBeDestroyed, - [this] { setGraphicsContext(nullptr); }); - } -} - -GraphicsContext *GLShader::graphicsContext() -{ - QMutexLocker lock(&m_mutex); - return m_graphicsContext; -} - - -QVector<QString> GLShader::uniformsNames() const -{ - return m_uniformsNames; -} - -QVector<QString> GLShader::attributesNames() const -{ - return m_attributesNames; -} - -QVector<QString> GLShader::uniformBlockNames() const -{ - return m_uniformBlockNames; -} - -QVector<QString> GLShader::storageBlockNames() const -{ - return m_shaderStorageBlockNames; -} - -QVector<QByteArray> GLShader::shaderCode() const -{ - return m_shaderCode; -} - -QHash<QString, ShaderUniform> GLShader::activeUniformsForUniformBlock(int blockIndex) const -{ - return m_uniformBlockIndexToShaderUniforms.value(blockIndex); -} - -ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex) -{ - for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { - if (m_uniformBlocks[i].m_index == blockIndex) { - return m_uniformBlocks[i]; - } - } - return ShaderUniformBlock(); -} - -ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId) -{ - for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { - if (m_uniformBlocks[i].m_nameId == blockNameId) { - return m_uniformBlocks[i]; - } - } - return ShaderUniformBlock(); -} - -ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName) -{ - for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { - if (m_uniformBlocks[i].m_name == blockName) { - return m_uniformBlocks[i]; - } - } - return ShaderUniformBlock(); -} - -ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex) -{ - for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { - if (m_shaderStorageBlocks[i].m_index == blockIndex) - return m_shaderStorageBlocks[i]; - } - return ShaderStorageBlock(); -} - -ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId) -{ - for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { - if (m_shaderStorageBlocks[i].m_nameId == blockNameId) - return m_shaderStorageBlocks[i]; - } - return ShaderStorageBlock(); -} - -ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName) -{ - for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { - if (m_shaderStorageBlocks[i].m_name == blockName) - return m_shaderStorageBlocks[i]; - } - return ShaderStorageBlock(); -} - -void GLShader::prepareUniforms(ShaderParameterPack &pack) -{ - const PackUniformHash &values = pack.uniforms(); - - auto it = values.keys.cbegin(); - const auto end = values.keys.cend(); - - while (it != end) { - // Find if there's a uniform with the same name id - for (const ShaderUniform &uniform : qAsConst(m_uniforms)) { - if (uniform.m_nameId == *it) { - pack.setSubmissionUniform(uniform); - break; - } - } - ++it; - } -} - -void GLShader::setFragOutputs(const QHash<QString, int> &fragOutputs) -{ - { - QMutexLocker lock(&m_mutex); - m_fragOutputs = fragOutputs; - } -// updateDNA(); -} - -const QHash<QString, int> GLShader::fragOutputs() const -{ - QMutexLocker lock(&m_mutex); - return m_fragOutputs; -} - -void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescription) -{ - m_uniforms = uniformsDescription; - m_uniformsNames.resize(uniformsDescription.size()); - m_uniformsNamesIds.reserve(uniformsDescription.size()); - m_standardUniformNamesIds.reserve(5); - QHash<QString, ShaderUniform> activeUniformsInDefaultBlock; - - static const QVector<int> standardUniformNameIds = { - Shader::modelMatrixNameId, - Shader::viewMatrixNameId, - Shader::projectionMatrixNameId, - Shader::modelViewMatrixNameId, - Shader::viewProjectionMatrixNameId, - Shader::modelViewProjectionNameId, - Shader::mvpNameId, - Shader::inverseModelMatrixNameId, - Shader::inverseViewMatrixNameId, - Shader::inverseProjectionMatrixNameId, - Shader::inverseModelViewNameId, - Shader::inverseViewProjectionMatrixNameId, - Shader::inverseModelViewProjectionNameId, - Shader::modelNormalMatrixNameId, - Shader::modelViewNormalNameId, - Shader::viewportMatrixNameId, - Shader::inverseViewportMatrixNameId, - Shader::aspectRatioNameId, - Shader::exposureNameId, - Shader::gammaNameId, - Shader::timeNameId, - Shader::eyePositionNameId, - Shader::skinningPaletteNameId, - }; - - for (int i = 0, m = uniformsDescription.size(); i < m; i++) { - m_uniformsNames[i] = m_uniforms[i].m_name; - const int nameId = StringToInt::lookupId(m_uniformsNames[i]); - m_uniforms[i].m_nameId = nameId; - - // Is the uniform a Qt3D "Standard" uniform or a user defined one? - if (standardUniformNameIds.contains(nameId)) - m_standardUniformNamesIds.push_back(nameId); - else - m_uniformsNamesIds.push_back(nameId); - - if (uniformsDescription[i].m_blockIndex == -1) { // Uniform is in default block - qCDebug(Shaders) << "Active Uniform in Default Block " << uniformsDescription[i].m_name << uniformsDescription[i].m_blockIndex; - activeUniformsInDefaultBlock.insert(uniformsDescription[i].m_name, uniformsDescription[i]); - } - } - m_uniformBlockIndexToShaderUniforms.insert(-1, activeUniformsInDefaultBlock); -} - -void GLShader::initializeAttributes(const QVector<ShaderAttribute> &attributesDescription) -{ - m_attributes = attributesDescription; - m_attributesNames.resize(attributesDescription.size()); - m_attributeNamesIds.resize(attributesDescription.size()); - for (int i = 0, m = attributesDescription.size(); i < m; i++) { - m_attributesNames[i] = attributesDescription[i].m_name; - m_attributes[i].m_nameId = StringToInt::lookupId(m_attributesNames[i]); - m_attributeNamesIds[i] = m_attributes[i].m_nameId; - qCDebug(Shaders) << "Active Attribute " << attributesDescription[i].m_name; - } -} - -void GLShader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformBlockDescription) -{ - m_uniformBlocks = uniformBlockDescription; - m_uniformBlockNames.resize(uniformBlockDescription.size()); - m_uniformBlockNamesIds.resize(uniformBlockDescription.size()); - for (int i = 0, m = uniformBlockDescription.size(); i < m; ++i) { - m_uniformBlockNames[i] = m_uniformBlocks[i].m_name; - m_uniformBlockNamesIds[i] = StringToInt::lookupId(m_uniformBlockNames[i]); - m_uniformBlocks[i].m_nameId = m_uniformBlockNamesIds[i]; - qCDebug(Shaders) << "Initializing Uniform Block {" << m_uniformBlockNames[i] << "}"; - - // Find all active uniforms for the shader block - QVector<ShaderUniform>::const_iterator uniformsIt = m_uniforms.cbegin(); - const QVector<ShaderUniform>::const_iterator uniformsEnd = m_uniforms.cend(); - - QVector<QString>::const_iterator uniformNamesIt = m_uniformsNames.cbegin(); - const QVector<QString>::const_iterator uniformNamesEnd = m_attributesNames.cend(); - - QHash<QString, ShaderUniform> activeUniformsInBlock; - - while (uniformsIt != uniformsEnd && uniformNamesIt != uniformNamesEnd) { - if (uniformsIt->m_blockIndex == uniformBlockDescription[i].m_index) { - QString uniformName = *uniformNamesIt; - if (!m_uniformBlockNames[i].isEmpty() && !uniformName.startsWith(m_uniformBlockNames[i])) - uniformName = m_uniformBlockNames[i] + QLatin1Char('.') + *uniformNamesIt; - activeUniformsInBlock.insert(uniformName, *uniformsIt); - qCDebug(Shaders) << "Active Uniform Block " << uniformName << " in block " << m_uniformBlockNames[i] << " at index " << uniformsIt->m_blockIndex; - } - ++uniformsIt; - ++uniformNamesIt; - } - m_uniformBlockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, activeUniformsInBlock); - } -} - -void GLShader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription) -{ - m_shaderStorageBlocks = shaderStorageBlockDescription; - m_shaderStorageBlockNames.resize(shaderStorageBlockDescription.size()); - m_shaderStorageBlockNamesIds.resize(shaderStorageBlockDescription.size()); - - for (int i = 0, m = shaderStorageBlockDescription.size(); i < m; ++i) { - m_shaderStorageBlockNames[i] = m_shaderStorageBlocks[i].m_name; - m_shaderStorageBlockNamesIds[i] = StringToInt::lookupId(m_shaderStorageBlockNames[i]); - m_shaderStorageBlocks[i].m_nameId =m_shaderStorageBlockNamesIds[i]; - qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] << "}"; - } -} - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/glshader_p.h b/src/render/renderers/opengl/renderer/glshader_p.h deleted file mode 100644 index dec085291..000000000 --- a/src/render/renderers/opengl/renderer/glshader_p.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GLSHADER_P_H -#define QT3DRENDER_RENDER_GLSHADER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - - -#include <Qt3DRender/private/shadervariables_p.h> -#include <Qt3DRender/private/shaderparameterpack_p.h> -#include <Qt3DRender/qshaderprogram.h> -#include <QMutex> - - -QT_BEGIN_NAMESPACE - -class QOpenGLShaderProgram; - -namespace Qt3DRender { - -namespace Render { - -class Q_AUTOTEST_EXPORT GLShader -{ -public: - GLShader(); - - void setGraphicsContext(GraphicsContext *context); - GraphicsContext *graphicsContext(); - - bool isLoaded() const { return m_isLoaded; } - void setLoaded(bool loaded) { m_isLoaded = loaded; } - - void prepareUniforms(ShaderParameterPack &pack); - - void setFragOutputs(const QHash<QString, int> &fragOutputs); - const QHash<QString, int> fragOutputs() const; - - inline QVector<int> uniformsNamesIds() const { return m_uniformsNamesIds; } - inline QVector<int> standardUniformNameIds() const { return m_standardUniformNamesIds; } - inline QVector<int> uniformBlockNamesIds() const { return m_uniformBlockNamesIds; } - inline QVector<int> storageBlockNamesIds() const { return m_shaderStorageBlockNamesIds; } - inline QVector<int> attributeNamesIds() const { return m_attributeNamesIds; } - - QVector<QString> uniformsNames() const; - QVector<QString> attributesNames() const; - QVector<QString> uniformBlockNames() const; - QVector<QString> storageBlockNames() const; - - inline QVector<ShaderUniform> uniforms() const { return m_uniforms; } - inline QVector<ShaderAttribute> attributes() const { return m_attributes; } - inline QVector<ShaderUniformBlock> uniformBlocks() const { return m_uniformBlocks; } - inline QVector<ShaderStorageBlock> storageBlocks() const { return m_shaderStorageBlocks; } - - QHash<QString, ShaderUniform> activeUniformsForUniformBlock(int blockIndex) const; - - ShaderUniformBlock uniformBlockForBlockIndex(int blockNameId); - ShaderUniformBlock uniformBlockForBlockNameId(int blockIndex); - ShaderUniformBlock uniformBlockForBlockName(const QString &blockName); - - ShaderStorageBlock storageBlockForBlockIndex(int blockIndex); - ShaderStorageBlock storageBlockForBlockNameId(int blockNameId); - ShaderStorageBlock storageBlockForBlockName(const QString &blockName); - - QOpenGLShaderProgram *shaderProgram() { return &m_shader; } - - void setShaderCode(const QVector<QByteArray> shaderCode) { m_shaderCode = shaderCode; } - QVector<QByteArray> shaderCode() const; - -private: - bool m_isLoaded; - QOpenGLShaderProgram m_shader; - GraphicsContext *m_graphicsContext; - - QVector<QString> m_uniformsNames; - QVector<int> m_uniformsNamesIds; - QVector<int> m_standardUniformNamesIds; - QVector<ShaderUniform> m_uniforms; - - QVector<QString> m_attributesNames; - QVector<int> m_attributeNamesIds; - QVector<ShaderAttribute> m_attributes; - - QVector<QString> m_uniformBlockNames; - QVector<int> m_uniformBlockNamesIds; - QVector<ShaderUniformBlock> m_uniformBlocks; - QHash<int, QHash<QString, ShaderUniform> > m_uniformBlockIndexToShaderUniforms; - - QVector<QString> m_shaderStorageBlockNames; - QVector<int> m_shaderStorageBlockNamesIds; - QVector<ShaderStorageBlock> m_shaderStorageBlocks; - - QHash<QString, int> m_fragOutputs; - QVector<QByteArray> m_shaderCode; - - // Private so that only GraphicContext can call it - void initializeUniforms(const QVector<ShaderUniform> &uniformsDescription); - void initializeAttributes(const QVector<ShaderAttribute> &attributesDescription); - void initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformBlockDescription); - void initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription); - - friend class GraphicsContext; - - mutable QMutex m_mutex; - QMetaObject::Connection m_contextConnection; -}; - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GLSHADER_P_H diff --git a/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp b/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp deleted file mode 100644 index 25a850a79..000000000 --- a/src/render/renderers/opengl/renderer/openglvertexarrayobject.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "openglvertexarrayobject_p.h" -#include <Qt3DRender/private/submissioncontext_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/glresourcemanagers_p.h> -#include <Qt3DRender/private/managers_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -OpenGLVertexArrayObject::OpenGLVertexArrayObject() - : m_ctx(nullptr) - , m_specified(false) - , m_supportsVao(false) -{} - -void OpenGLVertexArrayObject::bind() -{ - Q_ASSERT(m_ctx); - if (m_supportsVao) { - Q_ASSERT(!m_vao.isNull()); - Q_ASSERT(m_vao->isCreated()); - m_vao->bind(); - } else { - // Unbind any other VAO that may have been bound and not released correctly - if (m_ctx->m_currentVAO != nullptr && m_ctx->m_currentVAO != this) - m_ctx->m_currentVAO->release(); - - m_ctx->m_currentVAO = this; - // We need to specify array and vertex attributes - for (const SubmissionContext::VAOVertexAttribute &attr : qAsConst(m_vertexAttributes)) - m_ctx->enableAttribute(attr); - if (!m_indexAttribute.isNull()) - m_ctx->bindGLBuffer(m_ctx->m_renderer->glResourceManagers()->glBufferManager()->data(m_indexAttribute), - GLBuffer::IndexBuffer); - } -} - -void OpenGLVertexArrayObject::release() -{ - Q_ASSERT(m_ctx); - if (m_supportsVao) { - Q_ASSERT(!m_vao.isNull()); - Q_ASSERT(m_vao->isCreated()); - m_vao->release(); - } else { - if (m_ctx->m_currentVAO == this) { - for (const SubmissionContext::VAOVertexAttribute &attr : qAsConst(m_vertexAttributes)) - m_ctx->disableAttribute(attr); - m_ctx->m_currentVAO = nullptr; - } - } -} - -// called from Render thread -void OpenGLVertexArrayObject::create(SubmissionContext *ctx, const VAOIdentifier &key) -{ - QMutexLocker lock(&m_mutex); - - Q_ASSERT(!m_ctx && !m_vao); - - m_ctx = ctx; - m_supportsVao = m_ctx->supportsVAO(); - if (m_supportsVao) { - m_vao.reset(new QOpenGLVertexArrayObject()); - m_vao->create(); - } - m_owners = key; -} - -VAOIdentifier OpenGLVertexArrayObject::key() const -{ - return m_owners; -} - -// called from Render thread -void OpenGLVertexArrayObject::destroy() -{ - QMutexLocker locker(&m_mutex); - - Q_ASSERT(m_ctx); - cleanup(); -} - -void OpenGLVertexArrayObject::cleanup() -{ - m_vao.reset(); - m_ctx = nullptr; - m_specified = false; - m_supportsVao = false; - m_indexAttribute = SubmissionContext::VAOIndexAttribute(); - m_vertexAttributes.clear(); -} - -// called from job -bool OpenGLVertexArrayObject::isAbandoned(GeometryManager *geomMgr, GLShaderManager *shaderMgr) -{ - QMutexLocker lock(&m_mutex); - - if (!m_ctx) - return false; - - const bool geometryExists = (geomMgr->data(m_owners.first) != nullptr); - const bool shaderExists = (shaderMgr->lookupResource(m_owners.second) != nullptr); - - return !geometryExists || !shaderExists; -} - -void OpenGLVertexArrayObject::saveVertexAttribute(const SubmissionContext::VAOVertexAttribute &attr) -{ - // Remove any vertexAttribute already at location - for (auto i = m_vertexAttributes.size() - 1; i >= 0; --i) { - if (m_vertexAttributes.at(i).location == attr.location) { - m_vertexAttributes.removeAt(i); - break; - } - } - m_vertexAttributes.push_back(attr); -} - - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h b/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h deleted file mode 100644 index 362c699da..000000000 --- a/src/render/renderers/opengl/renderer/openglvertexarrayobject_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef OPENGLVERTEXARRAYOBJECT_H -#define OPENGLVERTEXARRAYOBJECT_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/qopenglvertexarrayobject.h> -#include <Qt3DRender/private/submissioncontext_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -class GeometryManager; -class GLShaderManager; - -typedef QPair<HGeometry, Qt3DCore::QNodeId> VAOIdentifier; - -class OpenGLVertexArrayObject -{ -public: - OpenGLVertexArrayObject(); - - void bind(); - void release(); - - void create(SubmissionContext *ctx, const VAOIdentifier &key); - VAOIdentifier key() const; - void destroy(); - void cleanup(); - - bool isAbandoned(GeometryManager *geomMgr, GLShaderManager *shaderMgr); - - QOpenGLVertexArrayObject *vao() { return m_vao.data(); } - const QOpenGLVertexArrayObject *vao() const { return m_vao.data(); } - - void setSpecified(bool b) { m_specified = b; } - bool isSpecified() const { return m_specified; } - - -private: - QMutex m_mutex; - SubmissionContext *m_ctx; - QScopedPointer<QOpenGLVertexArrayObject> m_vao; - bool m_specified; - bool m_supportsVao; - VAOIdentifier m_owners; - - friend class SubmissionContext; - - void saveVertexAttribute(const SubmissionContext::VAOVertexAttribute &attr); - inline void saveIndexAttribute(HGLBuffer glBufferHandle) { m_indexAttribute = glBufferHandle; } - - QVector<SubmissionContext::VAOVertexAttribute> m_vertexAttributes; - SubmissionContext::VAOIndexAttribute m_indexAttribute; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // OPENGLVERTEXARRAYOBJECT_H diff --git a/src/render/renderers/opengl/renderer/rendercommand.cpp b/src/render/renderers/opengl/renderer/rendercommand.cpp deleted file mode 100644 index c6d42fde1..000000000 --- a/src/render/renderers/opengl/renderer/rendercommand.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "rendercommand_p.h" - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -RenderCommand::RenderCommand() - : m_glShader(nullptr) - , m_stateSet(nullptr) - , m_depth(0.0f) - , m_changeCost(0) - , m_type(RenderCommand::Draw) - , m_primitiveCount(0) - , m_primitiveType(QGeometryRenderer::Triangles) - , m_restartIndexValue(-1) - , m_firstInstance(0) - , m_firstVertex(0) - , m_verticesPerPatch(0) - , m_instanceCount(0) - , m_indexOffset(0) - , m_indexAttributeByteOffset(0) - , m_indexAttributeDataType(GL_UNSIGNED_SHORT) - , m_indirectAttributeByteOffset(0) - , m_drawIndexed(false) - , m_drawIndirect(false) - , m_primitiveRestartEnabled(false) - , m_isValid(false) -{ - m_workGroups[0] = 0; - m_workGroups[1] = 0; - m_workGroups[2] = 0; -} - -bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept -{ - return (a.m_vao == b.m_vao && a.m_glShader == b.m_glShader && a.m_material == b.m_material && - a.m_stateSet == b.m_stateSet && a.m_geometry == b.m_geometry && a.m_geometryRenderer == b.m_geometryRenderer && - a.m_indirectDrawBuffer == b.m_indirectDrawBuffer && a.m_activeAttributes == b.m_activeAttributes && - a.m_depth == b.m_depth && a.m_changeCost == b.m_changeCost && a.m_shaderId == b.m_shaderId && - a.m_workGroups[0] == b.m_workGroups[0] && a.m_workGroups[1] == b.m_workGroups[1] && a.m_workGroups[2] == b.m_workGroups[2] && - a.m_primitiveCount == b.m_primitiveCount && a.m_primitiveType == b.m_primitiveType && a.m_restartIndexValue == b.m_restartIndexValue && - a.m_firstInstance == b.m_firstInstance && a.m_firstVertex == b.m_firstVertex && a.m_verticesPerPatch == b.m_verticesPerPatch && - a.m_instanceCount == b.m_instanceCount && a.m_indexOffset == b.m_indexOffset && a.m_indexAttributeByteOffset == b.m_indexAttributeByteOffset && - a.m_drawIndexed == b.m_drawIndexed && a.m_drawIndirect == b.m_drawIndirect && a.m_primitiveRestartEnabled == b.m_primitiveRestartEnabled && - a.m_isValid == b.m_isValid && a.m_computeCommand == b.m_computeCommand); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/rendercommand_p.h b/src/render/renderers/opengl/renderer/rendercommand_p.h deleted file mode 100644 index 44e34ecfb..000000000 --- a/src/render/renderers/opengl/renderer/rendercommand_p.h +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERCOMMAND_H -#define QT3DRENDER_RENDER_RENDERCOMMAND_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qglobal.h> -#include <Qt3DRender/private/shaderparameterpack_p.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/renderviewjobutils_p.h> -#include <Qt3DRender/private/gl_handle_types_p.h> -#include <Qt3DRender/qgeometryrenderer.h> -#include <QOpenGLShaderProgram> -#include <QOpenGLTexture> -#include <QMatrix4x4> - -QT_BEGIN_NAMESPACE - -class QOpenGLVertexArrayObject; - -namespace Qt3DRender { - -namespace Render { - -class RenderStateSet; -using RenderStateSetPtr = QSharedPointer<RenderStateSet>; -class GLShader; - -class Q_AUTOTEST_EXPORT RenderCommand -{ -public: - RenderCommand(); - - HVao m_vao; // VAO used during the submission step to store all states and VBOs - HMaterial m_material; // Purely used to ease sorting (minimize stage changes, binding changes ....) - GLShader *m_glShader; // GL Shader to be used at render time - Qt3DCore::QNodeId m_shaderId; // Shader for given pass and mesh - ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy the - // Texture while submission is happening. - RenderStateSetPtr m_stateSet; - - HGeometry m_geometry; - HGeometryRenderer m_geometryRenderer; - - HBuffer m_indirectDrawBuffer; // Reference to indirect draw buffer (valid only m_drawIndirect == true) - HComputeCommand m_computeCommand; - - // A QAttribute pack might be interesting - // This is a temporary fix in the meantime, to remove the hacked methods in Technique - QVector<int> m_activeAttributes; - - float m_depth; - int m_changeCost; - - enum CommandType { - Draw, - Compute - }; - - CommandType m_type; - int m_workGroups[3]; - - // Values filled for draw calls by Renderer (in prepare Submission) - GLsizei m_primitiveCount; - QGeometryRenderer::PrimitiveType m_primitiveType; - int m_restartIndexValue; - int m_firstInstance; - int m_firstVertex; - int m_verticesPerPatch; - int m_instanceCount; - int m_indexOffset; - uint m_indexAttributeByteOffset; - GLint m_indexAttributeDataType; - uint m_indirectAttributeByteOffset; - bool m_drawIndexed; - bool m_drawIndirect; - bool m_primitiveRestartEnabled; - bool m_isValid; -}; - -Q_AUTOTEST_EXPORT bool operator==(const RenderCommand &a, const RenderCommand &b) noexcept; - -inline bool operator!=(const RenderCommand &lhs, const RenderCommand &rhs) noexcept -{ return !operator==(lhs, rhs); } - -struct EntityRenderCommandData -{ - QVector<Entity *> entities; - QVector<RenderCommand> commands; - QVector<RenderPassParameterData> passesData; - - void reserve(int size) - { - entities.reserve(size); - commands.reserve(size); - passesData.reserve(size); - } - - inline int size() const { return entities.size(); } - - inline void push_back(Entity *e, const RenderCommand &c, const RenderPassParameterData &p) - { - entities.push_back(e); - commands.push_back(c); - passesData.push_back(p); - } - - inline void push_back(Entity *e, RenderCommand &&c, RenderPassParameterData &&p) - { - entities.push_back(e); - commands.push_back(std::move(c)); - passesData.push_back(std::move(p)); - } - - EntityRenderCommandData &operator+=(EntityRenderCommandData &&t) - { - entities += std::move(t.entities); - commands += std::move(t.commands); - passesData += std::move(t.passesData); - return *this; - } - -}; - -using EntityRenderCommandDataPtr = QSharedPointer<EntityRenderCommandData>; - - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERCOMMAND_H diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp deleted file mode 100644 index 680040f54..000000000 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ /dev/null @@ -1,2458 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderer_p.h" - -#include <Qt3DCore/qentity.h> - -#include <Qt3DRender/qmaterial.h> -#include <Qt3DRender/qmesh.h> -#include <Qt3DRender/qrenderpass.h> -#include <Qt3DRender/qshaderprogram.h> -#include <Qt3DRender/qtechnique.h> -#include <Qt3DRender/qrenderaspect.h> -#include <Qt3DRender/qeffect.h> - -#include <Qt3DRender/private/qsceneimporter_p.h> -#include <Qt3DRender/private/renderstates_p.h> -#include <Qt3DRender/private/cameraselectornode_p.h> -#include <Qt3DRender/private/framegraphvisitor_p.h> -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/cameralens_p.h> -#include <Qt3DRender/private/rendercommand_p.h> -#include <Qt3DRender/private/entity_p.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/material_p.h> -#include <Qt3DRender/private/renderpassfilternode_p.h> -#include <Qt3DRender/private/renderqueue_p.h> -#include <Qt3DRender/private/shader_p.h> -#include <Qt3DRender/private/buffer_p.h> -#include <Qt3DRender/private/glbuffer_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/technique_p.h> -#include <Qt3DRender/private/renderthread_p.h> -#include <Qt3DRender/private/renderview_p.h> -#include <Qt3DRender/private/scenemanager_p.h> -#include <Qt3DRender/private/techniquefilternode_p.h> -#include <Qt3DRender/private/viewportnode_p.h> -#include <Qt3DRender/private/vsyncframeadvanceservice_p.h> -#include <Qt3DRender/private/pickeventfilter_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/buffermanager_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/gltexture_p.h> -#include <Qt3DRender/private/geometryrenderermanager_p.h> -#include <Qt3DRender/private/techniquemanager_p.h> -#include <Qt3DRender/private/openglvertexarrayobject_p.h> -#include <Qt3DRender/private/platformsurfacefilter_p.h> -#include <Qt3DRender/private/loadbufferjob_p.h> -#include <Qt3DRender/private/rendercapture_p.h> -#include <Qt3DRender/private/updatelevelofdetailjob_p.h> -#include <Qt3DRender/private/buffercapture_p.h> -#include <Qt3DRender/private/offscreensurfacehelper_p.h> -#include <Qt3DRender/private/renderviewbuilder_p.h> -#include <Qt3DRender/private/setfence_p.h> -#include <Qt3DRender/private/subtreeenabler_p.h> -#include <Qt3DRender/private/qshaderprogrambuilder_p.h> -#include <Qt3DRender/private/qshaderprogram_p.h> -#include <Qt3DRender/private/filterentitybycomponentjob_p.h> -#include <Qt3DRender/private/commandexecuter_p.h> -#ifndef Q_OS_INTEGRITY -#include <Qt3DRender/private/imguirenderer_p.h> -#endif - -#include <Qt3DRender/private/glresourcemanagers_p.h> -#include <Qt3DRender/private/resourceaccessor_p.h> - -#include <Qt3DRender/qcameralens.h> -#include <Qt3DCore/private/qeventfilterservice_p.h> -#include <Qt3DCore/private/qabstractaspectjobmanager_p.h> -#include <Qt3DCore/private/qaspectmanager_p.h> -#include <Qt3DCore/private/qsysteminformationservice_p.h> -#include <Qt3DCore/private/qsysteminformationservice_p_p.h> - -#include <QStack> -#include <QOffscreenSurface> -#include <QSurface> -#include <QElapsedTimer> -#include <QLibraryInfo> -#include <QMutexLocker> -#include <QPluginLoader> -#include <QDir> -#include <QUrl> -#include <QOffscreenSurface> -#include <QWindow> -#include <QThread> - -#include <QtGui/private/qopenglcontext_p.h> -#include <Qt3DRender/private/frameprofiler_p.h> - -QT_BEGIN_NAMESPACE - -// Crashes on AMD Radeon drivers on Windows. Disable for now. -//#define SHADER_LOADING_IN_COMMAND_THREAD - -using namespace Qt3DCore; - -namespace Qt3DRender { -namespace Render { - -namespace { - -class SyncLightsGatherer -{ -public: - explicit SyncLightsGatherer(LightGathererPtr gatherJob, - RendererCache *cache) - : m_gatherJob(gatherJob) - , m_cache(cache) - { - } - - void operator()() - { - QMutexLocker lock(m_cache->mutex()); - m_cache->gatheredLights = m_gatherJob->lights(); - m_cache->environmentLight = m_gatherJob->takeEnvironmentLight(); - } - -private: - LightGathererPtr m_gatherJob; - RendererCache *m_cache; -}; - -class SyncRenderableEntities -{ -public: - explicit SyncRenderableEntities(RenderableEntityFilterPtr gatherJob, - RendererCache *cache) - : m_gatherJob(gatherJob) - , m_cache(cache) - { - } - - void operator()() - { - QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities(); - std::sort(selectedEntities.begin(), selectedEntities.end()); - - QMutexLocker lock(m_cache->mutex()); - m_cache->renderableEntities = selectedEntities; - } - -private: - RenderableEntityFilterPtr m_gatherJob; - RendererCache *m_cache; -}; - -class SyncComputableEntities -{ -public: - explicit SyncComputableEntities(ComputableEntityFilterPtr gatherJob, - RendererCache *cache) - : m_gatherJob(gatherJob) - , m_cache(cache) - { - } - - void operator()() - { - QVector<Entity *> selectedEntities = m_gatherJob->filteredEntities(); - std::sort(selectedEntities.begin(), selectedEntities.end()); - - QMutexLocker lock(m_cache->mutex()); - m_cache->computeEntities = selectedEntities; - } - -private: - ComputableEntityFilterPtr m_gatherJob; - RendererCache *m_cache; -}; - -} // anonymous - - -/*! - \internal - - Renderer shutdown procedure: - - Since the renderer relies on the surface and OpenGLContext to perform its cleanup, - it is shutdown when the surface is set to nullptr - - When the surface is set to nullptr this will request the RenderThread to terminate - and will prevent createRenderBinJobs from returning a set of jobs as there is nothing - more to be rendered. - - In turn, this will call shutdown which will make the OpenGL context current one last time - to allow cleanups requiring a call to QOpenGLContext::currentContext to execute properly. - At the end of that function, the GraphicsContext is set to null. - - At this point though, the QAspectThread is still running its event loop and will only stop - a short while after. - */ - -Renderer::Renderer(QRenderAspect::RenderType type) - : m_services(nullptr) - , m_nodesManager(nullptr) - , m_renderSceneRoot(nullptr) - , m_defaultRenderStateSet(nullptr) - , m_submissionContext(nullptr) - , m_renderQueue(new RenderQueue()) - , m_renderThread(type == QRenderAspect::Threaded ? new RenderThread(this) : nullptr) - , m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr)) - , m_waitForInitializationToBeCompleted(0) - , m_hasBeenInitializedMutex() - , m_pickEventFilter(new PickEventFilter()) - , m_exposed(0) - , m_lastFrameCorrect(0) - , m_glContext(nullptr) - , m_shareContext(nullptr) - , m_pickBoundingVolumeJob(PickBoundingVolumeJobPtr::create()) - , m_rayCastingJob(RayCastingJobPtr::create()) - , m_time(0) - , m_settings(nullptr) - , m_updateShaderDataTransformJob(Render::UpdateShaderDataTransformJobPtr::create()) - , m_cleanupJob(Render::FrameCleanupJobPtr::create()) - , m_worldTransformJob(Render::UpdateWorldTransformJobPtr::create()) - , m_expandBoundingVolumeJob(Render::ExpandBoundingVolumeJobPtr::create()) - , m_calculateBoundingVolumeJob(Render::CalculateBoundingVolumeJobPtr::create()) - , m_updateWorldBoundingVolumeJob(Render::UpdateWorldBoundingVolumeJobPtr::create()) - , m_updateTreeEnabledJob(Render::UpdateTreeEnabledJobPtr::create()) - , m_sendBufferCaptureJob(Render::SendBufferCaptureJobPtr::create()) - , m_updateSkinningPaletteJob(Render::UpdateSkinningPaletteJobPtr::create()) - , m_updateLevelOfDetailJob(Render::UpdateLevelOfDetailJobPtr::create()) - , m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create()) - , m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create()) - , m_updateEntityLayersJob(Render::UpdateEntityLayersJobPtr::create()) - , m_lightGathererJob(Render::LightGathererPtr::create()) - , m_renderableEntityFilterJob(Render::RenderableEntityFilterPtr::create()) - , m_computableEntityFilterJob(Render::ComputableEntityFilterPtr::create()) - , m_bufferGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering)) - , m_vaoGathererJob(SynchronizerJobPtr::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering)) - , m_textureGathererJob(SynchronizerJobPtr::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) - , m_sendSetFenceHandlesToFrontendJob(SynchronizerJobPtr::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) - , m_introspectShaderJob(SynchronizerPostFramePtr::create([this] { reloadDirtyShaders(); }, - [this] (Qt3DCore::QAspectManager *m) { sendShaderChangesToFrontend(m); }, - JobTypes::DirtyShaderGathering)) - , m_syncLoadingJobs(SynchronizerJobPtr::create([] {}, JobTypes::SyncLoadingJobs)) - , m_cacheRenderableEntitiesJob(SynchronizerJobPtr::create(SyncRenderableEntities(m_renderableEntityFilterJob, &m_cache), - JobTypes::EntityComponentTypeFiltering)) - , m_cacheComputableEntitiesJob(SynchronizerJobPtr::create(SyncComputableEntities(m_computableEntityFilterJob, &m_cache), - JobTypes::EntityComponentTypeFiltering)) - , m_cacheLightsJob(SynchronizerJobPtr::create(SyncLightsGatherer(m_lightGathererJob, &m_cache), - JobTypes::EntityComponentTypeFiltering)) - , m_ownedContext(false) - , m_offscreenHelper(nullptr) - , m_glResourceManagers(nullptr) - , m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this)) - , m_shouldSwapBuffers(true) - , m_imGuiRenderer(nullptr) - , m_jobsInLastFrame(0) -{ - // Set renderer as running - it will wait in the context of the - // RenderThread for RenderViews to be submitted - m_running.fetchAndStoreOrdered(1); - if (m_renderThread) - m_renderThread->waitForStart(); - - // Create jobs to update transforms and bounding volumes - // We can only update bounding volumes once all world transforms are known - m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob); - m_updateWorldBoundingVolumeJob->addDependency(m_calculateBoundingVolumeJob); - m_expandBoundingVolumeJob->addDependency(m_updateWorldBoundingVolumeJob); - m_updateShaderDataTransformJob->addDependency(m_worldTransformJob); - m_pickBoundingVolumeJob->addDependency(m_expandBoundingVolumeJob); - m_rayCastingJob->addDependency(m_expandBoundingVolumeJob); - // m_calculateBoundingVolumeJob's dependency on m_updateTreeEnabledJob is set in renderBinJobs - - // Ensures all skeletons are loaded before we try to update them - m_updateSkinningPaletteJob->addDependency(m_syncLoadingJobs); - - // All world stuff depends on the RenderEntity's localBoundingVolume - m_updateLevelOfDetailJob->addDependency(m_updateMeshTriangleListJob); - m_pickBoundingVolumeJob->addDependency(m_updateMeshTriangleListJob); - m_rayCastingJob->addDependency(m_updateMeshTriangleListJob); - - m_introspectShaderJob->addDependency(m_filterCompatibleTechniqueJob); - - m_cacheLightsJob->addDependency(m_lightGathererJob); - m_cacheRenderableEntitiesJob->addDependency(m_renderableEntityFilterJob); - m_cacheComputableEntitiesJob->addDependency(m_computableEntityFilterJob); - - m_filterCompatibleTechniqueJob->setRenderer(this); - - m_defaultRenderStateSet = new RenderStateSet; - m_defaultRenderStateSet->addState(StateVariant::createState<DepthTest>(GL_LESS)); - m_defaultRenderStateSet->addState(StateVariant::createState<CullFace>(GL_BACK)); - m_defaultRenderStateSet->addState(StateVariant::createState<ColorMask>(true, true, true, true)); -} - -Renderer::~Renderer() -{ - Q_ASSERT(m_running.fetchAndStoreOrdered(0) == 0); - if (m_renderThread) - Q_ASSERT(m_renderThread->isFinished()); - - delete m_renderQueue; - delete m_defaultRenderStateSet; - delete m_glResourceManagers; - - if (!m_ownedContext) - QObject::disconnect(m_contextConnection); - -#ifndef Q_OS_INTEGRITY - delete m_imGuiRenderer; -#endif -} - -void Renderer::dumpInfo() const -{ - qDebug() << Q_FUNC_INFO << "t =" << m_time; - - const ShaderManager *shaderManager = m_nodesManager->shaderManager(); - qDebug() << "=== Shader Manager ==="; - qDebug() << *shaderManager; - - const TextureManager *textureManager = m_nodesManager->textureManager(); - qDebug() << "=== Texture Manager ==="; - qDebug() << *textureManager; - - const TextureImageManager *textureImageManager = m_nodesManager->textureImageManager(); - qDebug() << "=== Texture Image Manager ==="; - qDebug() << *textureImageManager; -} - -qint64 Renderer::time() const -{ - return m_time; -} - -void Renderer::setTime(qint64 time) -{ - m_time = time; -} - -void Renderer::setJobsInLastFrame(int jobsInLastFrame) -{ - m_jobsInLastFrame = jobsInLastFrame; -} - -void Renderer::setNodeManagers(NodeManagers *managers) -{ - m_nodesManager = managers; - m_glResourceManagers = new GLResourceManagers(); - m_scene2DResourceAccessor.reset(new ResourceAccessor(this, m_nodesManager)); - - m_updateShaderDataTransformJob->setManagers(m_nodesManager); - m_cleanupJob->setManagers(m_nodesManager); - m_calculateBoundingVolumeJob->setManagers(m_nodesManager); - m_expandBoundingVolumeJob->setManagers(m_nodesManager); - m_worldTransformJob->setManagers(m_nodesManager); - m_pickBoundingVolumeJob->setManagers(m_nodesManager); - m_rayCastingJob->setManagers(m_nodesManager); - m_updateWorldBoundingVolumeJob->setManager(m_nodesManager->renderNodesManager()); - m_updateLevelOfDetailJob->setManagers(m_nodesManager); - m_updateSkinningPaletteJob->setManagers(m_nodesManager); - m_updateMeshTriangleListJob->setManagers(m_nodesManager); - m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager()); - m_updateEntityLayersJob->setManager(m_nodesManager); - m_updateTreeEnabledJob->setManagers(m_nodesManager); - m_sendBufferCaptureJob->setManagers(m_nodesManager); - m_lightGathererJob->setManager(m_nodesManager->renderNodesManager()); - m_renderableEntityFilterJob->setManager(m_nodesManager->renderNodesManager()); - m_computableEntityFilterJob->setManager(m_nodesManager->renderNodesManager()); -} - -void Renderer::setServices(QServiceLocator *services) -{ - m_services = services; - - m_nodesManager->sceneManager()->setDownloadService(m_services->downloadHelperService()); -} - -NodeManagers *Renderer::nodeManagers() const -{ - return m_nodesManager; -} - -/*! - \internal - - Return context which can be used to share resources safely - with qt3d main render context. -*/ -QOpenGLContext *Renderer::shareContext() const -{ - QMutexLocker lock(&m_shareContextMutex); - return m_shareContext ? m_shareContext - : (m_submissionContext->openGLContext() - ? m_submissionContext->openGLContext()->shareContext() - : nullptr); -} - -// Executed in the reloadDirtyShader job -void Renderer::loadShader(Shader *shader, HShader shaderHandle) -{ - Q_UNUSED(shader); - if (!m_dirtyShaders.contains(shaderHandle)) - m_dirtyShaders.push_back(shaderHandle); -} - -void Renderer::setOpenGLContext(QOpenGLContext *context) -{ - m_glContext = context; -} - -void Renderer::setScreen(QScreen *scr) -{ - m_screen = scr; -} - -QScreen *Renderer::screen() const -{ - return m_screen; -} - -bool Renderer::accessOpenGLTexture(Qt3DCore::QNodeId nodeId, - QOpenGLTexture **texture, - QMutex **lock, - bool readonly) -{ - Texture *tex = m_nodesManager->textureManager()->lookupResource(nodeId); - if (!tex) - return false; - - GLTexture *glTex = m_glResourceManagers->glTextureManager()->lookupResource(tex->peerId()); - if (!glTex) - return false; - - if (glTex->isDirty()) - return false; - - if (!readonly) - glTex->setExternalRenderingEnabled(true); - - GLTexture::TextureUpdateInfo texInfo = glTex->createOrUpdateGLTexture(); - *texture = texInfo.texture; - - if (!readonly) - *lock = glTex->externalRenderingLock(); - - return true; -} - -QSharedPointer<RenderBackendResourceAccessor> Renderer::resourceAccessor() const -{ - return m_scene2DResourceAccessor; -} - -// Called in RenderThread context by the run method of RenderThread -// RenderThread has locked the mutex already and unlocks it when this -// method termintates -void Renderer::initialize() -{ - QMutexLocker lock(&m_hasBeenInitializedMutex); - m_submissionContext.reset(new SubmissionContext); - m_submissionContext->setRenderer(this); - - QOpenGLContext* ctx = m_glContext; - - { - QMutexLocker lock(&m_shareContextMutex); - // If we are using our own context (not provided by QtQuick), - // we need to create it - if (!m_glContext) { - ctx = new QOpenGLContext; - if (m_screen) - ctx->setScreen(m_screen); - ctx->setShareContext(qt_gl_global_share_context()); - - // TO DO: Shouldn't we use the highest context available and trust - // QOpenGLContext to fall back on the best lowest supported ? - const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING"); - - if (!debugLoggingMode.isEmpty()) { - QSurfaceFormat sf = ctx->format(); - sf.setOption(QSurfaceFormat::DebugContext); - ctx->setFormat(sf); - } - - // Create OpenGL context - if (ctx->create()) - qCDebug(Backend) << "OpenGL context created with actual format" << ctx->format(); - else - qCWarning(Backend) << Q_FUNC_INFO << "OpenGL context creation failed"; - m_ownedContext = true; - - QObject::connect(m_glContext, &QOpenGLContext::aboutToBeDestroyed, - [this] { m_frameProfiler.reset(); }); - } else { - // Context is not owned by us, so we need to know if it gets destroyed - m_contextConnection = QObject::connect(m_glContext, &QOpenGLContext::aboutToBeDestroyed, - [this] { releaseGraphicsResources(); }); - } - - qCDebug(Backend) << "Qt3D shared context:" << ctx->shareContext(); - qCDebug(Backend) << "Qt global shared context:" << qt_gl_global_share_context(); - - if (!ctx->shareContext()) { - m_shareContext = new QOpenGLContext; - if (ctx->screen()) - m_shareContext->setScreen(ctx->screen()); - m_shareContext->setFormat(ctx->format()); - m_shareContext->setShareContext(ctx); - m_shareContext->create(); - } - - // Note: we don't have a surface at this point - // The context will be made current later on (at render time) - m_submissionContext->setOpenGLContext(ctx); - - // Store the format used by the context and queue up creating an - // offscreen surface in the main thread so that it is available - // for use when we want to shutdown the renderer. We need to create - // the offscreen surface on the main thread because on some platforms - // (MS Windows), an offscreen surface is just a hidden QWindow. - m_format = ctx->format(); - QMetaObject::invokeMethod(m_offscreenHelper, "createOffscreenSurface"); - } - - // Awake setScenegraphRoot in case it was waiting - m_waitForInitializationToBeCompleted.release(1); - // Allow the aspect manager to proceed - m_vsyncFrameAdvanceService->proceedToNextFrame(); - - // Force initial refresh - markDirty(AllDirty, nullptr); -} - -/*! - * \internal - * - * Signals for the renderer to stop rendering. If a threaded renderer is in use, - * the render thread will call releaseGraphicsResources() just before the thread exits. - * If rendering synchronously, this function will call releaseGraphicsResources(). - */ -void Renderer::shutdown() -{ - // Ensure we have waited to be fully initialized before trying to shut down - // (in case initialization is taking place at the same time) - QMutexLocker lock(&m_hasBeenInitializedMutex); - - qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer shutdown"; - m_running.storeRelaxed(0); - - // We delete any renderqueue that we may not have had time to render - // before the surface was destroyed - QMutexLocker lockRenderQueue(m_renderQueue->mutex()); - qDeleteAll(m_renderQueue->nextFrameQueue()); - m_renderQueue->reset(); - lockRenderQueue.unlock(); - - if (!m_renderThread) { - releaseGraphicsResources(); - } else { - // Wake up the render thread in case it is waiting for some renderviews - // to be ready. The isReadyToSubmit() function checks for a shutdown - // having been requested. - m_submitRenderViewsSemaphore.release(1); - m_renderThread->wait(); - } - - // Destroy internal managers - // This needs to be done before the nodeManager is destroy - // as the internal resources might somehow rely on nodeManager resources - delete m_glResourceManagers; - m_glResourceManagers = nullptr; -} - -/*! - \internal - - When using a threaded renderer this function is called in the context of the - RenderThread to do any shutdown and cleanup that needs to be performed in the - thread where the OpenGL context lives. - - When using Scene3D or anything that provides a custom QOpenGLContext (not - owned by Qt3D) this function is called whenever the signal - QOpenGLContext::aboutToBeDestroyed is emitted. In that case this function - is called in the context of the emitter's thread. -*/ -void Renderer::releaseGraphicsResources() -{ - // We may get called twice when running inside of a Scene3D. Once when Qt Quick - // wants to shutdown, and again when the render aspect gets unregistered. So - // check that we haven't already cleaned up before going any further. - if (!m_submissionContext) - return; - - // Try to temporarily make the context current so we can free up any resources - QMutexLocker locker(&m_offscreenSurfaceMutex); - QOffscreenSurface *offscreenSurface = m_offscreenHelper->offscreenSurface(); - if (!offscreenSurface) { - qWarning() << "Failed to make context current: OpenGL resources will not be destroyed"; - // We still need to delete the submission context - m_submissionContext.reset(nullptr); - return; - } - - QOpenGLContext *context = m_submissionContext->openGLContext(); - Q_ASSERT(context); - - if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) { - - // Clean up the graphics context and any resources - const QVector<HGLTexture> activeTexturesHandles = m_glResourceManagers->glTextureManager()->activeHandles(); - for (const HGLTexture &textureHandle : activeTexturesHandles) { - GLTexture *tex = m_glResourceManagers->glTextureManager()->data(textureHandle); - tex->destroy(); - } - - // Do the same thing with buffers - const QVector<HGLBuffer> activeBuffers = m_glResourceManagers->glBufferManager()->activeHandles(); - for (const HGLBuffer &bufferHandle : activeBuffers) { - GLBuffer *buffer = m_glResourceManagers->glBufferManager()->data(bufferHandle); - buffer->destroy(m_submissionContext.data()); - } - - // Do the same thing with shaders - const QVector<GLShader *> shaders = m_glResourceManagers->glShaderManager()->takeActiveResources(); - qDeleteAll(shaders); - - // Do the same thing with VAOs - const QVector<HVao> activeVaos = m_glResourceManagers->vaoManager()->activeHandles(); - for (const HVao &vaoHandle : activeVaos) { - OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(vaoHandle); - vao->destroy(); - } - - m_frameProfiler.reset(); - context->doneCurrent(); - } else { - qWarning() << "Failed to make context current: OpenGL resources will not be destroyed"; - } - - if (m_ownedContext) - delete context; - if (m_shareContext) - delete m_shareContext; - - m_submissionContext.reset(nullptr); - qCDebug(Backend) << Q_FUNC_INFO << "Renderer properly shutdown"; -} - -void Renderer::setSurfaceExposed(bool exposed) -{ - qCDebug(Backend) << "Window exposed: " << exposed; - m_exposed.fetchAndStoreOrdered(exposed); -} - -Render::FrameGraphNode *Renderer::frameGraphRoot() const -{ - Q_ASSERT(m_settings); - if (m_nodesManager && m_nodesManager->frameGraphManager() && m_settings) - return m_nodesManager->frameGraphManager()->lookupNode(m_settings->activeFrameGraphID()); - return nullptr; -} - -// QAspectThread context -// Order of execution : -// 1) RenderThread is created -> release 1 of m_waitForInitializationToBeCompleted when started -// 2) setSceneRoot waits to acquire initialization -// 3) submitRenderView -> check for surface -// -> make surface current + create proper glHelper if needed -void Renderer::setSceneRoot(Entity *sgRoot) -{ - Q_ASSERT(sgRoot); - - // If initialization hasn't been completed we must wait - m_waitForInitializationToBeCompleted.acquire(); - - m_renderSceneRoot = sgRoot; - if (!m_renderSceneRoot) - qCWarning(Backend) << "Failed to build render scene"; - m_renderSceneRoot->dump(); - qCDebug(Backend) << Q_FUNC_INFO << "DUMPING SCENE"; - - // Set the scene root on the jobs - m_worldTransformJob->setRoot(m_renderSceneRoot); - m_expandBoundingVolumeJob->setRoot(m_renderSceneRoot); - m_calculateBoundingVolumeJob->setRoot(m_renderSceneRoot); - m_cleanupJob->setRoot(m_renderSceneRoot); - m_pickBoundingVolumeJob->setRoot(m_renderSceneRoot); - m_rayCastingJob->setRoot(m_renderSceneRoot); - m_updateLevelOfDetailJob->setRoot(m_renderSceneRoot); - m_updateSkinningPaletteJob->setRoot(m_renderSceneRoot); - m_updateTreeEnabledJob->setRoot(m_renderSceneRoot); - - // Set all flags to dirty - m_dirtyBits.marked |= AbstractRenderer::AllDirty; -} - -void Renderer::registerEventFilter(QEventFilterService *service) -{ - qCDebug(Backend) << Q_FUNC_INFO << QThread::currentThread(); - service->registerEventFilter(m_pickEventFilter.data(), 1024); -} - -void Renderer::setSettings(RenderSettings *settings) -{ - m_settings = settings; -} - -RenderSettings *Renderer::settings() const -{ - return m_settings; -} - -void Renderer::render() -{ - // Traversing the framegraph tree from root to lead node - // Allows us to define the rendering set up - // Camera, RenderTarget ... - - // Utimately the renderer should be a framework - // For the processing of the list of renderviews - - // Matrice update, bounding volumes computation ... - // Should be jobs - - // namespace Qt3DCore has 2 distincts node trees - // One scene description - // One framegraph description - - while (m_running.loadRelaxed() > 0) { - doRender(); - // TO DO: Restore windows exposed detection - // Probably needs to happens some place else though - } -} - -// Either called by render if Qt3D is in charge of the RenderThread -// or by QRenderAspectPrivate::renderSynchronous (for Scene3D) -void Renderer::doRender(bool swapBuffers) -{ - Renderer::ViewSubmissionResultData submissionData; - bool hasCleanedQueueAndProceeded = false; - bool preprocessingComplete = false; - bool beganDrawing = false; - - // Blocking until RenderQueue is full - const bool canSubmit = isReadyToSubmit(); - m_shouldSwapBuffers = swapBuffers; - - // Lock the mutex to protect access to the renderQueue while we look for its state - QMutexLocker locker(m_renderQueue->mutex()); - const bool queueIsComplete = m_renderQueue->isFrameQueueComplete(); - const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0; - - // When using synchronous rendering (QtQuick) - // We are not sure that the frame queue is actually complete - // Since a call to render may not be synched with the completions - // of the RenderViewJobs - // In such a case we return early, waiting for a next call with - // the frame queue complete at this point - - // RenderQueue is complete (but that means it may be of size 0) - if (canSubmit && (queueIsComplete && !queueIsEmpty)) { - const QVector<Render::RenderView *> renderViews = m_renderQueue->nextFrameQueue(); - QTaskLogger submissionStatsPart1(m_services->systemInformation(), - {JobTypes::FrameSubmissionPart1, 0}, - QTaskLogger::Submission); - QTaskLogger submissionStatsPart2(m_services->systemInformation(), - {JobTypes::FrameSubmissionPart2, 0}, - QTaskLogger::Submission); - - if (canRender()) { - { // Scoped to destroy surfaceLock - QSurface *surface = nullptr; - for (const Render::RenderView *rv: renderViews) { - surface = rv->surface(); - if (surface) - break; - } - - SurfaceLocker surfaceLock(surface); - const bool surfaceIsValid = (surface && surfaceLock.isSurfaceValid()); - if (surfaceIsValid) { - // Reset state for each draw if we don't have complete control of the context - if (!m_ownedContext) - m_submissionContext->setCurrentStateSet(nullptr); - beganDrawing = m_submissionContext->beginDrawing(surface); - if (beganDrawing) { - // 1) Execute commands for buffer uploads, texture updates, shader loading first - updateGLResources(); - // 2) Update VAO and copy data into commands to allow concurrent submission - prepareCommandsSubmission(renderViews); - preprocessingComplete = true; - - // Purge shader which aren't used any longer - static int callCount = 0; - ++callCount; - const int shaderPurgePeriod = 600; - if (callCount % shaderPurgePeriod == 0) - m_glResourceManagers->glShaderManager()->purge(); - } - } - } - // 2) Proceed to next frame and start preparing frame n + 1 - m_renderQueue->reset(); - locker.unlock(); // Done protecting RenderQueue - m_vsyncFrameAdvanceService->proceedToNextFrame(); - hasCleanedQueueAndProceeded = true; - - // Only try to submit the RenderViews if the preprocessing was successful - // This part of the submission is happening in parallel to the RV building for the next frame - if (preprocessingComplete) { - submissionStatsPart1.end(submissionStatsPart2.restart()); - - // 3) Submit the render commands for frame n (making sure we never reference something that could be changing) - // Render using current device state and renderer configuration - submissionData = submitRenderViews(renderViews); - - // Perform any required cleanup of the Graphics resources (Buffers deleted, Shader deleted...) - cleanGraphicsResources(); - } - } - - // Execute the pending shell commands - m_commandExecuter->performAsynchronousCommandExecution(renderViews); - - // Delete all the RenderViews which will clear the allocators - // that were used for their allocation - qDeleteAll(renderViews); - - if (preprocessingComplete && activeProfiler()) - m_frameProfiler->writeResults(); - } - - // If hasCleanedQueueAndProceeded isn't true this implies that something went wrong - // with the rendering and/or the renderqueue is incomplete from some reason - // or alternatively it could be complete but empty (RenderQueue of size 0) - - if (!hasCleanedQueueAndProceeded) { - // RenderQueue was full but something bad happened when - // trying to render it and therefore proceedToNextFrame was not called - // Note: in this case the renderQueue mutex is still locked - - // Reset the m_renderQueue so that we won't try to render - // with a queue used by a previous frame with corrupted content - // if the current queue was correctly submitted - m_renderQueue->reset(); - - // We allow the RenderTickClock service to proceed to the next frame - // In turn this will allow the aspect manager to request a new set of jobs - // to be performed for each aspect - m_vsyncFrameAdvanceService->proceedToNextFrame(); - } - - // Perform the last swapBuffers calls after the proceedToNextFrame - // as this allows us to gain a bit of time for the preparation of the - // next frame - // Finish up with last surface used in the list of RenderViews - if (beganDrawing) { - SurfaceLocker surfaceLock(submissionData.surface); - // Finish up with last surface used in the list of RenderViews - const bool swapBuffers = submissionData.lastBoundFBOId == m_submissionContext->defaultFBO() - && surfaceLock.isSurfaceValid() - && m_shouldSwapBuffers; - m_submissionContext->endDrawing(swapBuffers); - } -} - -// Called by RenderViewJobs -// When the frameQueue is complete and we are using a renderThread -// we allow the render thread to proceed -void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder) -{ - QMutexLocker locker(m_renderQueue->mutex()); // Prevent out of order execution - // We cannot use a lock free primitive here because: - // - QVector is not thread safe - // - Even if the insert is made correctly, the isFrameComplete call - // could be invalid since depending on the order of execution - // the counter could be complete but the renderview not yet added to the - // buffer depending on whichever order the cpu decides to process this - const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder); - locker.unlock(); // We're done protecting the queue at this point - if (isQueueComplete) { - if (m_renderThread && m_running.loadRelaxed()) - Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0); - m_submitRenderViewsSemaphore.release(1); - } -} - -bool Renderer::canRender() const - -{ - // Make sure that we've not been told to terminate - if (m_renderThread && !m_running.loadRelaxed()) { - qCDebug(Rendering) << "RenderThread termination requested whilst waiting"; - return false; - } - - // TO DO: Check if all surfaces have been destroyed... - // It may be better if the last window to be closed trigger a call to shutdown - // Rather than having checks for the surface everywhere - - return true; -} - -Profiling::FrameProfiler *Renderer::activeProfiler() const -{ - if (m_services && m_services->systemInformation()->isGraphicsTraceEnabled()) { - if (m_frameProfiler.isNull()) - m_frameProfiler.reset(new Profiling::FrameProfiler(m_services->systemInformation())); - - return m_frameProfiler.data(); - } - - return nullptr; -} - -bool Renderer::isReadyToSubmit() -{ - // Make sure that we've been told to render before rendering - // Prevent ouf of order execution - m_submitRenderViewsSemaphore.acquire(1); - - // Check if shutdown has been requested - if (m_running.loadRelaxed() == 0) - return false; - - // The semaphore should only - // be released when the frame queue is complete and there's - // something to render - // The case of shutdown should have been handled just before - Q_ASSERT(m_renderQueue->isFrameQueueComplete()); - return true; -} - -// Main thread -QVariant Renderer::executeCommand(const QStringList &args) -{ - return m_commandExecuter->executeCommand(args); -} - -/*! - \internal - Called in the context of the aspect thread from QRenderAspect::onRegistered -*/ -void Renderer::setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) -{ - QMutexLocker locker(&m_offscreenSurfaceMutex); - m_offscreenHelper = helper; -} - -QSurfaceFormat Renderer::format() -{ - return m_format; -} - -// When this function is called, we must not be processing the commands for frame n+1 -void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderViews) -{ - OpenGLVertexArrayObject *vao = nullptr; - QHash<HVao, bool> updatedTable; - - for (RenderView *rv: renderViews) { - QVector<RenderCommand> &commands = rv->commands(); - for (RenderCommand &command : commands) { - // Update/Create VAO - if (command.m_type == RenderCommand::Draw) { - Geometry *rGeometry = m_nodesManager->data<Geometry, GeometryManager>(command.m_geometry); - GeometryRenderer *rGeometryRenderer = m_nodesManager->data<GeometryRenderer, GeometryRendererManager>(command.m_geometryRenderer); - GLShader *shader = command.m_glShader; - - // We should never have inserted a command for which these are null - // in the first place - Q_ASSERT(rGeometry && rGeometryRenderer && shader); - - // The VAO should be created only once for a QGeometry and a ShaderProgram - // Manager should have a VAO Manager that are indexed by QMeshData and Shader - // RenderCommand should have a handle to the corresponding VAO for the Mesh and Shader - HVao vaoHandle; - - // Create VAO or return already created instance associated with command shader/geometry - // (VAO is emulated if not supported) - createOrUpdateVAO(&command, &vaoHandle, &vao); - command.m_vao = vaoHandle; - - // Avoids redoing the same thing for the same VAO - if (!updatedTable.contains(vaoHandle)) { - updatedTable.insert(vaoHandle, true); - - // Do we have any attributes that are dirty ? - const bool requiresPartialVAOUpdate = requiresVAOAttributeUpdate(rGeometry, &command); - - // If true, we need to reupload all attributes to set the VAO - // Otherwise only dirty attributes will be updates - const bool requiresFullVAOUpdate = (!vao->isSpecified()) || (rGeometry->isDirty() || rGeometryRenderer->isDirty()); - - // Append dirty Geometry to temporary vector - // so that its dirtiness can be unset later - if (rGeometry->isDirty()) - m_dirtyGeometry.push_back(rGeometry); - - if (!command.m_activeAttributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) { - Profiling::GLTimeRecorder recorder(Profiling::VAOUpload, activeProfiler()); - // Activate shader - m_submissionContext->activateShader(shader); - // Bind VAO - vao->bind(); - // Update or set Attributes and Buffers for the given rGeometry and Command - // Note: this fills m_dirtyAttributes as well - if (updateVAOWithAttributes(rGeometry, &command, shader, requiresFullVAOUpdate)) - vao->setSpecified(true); - } - } - - // Unset dirtiness on rGeometryRenderer only - // The rGeometry may be shared by several rGeometryRenderer - // so we cannot unset its dirtiness at this point - if (rGeometryRenderer->isDirty()) - rGeometryRenderer->unsetDirty(); - - // Prepare the ShaderParameterPack based on the active uniforms of the shader - shader->prepareUniforms(command.m_parameterPack); - - } else if (command.m_type == RenderCommand::Compute) { - GLShader *shader = command.m_glShader; - Q_ASSERT(shader); - - // Prepare the ShaderParameterPack based on the active uniforms of the shader - shader->prepareUniforms(command.m_parameterPack); - } - } - } - - // Make sure we leave nothing bound - if (vao) - vao->release(); - - // Unset dirtiness on Geometry and Attributes - // Note: we cannot do it in the loop above as we want to be sure that all - // the VAO which reference the geometry/attributes are properly updated - for (Attribute *attribute : qAsConst(m_dirtyAttributes)) - attribute->unsetDirty(); - m_dirtyAttributes.clear(); - - for (Geometry *geometry : qAsConst(m_dirtyGeometry)) - geometry->unsetDirty(); - m_dirtyGeometry.clear(); -} - -// Executed in a job -void Renderer::lookForAbandonedVaos() -{ - const QVector<HVao> activeVaos = m_glResourceManagers->vaoManager()->activeHandles(); - for (HVao handle : activeVaos) { - OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(handle); - - // Make sure to only mark VAOs for deletion that were already created - // (ignore those that might be currently under construction in the render thread) - if (vao && vao->isAbandoned(m_nodesManager->geometryManager(), m_glResourceManagers->glShaderManager())) { - m_abandonedVaosMutex.lock(); - m_abandonedVaos.push_back(handle); - m_abandonedVaosMutex.unlock(); - } - } -} - -// Executed in a job -void Renderer::lookForDirtyBuffers() -{ - const QVector<HBuffer> activeBufferHandles = m_nodesManager->bufferManager()->activeHandles(); - for (const HBuffer &handle: activeBufferHandles) { - Buffer *buffer = m_nodesManager->bufferManager()->data(handle); - if (buffer->isDirty()) - m_dirtyBuffers.push_back(handle); - } -} - -// Called in prepareSubmission -void Renderer::lookForDownloadableBuffers() -{ - m_downloadableBuffers.clear(); - const QVector<HBuffer> activeBufferHandles = m_nodesManager->bufferManager()->activeHandles(); - for (const HBuffer &handle : activeBufferHandles) { - Buffer *buffer = m_nodesManager->bufferManager()->data(handle); - if (buffer->access() & QBuffer::Read) - m_downloadableBuffers.push_back(buffer->peerId()); - } -} - -// Executed in a job -void Renderer::lookForDirtyTextures() -{ - // To avoid having Texture or TextureImage maintain relationships between - // one another, we instead perform a lookup here to check if a texture - // image has been updated to then notify textures referencing the image - // that they need to be updated - TextureImageManager *imageManager = m_nodesManager->textureImageManager(); - const QVector<HTextureImage> activeTextureImageHandles = imageManager->activeHandles(); - Qt3DCore::QNodeIdVector dirtyImageIds; - for (const HTextureImage &handle: activeTextureImageHandles) { - TextureImage *image = imageManager->data(handle); - if (image->isDirty()) { - dirtyImageIds.push_back(image->peerId()); - image->unsetDirty(); - } - } - - TextureManager *textureManager = m_nodesManager->textureManager(); - const QVector<HTexture> activeTextureHandles = textureManager->activeHandles(); - for (const HTexture &handle: activeTextureHandles) { - Texture *texture = textureManager->data(handle); - const QNodeIdVector imageIds = texture->textureImageIds(); - - // Does the texture reference any of the dirty texture images? - for (const QNodeId imageId: imageIds) { - if (dirtyImageIds.contains(imageId)) { - texture->addDirtyFlag(Texture::DirtyImageGenerators); - break; - } - } - - // Dirty meaning that something has changed on the texture - // either properties, parameters, shared texture id, generator or a texture image - if (texture->dirtyFlags() != Texture::NotDirty) - m_dirtyTextures.push_back(handle); - // Note: texture dirty flags are reset when actually updating the - // textures in updateGLResources() as resetting flags here would make - // us lose information about what was dirty exactly. - } -} - -// Executed in a job -void Renderer::reloadDirtyShaders() -{ - Q_ASSERT(isRunning()); - const QVector<HTechnique> activeTechniques = m_nodesManager->techniqueManager()->activeHandles(); - const QVector<HShaderBuilder> activeBuilders = m_nodesManager->shaderBuilderManager()->activeHandles(); - for (const HTechnique &techniqueHandle : activeTechniques) { - Technique *technique = m_nodesManager->techniqueManager()->data(techniqueHandle); - // If api of the renderer matches the one from the technique - if (technique->isCompatibleWithRenderer()) { - const auto passIds = technique->renderPasses(); - for (const QNodeId &passId : passIds) { - RenderPass *renderPass = m_nodesManager->renderPassManager()->lookupResource(passId); - HShader shaderHandle = m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram()); - Shader *shader = m_nodesManager->shaderManager()->data(shaderHandle); - - ShaderBuilder *shaderBuilder = nullptr; - for (const HShaderBuilder &builderHandle : activeBuilders) { - ShaderBuilder *builder = m_nodesManager->shaderBuilderManager()->data(builderHandle); - if (builder->shaderProgramId() == shader->peerId()) { - shaderBuilder = builder; - break; - } - } - - if (shaderBuilder) { - shaderBuilder->setGraphicsApi(*technique->graphicsApiFilter()); - - for (int i = 0; i <= QShaderProgram::Compute; i++) { - const auto shaderType = static_cast<QShaderProgram::ShaderType>(i); - if (!shaderBuilder->shaderGraph(shaderType).isValid()) - continue; - - if (shaderBuilder->isShaderCodeDirty(shaderType)) { - shaderBuilder->generateCode(shaderType); - m_shaderBuilderUpdates.append(shaderBuilder->takePendingUpdates()); - } - - const auto code = shaderBuilder->shaderCode(shaderType); - shader->setShaderCode(shaderType, code); - } - } - - if (shader != nullptr && shader->isDirty()) - loadShader(shader, shaderHandle); - } - } - } -} - -// Executed in job (in main thread when jobs are done) -void Renderer::sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager) -{ - Q_ASSERT(isRunning()); - - // Sync Shader - const QVector<HShader> activeShaders = m_nodesManager->shaderManager()->activeHandles(); - for (const HShader &handle :activeShaders) { - Shader *s = m_nodesManager->shaderManager()->data(handle); - if (s->requiresFrontendSync()) { - QShaderProgram *frontend = static_cast<decltype(frontend)>(manager->lookupNode(s->peerId())); - QShaderProgramPrivate *dFrontend = static_cast<decltype(dFrontend)>(QNodePrivate::get(frontend)); - s->unsetRequiresFrontendSync(); - dFrontend->setStatus(s->status()); - dFrontend->setLog(s->log()); - } - } - - // Sync ShaderBuilder - const QVector<ShaderBuilderUpdate> shaderBuilderUpdates = std::move(m_shaderBuilderUpdates); - for (const ShaderBuilderUpdate &update : shaderBuilderUpdates) { - QShaderProgramBuilder *builder = static_cast<decltype(builder)>(manager->lookupNode(update.builderId)); - QShaderProgramBuilderPrivate *dBuilder = static_cast<decltype(dBuilder)>(QNodePrivate::get(builder)); - dBuilder->setShaderCode(update.shaderCode, update.shaderType); - } -} - -// Executed in a job (in main thread when jobs are done) -void Renderer::sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager) -{ - const QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> updateTextureProperties = std::move(m_updatedTextureProperties); - for (const auto &pair : updateTextureProperties) { - const Qt3DCore::QNodeIdVector targetIds = pair.second; - for (const Qt3DCore::QNodeId &targetId: targetIds) { - // Lookup texture - Texture *t = m_nodesManager->textureManager()->lookupResource(targetId); - // If backend texture is Dirty, some property has changed and the properties we are - // about to send are already outdate - if (t == nullptr || t->dirtyFlags() != Texture::NotDirty) - continue; - - QAbstractTexture *texture = static_cast<QAbstractTexture *>(manager->lookupNode(targetId)); - if (!texture) - continue; - const TextureProperties &properties = pair.first.properties; - - const bool blocked = texture->blockNotifications(true); - texture->setWidth(properties.width); - texture->setHeight(properties.height); - texture->setDepth(properties.depth); - texture->setLayers(properties.layers); - texture->setFormat(properties.format); - texture->blockNotifications(blocked); - - QAbstractTexturePrivate *dTexture = static_cast<QAbstractTexturePrivate *>(QNodePrivate::get(texture)); - - dTexture->setStatus(properties.status); - dTexture->setHandleType(pair.first.handleType); - dTexture->setHandle(pair.first.handle); - } - } -} - -// Executed in a job -void Renderer::sendSetFenceHandlesToFrontend() -{ - const QVector<QPair<Qt3DCore::QNodeId, GLFence>> updatedSetFence = std::move(m_updatedSetFences); - FrameGraphManager *fgManager = m_nodesManager->frameGraphManager(); - for (const auto &pair : updatedSetFence) { - FrameGraphNode *fgNode = fgManager->lookupNode(pair.first); - if (fgNode != nullptr) { // Node could have been deleted before we got a chance to notify it - Q_ASSERT(fgNode->nodeType() == FrameGraphNode::SetFence); - SetFence *setFenceNode = static_cast<SetFence *>(fgNode); - setFenceNode->setHandleType(QSetFence::OpenGLFenceId); - setFenceNode->setHandle(QVariant::fromValue(pair.second)); - } - } -} - -// Executed in a job (in main thread when jobs done) -void Renderer::sendDisablesToFrontend(Qt3DCore::QAspectManager *manager) -{ - // SubtreeEnabled - const auto updatedDisables = std::move(m_updatedDisableSubtreeEnablers); - for (const auto &nodeId : updatedDisables) { - QSubtreeEnabler *frontend = static_cast<decltype(frontend)>(manager->lookupNode(nodeId)); - frontend->setEnabled(false); - } - - // Compute Commands - const QVector<HComputeCommand> activeCommands = m_nodesManager->computeJobManager()->activeHandles(); - for (const HComputeCommand &handle :activeCommands) { - ComputeCommand *c = m_nodesManager->computeJobManager()->data(handle); - if (c->hasReachedFrameCount()) { - QComputeCommand *frontend = static_cast<decltype(frontend)>(manager->lookupNode(c->peerId())); - frontend->setEnabled(false); - c->resetHasReachedFrameCount(); - } - } -} - -// Render Thread (or QtQuick RenderThread when using Scene3D) -// Scene3D: When using Scene3D rendering, we can't assume that when -// updateGLResources is called, the resource handles points to still existing -// objects. This is because Scene3D calls doRender independently of whether all -// jobs have completed or not which in turn calls proceedToNextFrame under some -// conditions. Such conditions are usually met on startup to avoid deadlocks. -// proceedToNextFrame triggers the syncChanges calls for the next frame, which -// may contain destruction changes targeting resources. When the above -// happens, this can result in the dirtyResource vectors containing handles of -// objects that may already have been destroyed -void Renderer::updateGLResources() -{ - { - // Update active fence objects: - // - Destroy fences that have reached their signaled state - GLFenceManager *fenceManager = m_glResourceManagers->glFenceManager(); - const auto end = fenceManager->end(); - auto it = fenceManager->begin(); - while (it != end) { - const GLFence fence = it.value(); - if (m_submissionContext->wasSyncSignaled(fence)) { - // Fence was signaled, we delete it - // before removing the entry from the manager - m_submissionContext->deleteSync(fence); - it = fenceManager->erase(it); - } else { - ++it; - } - } - } - - { - Profiling::GLTimeRecorder recorder(Profiling::BufferUpload, activeProfiler()); - const QVector<HBuffer> dirtyBufferHandles = std::move(m_dirtyBuffers); - for (const HBuffer &handle: dirtyBufferHandles) { - Buffer *buffer = m_nodesManager->bufferManager()->data(handle); - - // Can be null when using Scene3D rendering - if (buffer == nullptr) - continue; - - // Forces creation if it doesn't exit - // Also note the binding point doesn't really matter here, we just upload data - if (!m_submissionContext->hasGLBufferForBuffer(buffer)) - m_submissionContext->glBufferForRenderBuffer(buffer); - // Update the glBuffer data - m_submissionContext->updateBuffer(buffer); - buffer->unsetDirty(); - } - } - -#ifndef SHADER_LOADING_IN_COMMAND_THREAD - { - Profiling::GLTimeRecorder recorder(Profiling::ShaderUpload, activeProfiler()); - const QVector<HShader> dirtyShaderHandles = std::move(m_dirtyShaders); - ShaderManager *shaderManager = m_nodesManager->shaderManager(); - for (const HShader &handle: dirtyShaderHandles) { - Shader *shader = shaderManager->data(handle); - - // Can be null when using Scene3D rendering - if (shader == nullptr) - continue; - - // Compile shader - m_submissionContext->loadShader(shader, shaderManager, m_glResourceManagers->glShaderManager()); - } - } -#endif - - { - Profiling::GLTimeRecorder recorder(Profiling::TextureUpload, activeProfiler()); - const QVector<HTexture> activeTextureHandles = std::move(m_dirtyTextures); - for (const HTexture &handle: activeTextureHandles) { - Texture *texture = m_nodesManager->textureManager()->data(handle); - - // Can be null when using Scene3D rendering - if (texture == nullptr) - continue; - - // Create or Update GLTexture (the GLTexture instance is created if required - // and all things that can take place without a GL context are done here) - updateTexture(texture); - } - // We want to upload textures data at this point as the SubmissionThread and - // AspectThread are locked ensuring no races between Texture/TextureImage and - // GLTexture - if (m_submissionContext != nullptr) { - GLTextureManager *glTextureManager = m_glResourceManagers->glTextureManager(); - const QVector<HGLTexture> glTextureHandles = glTextureManager->activeHandles(); - // Upload texture data - for (const HGLTexture &glTextureHandle : glTextureHandles) { - GLTexture *glTexture = glTextureManager->data(glTextureHandle); - - // We create/update the actual GL texture using the GL context at this point - const GLTexture::TextureUpdateInfo info = glTexture->createOrUpdateGLTexture(); - - // GLTexture creation provides us width/height/format ... information - // for textures which had not initially specified these information (TargetAutomatic...) - // Gather these information and store them to be distributed by a change next frame - const QNodeIdVector referenceTextureIds = { glTextureManager->texNodeIdForGLTexture.value(glTexture) }; - // Store properties and referenceTextureIds - if (info.wasUpdated) { - Texture::TextureUpdateInfo updateInfo; - updateInfo.properties = info.properties; - updateInfo.handleType = QAbstractTexture::OpenGLTextureId; - updateInfo.handle = info.texture ? QVariant(info.texture->textureId()) : QVariant(); - m_updatedTextureProperties.push_back({updateInfo, referenceTextureIds}); - } - } - } - - // Record ids of texture to cleanup while we are still blocking the aspect thread - m_textureIdsToCleanup += m_nodesManager->textureManager()->takeTexturesIdsToCleanup(); - } - - // Record list of buffer that might need uploading - lookForDownloadableBuffers(); -} - -// Render Thread -void Renderer::updateTexture(Texture *texture) -{ - // Check that the current texture images are still in place, if not, do not update - const bool isValid = texture->isValid(m_nodesManager->textureImageManager()); - if (!isValid) { - qWarning() << Q_FUNC_INFO << "QTexture referencing invalid QTextureImages"; - return; - } - - // All textures are unique, if you instanciate twice the exact same texture - // this will create 2 identical GLTextures, no sharing will take place - - // Try to find the associated GLTexture for the backend Texture - GLTextureManager *glTextureManager = m_glResourceManagers->glTextureManager(); - GLTexture *glTexture = glTextureManager->lookupResource(texture->peerId()); - - // No GLTexture associated yet -> create it - if (glTexture == nullptr) { - glTexture = glTextureManager->getOrCreateResource(texture->peerId()); - glTextureManager->texNodeIdForGLTexture.insert(glTexture, texture->peerId()); - } - - // Update GLTexture to match Texture instance - const Texture::DirtyFlags dirtyFlags = texture->dirtyFlags(); - if (dirtyFlags.testFlag(Texture::DirtySharedTextureId)) - glTexture->setSharedTextureId(texture->sharedTextureId()); - - if (dirtyFlags.testFlag(Texture::DirtyProperties)) - glTexture->setProperties(texture->properties()); - - if (dirtyFlags.testFlag(Texture::DirtyParameters)) - glTexture->setParameters(texture->parameters()); - - // Will make the texture requestUpload - if (dirtyFlags.testFlag(Texture::DirtyImageGenerators)) { - const QNodeIdVector textureImageIds = texture->textureImageIds(); - QVector<GLTexture::Image> images; - images.reserve(textureImageIds.size()); - // TODO: Move this into GLTexture directly - for (const QNodeId textureImageId : textureImageIds) { - const TextureImage *img = m_nodesManager->textureImageManager()->lookupResource(textureImageId); - if (img == nullptr) { - qWarning() << Q_FUNC_INFO << "invalid TextureImage handle"; - } else { - GLTexture::Image glImg {img->dataGenerator(), img->layer(), img->mipLevel(), img->face()}; - images.push_back(glImg); - } - } - glTexture->setImages(images); - } - - // Will make the texture requestUpload - if (dirtyFlags.testFlag(Texture::DirtyDataGenerator)) - glTexture->setGenerator(texture->dataGenerator()); - - // Will make the texture requestUpload - if (dirtyFlags.testFlag(Texture::DirtyPendingDataUpdates)) - glTexture->addTextureDataUpdates(texture->takePendingTextureDataUpdates()); - - // Unset the dirty flag on the texture - texture->unsetDirty(); -} - -// Render Thread -void Renderer::cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId) -{ - GLTextureManager *glTextureManager = m_glResourceManagers->glTextureManager(); - GLTexture *glTexture = glTextureManager->lookupResource(cleanedUpTextureId); - - // Destroying the GLTexture implicitely also destroy the GL resources - if (glTexture != nullptr) { - glTextureManager->releaseResource(cleanedUpTextureId); - glTextureManager->texNodeIdForGLTexture.remove(glTexture); - } -} - -// Render Thread -void Renderer::cleanupShader(const Shader *shader) -{ - GLShaderManager *glShaderManager = m_glResourceManagers->glShaderManager(); - GLShader *glShader = glShaderManager->lookupResource(shader->peerId()); - - if (glShader != nullptr) - glShaderManager->abandon(glShader, shader); -} - -// Called by SubmitRenderView -void Renderer::downloadGLBuffers() -{ - const QVector<Qt3DCore::QNodeId> downloadableHandles = std::move(m_downloadableBuffers); - for (const Qt3DCore::QNodeId &bufferId : downloadableHandles) { - BufferManager *bufferManager = m_nodesManager->bufferManager(); - BufferManager::ReadLocker locker(const_cast<const BufferManager *>(bufferManager)); - Buffer *buffer = bufferManager->lookupResource(bufferId); - // Buffer could have been destroyed at this point - if (!buffer) - continue; - // locker is protecting us from the buffer being destroy while we're looking - // up its content - const QByteArray content = m_submissionContext->downloadBufferContent(buffer); - m_sendBufferCaptureJob->addRequest(QPair<Qt3DCore::QNodeId, QByteArray>(bufferId, content)); - } -} - -// Happens in RenderThread context when all RenderViewJobs are done -// Returns the id of the last bound FBO -Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Render::RenderView *> &renderViews) -{ - QElapsedTimer timer; - quint64 queueElapsed = 0; - timer.start(); - - const int renderViewsCount = renderViews.size(); - quint64 frameElapsed = queueElapsed; - m_lastFrameCorrect.storeRelaxed(1); // everything fine until now..... - - qCDebug(Memory) << Q_FUNC_INFO << "rendering frame "; - - // We might not want to render on the default FBO - uint lastBoundFBOId = m_submissionContext->boundFrameBufferObject(); - QSurface *surface = nullptr; - QSurface *previousSurface = nullptr; - for (const Render::RenderView *rv: renderViews) { - previousSurface = rv->surface(); - if (previousSurface) - break; - } - QSurface *lastUsedSurface = nullptr; - - bool imGuiOverlayShown = false; - for (int i = 0; i < renderViewsCount; ++i) { - // Initialize GraphicsContext for drawing - // If the RenderView has a RenderStateSet defined - const RenderView *renderView = renderViews.at(i); - - // Check if using the same surface as the previous RenderView. - // If not, we have to free up the context from the previous surface - // and make the context current on the new surface - surface = renderView->surface(); - SurfaceLocker surfaceLock(surface); - - // TO DO: Make sure that the surface we are rendering too has not been unset - - // For now, if we do not have a surface, skip this renderview - // TODO: Investigate if it's worth providing a fallback offscreen surface - // to use when surface is null. Or if we should instead expose an - // offscreensurface to Qt3D. - if (!surface || !surfaceLock.isSurfaceValid()) { - m_lastFrameCorrect.storeRelaxed(0); - continue; - } - - lastUsedSurface = surface; - const bool surfaceHasChanged = surface != previousSurface; - - if (surfaceHasChanged && previousSurface) { - const bool swapBuffers = lastBoundFBOId == m_submissionContext->defaultFBO() - && surfaceLock.isSurfaceValid() - && m_shouldSwapBuffers; - // We only call swap buffer if we are sure the previous surface is still valid - m_submissionContext->endDrawing(swapBuffers); - } - - if (surfaceHasChanged) { - // If we can't make the context current on the surface, skip to the - // next RenderView. We won't get the full frame but we may get something - if (!m_submissionContext->beginDrawing(surface)) { - qWarning() << "Failed to make OpenGL context current on surface"; - m_lastFrameCorrect.storeRelaxed(0); - continue; - } - - previousSurface = surface; - lastBoundFBOId = m_submissionContext->boundFrameBufferObject(); - } - - // Apply Memory Barrier if needed - if (renderView->memoryBarrier() != QMemoryBarrier::None) - m_submissionContext->memoryBarrier(renderView->memoryBarrier()); - - - // Insert Fence into command stream if needed - const Qt3DCore::QNodeIdVector insertFenceIds = renderView->insertFenceIds(); - GLFenceManager *fenceManager = m_glResourceManagers->glFenceManager(); - for (const Qt3DCore::QNodeId insertFenceId : insertFenceIds) { - // If the fence is not in the manager, then it hasn't been inserted - // into the command stream yet. - if (fenceManager->find(insertFenceId) == fenceManager->end()) { - // Insert fence into command stream - GLFence glFence = m_submissionContext->fenceSync(); - // Record glFence - fenceManager->insert(insertFenceId, glFence); - // Add entry for notification changes to be sent - m_updatedSetFences.push_back({insertFenceId, glFence}); - } - // If it is in the manager, then it hasn't been signaled yet, - // nothing we can do but try at the next frame - } - - // Wait for fences if needed - const QVector<QWaitFenceData> waitFences = renderView->waitFences(); - for (const QWaitFenceData &waitFence : waitFences) { - // TO DO - if (waitFence.handleType != QWaitFence::OpenGLFenceId) { - qWarning() << "WaitFence handleType should be OpenGLFenceId when using the Qt 3D OpenGL renderer"; - continue; - } - GLFence fence = reinterpret_cast<GLFence>(waitFence.handle.value<qintptr>()); - if (fence == nullptr) - continue; - - if (waitFence.waitOnCPU) { - m_submissionContext->clientWaitSync(fence, - waitFence.timeout); - } else { - m_submissionContext->waitSync(fence); - } - } - - // Note: the RenderStateSet is allocated once per RV if needed - // and it contains a list of StateVariant value types - RenderStateSet *renderViewStateSet = renderView->stateSet(); - - { - Profiling::GLTimeRecorder recorder(Profiling::StateUpdate, activeProfiler()); - // Set the RV state if not null, - if (renderViewStateSet != nullptr) - m_submissionContext->setCurrentStateSet(renderViewStateSet); - else - m_submissionContext->setCurrentStateSet(m_defaultRenderStateSet); - } - - // Set RenderTarget ... - // Activate RenderTarget - { - Profiling::GLTimeRecorder recorder(Profiling::RenderTargetUpdate, activeProfiler()); - m_submissionContext->activateRenderTarget(renderView->renderTargetId(), - renderView->attachmentPack(), - lastBoundFBOId); - } - - { - Profiling::GLTimeRecorder recorder(Profiling::ClearBuffer, activeProfiler()); - // set color, depth, stencil clear values (only if needed) - auto clearBufferTypes = renderView->clearTypes(); - if (clearBufferTypes & QClearBuffers::ColorBuffer) { - const QVector4D vCol = renderView->globalClearColorBufferInfo().clearColor; - m_submissionContext->clearColor(QColor::fromRgbF(vCol.x(), vCol.y(), vCol.z(), vCol.w())); - } - if (clearBufferTypes & QClearBuffers::DepthBuffer) - m_submissionContext->clearDepthValue(renderView->clearDepthValue()); - if (clearBufferTypes & QClearBuffers::StencilBuffer) - m_submissionContext->clearStencilValue(renderView->clearStencilValue()); - - // Clear BackBuffer - m_submissionContext->clearBackBuffer(clearBufferTypes); - - // if there are ClearColors set for different draw buffers, - // clear each of these draw buffers individually now - const QVector<ClearBufferInfo> clearDrawBuffers = renderView->specificClearColorBufferInfo(); - for (const ClearBufferInfo &clearBuffer : clearDrawBuffers) - m_submissionContext->clearBufferf(clearBuffer.drawBufferIndex, clearBuffer.clearColor); - } - - // Set the Viewport - m_submissionContext->setViewport(renderView->viewport(), renderView->surfaceSize()); - - // Execute the render commands - if (!executeCommandsSubmission(renderView)) - m_lastFrameCorrect.storeRelaxed(0); // something went wrong; make sure to render the next frame! - - // executeCommandsSubmission takes care of restoring the stateset to the value - // of gc->currentContext() at the moment it was called (either - // renderViewStateSet or m_defaultRenderStateSet) - if (!renderView->renderCaptureNodeId().isNull()) { - const QRenderCaptureRequest request = renderView->renderCaptureRequest(); - const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize()); - QRect rect(QPoint(0, 0), size); - if (!request.rect.isEmpty()) - rect = rect.intersected(request.rect); - QImage image; - if (!rect.isEmpty()) { - // Bind fbo as read framebuffer - m_submissionContext->bindFramebuffer(m_submissionContext->activeFBO(), GraphicsHelperInterface::FBORead); - image = m_submissionContext->readFramebuffer(rect); - } else { - qWarning() << "Requested capture rectangle is outside framebuffer"; - } - Render::RenderCapture *renderCapture = - static_cast<Render::RenderCapture*>(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId())); - renderCapture->addRenderCapture(request.captureId, image); - if (!m_pendingRenderCaptureSendRequests.contains(renderView->renderCaptureNodeId())) - m_pendingRenderCaptureSendRequests.push_back(renderView->renderCaptureNodeId()); - } - - if (renderView->isDownloadBuffersEnable()) - downloadGLBuffers(); - - // Perform BlitFramebuffer operations - if (renderView->hasBlitFramebufferInfo()) { - const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo(); - const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId; - const QNodeId outputTargetId = blitFramebufferInfo.destinationRenderTargetId; - const QRect inputRect = blitFramebufferInfo.sourceRect; - const QRect outputRect = blitFramebufferInfo.destinationRect; - const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = blitFramebufferInfo.sourceAttachmentPoint; - const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = blitFramebufferInfo.destinationAttachmentPoint; - const QBlitFramebuffer::InterpolationMethod interpolationMethod = blitFramebufferInfo.interpolationMethod; - m_submissionContext->blitFramebuffer(inputTargetId, outputTargetId, inputRect, outputRect, lastBoundFBOId, - inputAttachmentPoint, outputAttachmentPoint, - interpolationMethod); - } - -#ifndef Q_OS_INTEGRITY - if (!imGuiOverlayShown && renderView->showDebugOverlay()) { - imGuiOverlayShown = true; - if (!m_imGuiRenderer) { - m_imGuiRenderer = new Debug::ImGuiRenderer(this); - if (m_settings) - m_imGuiRenderer->setCapabilities(m_settings->capabilities()); - } - - { - QMutexLocker l(&m_frameEventsMutex); - for (auto &keyEvent: m_frameKeyEvents) - m_imGuiRenderer->processEvent(&keyEvent); - for (auto &mouseEvent: m_frameMouseEvents) - m_imGuiRenderer->processEvent(&mouseEvent.second); - } - m_imGuiRenderer->renderDebugOverlay(renderViews, renderView, m_jobsInLastFrame); - } -#endif - - frameElapsed = timer.elapsed() - frameElapsed; - qCDebug(Rendering) << Q_FUNC_INFO << "Submitted Renderview " << i + 1 << "/" << renderViewsCount << "in " << frameElapsed << "ms"; - frameElapsed = timer.elapsed(); - } - - // Bind lastBoundFBOId back. Needed also in threaded mode. - // lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf node/renderView - // contains RenderTargetSelector/RenderTarget - if (lastBoundFBOId != m_submissionContext->activeFBO()) - m_submissionContext->bindFramebuffer(lastBoundFBOId, GraphicsHelperInterface::FBOReadAndDraw); - - // Reset state and call doneCurrent if the surface - // is valid and was actually activated - if (lastUsedSurface && m_submissionContext->hasValidGLHelper()) { - // Reset state to the default state if the last stateset is not the - // defaultRenderStateSet - if (m_submissionContext->currentStateSet() != m_defaultRenderStateSet) - m_submissionContext->setCurrentStateSet(m_defaultRenderStateSet); - } - - queueElapsed = timer.elapsed() - queueElapsed; - qCDebug(Rendering) << Q_FUNC_INFO << "Submission of Queue in " << queueElapsed << "ms <=> " << queueElapsed / renderViewsCount << "ms per RenderView <=> Avg " << 1000.0f / (queueElapsed * 1.0f/ renderViewsCount * 1.0f) << " RenderView/s"; - qCDebug(Rendering) << Q_FUNC_INFO << "Submission Completed in " << timer.elapsed() << "ms"; - - // Stores the necessary information to safely perform - // the last swap buffer call - ViewSubmissionResultData resultData; - resultData.lastBoundFBOId = lastBoundFBOId; - resultData.surface = lastUsedSurface; - return resultData; -} - -void Renderer::markDirty(BackendNodeDirtySet changes, BackendNode *node) -{ - Q_UNUSED(node) - m_dirtyBits.marked |= changes; -} - -Renderer::BackendNodeDirtySet Renderer::dirtyBits() -{ - return m_dirtyBits.marked; -} - -#if defined(QT_BUILD_INTERNAL) -void Renderer::clearDirtyBits(BackendNodeDirtySet changes) -{ - m_dirtyBits.remaining &= ~changes; - m_dirtyBits.marked &= ~changes; -} -#endif - -bool Renderer::shouldRender() const -{ - // Only render if something changed during the last frame, or the last frame - // was not rendered successfully (or render-on-demand is disabled) - return (m_settings->renderPolicy() == QRenderSettings::Always - || m_dirtyBits.marked != 0 - || m_dirtyBits.remaining != 0 - || !m_lastFrameCorrect.loadRelaxed()); -} - -void Renderer::skipNextFrame() -{ - Q_ASSERT(m_settings->renderPolicy() != QRenderSettings::Always); - - // make submitRenderViews() actually run - m_renderQueue->setNoRender(); - m_submitRenderViewsSemaphore.release(1); -} - -void Renderer::jobsDone(Qt3DCore::QAspectManager *manager) -{ - // called in main thread once all jobs are done running - - // sync captured renders to frontend - const QVector<Qt3DCore::QNodeId> pendingCaptureIds = std::move(m_pendingRenderCaptureSendRequests); - for (const Qt3DCore::QNodeId &id : qAsConst(pendingCaptureIds)) { - auto *backend = static_cast<Qt3DRender::Render::RenderCapture *> - (m_nodesManager->frameGraphManager()->lookupNode(id)); - backend->syncRenderCapturesToFrontend(manager); - } - - // Do we need to notify any texture about property changes? - if (m_updatedTextureProperties.size() > 0) - sendTextureChangesToFrontend(manager); - - sendDisablesToFrontend(manager); -} - -// Jobs we may have to run even if no rendering will happen -QVector<QAspectJobPtr> Renderer::preRenderingJobs() -{ - { - QMutexLocker l(&m_frameEventsMutex); - m_frameMouseEvents = m_pickEventFilter->pendingMouseEvents(); - m_frameKeyEvents = m_pickEventFilter->pendingKeyEvents(); - } - - // Set values on picking jobs - RenderSettings *renderSetting = settings(); - if (renderSetting != nullptr) { - m_pickBoundingVolumeJob->setRenderSettings(renderSetting); - m_pickBoundingVolumeJob->setFrameGraphRoot(frameGraphRoot()); - m_pickBoundingVolumeJob->setMouseEvents(m_frameMouseEvents); - m_pickBoundingVolumeJob->setKeyEvents(m_frameKeyEvents); - - m_rayCastingJob->setRenderSettings(renderSetting); - m_rayCastingJob->setFrameGraphRoot(frameGraphRoot()); - } - - QVector<QAspectJobPtr> jobs; - - // Do we need to notify frontend about fence change? - if (m_updatedSetFences.size() > 0) - jobs.push_back(m_sendSetFenceHandlesToFrontendJob); - - if (m_sendBufferCaptureJob->hasRequests()) - jobs.push_back(m_sendBufferCaptureJob); - - jobs.append(pickBoundingVolumeJob()); - jobs.append(rayCastingJob()); - - return jobs; -} - -// Waits to be told to create jobs for the next frame -// Called by QRenderAspect jobsToExecute context of QAspectThread -// Returns all the jobs (and with proper dependency chain) required -// for the rendering of the scene -QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() -{ - QVector<QAspectJobPtr> renderBinJobs; - // Create the jobs to build the frame - const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs(); - - // Remove previous dependencies - m_calculateBoundingVolumeJob->removeDependency(QWeakPointer<QAspectJob>()); - m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>()); - - // Set dependencies - for (const QAspectJobPtr &bufferJob : bufferJobs) - m_calculateBoundingVolumeJob->addDependency(bufferJob); - - m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot()); - - const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining; - m_dirtyBits.marked = {}; - m_dirtyBits.remaining = {}; - BackendNodeDirtySet notCleared = {}; - - // Add jobs - const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty; - if (entitiesEnabledDirty) { - renderBinJobs.push_back(m_updateTreeEnabledJob); - // This dependency is added here because we clear all dependencies - // at the start of this function. - m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob); - } - - if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) { - renderBinJobs.push_back(m_worldTransformJob); - renderBinJobs.push_back(m_updateWorldBoundingVolumeJob); - renderBinJobs.push_back(m_updateShaderDataTransformJob); - } - - if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty || - dirtyBitsForFrame & AbstractRenderer::BuffersDirty) { - renderBinJobs.push_back(m_calculateBoundingVolumeJob); - renderBinJobs.push_back(m_updateMeshTriangleListJob); - } - - if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty || - dirtyBitsForFrame & AbstractRenderer::TransformDirty) { - renderBinJobs.push_back(m_expandBoundingVolumeJob); - } - - // TO DO: Conditionally add if skeletons dirty - renderBinJobs.push_back(m_syncLoadingJobs); - m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints()); - renderBinJobs.push_back(m_updateSkinningPaletteJob); - renderBinJobs.push_back(m_updateLevelOfDetailJob); - renderBinJobs.push_back(m_cleanupJob); - renderBinJobs.append(bufferJobs); - - // Jobs to prepare GL Resource upload - renderBinJobs.push_back(m_vaoGathererJob); - - if (dirtyBitsForFrame & AbstractRenderer::BuffersDirty) - renderBinJobs.push_back(m_bufferGathererJob); - - if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) - renderBinJobs.push_back(m_textureGathererJob); - - - // Layer cache is dependent on layers, layer filters (hence FG structure - // changes) and the enabled flag on entities - const bool frameGraphDirty = dirtyBitsForFrame & AbstractRenderer::FrameGraphDirty; - const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty; - const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty || frameGraphDirty; - const bool shadersDirty = dirtyBitsForFrame & AbstractRenderer::ShadersDirty; - const bool materialDirty = dirtyBitsForFrame & AbstractRenderer::MaterialDirty; - const bool lightsDirty = dirtyBitsForFrame & AbstractRenderer::LightsDirty; - const bool computeableDirty = dirtyBitsForFrame & AbstractRenderer::ComputeDirty; - const bool renderableDirty = dirtyBitsForFrame & AbstractRenderer::GeometryDirty; - const bool materialCacheNeedsToBeRebuilt = shadersDirty || materialDirty || frameGraphDirty; - const bool renderCommandsDirty = materialCacheNeedsToBeRebuilt || renderableDirty || computeableDirty; - - // Rebuild Entity Layers list if layers are dirty - if (layersDirty) - renderBinJobs.push_back(m_updateEntityLayersJob); - - if (renderableDirty) { - renderBinJobs.push_back(m_renderableEntityFilterJob); - renderBinJobs.push_back(m_cacheRenderableEntitiesJob); - } - - if (computeableDirty) { - renderBinJobs.push_back(m_computableEntityFilterJob); - renderBinJobs.push_back(m_cacheComputableEntitiesJob); - } - - if (lightsDirty) { - renderBinJobs.push_back(m_lightGathererJob); - renderBinJobs.push_back(m_cacheLightsJob); - } - - QMutexLocker lock(m_renderQueue->mutex()); - if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case) - // Traverse the current framegraph. For each leaf node create a - // RenderView and set its configuration then create a job to - // populate the RenderView with a set of RenderCommands that get - // their details from the RenderNodes that are visible to the - // Camera selected by the framegraph configuration - if (frameGraphDirty) { - FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); - m_frameGraphLeaves = visitor.traverse(frameGraphRoot()); - // Remove leaf nodes that no longer exist from cache - const QList<FrameGraphNode *> keys = m_cache.leafNodeCache.keys(); - for (FrameGraphNode *leafNode : keys) { - if (!m_frameGraphLeaves.contains(leafNode)) - m_cache.leafNodeCache.remove(leafNode); - } - - // Handle single shot subtree enablers - const auto subtreeEnablers = visitor.takeEnablersToDisable(); - for (auto *node : subtreeEnablers) - m_updatedDisableSubtreeEnablers.push_back(node->peerId()); - } - - const int fgBranchCount = m_frameGraphLeaves.size(); - for (int i = 0; i < fgBranchCount; ++i) { - FrameGraphNode *leaf = m_frameGraphLeaves.at(i); - RenderViewBuilder builder(leaf, i, this); - // If we have a new RV (wasn't in the cache before, then it contains no cached data) - const bool isNewRV = !m_cache.leafNodeCache.contains(leaf); - builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt || isNewRV); - builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt || isNewRV); - builder.setRenderCommandCacheNeedsToBeRebuilt(renderCommandsDirty || isNewRV); - - builder.prepareJobs(); - renderBinJobs.append(builder.buildJobHierachy()); - } - - // Set target number of RenderViews - m_renderQueue->setTargetRenderViewCount(fgBranchCount); - } else { - // FilterLayerEntityJob is part of the RenderViewBuilder jobs and must be run later - // if none of those jobs are started this frame - notCleared |= AbstractRenderer::EntityEnabledDirty; - notCleared |= AbstractRenderer::FrameGraphDirty; - notCleared |= AbstractRenderer::LayersDirty; - } - - if (isRunning() && m_submissionContext->isInitialized()) { - if (dirtyBitsForFrame & AbstractRenderer::TechniquesDirty ) - renderBinJobs.push_back(m_filterCompatibleTechniqueJob); - if (dirtyBitsForFrame & AbstractRenderer::ShadersDirty) - renderBinJobs.push_back(m_introspectShaderJob); - } else { - notCleared |= AbstractRenderer::TechniquesDirty; - notCleared |= AbstractRenderer::ShadersDirty; - } - - m_dirtyBits.remaining = dirtyBitsForFrame & notCleared; - - return renderBinJobs; -} - -QAspectJobPtr Renderer::pickBoundingVolumeJob() -{ - return m_pickBoundingVolumeJob; -} - -QAspectJobPtr Renderer::rayCastingJob() -{ - return m_rayCastingJob; -} - -QAspectJobPtr Renderer::syncLoadingJobs() -{ - return m_syncLoadingJobs; -} - -QAspectJobPtr Renderer::expandBoundingVolumeJob() -{ - return m_expandBoundingVolumeJob; -} - -QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const -{ - return static_cast<Qt3DCore::QAbstractFrameAdvanceService *>(m_vsyncFrameAdvanceService.data()); -} - -// Called by executeCommands -void Renderer::performDraw(RenderCommand *command) -{ - // Indirect Draw Calls - if (command->m_drawIndirect) { - - // Bind the indirect draw buffer - Buffer *indirectDrawBuffer = m_nodesManager->bufferManager()->data(command->m_indirectDrawBuffer); - if (Q_UNLIKELY(indirectDrawBuffer == nullptr)) { - qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve Buffer"; - return; - } - - // Get GLBuffer from Buffer; - GLBuffer *indirectDrawGLBuffer = m_submissionContext->glBufferForRenderBuffer(indirectDrawBuffer); - if (Q_UNLIKELY(indirectDrawGLBuffer == nullptr)) { - qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve GLBuffer"; - return; - } - - // Bind GLBuffer - const bool successfullyBound = indirectDrawGLBuffer->bind(m_submissionContext.data(), GLBuffer::DrawIndirectBuffer); - - if (Q_LIKELY(successfullyBound)) { - // TO DO: Handle multi draw variants if attribute count > 1 - if (command->m_drawIndexed) { - m_submissionContext->drawElementsIndirect(command->m_primitiveType, - command->m_indexAttributeDataType, - reinterpret_cast<void*>(quintptr(command->m_indirectAttributeByteOffset))); - } else { - m_submissionContext->drawArraysIndirect(command->m_primitiveType, - reinterpret_cast<void*>(quintptr(command->m_indirectAttributeByteOffset))); - } - } else { - qWarning() << "Failed to bind IndirectDrawBuffer"; - } - - } else { // Direct Draw Calls - - // TO DO: Add glMulti Draw variants - if (command->m_primitiveType == QGeometryRenderer::Patches) - m_submissionContext->setVerticesPerPatch(command->m_verticesPerPatch); - - if (command->m_primitiveRestartEnabled) - m_submissionContext->enablePrimitiveRestart(command->m_restartIndexValue); - - // TO DO: Add glMulti Draw variants - if (command->m_drawIndexed) { - Profiling::GLTimeRecorder recorder(Profiling::DrawElement, activeProfiler()); - m_submissionContext->drawElementsInstancedBaseVertexBaseInstance(command->m_primitiveType, - command->m_primitiveCount, - command->m_indexAttributeDataType, - reinterpret_cast<void*>(quintptr(command->m_indexAttributeByteOffset)), - command->m_instanceCount, - command->m_indexOffset, - command->m_firstInstance); - } else { - Profiling::GLTimeRecorder recorder(Profiling::DrawArray, activeProfiler()); - m_submissionContext->drawArraysInstancedBaseInstance(command->m_primitiveType, - command->m_firstVertex, - command->m_primitiveCount, - command->m_instanceCount, - command->m_firstInstance); - } - } - -#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG) - int err = m_submissionContext->openGLContext()->functions()->glGetError(); - if (err) - qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); -#endif - - if (command->m_primitiveRestartEnabled) - m_submissionContext->disablePrimitiveRestart(); -} - -void Renderer::performCompute(const RenderView *, RenderCommand *command) -{ - { - Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate, activeProfiler()); - GLShader *shader = m_glResourceManagers->glShaderManager()->lookupResource(command->m_shaderId); - m_submissionContext->activateShader(shader); - } - { - Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate, activeProfiler()); - m_submissionContext->setParameters(command->m_parameterPack); - } - { - Profiling::GLTimeRecorder recorder(Profiling::DispatchCompute, activeProfiler()); - m_submissionContext->dispatchCompute(command->m_workGroups[0], - command->m_workGroups[1], - command->m_workGroups[2]); - } - // HACK: Reset the compute flag to dirty - m_dirtyBits.marked |= AbstractRenderer::ComputeDirty; - -#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG) - int err = m_submissionContext->openGLContext()->functions()->glGetError(); - if (err) - qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); -#endif -} - -void Renderer::createOrUpdateVAO(RenderCommand *command, - HVao *previousVaoHandle, - OpenGLVertexArrayObject **vao) -{ - const VAOIdentifier vaoKey(command->m_geometry, command->m_shaderId); - - VAOManager *vaoManager = m_glResourceManagers->vaoManager(); - command->m_vao = vaoManager->lookupHandle(vaoKey); - - if (command->m_vao.isNull()) { - qCDebug(Rendering) << Q_FUNC_INFO << "Allocating new VAO"; - command->m_vao = vaoManager->getOrAcquireHandle(vaoKey); - vaoManager->data(command->m_vao)->create(m_submissionContext.data(), vaoKey); - } - - if (*previousVaoHandle != command->m_vao) { - *previousVaoHandle = command->m_vao; - *vao = vaoManager->data(command->m_vao); - } - Q_ASSERT(*vao); -} - -// Called by RenderView->submit() in RenderThread context -// Returns true, if all RenderCommands were sent to the GPU -bool Renderer::executeCommandsSubmission(const RenderView *rv) -{ - bool allCommandsIssued = true; - - // Render drawing commands - QVector<RenderCommand> commands = rv->commands(); - - // Use the graphicscontext to submit the commands to the underlying - // graphics API (OpenGL) - - // Save the RenderView base stateset - RenderStateSet *globalState = m_submissionContext->currentStateSet(); - OpenGLVertexArrayObject *vao = nullptr; - - for (RenderCommand &command : commands) { - - if (command.m_type == RenderCommand::Compute) { // Compute Call - performCompute(rv, &command); - } else { // Draw Command - // Check if we have a valid command that can be drawn - if (!command.m_isValid) { - allCommandsIssued = false; - continue; - } - - vao = m_glResourceManagers->vaoManager()->data(command.m_vao); - - // something may have went wrong when initializing the VAO - if (!vao->isSpecified()) { - allCommandsIssued = false; - continue; - } - - { - Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate, activeProfiler()); - //// We activate the shader here - GLShader *shader = command.m_glShader; - if (!m_submissionContext->activateShader(shader)) { - allCommandsIssued = false; - continue; - } - } - - { - Profiling::GLTimeRecorder recorder(Profiling::VAOUpdate, activeProfiler()); - // Bind VAO - vao->bind(); - } - - { - Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate, activeProfiler()); - //// Update program uniforms - if (!m_submissionContext->setParameters(command.m_parameterPack)) { - allCommandsIssued = false; - // If we have failed to set uniform (e.g unable to bind a texture) - // we won't perform the draw call which could show invalid content - continue; - } - } - - //// OpenGL State - // TO DO: Make states not dependendent on their backend node for this step - // Set state - RenderStateSet *localState = command.m_stateSet.data(); - - - { - Profiling::GLTimeRecorder recorder(Profiling::StateUpdate, activeProfiler()); - // Merge the RenderCommand state with the globalState of the RenderView - // Or restore the globalState if no stateSet for the RenderCommand - if (localState != nullptr) { - command.m_stateSet->merge(globalState); - m_submissionContext->setCurrentStateSet(localState); - } else { - m_submissionContext->setCurrentStateSet(globalState); - } - } - // All Uniforms for a pass are stored in the QUniformPack of the command - // Uniforms for Effect, Material and Technique should already have been correctly resolved - // at that point - - //// Draw Calls - performDraw(&command); - } - } // end of RenderCommands loop - - // We cache the VAO and release it only at the end of the exectute frame - // We try to minimize VAO binding between RenderCommands - if (vao) - vao->release(); - - // Reset to the state we were in before executing the render commands - m_submissionContext->setCurrentStateSet(globalState); - - return allCommandsIssued; -} - -bool Renderer::updateVAOWithAttributes(Geometry *geometry, - const RenderCommand *command, - GLShader *shader, - bool forceUpdate) -{ - m_dirtyAttributes.reserve(m_dirtyAttributes.size() + geometry->attributes().size()); - const auto attributeIds = geometry->attributes(); - - for (QNodeId attributeId : attributeIds) { - // TO DO: Improvement we could store handles and use the non locking policy on the attributeManager - Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId); - - if (attribute == nullptr) - return false; - - Buffer *buffer = m_nodesManager->bufferManager()->lookupResource(attribute->bufferId()); - - // Buffer update was already performed at this point - // Just make sure the attribute reference a valid buffer - if (buffer == nullptr) - return false; - - // Index Attribute - bool attributeWasDirty = false; - if (attribute->attributeType() == QAttribute::IndexAttribute) { - if ((attributeWasDirty = attribute->isDirty()) == true || forceUpdate) - m_submissionContext->specifyIndices(buffer); - // Vertex Attribute - } else if (command->m_activeAttributes.contains(attribute->nameId())) { - if ((attributeWasDirty = attribute->isDirty()) == true || forceUpdate) { - // Find the location for the attribute - const QVector<ShaderAttribute> shaderAttributes = shader->attributes(); - const ShaderAttribute *attributeDescription = nullptr; - for (const ShaderAttribute &shaderAttribute : shaderAttributes) { - if (shaderAttribute.m_nameId == attribute->nameId()) { - attributeDescription = &shaderAttribute; - break; - } - } - if (!attributeDescription || attributeDescription->m_location < 0) - return false; - m_submissionContext->specifyAttribute(attribute, buffer, attributeDescription); - } - } - - // Append attribute to temporary vector so that its dirtiness - // can be cleared at the end of the frame - if (attributeWasDirty) - m_dirtyAttributes.push_back(attribute); - - // Note: We cannot call unsertDirty on the Attribute at this - // point as we don't know if the attributes are being shared - // with other geometry / geometryRenderer in which case they still - // should remain dirty so that VAO for these commands are properly - // updated - } - - return true; -} - -bool Renderer::requiresVAOAttributeUpdate(Geometry *geometry, - const RenderCommand *command) const -{ - const auto attributeIds = geometry->attributes(); - - for (QNodeId attributeId : attributeIds) { - // TO DO: Improvement we could store handles and use the non locking policy on the attributeManager - Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId); - - if (attribute == nullptr) - continue; - - if ((attribute->attributeType() == QAttribute::IndexAttribute && attribute->isDirty()) || - (command->m_activeAttributes.contains(attribute->nameId()) && attribute->isDirty())) - return true; - } - return false; -} - -// Erase graphics related resources that may become unused after a frame -void Renderer::cleanGraphicsResources() -{ - // Clean buffers - const QVector<Qt3DCore::QNodeId> buffersToRelease = m_nodesManager->bufferManager()->takeBuffersToRelease(); - for (Qt3DCore::QNodeId bufferId : buffersToRelease) - m_submissionContext->releaseBuffer(bufferId); - - // When Textures are cleaned up, their id is saved so that they can be - // cleaned up in the render thread - const QVector<Qt3DCore::QNodeId> cleanedUpTextureIds = std::move(m_textureIdsToCleanup); - for (const Qt3DCore::QNodeId textureCleanedUpId: cleanedUpTextureIds) - cleanupTexture(textureCleanedUpId); - - // Delete abandoned VAOs - m_abandonedVaosMutex.lock(); - const QVector<HVao> abandonedVaos = std::move(m_abandonedVaos); - m_abandonedVaosMutex.unlock(); - for (const HVao &vaoHandle : abandonedVaos) { - // might have already been destroyed last frame, but added by the cleanup job before, so - // check if the VAO is really still existent - OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(vaoHandle); - if (vao) { - vao->destroy(); - // We remove VAO from manager using its VAOIdentifier - m_glResourceManagers->vaoManager()->release(vaoHandle); - } - } - - // Abandon GL shaders when a Shader node is destroyed Note: We are sure - // that when this gets executed, all scene changes have been received and - // shader nodes updated - const QVector<Qt3DCore::QNodeId> cleanedUpShaderIds = m_nodesManager->shaderManager()->takeShaderIdsToCleanup(); - for (const Qt3DCore::QNodeId shaderCleanedUpId: cleanedUpShaderIds) { - cleanupShader(m_nodesManager->shaderManager()->lookupResource(shaderCleanedUpId)); - // We can really release the texture at this point - m_nodesManager->shaderManager()->releaseResource(shaderCleanedUpId); - } -} - -const GraphicsApiFilterData *Renderer::contextInfo() const -{ - return m_submissionContext->contextInfo(); -} - -SubmissionContext *Renderer::submissionContext() const -{ - return m_submissionContext.data(); -} - -// Returns a vector of jobs to be performed for dirty buffers -// 1 dirty buffer == 1 job, all job can be performed in parallel -QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBufferJobs() const -{ - const QVector<QNodeId> dirtyBuffers = m_nodesManager->bufferManager()->takeDirtyBuffers(); - QVector<QAspectJobPtr> dirtyBuffersJobs; - dirtyBuffersJobs.reserve(dirtyBuffers.size()); - - for (const QNodeId bufId : dirtyBuffers) { - Render::HBuffer bufferHandle = m_nodesManager->lookupHandle<Render::Buffer, Render::BufferManager, Render::HBuffer>(bufId); - if (!bufferHandle.isNull()) { - // Create new buffer job - auto job = Render::LoadBufferJobPtr::create(bufferHandle); - job->setNodeManager(m_nodesManager); - dirtyBuffersJobs.push_back(job); - } - } - - return dirtyBuffersJobs; -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/renderer.pri b/src/render/renderers/opengl/renderer/renderer.pri deleted file mode 100644 index 3e2f9fde9..000000000 --- a/src/render/renderers/opengl/renderer/renderer.pri +++ /dev/null @@ -1,24 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/openglvertexarrayobject.cpp \ - $$PWD/rendercommand.cpp \ - $$PWD/renderer.cpp \ - $$PWD/renderqueue.cpp \ - $$PWD/renderview.cpp \ - $$PWD/renderviewbuilder.cpp \ - $$PWD/shaderparameterpack.cpp \ - $$PWD/glshader.cpp - -HEADERS += \ - $$PWD/openglvertexarrayobject_p.h \ - $$PWD/renderercache_p.h \ - $$PWD/rendercommand_p.h \ - $$PWD/renderer_p.h \ - $$PWD/renderqueue_p.h \ - $$PWD/renderview_p.h \ - $$PWD/renderviewbuilder_p.h \ - $$PWD/shaderparameterpack_p.h \ - $$PWD/shadervariables_p.h \ - $$PWD/glshader_p.h - diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h deleted file mode 100644 index e8929e67a..000000000 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ /dev/null @@ -1,477 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERER_H -#define QT3DRENDER_RENDER_RENDERER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qrenderaspect.h> -#include <Qt3DRender/qtechnique.h> -#include <Qt3DRender/private/shaderparameterpack_p.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/gl_handle_types_p.h> -#include <Qt3DRender/private/abstractrenderer_p.h> -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/qt3drender_global_p.h> -#include <Qt3DRender/private/pickboundingvolumejob_p.h> -#include <Qt3DRender/private/raycastingjob_p.h> -#include <Qt3DRender/private/rendersettings_p.h> -#include <Qt3DRender/private/renderviewinitializerjob_p.h> -#include <Qt3DRender/private/expandboundingvolumejob_p.h> -#include <Qt3DRender/private/updateworldtransformjob_p.h> -#include <Qt3DRender/private/calcboundingvolumejob_p.h> -#include <Qt3DRender/private/updateshaderdatatransformjob_p.h> -#include <Qt3DRender/private/framecleanupjob_p.h> -#include <Qt3DRender/private/updateworldboundingvolumejob_p.h> -#include <Qt3DRender/private/updatetreeenabledjob_p.h> -#include <Qt3DRender/private/platformsurfacefilter_p.h> -#include <Qt3DRender/private/sendbuffercapturejob_p.h> -#include <Qt3DRender/private/genericlambdajob_p.h> -#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h> -#include <Qt3DRender/private/filtercompatibletechniquejob_p.h> -#include <Qt3DRender/private/updateskinningpalettejob_p.h> -#include <Qt3DRender/private/updateentitylayersjob_p.h> -#include <Qt3DRender/private/renderercache_p.h> -#include <Qt3DRender/private/texture_p.h> -#include <Qt3DRender/private/glfence_p.h> -#include <Qt3DRender/private/shaderbuilder_p.h> -#include <Qt3DRender/private/lightgatherer_p.h> - -#include <QHash> -#include <QMatrix4x4> -#include <QObject> - -#include <QOpenGLShaderProgram> -#include <QOpenGLVertexArrayObject> -#include <QOpenGLBuffer> -#include <QMutex> -#include <QWaitCondition> -#include <QAtomicInt> -#include <QScopedPointer> -#include <QSemaphore> - -#include <functional> - -#if defined(QT_BUILD_INTERNAL) -class tst_Renderer; -#endif - -QT_BEGIN_NAMESPACE - -class QSurface; -class QMouseEvent; -class QScreen; - -namespace Qt3DCore { -class QEntity; -class QFrameAllocator; -class QEventFilterService; -} - -namespace Qt3DRender { - -class QCamera; -class QMaterial; -class QShaderProgram; -class QMesh; -class QRenderPass; -class QAbstractShapeMesh; -struct GraphicsApiFilterData; -class QSceneImporter; - -namespace Debug { -class CommandExecuter; -} - -namespace Render { - -namespace Profiling { -class FrameProfiler; -} - -class CameraLens; -class SubmissionContext; -class FrameGraphNode; -class Material; -class Technique; -class Shader; -class Entity; -class RenderCommand; -class RenderQueue; -class RenderView; -class Effect; -class RenderPass; -class RenderThread; -class RenderStateSet; -class VSyncFrameAdvanceService; -class PickEventFilter; -class NodeManagers; -class GLResourceManagers; -class GLShader; -class ResourceAccessor; - -class UpdateLevelOfDetailJob; -typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr; - -using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; -using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>; - -template<typename T, typename ... Ts> -class FilterEntityByComponentJob; -template<typename T, typename ... Ts> -using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<T, Ts...>>; -using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>; -using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>; - -namespace Debug { -class ImGuiRenderer; -} - -class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer -{ -public: - explicit Renderer(QRenderAspect::RenderType type); - ~Renderer(); - - void dumpInfo() const override; - API api() const override { return AbstractRenderer::OpenGL; } - - qint64 time() const override; - void setTime(qint64 time) override; - void setJobsInLastFrame(int jobsInLastFrame) override; - - void setNodeManagers(NodeManagers *managers) override; - void setServices(Qt3DCore::QServiceLocator *services) override; - void setSurfaceExposed(bool exposed) override; - - NodeManagers *nodeManagers() const override; - Qt3DCore::QServiceLocator *services() const override { return m_services; } - - void initialize() override; - void shutdown() override; - void releaseGraphicsResources() override; - - void render() override; - void doRender(bool swapBuffers = true) override; - void cleanGraphicsResources() override; - - bool isRunning() const override { return m_running.loadRelaxed(); } - - void setSceneRoot(Entity *sgRoot) override; - Entity *sceneRoot() const override { return m_renderSceneRoot; } - - FrameGraphNode *frameGraphRoot() const override; - RenderQueue *renderQueue() const { return m_renderQueue; } - - void markDirty(BackendNodeDirtySet changes, BackendNode *node) override; - BackendNodeDirtySet dirtyBits() override; - -#if defined(QT_BUILD_INTERNAL) - void clearDirtyBits(BackendNodeDirtySet changes) override; -#endif - bool shouldRender() const override; - void skipNextFrame() override; - void jobsDone(Qt3DCore::QAspectManager *manager) override; - - QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override; - QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override; - Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override; - Qt3DCore::QAspectJobPtr rayCastingJob() override; - Qt3DCore::QAspectJobPtr syncLoadingJobs() override; - Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override; - - QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const; - - inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; } - inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; } - inline CalculateBoundingVolumeJobPtr calculateBoundingVolumeJob() const { return m_calculateBoundingVolumeJob; } - inline UpdateTreeEnabledJobPtr updateTreeEnabledJob() const { return m_updateTreeEnabledJob; } - inline UpdateWorldTransformJobPtr updateWorldTransformJob() const { return m_worldTransformJob; } - inline UpdateWorldBoundingVolumeJobPtr updateWorldBoundingVolumeJob() const { return m_updateWorldBoundingVolumeJob; } - inline UpdateLevelOfDetailJobPtr updateLevelOfDetailJob() const { return m_updateLevelOfDetailJob; } - inline UpdateMeshTriangleListJobPtr updateMeshTriangleListJob() const { return m_updateMeshTriangleListJob; } - inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; } - inline SynchronizerJobPtr syncLoadingJobs() const { return m_syncLoadingJobs; } - inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; } - inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; } - inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; } - inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; } - inline UpdateEntityLayersJobPtr updateEntityLayersJob() const { return m_updateEntityLayersJob; } - inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; } - inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; } - inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; } - inline SynchronizerJobPtr cacheLightJob() const { return m_cacheLightsJob; } - inline SynchronizerJobPtr cacheRenderableEntitiesJob() const { return m_cacheRenderableEntitiesJob; } - inline SynchronizerJobPtr cacheComputableEntitiesJob() const { return m_cacheComputableEntitiesJob; } - - Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override; - - void registerEventFilter(Qt3DCore::QEventFilterService *service) override; - - void setSettings(RenderSettings *settings) override; - RenderSettings *settings() const override; - QOpenGLContext *shareContext() const override; - - inline GLResourceManagers *glResourceManagers() const { return m_glResourceManagers; } - - // Executed in secondary GL thread - void loadShader(Shader *shader, Qt3DRender::Render::HShader shaderHandle) override; - - - void updateGLResources(); - void updateTexture(Texture *texture); - void cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId); - void cleanupShader(const Shader *shader); - void downloadGLBuffers(); - void blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, - Qt3DCore::QNodeId outputRenderTargetId, - QRect inputRect, - QRect outputRect, - GLuint defaultFramebuffer); - - void prepareCommandsSubmission(const QVector<RenderView *> &renderViews); - bool executeCommandsSubmission(const RenderView *rv); - bool updateVAOWithAttributes(Geometry *geometry, - const RenderCommand *command, - GLShader *shader, - bool forceUpdate); - - bool requiresVAOAttributeUpdate(Geometry *geometry, - const RenderCommand *command) const; - - // For Scene2D rendering - void setOpenGLContext(QOpenGLContext *context) override; - bool accessOpenGLTexture(Qt3DCore::QNodeId nodeId, - QOpenGLTexture **texture, - QMutex **lock, - bool readonly) override; - QSharedPointer<RenderBackendResourceAccessor> resourceAccessor() const override; - - - const GraphicsApiFilterData *contextInfo() const; - SubmissionContext *submissionContext() const; - - inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; } - - void enqueueRenderView(RenderView *renderView, int submitOrder); - bool isReadyToSubmit(); - - QVariant executeCommand(const QStringList &args) override; - void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) override; - QSurfaceFormat format() override; - - struct ViewSubmissionResultData - { - ViewSubmissionResultData() - : lastBoundFBOId(0) - , surface(nullptr) - {} - - uint lastBoundFBOId; - QSurface *surface; - }; - - ViewSubmissionResultData submitRenderViews(const QVector<Render::RenderView *> &renderViews); - - RendererCache *cache() { return &m_cache; } - void setScreen(QScreen *scr) override; - QScreen *screen() const override; - -#ifdef QT3D_RENDER_UNIT_TESTS -public: -#else - -private: -#endif - bool canRender() const; - Profiling::FrameProfiler *activeProfiler() const; - - Qt3DCore::QServiceLocator *m_services; - NodeManagers *m_nodesManager; - - // Frame graph root - Qt3DCore::QNodeId m_frameGraphRootUuid; - - Entity *m_renderSceneRoot; - - // Fail safe values that we can use if a RenderCommand - // is missing a shader - RenderStateSet *m_defaultRenderStateSet; - ShaderParameterPack m_defaultUniformPack; - - QScopedPointer<SubmissionContext> m_submissionContext; - QSurfaceFormat m_format; - - RenderQueue *m_renderQueue; - QScopedPointer<RenderThread> m_renderThread; - QScopedPointer<VSyncFrameAdvanceService> m_vsyncFrameAdvanceService; - - QSemaphore m_submitRenderViewsSemaphore; - QSemaphore m_waitForInitializationToBeCompleted; - QMutex m_hasBeenInitializedMutex; - - QAtomicInt m_running; - - QScopedPointer<PickEventFilter> m_pickEventFilter; - - QVector<Attribute *> m_dirtyAttributes; - QVector<Geometry *> m_dirtyGeometry; - QAtomicInt m_exposed; - - struct DirtyBits { - BackendNodeDirtySet marked; // marked dirty since last job build - BackendNodeDirtySet remaining; // remaining dirty after jobs have finished - }; - DirtyBits m_dirtyBits; - - QAtomicInt m_lastFrameCorrect; - QOpenGLContext *m_glContext; - QOpenGLContext *m_shareContext; - mutable QMutex m_shareContextMutex; - PickBoundingVolumeJobPtr m_pickBoundingVolumeJob; - RayCastingJobPtr m_rayCastingJob; - - qint64 m_time; - - RenderSettings *m_settings; - - UpdateShaderDataTransformJobPtr m_updateShaderDataTransformJob; - FrameCleanupJobPtr m_cleanupJob; - UpdateWorldTransformJobPtr m_worldTransformJob; - ExpandBoundingVolumeJobPtr m_expandBoundingVolumeJob; - CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob; - UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob; - UpdateTreeEnabledJobPtr m_updateTreeEnabledJob; - SendBufferCaptureJobPtr m_sendBufferCaptureJob; - UpdateSkinningPaletteJobPtr m_updateSkinningPaletteJob; - UpdateLevelOfDetailJobPtr m_updateLevelOfDetailJob; - UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob; - FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob; - UpdateEntityLayersJobPtr m_updateEntityLayersJob; - LightGathererPtr m_lightGathererJob; - RenderableEntityFilterPtr m_renderableEntityFilterJob; - ComputableEntityFilterPtr m_computableEntityFilterJob; - - QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests; - - void performDraw(RenderCommand *command); - void performCompute(const RenderView *rv, RenderCommand *command); - void createOrUpdateVAO(RenderCommand *command, - HVao *previousVAOHandle, - OpenGLVertexArrayObject **vao); - - SynchronizerJobPtr m_bufferGathererJob; - SynchronizerJobPtr m_vaoGathererJob; - SynchronizerJobPtr m_textureGathererJob; - SynchronizerJobPtr m_sendSetFenceHandlesToFrontendJob; - SynchronizerPostFramePtr m_introspectShaderJob; - SynchronizerJobPtr m_syncLoadingJobs; - SynchronizerJobPtr m_cacheRenderableEntitiesJob; - SynchronizerJobPtr m_cacheComputableEntitiesJob; - SynchronizerJobPtr m_cacheLightsJob; - - void lookForAbandonedVaos(); - void lookForDirtyBuffers(); - void lookForDownloadableBuffers(); - void lookForDirtyTextures(); - void reloadDirtyShaders(); - void sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager); - void sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager); - void sendSetFenceHandlesToFrontend(); - void sendDisablesToFrontend(Qt3DCore::QAspectManager *manager); - - QMutex m_abandonedVaosMutex; - QVector<HVao> m_abandonedVaos; - - QVector<HBuffer> m_dirtyBuffers; - QVector<Qt3DCore::QNodeId> m_downloadableBuffers; - QVector<HShader> m_dirtyShaders; - QVector<HTexture> m_dirtyTextures; - QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties; - QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences; - QVector<Qt3DCore::QNodeId> m_updatedDisableSubtreeEnablers; - Qt3DCore::QNodeIdVector m_textureIdsToCleanup; - QVector<ShaderBuilderUpdate> m_shaderBuilderUpdates; - - bool m_ownedContext; - - OffscreenSurfaceHelper *m_offscreenHelper; - GLResourceManagers *m_glResourceManagers; - QMutex m_offscreenSurfaceMutex; - - QScopedPointer<Qt3DRender::Debug::CommandExecuter> m_commandExecuter; - - mutable QScopedPointer<Qt3DRender::Render::Profiling::FrameProfiler> m_frameProfiler; - -#ifdef QT_BUILD_INTERNAL - friend class ::tst_Renderer; -#endif - - QMetaObject::Connection m_contextConnection; - RendererCache m_cache; - bool m_shouldSwapBuffers; - - QVector<FrameGraphNode *> m_frameGraphLeaves; - QScreen *m_screen = nullptr; - QSharedPointer<ResourceAccessor> m_scene2DResourceAccessor; - - Debug::ImGuiRenderer *m_imGuiRenderer; - QList<QPair<QObject *, QMouseEvent>> m_frameMouseEvents; - QList<QKeyEvent> m_frameKeyEvents; - QMutex m_frameEventsMutex; - int m_jobsInLastFrame; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERER_H diff --git a/src/render/renderers/opengl/renderer/renderercache_p.h b/src/render/renderers/opengl/renderer/renderercache_p.h deleted file mode 100644 index 02fe4ff41..000000000 --- a/src/render/renderers/opengl/renderer/renderercache_p.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERERCACHE_P_H -#define QT3DRENDER_RENDER_RENDERERCACHE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/QFrameGraphNode> - -#include <Qt3DRender/private/entity_p.h> -#include <Qt3DRender/private/renderviewjobutils_p.h> -#include <Qt3DRender/private/lightsource_p.h> -#include <Qt3DRender/private/rendercommand_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -struct RendererCache -{ - struct LeafNodeData - { - QVector<Entity *> filterEntitiesByLayer; - MaterialParameterGathererData materialParameterGatherer; - EntityRenderCommandData renderCommandData; - }; - - // Shared amongst all RV cache - QVector<Entity *> renderableEntities; - QVector<Entity *> computeEntities; - QVector<LightSource> gatheredLights; - EnvironmentLight* environmentLight; - - // Per RV cache - QHash<FrameGraphNode *, LeafNodeData> leafNodeCache; - - QMutex *mutex() { return &m_mutex; } - -private: - QMutex m_mutex; -}; - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERERCACHE_P_H diff --git a/src/render/renderers/opengl/renderer/renderqueue.cpp b/src/render/renderers/opengl/renderer/renderqueue.cpp deleted file mode 100644 index bd9d3ee59..000000000 --- a/src/render/renderers/opengl/renderer/renderqueue.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderqueue_p.h" -#include <Qt3DRender/private/renderview_p.h> -#include <QThread> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -RenderQueue::RenderQueue() - : m_noRender(false) - , m_wasReset(true) - , m_targetRenderViewCount(0) - , m_currentRenderViewCount(0) - , m_currentWorkQueue(1) -{ -} - -int RenderQueue::currentRenderViewCount() const -{ - return m_currentRenderViewCount; -} - -/* - * In case the framegraph changed or when the current number of render queue - * needs to be reset. - */ -void RenderQueue::reset() -{ - m_currentRenderViewCount = 0; - m_targetRenderViewCount = 0; - m_currentWorkQueue.clear(); - m_noRender = false; - m_wasReset = true; -} - -void RenderQueue::setNoRender() -{ - Q_ASSERT(m_targetRenderViewCount == 0); - m_noRender = true; -} - -/* - * Queue up a RenderView for the frame being built. - * Thread safe as this is called from the renderer which is locked. - * Returns true if the renderView is complete - */ -bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIndex) -{ - Q_ASSERT(!m_noRender); - m_currentWorkQueue[submissionOrderIndex] = renderView; - ++m_currentRenderViewCount; - Q_ASSERT(m_currentRenderViewCount <= m_targetRenderViewCount); - return isFrameQueueComplete(); -} - -/* - * Called by the Rendering Thread to retrieve the a frame queue to render. - * A call to reset is required after rendering of the frame. Otherwise under some - * conditions the current but then invalidated frame queue could be reused. - */ -QVector<RenderView *> RenderQueue::nextFrameQueue() -{ - return m_currentWorkQueue; -} - -/* - * Sets the number \a targetRenderViewCount of RenderView objects that make up a frame. - */ -void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount) -{ - Q_ASSERT(!m_noRender); - m_targetRenderViewCount = targetRenderViewCount; - m_currentWorkQueue.resize(targetRenderViewCount); - m_wasReset = false; -} - -/* - * Returns true if all the RenderView objects making up the current frame have been queued. - * Returns false otherwise. - * \note a frameQueue or size 0 is considered incomplete. - */ -bool RenderQueue::isFrameQueueComplete() const -{ - return (m_noRender - || (m_targetRenderViewCount > 0 && m_targetRenderViewCount == m_currentRenderViewCount)); -} - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/renderqueue_p.h b/src/render/renderers/opengl/renderer/renderqueue_p.h deleted file mode 100644 index e565115f2..000000000 --- a/src/render/renderers/opengl/renderer/renderqueue_p.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERQUEUE_H -#define QT3DRENDER_RENDER_RENDERQUEUE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QVector> -#include <QtGlobal> -#include <QMutex> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class RenderView; - -class Q_AUTOTEST_EXPORT RenderQueue -{ -public: - RenderQueue(); - - void setTargetRenderViewCount(int targetRenderViewCount); - int targetRenderViewCount() const { return m_targetRenderViewCount; } - int currentRenderViewCount() const; - bool isFrameQueueComplete() const; - - bool queueRenderView(RenderView *renderView, uint submissionOrderIndex); - QVector<RenderView *> nextFrameQueue(); - void reset(); - - void setNoRender(); - inline bool isNoRender() const { return m_noRender; } - - inline bool wasReset() const { return m_wasReset; } - - inline QMutex *mutex() { return &m_mutex; } - -private: - bool m_noRender; - bool m_wasReset; - int m_targetRenderViewCount; - int m_currentRenderViewCount; - QVector<RenderView *> m_currentWorkQueue; - QMutex m_mutex; -}; - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERQUEUE_H diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp deleted file mode 100644 index 6b6de01a7..000000000 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ /dev/null @@ -1,1236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderview_p.h" -#include <Qt3DRender/qmaterial.h> -#include <Qt3DRender/qrenderaspect.h> -#include <Qt3DRender/qrendertarget.h> -#include <Qt3DRender/qabstractlight.h> -#include <Qt3DRender/private/sphere_p.h> - -#include <Qt3DRender/private/cameraselectornode_p.h> -#include <Qt3DRender/private/framegraphnode_p.h> -#include <Qt3DRender/private/layerfilternode_p.h> -#include <Qt3DRender/private/qparameter_p.h> -#include <Qt3DRender/private/cameralens_p.h> -#include <Qt3DRender/private/rendercommand_p.h> -#include <Qt3DRender/private/effect_p.h> -#include <Qt3DRender/private/entity_p.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/layer_p.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/renderpassfilternode_p.h> -#include <Qt3DRender/private/renderpass_p.h> -#include <Qt3DRender/private/geometryrenderer_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/techniquefilternode_p.h> -#include <Qt3DRender/private/viewportnode_p.h> -#include <Qt3DRender/private/buffermanager_p.h> -#include <Qt3DRender/private/geometryrenderermanager_p.h> -#include <Qt3DRender/private/rendercapture_p.h> -#include <Qt3DRender/private/buffercapture_p.h> -#include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DRender/private/submissioncontext_p.h> -#include <Qt3DRender/private/glresourcemanagers_p.h> -#include <Qt3DCore/qentity.h> -#include <QtGui/qsurface.h> -#include <algorithm> - -#include <QDebug> -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) -#include <QElapsedTimer> -#endif - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - - -namespace { - -// register our QNodeId's as a metatype during program loading -const int Q_DECL_UNUSED qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>(); - -const int MAX_LIGHTS = 8; - -#define LIGHT_POSITION_NAME QLatin1String(".position") -#define LIGHT_TYPE_NAME QLatin1String(".type") -#define LIGHT_COLOR_NAME QLatin1String(".color") -#define LIGHT_INTENSITY_NAME QLatin1String(".intensity") - -int LIGHT_COUNT_NAME_ID = 0; -int LIGHT_POSITION_NAMES[MAX_LIGHTS]; -int LIGHT_TYPE_NAMES[MAX_LIGHTS]; -int LIGHT_COLOR_NAMES[MAX_LIGHTS]; -int LIGHT_INTENSITY_NAMES[MAX_LIGHTS]; -QString LIGHT_STRUCT_NAMES[MAX_LIGHTS]; - -int LIGHT_POSITION_UNROLL_NAMES[MAX_LIGHTS]; -int LIGHT_TYPE_UNROLL_NAMES[MAX_LIGHTS]; -int LIGHT_COLOR_UNROLL_NAMES[MAX_LIGHTS]; -int LIGHT_INTENSITY_UNROLL_NAMES[MAX_LIGHTS]; -QString LIGHT_STRUCT_UNROLL_NAMES[MAX_LIGHTS]; - -bool wasInitialized = false; - -} // anonymous namespace - -RenderView::StandardUniformsNameToTypeHash RenderView::ms_standardUniformSetters; - - -RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniformSetters() -{ - RenderView::StandardUniformsNameToTypeHash setters; - - setters.insert(Shader::modelMatrixNameId, ModelMatrix); - setters.insert(Shader::viewMatrixNameId, ViewMatrix); - setters.insert(Shader::projectionMatrixNameId, ProjectionMatrix); - setters.insert(Shader::modelViewMatrixNameId, ModelViewMatrix); - setters.insert(Shader::viewProjectionMatrixNameId, ViewProjectionMatrix); - setters.insert(Shader::modelViewProjectionNameId, ModelViewProjectionMatrix); - setters.insert(Shader::mvpNameId, ModelViewProjectionMatrix); - setters.insert(Shader::inverseModelMatrixNameId, InverseModelMatrix); - setters.insert(Shader::inverseViewMatrixNameId, InverseViewMatrix); - setters.insert(Shader::inverseProjectionMatrixNameId, InverseProjectionMatrix); - setters.insert(Shader::inverseModelViewNameId, InverseModelViewMatrix); - setters.insert(Shader::inverseViewProjectionMatrixNameId, InverseViewProjectionMatrix); - setters.insert(Shader::inverseModelViewProjectionNameId, InverseModelViewProjectionMatrix); - setters.insert(Shader::modelNormalMatrixNameId, ModelNormalMatrix); - setters.insert(Shader::modelViewNormalNameId, ModelViewNormalMatrix); - setters.insert(Shader::viewportMatrixNameId, ViewportMatrix); - setters.insert(Shader::inverseViewportMatrixNameId, InverseViewportMatrix); - setters.insert(Shader::aspectRatioNameId, AspectRatio); - setters.insert(Shader::exposureNameId, Exposure); - setters.insert(Shader::gammaNameId, Gamma); - setters.insert(Shader::timeNameId, Time); - setters.insert(Shader::eyePositionNameId, EyePosition); - setters.insert(Shader::skinningPaletteNameId, SkinningPalette); - - return setters; -} - -// TODO: Move this somewhere global where GraphicsContext::setViewport() can use it too -static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &surfaceSize) -{ - return QRectF(fractionalViewport.x() * surfaceSize.width(), - (1.0 - fractionalViewport.y() - fractionalViewport.height()) * surfaceSize.height(), - fractionalViewport.width() * surfaceSize.width(), - fractionalViewport.height() * surfaceSize.height()); -} - -static Matrix4x4 getProjectionMatrix(const CameraLens *lens) -{ - if (!lens) - qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame Graph or make sure that no entities will be rendered."; - return lens ? lens->projection() : Matrix4x4(); -} - -UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standardUniformType, - Entity *entity, - const Matrix4x4 &model) const -{ - switch (standardUniformType) { - case ModelMatrix: - return UniformValue(model); - case ViewMatrix: - return UniformValue(m_data.m_viewMatrix); - case ProjectionMatrix: - return UniformValue(getProjectionMatrix(m_data.m_renderCameraLens)); - case ModelViewMatrix: - return UniformValue(m_data.m_viewMatrix * model); - case ViewProjectionMatrix: - return UniformValue(getProjectionMatrix(m_data.m_renderCameraLens) * m_data.m_viewMatrix); - case ModelViewProjectionMatrix: - return UniformValue(m_data.m_viewProjectionMatrix * model); - case InverseModelMatrix: - return UniformValue(model.inverted()); - case InverseViewMatrix: - return UniformValue(m_data.m_viewMatrix.inverted()); - case InverseProjectionMatrix: { - return UniformValue(getProjectionMatrix(m_data.m_renderCameraLens).inverted()); - } - case InverseModelViewMatrix: - return UniformValue((m_data.m_viewMatrix * model).inverted()); - case InverseViewProjectionMatrix: { - const Matrix4x4 viewProjectionMatrix = getProjectionMatrix(m_data.m_renderCameraLens) * m_data.m_viewMatrix; - return UniformValue(viewProjectionMatrix.inverted()); - } - case InverseModelViewProjectionMatrix: - return UniformValue((m_data.m_viewProjectionMatrix * model).inverted()); - case ModelNormalMatrix: - return UniformValue(convertToQMatrix4x4(model).normalMatrix()); - case ModelViewNormalMatrix: - return UniformValue(convertToQMatrix4x4(m_data.m_viewMatrix * model).normalMatrix()); - case ViewportMatrix: { - QMatrix4x4 viewportMatrix; - // TO DO: Implement on Matrix4x4 - viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize)); - return UniformValue(Matrix4x4(viewportMatrix)); - } - case InverseViewportMatrix: { - QMatrix4x4 viewportMatrix; - // TO DO: Implement on Matrix4x4 - viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize)); - return UniformValue(Matrix4x4(viewportMatrix.inverted())); - } - case AspectRatio: - return float(m_surfaceSize.width()) / std::max(1.f, float(m_surfaceSize.height())); - case Exposure: - return UniformValue(m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f); - case Gamma: - return UniformValue(m_gamma); - case Time: - return UniformValue(float(m_renderer->time() / 1000000000.0f)); - case EyePosition: - return UniformValue(m_data.m_eyePos); - case SkinningPalette: { - const Armature *armature = entity->renderComponent<Armature>(); - if (!armature) { - qCWarning(Jobs, "Requesting skinningPalette uniform but no armature set on entity"); - return UniformValue(); - } - return armature->skinningPaletteUniform(); - } - default: - Q_UNREACHABLE(); - return UniformValue(); - } -} - -RenderView::RenderView() - : m_isDownloadBuffersEnable(false) - , m_hasBlitFramebufferInfo(false) - , m_renderer(nullptr) - , m_manager(nullptr) - , m_devicePixelRatio(1.) - , m_viewport(QRectF(0., 0., 1., 1.)) - , m_gamma(2.2f) - , m_surface(nullptr) - , m_clearBuffer(QClearBuffers::None) - , m_clearDepthValue(1.f) - , m_clearStencilValue(0) - , m_stateSet(nullptr) - , m_noDraw(false) - , m_compute(false) - , m_frustumCulling(false) - , m_showDebugOverlay(false) - , m_memoryBarrier(QMemoryBarrier::None) - , m_environmentLight(nullptr) -{ - m_workGroups[0] = 1; - m_workGroups[1] = 1; - m_workGroups[2] = 1; - - if (Q_UNLIKELY(!wasInitialized)) { - // Needed as we can control the init order of static/global variables across compile units - // and this hash relies on the static StringToInt class - wasInitialized = true; - RenderView::ms_standardUniformSetters = RenderView::initializeStandardUniformSetters(); - LIGHT_COUNT_NAME_ID = StringToInt::lookupId(QLatin1String("lightCount")); - for (int i = 0; i < MAX_LIGHTS; ++i) { - Q_STATIC_ASSERT_X(MAX_LIGHTS < 10, "can't use the QChar trick anymore"); - LIGHT_STRUCT_NAMES[i] = QLatin1String("lights[") + QLatin1Char(char('0' + i)) + QLatin1Char(']'); - LIGHT_POSITION_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_POSITION_NAME); - LIGHT_TYPE_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_TYPE_NAME); - LIGHT_COLOR_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_COLOR_NAME); - LIGHT_INTENSITY_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_INTENSITY_NAME); - - LIGHT_STRUCT_UNROLL_NAMES[i] = QLatin1String("light_") + QLatin1Char(char('0' + i)); - LIGHT_POSITION_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_POSITION_NAME); - LIGHT_TYPE_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_TYPE_NAME); - LIGHT_COLOR_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_COLOR_NAME); - LIGHT_INTENSITY_UNROLL_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_UNROLL_NAMES[i] + LIGHT_INTENSITY_NAME); - } - } -} - -RenderView::~RenderView() -{ - delete m_stateSet; -} - -namespace { - -template<int SortType> -struct AdjacentSubRangeFinder -{ - static bool adjacentSubRange(const RenderCommand &, const RenderCommand &) - { - Q_UNREACHABLE(); - return false; - } -}; - -template<> -struct AdjacentSubRangeFinder<QSortPolicy::StateChangeCost> -{ - static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b) - { - return a.m_changeCost == b.m_changeCost; - } -}; - -template<> -struct AdjacentSubRangeFinder<QSortPolicy::BackToFront> -{ - static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b) - { - return a.m_depth == b.m_depth; - } -}; - -template<> -struct AdjacentSubRangeFinder<QSortPolicy::Material> -{ - static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b) - { - return a.m_glShader == b.m_glShader; - } -}; - -template<> -struct AdjacentSubRangeFinder<QSortPolicy::FrontToBack> -{ - static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b) - { - return a.m_depth == b.m_depth; - } -}; - -template<> -struct AdjacentSubRangeFinder<QSortPolicy::Texture> -{ - static bool adjacentSubRange(const RenderCommand &a, const RenderCommand &b) - { - // Two renderCommands are adjacent if one contains all the other command's textures - QVector<ShaderParameterPack::NamedResource> texturesA = a.m_parameterPack.textures(); - QVector<ShaderParameterPack::NamedResource> texturesB = b.m_parameterPack.textures(); - - if (texturesB.size() > texturesA.size()) - qSwap(texturesA, texturesB); - - // textureB.size() is always <= textureA.size() - for (const ShaderParameterPack::NamedResource &texB : qAsConst(texturesB)) { - if (!texturesA.contains(texB)) - return false; - } - return true; - } -}; - -template<typename Predicate> -int advanceUntilNonAdjacent(const QVector<RenderCommand> &commands, - const int beg, const int end, Predicate pred) -{ - int i = beg + 1; - while (i < end) { - if (!pred(*(commands.begin() + beg), *(commands.begin() + i))) - break; - ++i; - } - return i; -} - - -using CommandIt = QVector<RenderCommand>::iterator; - -template<int SortType> -struct SubRangeSorter -{ - static void sortSubRange(CommandIt begin, const CommandIt end) - { - Q_UNUSED(begin); - Q_UNUSED(end); - Q_UNREACHABLE(); - } -}; - -template<> -struct SubRangeSorter<QSortPolicy::StateChangeCost> -{ - static void sortSubRange(CommandIt begin, const CommandIt end) - { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { - return a.m_changeCost > b.m_changeCost; - }); - } -}; - -template<> -struct SubRangeSorter<QSortPolicy::BackToFront> -{ - static void sortSubRange(CommandIt begin, const CommandIt end) - { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { - return a.m_depth > b.m_depth; - }); - } -}; - -template<> -struct SubRangeSorter<QSortPolicy::Material> -{ - static void sortSubRange(CommandIt begin, const CommandIt end) - { - // First we sort by shader - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { - return a.m_glShader > b.m_glShader; - }); - } -}; - -template<> -struct SubRangeSorter<QSortPolicy::FrontToBack> -{ - static void sortSubRange(CommandIt begin, const CommandIt end) - { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { - return a.m_depth < b.m_depth; - }); - } -}; - -template<> -struct SubRangeSorter<QSortPolicy::Texture> -{ - static void sortSubRange(CommandIt begin, const CommandIt end) - { - std::stable_sort(begin, end, [] (const RenderCommand &a, const RenderCommand &b) { - QVector<ShaderParameterPack::NamedResource> texturesA = a.m_parameterPack.textures(); - QVector<ShaderParameterPack::NamedResource> texturesB = b.m_parameterPack.textures(); - - const int originalTextureASize = texturesA.size(); - - if (texturesB.size() > texturesA.size()) - qSwap(texturesA, texturesB); - - int identicalTextureCount = 0; - - for (const ShaderParameterPack::NamedResource &texB : qAsConst(texturesB)) { - if (texturesA.contains(texB)) - ++identicalTextureCount; - } - - return identicalTextureCount < originalTextureASize; - }); - } -}; - -int findSubRange(const QVector<RenderCommand> &commands, - const int begin, const int end, - const QSortPolicy::SortType sortType) -{ - switch (sortType) { - case QSortPolicy::StateChangeCost: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::StateChangeCost>::adjacentSubRange); - case QSortPolicy::BackToFront: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::BackToFront>::adjacentSubRange); - case QSortPolicy::Material: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange); - case QSortPolicy::FrontToBack: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::FrontToBack>::adjacentSubRange); - case QSortPolicy::Texture: - return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Texture>::adjacentSubRange); - case QSortPolicy::Uniform: - return end; - default: - Q_UNREACHABLE(); - return end; - } -} - -void sortByMaterial(QVector<RenderCommand> &commands, int begin, const int end) -{ - // We try to arrange elements so that their rendering cost is minimized for a given shader - int rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange); - while (begin != end) { - if (begin + 1 < rangeEnd) { - std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, [] (const RenderCommand &a, const RenderCommand &b){ - return a.m_material.handle() < b.m_material.handle(); - }); - } - begin = rangeEnd; - rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange); - } -} - -void sortCommandRange(QVector<RenderCommand> &commands, int begin, const int end, const int level, - const QVector<Qt3DRender::QSortPolicy::SortType> &sortingTypes) -{ - if (level >= sortingTypes.size()) - return; - - switch (sortingTypes.at(level)) { - case QSortPolicy::StateChangeCost: - SubRangeSorter<QSortPolicy::StateChangeCost>::sortSubRange(commands.begin() + begin, commands.begin() + end); - break; - case QSortPolicy::BackToFront: - SubRangeSorter<QSortPolicy::BackToFront>::sortSubRange(commands.begin() + begin, commands.begin() + end); - break; - case QSortPolicy::Material: - // Groups all same shader DNA together - SubRangeSorter<QSortPolicy::Material>::sortSubRange(commands.begin() + begin, commands.begin() + end); - // Group all same material together (same parameters most likely) - sortByMaterial(commands, begin, end); - break; - case QSortPolicy::FrontToBack: - SubRangeSorter<QSortPolicy::FrontToBack>::sortSubRange(commands.begin() + begin, commands.begin() + end); - break; - case QSortPolicy::Texture: - SubRangeSorter<QSortPolicy::Texture>::sortSubRange(commands.begin() + begin, commands.begin() + end); - break; - case QSortPolicy::Uniform: - break; - default: - Q_UNREACHABLE(); - } - - // For all sub ranges of adjacent item for sortType[i] - // Perform filtering with sortType[i + 1] - int rangeEnd = findSubRange(commands, begin, end, sortingTypes.at(level)); - while (begin != end) { - sortCommandRange(commands, begin, rangeEnd, level + 1, sortingTypes); - begin = rangeEnd; - rangeEnd = findSubRange(commands, begin, end, sortingTypes.at(level)); - } -} - -} // anonymous - -void RenderView::sort() -{ - // Compares the bitsetKey of the RenderCommands - // Key[Depth | StateCost | Shader] - sortCommandRange(m_commands, 0, m_commands.size(), 0, m_data.m_sortingTypes); - - // For RenderCommand with the same shader - // We compute the adjacent change cost - - // Only perform uniform minimization if we explicitly asked for it - if (!m_data.m_sortingTypes.contains(QSortPolicy::Uniform)) - return; - - // Minimize uniform changes - int i = 0; - const int commandSize = m_commands.size(); - while (i < commandSize) { - int j = i; - - // Advance while commands share the same shader - while (i < commandSize && - m_commands[j].m_glShader == m_commands[i].m_glShader) - ++i; - - if (i - j > 0) { // Several commands have the same shader, so we minimize uniform changes - PackUniformHash cachedUniforms = m_commands[j++].m_parameterPack.uniforms(); - - while (j < i) { - // We need the reference here as we are modifying the original container - // not the copy - PackUniformHash &uniforms = m_commands[j].m_parameterPack.m_uniforms; - - for (int u = 0; u < uniforms.keys.size();) { - // We are comparing the values: - // - raw uniform values - // - the texture Node id if the uniform represents a texture - // since all textures are assigned texture units before the RenderCommands - // sharing the same material (shader) are rendered, we can't have the case - // where two uniforms, referencing the same texture eventually have 2 different - // texture unit values - const int uniformNameId = uniforms.keys.at(u); - const UniformValue &refValue = cachedUniforms.value(uniformNameId); - const UniformValue &newValue = uniforms.values.at(u); - if (newValue == refValue) { - uniforms.erase(u); - } else { - // Record updated value so that subsequent comparison - // for the next command will be made againts latest - // uniform value - cachedUniforms.insert(uniformNameId, newValue); - ++u; - } - } - ++j; - } - } - } -} - -void RenderView::setRenderer(Renderer *renderer) -{ - m_renderer = renderer; - m_manager = renderer->nodeManagers(); -} - -void RenderView::addClearBuffers(const ClearBuffers *cb) { - QClearBuffers::BufferTypeFlags type = cb->type(); - - if (type & QClearBuffers::StencilBuffer) { - m_clearStencilValue = cb->clearStencilValue(); - m_clearBuffer |= QClearBuffers::StencilBuffer; - } - if (type & QClearBuffers::DepthBuffer) { - m_clearDepthValue = cb->clearDepthValue(); - m_clearBuffer |= QClearBuffers::DepthBuffer; - } - // keep track of global ClearColor (if set) and collect all DrawBuffer-specific - // ClearColors - if (type & QClearBuffers::ColorBuffer) { - ClearBufferInfo clearBufferInfo; - clearBufferInfo.clearColor = cb->clearColor(); - - if (cb->clearsAllColorBuffers()) { - m_globalClearColorBuffer = clearBufferInfo; - m_clearBuffer |= QClearBuffers::ColorBuffer; - } else { - if (cb->bufferId()) { - const RenderTargetOutput *targetOutput = m_manager->attachmentManager()->lookupResource(cb->bufferId()); - if (targetOutput) { - clearBufferInfo.attchmentPoint = targetOutput->point(); - // Note: a job is later performed to find the drawIndex from the buffer attachment point - // using the AttachmentPack - m_specificClearColorBuffers.push_back(clearBufferInfo); - } - } - } - } -} - -// If we are there, we know that entity had a GeometryRenderer + Material -EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities, - int offset, int count) const -{ - GLShaderManager *glShaderManager = m_renderer->glResourceManagers()->glShaderManager(); - EntityRenderCommandData commands; - - commands.reserve(count); - - for (int i = 0; i < count; ++i) { - const int idx = offset + i; - Entity *entity = entities.at(idx); - GeometryRenderer *geometryRenderer = nullptr; - HGeometryRenderer geometryRendererHandle = entity->componentHandle<GeometryRenderer>(); - - // There is a geometry renderer with geometry - if ((geometryRenderer = m_manager->geometryRendererManager()->data(geometryRendererHandle)) != nullptr - && geometryRenderer->isEnabled() - && !geometryRenderer->geometryId().isNull()) { - - const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>(); - const HMaterial materialHandle = entity->componentHandle<Material>(); - const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId); - - HGeometry geometryHandle = m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId()); - Geometry *geometry = m_manager->geometryManager()->data(geometryHandle); - - // 1 RenderCommand per RenderPass pass on an Entity with a Mesh - for (const RenderPassParameterData &passData : renderPassData) { - // Add the RenderPass Parameters - RenderCommand command = {}; - command.m_geometryRenderer = geometryRendererHandle; - command.m_geometry = geometryHandle; - - command.m_material = materialHandle; - // For RenderPass based states we use the globally set RenderState - // if no renderstates are defined as part of the pass. That means: - // RenderPass { renderStates: [] } will use the states defined by - // StateSet in the FrameGraph - RenderPass *pass = passData.pass; - if (pass->hasRenderStates()) { - command.m_stateSet = RenderStateSetPtr::create(); - addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), m_manager->renderStateManager()); - if (m_stateSet != nullptr) - command.m_stateSet->merge(m_stateSet); - command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data()); - } - command.m_shaderId = pass->shaderProgram(); - command.m_glShader = glShaderManager->lookupResource(command.m_shaderId); - - // It takes two frames to have a valid command as we can only - // reference a glShader at frame n if it has been loaded at frame n - 1 - if (!command.m_glShader) - continue; - - { // Scoped to show extent - - // Update the draw command with what's going to be needed for the drawing - int primitiveCount = geometryRenderer->vertexCount(); - int estimatedCount = 0; - Attribute *indexAttribute = nullptr; - Attribute *indirectAttribute = nullptr; - - const QVector<Qt3DCore::QNodeId> attributeIds = geometry->attributes(); - for (Qt3DCore::QNodeId attributeId : attributeIds) { - Attribute *attribute = m_manager->attributeManager()->lookupResource(attributeId); - switch (attribute->attributeType()) { - case QAttribute::IndexAttribute: - indexAttribute = attribute; - break; - case QAttribute::DrawIndirectAttribute: - indirectAttribute = attribute; - break; - case QAttribute::VertexAttribute: - estimatedCount = std::max(int(attribute->count()), estimatedCount); - break; - default: - Q_UNREACHABLE(); - break; - } - } - - command.m_drawIndexed = (indexAttribute != nullptr); - command.m_drawIndirect = (indirectAttribute != nullptr); - - // Update the draw command with all the information required for the drawing - if (command.m_drawIndexed) { - command.m_indexAttributeDataType = GraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->vertexBaseType()); - command.m_indexAttributeByteOffset = indexAttribute->byteOffset() + geometryRenderer->indexBufferByteOffset(); - } - - // Note: we only care about the primitiveCount when using direct draw calls - // For indirect draw calls it is assumed the buffer was properly set already - if (command.m_drawIndirect) { - command.m_indirectAttributeByteOffset = indirectAttribute->byteOffset(); - command.m_indirectDrawBuffer = m_manager->bufferManager()->lookupHandle(indirectAttribute->bufferId()); - } else { - // Use the count specified by the GeometryRender - // If not specify use the indexAttribute count if present - // Otherwise tries to use the count from the attribute with the highest count - if (primitiveCount == 0) { - if (indexAttribute) - primitiveCount = indexAttribute->count(); - else - primitiveCount = estimatedCount; - } - } - - command.m_primitiveCount = primitiveCount; - command.m_primitiveType = geometryRenderer->primitiveType(); - command.m_primitiveRestartEnabled = geometryRenderer->primitiveRestartEnabled(); - command.m_restartIndexValue = geometryRenderer->restartIndexValue(); - command.m_firstInstance = geometryRenderer->firstInstance(); - command.m_instanceCount = geometryRenderer->instanceCount(); - command.m_firstVertex = geometryRenderer->firstVertex(); - command.m_indexOffset = geometryRenderer->indexOffset(); - command.m_verticesPerPatch = geometryRenderer->verticesPerPatch(); - } // scope - - - commands.push_back(entity, - std::move(command), - std::move(passData)); - } - } - } - - return commands; -} - -EntityRenderCommandData RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities, - int offset, int count) const -{ - // If the RenderView contains only a ComputeDispatch then it cares about - // A ComputeDispatch is also implicitely a NoDraw operation - // enabled flag - // layer component - // material/effect/technique/parameters/filters/ - EntityRenderCommandData commands; - GLShaderManager *glShaderManager = m_renderer->glResourceManagers()->glShaderManager(); - - commands.reserve(count); - - for (int i = 0; i < count; ++i) { - const int idx = offset + i; - Entity *entity = entities.at(idx); - ComputeCommand *computeJob = nullptr; - HComputeCommand computeCommandHandle = entity->componentHandle<ComputeCommand>(); - if ((computeJob = nodeManagers()->computeJobManager()->data(computeCommandHandle)) != nullptr - && computeJob->isEnabled()) { - - const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>(); - const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId); - - // 1 RenderCommand per RenderPass pass on an Entity with a Mesh - for (const RenderPassParameterData &passData : renderPassData) { - // Add the RenderPass Parameters - RenderCommand command = {}; - RenderPass *pass = passData.pass; - - if (pass->hasRenderStates()) { - command.m_stateSet = RenderStateSetPtr::create(); - addStatesToRenderStateSet(command.m_stateSet.data(), pass->renderStates(), m_manager->renderStateManager()); - - // Merge per pass stateset with global stateset - // so that the local stateset only overrides - if (m_stateSet != nullptr) - command.m_stateSet->merge(m_stateSet); - command.m_changeCost = m_renderer->defaultRenderState()->changeCost(command.m_stateSet.data()); - } - command.m_shaderId = pass->shaderProgram(); - command.m_glShader = glShaderManager->lookupResource(command.m_shaderId); - - // It takes two frames to have a valid command as we can only - // reference a glShader at frame n if it has been loaded at frame n - 1 - if (!command.m_glShader) - continue; - - command.m_computeCommand = computeCommandHandle; - command.m_type = RenderCommand::Compute; - command.m_workGroups[0] = std::max(m_workGroups[0], computeJob->x()); - command.m_workGroups[1] = std::max(m_workGroups[1], computeJob->y()); - command.m_workGroups[2] = std::max(m_workGroups[2], computeJob->z()); - - commands.push_back(entity, - std::move(command), - std::move(passData)); - } - } - } - - return commands; -} - -void RenderView::updateRenderCommand(EntityRenderCommandData *renderCommandData, - int offset, - int count) -{ - // Note: since many threads can be building render commands - // we need to ensure that the UniformBlockValueBuilder they are using - // is only accessed from the same thread - UniformBlockValueBuilder *builder = new UniformBlockValueBuilder(); - builder->shaderDataManager = m_manager->shaderDataManager(); - builder->textureManager = m_manager->textureManager(); - m_localData.setLocalData(builder); - - for (int i = 0, m = count; i < m; ++i) { - const int idx = offset + i; - Entity *entity = renderCommandData->entities.at(idx); - const RenderPassParameterData passData = renderCommandData->passesData.at(idx); - RenderCommand &command = renderCommandData->commands[idx]; - - // Pick which lights to take in to account. - // For now decide based on the distance by taking the MAX_LIGHTS closest lights. - // Replace with more sophisticated mechanisms later. - // Copy vector so that we can sort it concurrently and we only want to sort the one for the current command - QVector<LightSource> lightSources; - EnvironmentLight *environmentLight = nullptr; - - if (command.m_type == RenderCommand::Draw) { - // Project the camera-to-object-center vector onto the camera - // view vector. This gives a depth value suitable as the key - // for BackToFront sorting. - command.m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir); - - environmentLight = m_environmentLight; - lightSources = m_lightSources; - - if (lightSources.size() > 1) { - const Vector3D entityCenter = entity->worldBoundingVolume()->center(); - std::sort(lightSources.begin(), lightSources.end(), - [&] (const LightSource &a, const LightSource &b) { - const float distA = entityCenter.distanceToPoint(a.entity->worldBoundingVolume()->center()); - const float distB = entityCenter.distanceToPoint(b.entity->worldBoundingVolume()->center()); - return distA < distB; - }); - } - lightSources = lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS)); - } else { // Compute - // Note: if frameCount has reached 0 in the previous frame, isEnabled - // would be false - ComputeCommand *computeJob = m_manager->computeJobManager()->data(command.m_computeCommand); - if (computeJob->runType() == QComputeCommand::Manual) - computeJob->updateFrameCount(); - } - - ParameterInfoList globalParameters = passData.parameterInfo; - // setShaderAndUniforms can initialize a localData - // make sure this is cleared before we leave this function - - setShaderAndUniforms(&command, - globalParameters, - entity, - lightSources, - environmentLight); - } - - // We reset the local data once we are done with it - m_localData.setLocalData(nullptr); -} - -void RenderView::updateMatrices() -{ - if (m_data.m_renderCameraNode && m_data.m_renderCameraLens && m_data.m_renderCameraLens->isEnabled()) { - const Matrix4x4 cameraWorld = *(m_data.m_renderCameraNode->worldTransform()); - setViewMatrix(m_data.m_renderCameraLens->viewMatrix(cameraWorld)); - - setViewProjectionMatrix(m_data.m_renderCameraLens->projection() * viewMatrix()); - //To get the eyePosition of the camera, we need to use the inverse of the - //camera's worldTransform matrix. - const Matrix4x4 inverseWorldTransform = viewMatrix().inverted(); - const Vector3D eyePosition(inverseWorldTransform.column(3)); - setEyePosition(eyePosition); - - // Get the viewing direction of the camera. Use the normal matrix to - // ensure non-uniform scale works too. - const QMatrix3x3 normalMat = convertToQMatrix4x4(m_data.m_viewMatrix).normalMatrix(); - // dir = normalize(QVector3D(0, 0, -1) * normalMat) - setEyeViewDirection(Vector3D(-normalMat(2, 0), -normalMat(2, 1), -normalMat(2, 2)).normalized()); - } -} - -void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const -{ - // At this point a uniform value can only be a scalar type - // or a Qt3DCore::QNodeId corresponding to a Texture or Image - // ShaderData/Buffers would be handled as UBO/SSBO and would therefore - // not be in the default uniform block - if (value.valueType() == UniformValue::NodeId) { - const Qt3DCore::QNodeId *nodeIds = value.constData<Qt3DCore::QNodeId>(); - - const int uniformArraySize = value.byteSize() / sizeof(Qt3DCore::QNodeId); - UniformValue::ValueType resourceType = UniformValue::TextureValue; - - for (int i = 0; i < uniformArraySize; ++i) { - const Qt3DCore::QNodeId resourceId = nodeIds[i]; - - const Texture *tex = m_manager->textureManager()->lookupResource(resourceId); - if (tex != nullptr) { - uniformPack.setTexture(nameId, i, resourceId); - } else { - const ShaderImage *img = m_manager->shaderImageManager()->lookupResource(resourceId); - if (img != nullptr) { - resourceType = UniformValue::ShaderImageValue; - uniformPack.setImage(nameId, i, resourceId); - } - } - } - - // This uniform will be overridden in SubmissionContext::setParameters - // and -1 values will be replaced by valid Texture or Image units - UniformValue uniformValue(uniformArraySize * sizeof(int), resourceType); - std::fill(uniformValue.data<int>(), uniformValue.data<int>() + uniformArraySize, -1); - uniformPack.setUniform(nameId, uniformValue); - } else { - uniformPack.setUniform(nameId, value); - } -} - -void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack, - int glslNameId, - int nameId, - Entity *entity, - const Matrix4x4 &worldTransform) const -{ - uniformPack.setUniform(glslNameId, standardUniformValue(ms_standardUniformSetters[nameId], entity, worldTransform)); -} - -void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, - GLShader *shader, - const ShaderUniformBlock &block, - const UniformValue &value) const -{ - Q_UNUSED(shader) - - if (value.valueType() == UniformValue::NodeId) { - - Buffer *buffer = nullptr; - if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) { - BlockToUBO uniformBlockUBO; - uniformBlockUBO.m_blockIndex = block.m_index; - uniformBlockUBO.m_bufferID = buffer->peerId(); - uniformBlockUBO.m_needsUpdate = false; - uniformPack.setUniformBuffer(std::move(uniformBlockUBO)); - // Buffer update to GL buffer will be done at render time - } - } -} - -void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack, - GLShader *shader, - const ShaderStorageBlock &block, - const UniformValue &value) const -{ - Q_UNUSED(shader) - if (value.valueType() == UniformValue::NodeId) { - Buffer *buffer = nullptr; - if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) { - BlockToSSBO shaderStorageBlock; - shaderStorageBlock.m_blockIndex = block.m_index; - shaderStorageBlock.m_bufferID = buffer->peerId(); - shaderStorageBlock.m_bindingIndex = block.m_binding; - uniformPack.setShaderStorageBuffer(shaderStorageBlock); - // Buffer update to GL buffer will be done at render time - } - } -} - -void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, GLShader *shader, ShaderData *shaderData, const QString &structName) const -{ - UniformBlockValueBuilder *builder = m_localData.localData(); - builder->activeUniformNamesToValue.clear(); - - // Set the view matrix to be used to transform "Transformed" properties in the ShaderData - builder->viewMatrix = m_data.m_viewMatrix; - // Force to update the whole block - builder->updatedPropertiesOnly = false; - // Retrieve names and description of each active uniforms in the uniform block - builder->uniforms = shader->activeUniformsForUniformBlock(-1); - // Build name-value map for the block - builder->buildActiveUniformNameValueMapStructHelper(shaderData, structName); - // Set uniform values for each entrie of the block name-value map - QHash<int, QVariant>::const_iterator activeValuesIt = builder->activeUniformNamesToValue.constBegin(); - const QHash<int, QVariant>::const_iterator activeValuesEnd = builder->activeUniformNamesToValue.constEnd(); - - // TO DO: Make the ShaderData store UniformValue - while (activeValuesIt != activeValuesEnd) { - setUniformValue(uniformPack, activeValuesIt.key(), UniformValue::fromVariant(activeValuesIt.value())); - ++activeValuesIt; - } -} - -void RenderView::setShaderAndUniforms(RenderCommand *command, - ParameterInfoList ¶meters, - Entity *entity, - const QVector<LightSource> &activeLightSources, - EnvironmentLight *environmentLight) const -{ - // The VAO Handle is set directly in the renderer thread so as to avoid having to use a mutex here - // Set shader, technique, and effect by basically doing : - // ShaderProgramManager[MaterialManager[frontentEntity->id()]->Effect->Techniques[TechniqueFilter->name]->RenderPasses[RenderPassFilter->name]]; - // The Renderer knows that if one of those is null, a default material / technique / effect as to be used - - // Find all RenderPasses (in order) matching values set in the RenderPassFilter - // Get list of parameters for the Material, Effect, and Technique - // For each ParameterBinder in the RenderPass -> create a QUniformPack - // Once that works, improve that to try and minimize QUniformPack updates - - GLShader *shader = command->m_glShader; - if (shader != nullptr && shader->isLoaded()) { - - // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings - // If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name - // equals to the parameter name - const QVector<int> uniformNamesIds = shader->uniformsNamesIds(); - const QVector<int> standardUniformNamesIds = shader->standardUniformNameIds(); - const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds(); - const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds(); - const QVector<int> attributeNamesIds = shader->attributeNamesIds(); - - // Set fragData Name and index - // Later on we might want to relink the shader if attachments have changed - // But for now we set them once and for all - if (!m_renderTarget.isNull() && !shader->isLoaded()) { - QHash<QString, int> fragOutputs; - const auto atts = m_attachmentPack.attachments(); - for (const Attachment &att : atts) { - if (att.m_point <= QRenderTargetOutput::Color15) - fragOutputs.insert(att.m_name, att.m_point); - } - // Set frag outputs in the shaders if hash not empty - if (!fragOutputs.isEmpty()) - shader->setFragOutputs(fragOutputs); - } - - if (!uniformNamesIds.isEmpty() || !standardUniformNamesIds.isEmpty() || - !attributeNamesIds.isEmpty() || - !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) { - - // Set default standard uniforms without bindings - const Matrix4x4 worldTransform = *(entity->worldTransform()); - - for (const int uniformNameId : standardUniformNamesIds) - setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform); - - // Set default attributes - command->m_activeAttributes = attributeNamesIds; - - // At this point we know whether the command is a valid draw command or not - // We still need to process the uniforms as the command could be a compute command - command->m_isValid = !command->m_activeAttributes.empty(); - - // Parameters remaining could be - // -> uniform scalar / vector - // -> uniform struct / arrays - // -> uniform block / array (4.3) - // -> ssbo block / array (4.3) - - ParameterInfoList::const_iterator it = parameters.cbegin(); - const ParameterInfoList::const_iterator parametersEnd = parameters.cend(); - - while (it != parametersEnd) { - Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle); - const UniformValue &uniformValue = param->uniformValue(); - if (uniformNamesIds.contains(it->nameId)) { // Parameter is a regular uniform - setUniformValue(command->m_parameterPack, it->nameId, uniformValue); - } else if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block - setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), uniformValue); - } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO - setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), uniformValue); - } else { // Parameter is a struct - ShaderData *shaderData = nullptr; - if (uniformValue.valueType() == UniformValue::NodeId && - (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) { - // Try to check if we have a struct or array matching a QShaderData parameter - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId)); - } - // Otherwise: param unused by current shader - } - ++it; - } - - // Lights - - int lightIdx = 0; - for (const LightSource &lightSource : activeLightSources) { - if (lightIdx == MAX_LIGHTS) - break; - Entity *lightEntity = lightSource.entity; - const Matrix4x4 lightWorldTransform = *(lightEntity->worldTransform()); - const Vector3D worldPos = lightWorldTransform * Vector3D(0.0f, 0.0f, 0.0f); - for (Light *light : lightSource.lights) { - if (!light->isEnabled()) - continue; - - ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData()); - if (!shaderData) - continue; - - if (lightIdx == MAX_LIGHTS) - break; - - // Note: implicit conversion of values to UniformValue - setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos); - setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight)); - setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f)); - setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f); - - setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[lightIdx], worldPos); - setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[lightIdx], int(QAbstractLight::PointLight)); - setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f)); - setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[lightIdx], 0.5f); - - - // There is no risk in doing that even if multithreaded - // since we are sure that a shaderData is unique for a given light - // and won't ever be referenced as a Component either - Matrix4x4 *worldTransform = lightEntity->worldTransform(); - if (worldTransform) - shaderData->updateWorldTransform(*worldTransform); - - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_NAMES[lightIdx]); - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_UNROLL_NAMES[lightIdx]); - ++lightIdx; - } - } - - if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID)) - setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx))); - - // If no active light sources and no environment light, add a default light - if (activeLightSources.isEmpty() && !environmentLight) { - // Note: implicit conversion of values to UniformValue - setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f)); - setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight)); - setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f)); - setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f); - - setUniformValue(command->m_parameterPack, LIGHT_POSITION_UNROLL_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f)); - setUniformValue(command->m_parameterPack, LIGHT_TYPE_UNROLL_NAMES[0], int(QAbstractLight::PointLight)); - setUniformValue(command->m_parameterPack, LIGHT_COLOR_UNROLL_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f)); - setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_UNROLL_NAMES[0], 0.5f); - } - - // Environment Light - int envLightCount = 0; - if (environmentLight && environmentLight->isEnabled()) { - ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData()); - if (shaderData) { - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, QStringLiteral("envLight")); - envLightCount = 1; - } - } else { - // with some drivers, samplers (like the envbox sampler) need to be bound even though - // they may not be actually used, otherwise draw calls can fail - static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight.irradiance")); - static const int specularId = StringToInt::lookupId(QLatin1String("envLight.specular")); - setUniformValue(command->m_parameterPack, irradianceId, m_renderer->submissionContext()->maxTextureUnitsCount()); - setUniformValue(command->m_parameterPack, specularId, m_renderer->submissionContext()->maxTextureUnitsCount()); - } - setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount); - } - } -} - -bool RenderView::hasBlitFramebufferInfo() const -{ - return m_hasBlitFramebufferInfo; -} - -void RenderView::setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo) -{ - m_hasBlitFramebufferInfo = hasBlitFramebufferInfo; -} - -BlitFramebufferInfo RenderView::blitFrameBufferInfo() const -{ - return m_blitFrameBufferInfo; -} - -void RenderView::setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo) -{ - m_blitFrameBufferInfo = blitFrameBufferInfo; -} - -bool RenderView::isDownloadBuffersEnable() const -{ - return m_isDownloadBuffersEnable; -} - -void RenderView::setIsDownloadBuffersEnable(bool isDownloadBuffersEnable) -{ - m_isDownloadBuffersEnable = isDownloadBuffersEnable; -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/renderview_p.h b/src/render/renderers/opengl/renderer/renderview_p.h deleted file mode 100644 index f00228c84..000000000 --- a/src/render/renderers/opengl/renderer/renderview_p.h +++ /dev/null @@ -1,410 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERVIEW_H -#define QT3DRENDER_RENDER_RENDERVIEW_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qparameter.h> -#include <Qt3DRender/qclearbuffers.h> -#include <Qt3DRender/qlayerfilter.h> -#include <Qt3DRender/private/renderer_p.h> -#include <Qt3DRender/private/clearbuffers_p.h> -#include <Qt3DRender/private/cameralens_p.h> -#include <Qt3DRender/private/attachmentpack_p.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/qsortpolicy_p.h> -#include <Qt3DRender/private/lightsource_p.h> -#include <Qt3DRender/private/qmemorybarrier_p.h> -#include <Qt3DRender/private/qrendercapture_p.h> -#include <Qt3DRender/private/qblitframebuffer_p.h> -#include <Qt3DRender/private/qwaitfence_p.h> - -#include <Qt3DCore/private/qframeallocator_p.h> -#include <Qt3DRender/private/aligned_malloc_p.h> - -// TODO: Move out once this is all refactored -#include <Qt3DRender/private/renderviewjobutils_p.h> - -#include <QVector> -#include <QSurface> -#include <QMutex> -#include <QColor> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -class QRenderPass; - -namespace Render { - -class Renderer; -class NodeManagers; -class RenderCommand; -class RenderPassFilter; -class TechniqueFilter; -class ViewportNode; -class Effect; -class RenderPass; - -typedef QPair<ShaderUniform, QVariant> ActivePropertyContent; -typedef QPair<QString, ActivePropertyContent > ActiveProperty; - -struct Q_AUTOTEST_EXPORT Plane -{ - explicit Plane(const Vector4D &planeEquation) - : planeEquation(planeEquation) - , normal(Vector3D(planeEquation).normalized()) - , d(planeEquation.w() / Vector3D(planeEquation).length()) - {} - - const Vector4D planeEquation; - const Vector3D normal; - const float d; -}; - -struct Q_AUTOTEST_EXPORT ClearBufferInfo -{ - int drawBufferIndex = 0; - QRenderTargetOutput::AttachmentPoint attchmentPoint = QRenderTargetOutput::Color0; - QVector4D clearColor; -}; - -struct Q_AUTOTEST_EXPORT BlitFramebufferInfo -{ - Qt3DCore::QNodeId sourceRenderTargetId; - Qt3DCore::QNodeId destinationRenderTargetId; - QRect sourceRect; - QRect destinationRect; - Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint; - Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint; - QBlitFramebuffer::InterpolationMethod interpolationMethod; -}; - -// This class is kind of analogous to RenderBin but I want to avoid trampling -// on that until we get this working - -class Q_AUTOTEST_EXPORT RenderView -{ -public: - RenderView(); - ~RenderView(); - - QT3D_ALIGNED_MALLOC_AND_FREE() - - // TODO: Add a way to specify a sort predicate for the RenderCommands - void sort(); - - void setRenderer(Renderer *renderer); - inline void setSurfaceSize(const QSize &size) Q_DECL_NOTHROW { m_surfaceSize = size; } - inline Renderer *renderer() const Q_DECL_NOTHROW { return m_renderer; } - inline NodeManagers *nodeManagers() const Q_DECL_NOTHROW { return m_manager; } - inline const QSize &surfaceSize() const Q_DECL_NOTHROW { return m_surfaceSize; } - inline void setDevicePixelRatio(qreal r) Q_DECL_NOTHROW { m_devicePixelRatio = r; } - inline qreal devicePixelRatio() const Q_DECL_NOTHROW { return m_devicePixelRatio; } - - inline void setRenderCameraLens(CameraLens *renderCameraLens) Q_DECL_NOTHROW { m_data.m_renderCameraLens = renderCameraLens; } - inline CameraLens *renderCameraLens() const Q_DECL_NOTHROW { return m_data.m_renderCameraLens; } - - inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW { m_data.m_renderCameraNode = renderCameraNode; } - inline Entity *renderCameraEntity() const Q_DECL_NOTHROW { return m_data.m_renderCameraNode; } - - inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_data.m_viewMatrix = viewMatrix; } - inline Matrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_data.m_viewMatrix; } - - inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_data.m_viewProjectionMatrix = viewProjectionMatrix; } - inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_data.m_viewProjectionMatrix; } - - inline void setEyePosition(const Vector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; } - inline Vector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; } - - inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW { m_data.m_eyeViewDir = dir; } - inline Vector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_data.m_eyeViewDir; } - - inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); } - inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; } - - inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_data.m_proximityFilterIds.push_back(proximityFilterId); } - inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_data.m_proximityFilterIds; } - - inline void appendInsertFenceId(const Qt3DCore::QNodeId setFenceId) { m_insertFenceIds.push_back(setFenceId); } - // We prefix with get to avoid confusion when it is called - inline Qt3DCore::QNodeIdVector insertFenceIds() const { return m_insertFenceIds; } - - inline void appendWaitFence(const QWaitFenceData &data) { m_waitFences.push_back(data); } - inline QVector<QWaitFenceData> waitFences() const { return m_waitFences; } - - inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; } - inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; } - - inline void setTechniqueFilter(const TechniqueFilter *filter) Q_DECL_NOTHROW { m_data.m_techniqueFilter = filter; } - inline const TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_data.m_techniqueFilter; } - - inline RenderStateSet *stateSet() const Q_DECL_NOTHROW { return m_stateSet; } - void setStateSet(RenderStateSet *stateSet) Q_DECL_NOTHROW { m_stateSet = stateSet; } - - inline bool noDraw() const Q_DECL_NOTHROW { return m_noDraw; } - void setNoDraw(bool noDraw) Q_DECL_NOTHROW { m_noDraw = noDraw; } - - inline bool isCompute() const Q_DECL_NOTHROW { return m_compute; } - void setCompute(bool compute) Q_DECL_NOTHROW { m_compute = compute; } - - void setComputeWorkgroups(int x, int y, int z) Q_DECL_NOTHROW { m_workGroups[0] = x; m_workGroups[1] = y; m_workGroups[2] = z; } - const int *computeWorkGroups() const Q_DECL_NOTHROW { return m_workGroups; } - inline bool frustumCulling() const Q_DECL_NOTHROW { return m_frustumCulling; } - void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW { m_frustumCulling = frustumCulling; } - bool showDebugOverlay() const Q_DECL_NOTHROW { return m_showDebugOverlay; } - void setShowDebugOverlay(bool showDebugOverlay) Q_DECL_NOTHROW { m_showDebugOverlay = showDebugOverlay; } - - inline void setMaterialParameterTable(const MaterialParameterGathererData ¶meters) Q_DECL_NOTHROW { m_parameters = parameters; } - - // TODO: Get rid of this overly complex memory management by splitting out the - // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode - // and passed along with the RenderView to the functions that populate the renderview - inline void setViewport(const QRectF &vp) Q_DECL_NOTHROW { m_viewport = vp; } - inline QRectF viewport() const Q_DECL_NOTHROW { return m_viewport; } - - inline float gamma() const Q_DECL_NOTHROW { return m_gamma; } - inline void setGamma(float gamma) Q_DECL_NOTHROW { m_gamma = gamma; } - - // depth and stencil ClearBuffers are cached locally - // color ClearBuffers are collected, as there may be multiple - // color buffers to be cleared. we need to apply all these at rendering - void addClearBuffers(const ClearBuffers *cb); - inline QVector<ClearBufferInfo> specificClearColorBufferInfo() const { return m_specificClearColorBuffers; } - inline QVector<ClearBufferInfo> &specificClearColorBufferInfo() { return m_specificClearColorBuffers; } - inline ClearBufferInfo globalClearColorBufferInfo() const { return m_globalClearColorBuffer; } - - inline QClearBuffers::BufferTypeFlags clearTypes() const { return m_clearBuffer; } - inline float clearDepthValue() const { return m_clearDepthValue; } - inline int clearStencilValue() const { return m_clearStencilValue; } - - RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true); - - EntityRenderCommandData buildDrawRenderCommands(const QVector<Entity *> &entities, - int offset, int count) const; - EntityRenderCommandData buildComputeRenderCommands(const QVector<Entity *> &entities, - int offset, int count) const; - - - void updateRenderCommand(EntityRenderCommandData *renderCommandData, - int offset, int count); - - - void setCommands(const QVector<RenderCommand> &commands) Q_DECL_NOTHROW { m_commands = commands; } - QVector<RenderCommand> &commands() { return m_commands; } - QVector<RenderCommand> commands() const { return m_commands; } - - void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; } - const AttachmentPack &attachmentPack() const { return m_attachmentPack; } - - void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) Q_DECL_NOTHROW { m_renderTarget = renderTargetId; } - Qt3DCore::QNodeId renderTargetId() const Q_DECL_NOTHROW { return m_renderTarget; } - - void addSortType(const QVector<Qt3DRender::QSortPolicy::SortType> &sortTypes) { m_data.m_sortingTypes.append(sortTypes); } - - void setSurface(QSurface *surface) { m_surface = surface; } - QSurface *surface() const { return m_surface; } - - void setLightSources(const QVector<LightSource> &lightSources) Q_DECL_NOTHROW { m_lightSources = lightSources; } - void setEnvironmentLight(EnvironmentLight *environmentLight) Q_DECL_NOTHROW { m_environmentLight = environmentLight; } - - void updateMatrices(); - - inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW { m_renderCaptureNodeId = nodeId; } - inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW { return m_renderCaptureNodeId; } - inline void setRenderCaptureRequest(const QRenderCaptureRequest& request) Q_DECL_NOTHROW { m_renderCaptureRequest = request; } - inline const QRenderCaptureRequest renderCaptureRequest() const Q_DECL_NOTHROW { return m_renderCaptureRequest; } - - void setMemoryBarrier(QMemoryBarrier::Operations barrier) Q_DECL_NOTHROW { m_memoryBarrier = barrier; } - QMemoryBarrier::Operations memoryBarrier() const Q_DECL_NOTHROW { return m_memoryBarrier; } - - // Helps making the size of RenderView smaller - // Contains all the data needed for the actual building of the RenderView - // But that aren't used later by the Renderer - struct InnerData { - InnerData() - : m_renderCameraLens(nullptr) - , m_renderCameraNode(nullptr) - , m_techniqueFilter(nullptr) - , m_passFilter(nullptr) - { - } - CameraLens *m_renderCameraLens; - Entity *m_renderCameraNode; - const TechniqueFilter *m_techniqueFilter; - const RenderPassFilter *m_passFilter; - Matrix4x4 m_viewMatrix; - Matrix4x4 m_viewProjectionMatrix; - Qt3DCore::QNodeIdVector m_layerFilterIds; - QVector<Qt3DRender::QSortPolicy::SortType> m_sortingTypes; - Vector3D m_eyePos; - Vector3D m_eyeViewDir; - Qt3DCore::QNodeIdVector m_proximityFilterIds; - }; - - bool isDownloadBuffersEnable() const; - void setIsDownloadBuffersEnable(bool isDownloadBuffersEnable); - - BlitFramebufferInfo blitFrameBufferInfo() const; - void setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo); - - bool hasBlitFramebufferInfo() const; - void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo); - -private: - void setShaderAndUniforms(RenderCommand *command, - ParameterInfoList ¶meters, - Entity *entity, - const QVector<LightSource> &activeLightSources, - EnvironmentLight *environmentLight) const; - mutable QThreadStorage<UniformBlockValueBuilder*> m_localData; - - Qt3DCore::QNodeId m_renderCaptureNodeId; - QRenderCaptureRequest m_renderCaptureRequest; - bool m_isDownloadBuffersEnable; - - bool m_hasBlitFramebufferInfo; - BlitFramebufferInfo m_blitFrameBufferInfo; - - Renderer *m_renderer; - NodeManagers *m_manager; - QSize m_surfaceSize; - qreal m_devicePixelRatio; - - InnerData m_data; - - QRectF m_viewport; - float m_gamma; - Qt3DCore::QNodeId m_renderTarget; - QSurface *m_surface; - AttachmentPack m_attachmentPack; - QClearBuffers::BufferTypeFlags m_clearBuffer; - float m_clearDepthValue; - int m_clearStencilValue; - ClearBufferInfo m_globalClearColorBuffer; // global ClearColor - QVector<ClearBufferInfo> m_specificClearColorBuffers; // different draw buffers with distinct colors - RenderStateSet *m_stateSet; - bool m_noDraw:1; - bool m_compute:1; - bool m_frustumCulling:1; - bool m_showDebugOverlay:1; - int m_workGroups[3]; - QMemoryBarrier::Operations m_memoryBarrier; - QVector<Qt3DCore::QNodeId> m_insertFenceIds; - QVector<QWaitFenceData> m_waitFences; - - QVector<RenderCommand> m_commands; - mutable QVector<LightSource> m_lightSources; - EnvironmentLight *m_environmentLight; - - MaterialParameterGathererData m_parameters; - - enum StandardUniform - { - ModelMatrix, - ViewMatrix, - ProjectionMatrix, - ModelViewMatrix, - ViewProjectionMatrix, - ModelViewProjectionMatrix, - InverseModelMatrix, - InverseViewMatrix, - InverseProjectionMatrix, - InverseModelViewMatrix, - InverseViewProjectionMatrix, - InverseModelViewProjectionMatrix, - ModelNormalMatrix, - ModelViewNormalMatrix, - ViewportMatrix, - InverseViewportMatrix, - AspectRatio, - Time, - Exposure, - Gamma, - EyePosition, - SkinningPalette - }; - - typedef QHash<int, StandardUniform> StandardUniformsNameToTypeHash; - static StandardUniformsNameToTypeHash ms_standardUniformSetters; - static StandardUniformsNameToTypeHash initializeStandardUniformSetters(); - - UniformValue standardUniformValue(StandardUniform standardUniformType, - Entity *entity, - const Matrix4x4 &model) const; - - void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const; - void setStandardUniformValue(ShaderParameterPack &uniformPack, - int glslNameId, - int nameId, - Entity *entity, - const Matrix4x4 &worldTransform) const; - void setUniformBlockValue(ShaderParameterPack &uniformPack, - GLShader *shader, - const ShaderUniformBlock &block, - const UniformValue &value) const; - void setShaderStorageValue(ShaderParameterPack &uniformPack, - GLShader *shader, - const ShaderStorageBlock &block, - const UniformValue &value) const; - void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, - GLShader *shader, - ShaderData *shaderData, - const QString &structName) const; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERVIEW_H diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp b/src/render/renderers/opengl/renderer/renderviewbuilder.cpp deleted file mode 100644 index 4034af146..000000000 --- a/src/render/renderers/opengl/renderer/renderviewbuilder.cpp +++ /dev/null @@ -1,803 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewbuilder_p.h" - -#include <QThread> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -// In some cases having less jobs is better (especially on fast cpus where -// splitting just adds more overhead). Ideally, we should try to set the value -// depending on the platform/CPU/nbr of cores -const int RenderViewBuilder::m_optimalParallelJobCount = QThread::idealThreadCount(); - -namespace { - -int findIdealNumberOfWorkers(int elementCount, int packetSize = 100) -{ - if (elementCount == 0 || packetSize == 0) - return 0; - return std::min(std::max(elementCount / packetSize, 1), RenderViewBuilder::optimalJobCount()); -} - - -class SyncPreCommandBuilding -{ -public: - explicit SyncPreCommandBuilding(RenderViewInitializerJobPtr renderViewInitializerJob, - const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_renderViewInitializer(renderViewInitializerJob) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - { - } - - void operator()() - { - // Split commands to build among jobs - QMutexLocker lock(m_renderer->cache()->mutex()); - // Rebuild RenderCommands for all entities in RV (ignoring filtering) - RendererCache *cache = m_renderer->cache(); - const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode]; - RenderView *rv = m_renderViewInitializer->renderView(); - const auto entities = !rv->isCompute() ? cache->renderableEntities : cache->computeEntities; - - rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer); - - lock.unlock(); - - // Split among the ideal number of command builders - const int idealPacketSize = std::min(std::max(100, entities.size() / RenderViewBuilder::optimalJobCount()), entities.size()); - // Try to split work into an ideal number of workers - const int m = findIdealNumberOfWorkers(entities.size(), idealPacketSize); - - for (int i = 0; i < m; ++i) { - const RenderViewCommandBuilderJobPtr renderViewCommandBuilder = m_renderViewCommandBuilderJobs.at(i); - const int count = (i == m - 1) ? entities.size() - (i * idealPacketSize) : idealPacketSize; - renderViewCommandBuilder->setEntities(entities, i * idealPacketSize, count); - } - } - -private: - RenderViewInitializerJobPtr m_renderViewInitializer; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; -}; - -class SyncRenderViewPostCommandUpdate -{ -public: - explicit SyncRenderViewPostCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob, - const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdateJobs, - Renderer *renderer) - : m_renderViewJob(renderViewJob) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdateJobs) - , m_renderer(renderer) - {} - - void operator()() - { - // Append all the commands and sort them - RenderView *rv = m_renderViewJob->renderView(); - - const EntityRenderCommandDataPtr commandData = m_renderViewCommandUpdaterJobs.first()->renderables(); - - if (commandData) { - const QVector<RenderCommand> commands = std::move(commandData->commands); - rv->setCommands(commands); - - // TO DO: Find way to store commands once or at least only when required - // Sort the commands - rv->sort(); - } - - // Enqueue our fully populated RenderView with the RenderThread - m_renderer->enqueueRenderView(rv, m_renderViewJob->submitOrderIndex()); - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - Renderer *m_renderer; -}; - -class SyncPreFrustumCulling -{ -public: - explicit SyncPreFrustumCulling(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCulling) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCulling) - {} - - void operator()() - { - RenderView *rv = m_renderViewJob->renderView(); - - // Update matrices now that all transforms have been updated - rv->updateMatrices(); - - // Frustum culling - m_frustumCullingJob->setViewProjection(rv->viewProjectionMatrix()); - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - FrustumCullingJobPtr m_frustumCullingJob; -}; - -class SyncRenderViewPostInitialization -{ -public: - explicit SyncRenderViewPostInitialization(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCullingJob, - const FilterLayerEntityJobPtr &filterEntityByLayerJob, - const FilterProximityDistanceJobPtr &filterProximityJob, - const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs, - const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdaterJobs, - const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCullingJob) - , m_filterEntityByLayerJob(filterEntityByLayerJob) - , m_filterProximityJob(filterProximityJob) - , m_materialGathererJobs(materialGathererJobs) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - {} - - void operator()() - { - RenderView *rv = m_renderViewJob->renderView(); - - // Layer filtering - if (!m_filterEntityByLayerJob.isNull()) - m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters()); - - // Proximity filtering - m_filterProximityJob->setProximityFilterIds(rv->proximityFilterIds()); - - // Material Parameter building - for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { - materialGatherer->setRenderPassFilter(const_cast<RenderPassFilter *>(rv->renderPassFilter())); - materialGatherer->setTechniqueFilter(const_cast<TechniqueFilter *>(rv->techniqueFilter())); - } - - // Command builders and updates - for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs)) - renderViewCommandUpdater->setRenderView(rv); - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) - renderViewCommandBuilder->setRenderView(rv); - - // Set whether frustum culling is enabled or not - m_frustumCullingJob->setActive(rv->frustumCulling()); - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - FrustumCullingJobPtr m_frustumCullingJob; - FilterLayerEntityJobPtr m_filterEntityByLayerJob; - FilterProximityDistanceJobPtr m_filterProximityJob; - QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; -}; - -class SyncRenderViewPreCommandUpdate -{ -public: - explicit SyncRenderViewPreCommandUpdate(const RenderViewInitializerJobPtr &renderViewJob, - const FrustumCullingJobPtr &frustumCullingJob, - const FilterProximityDistanceJobPtr &filterProximityJob, - const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs, - const QVector<RenderViewCommandUpdaterJobPtr> &renderViewCommandUpdaterJobs, - const QVector<RenderViewCommandBuilderJobPtr> &renderViewCommandBuilderJobs, - Renderer *renderer, - FrameGraphNode *leafNode, - bool fullCommandRebuild) - : m_renderViewJob(renderViewJob) - , m_frustumCullingJob(frustumCullingJob) - , m_filterProximityJob(filterProximityJob) - , m_materialGathererJobs(materialGathererJobs) - , m_renderViewCommandUpdaterJobs(renderViewCommandUpdaterJobs) - , m_renderViewCommandBuilderJobs(renderViewCommandBuilderJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - , m_fullRebuild(fullCommandRebuild) - {} - - void operator()() - { - // Set the result of previous job computations - // for final RenderCommand building - RenderView *rv = m_renderViewJob->renderView(); - - if (!rv->noDraw()) { - ///////// CACHE LOCKED //////////// - // Retrieve Data from Cache - RendererCache *cache = m_renderer->cache(); - QMutexLocker lock(cache->mutex()); - Q_ASSERT(cache->leafNodeCache.contains(m_leafNode)); - - const bool isDraw = !rv->isCompute(); - const RendererCache::LeafNodeData &dataCacheForLeaf = cache->leafNodeCache[m_leafNode]; - - // Rebuild RenderCommands if required - // This should happen fairly infrequently (FrameGraph Change, Geometry/Material change) - // and allow to skip that step most of the time - if (m_fullRebuild) { - EntityRenderCommandData commandData; - // Reduction - { - int totalCommandCount = 0; - for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) - totalCommandCount += renderViewCommandBuilder->commandData().size(); - commandData.reserve(totalCommandCount); - for (const RenderViewCommandBuilderJobPtr &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) - commandData += std::move(renderViewCommandBuilder->commandData()); - } - - - // Store new cache - RendererCache::LeafNodeData &writableCacheForLeaf = cache->leafNodeCache[m_leafNode]; - writableCacheForLeaf.renderCommandData = std::move(commandData); - } - const EntityRenderCommandData commandData = dataCacheForLeaf.renderCommandData; - const QVector<Entity *> filteredEntities = dataCacheForLeaf.filterEntitiesByLayer; - QVector<Entity *> renderableEntities = isDraw ? cache->renderableEntities : cache->computeEntities; - QVector<LightSource> lightSources = cache->gatheredLights; - - rv->setMaterialParameterTable(dataCacheForLeaf.materialParameterGatherer); - rv->setEnvironmentLight(cache->environmentLight); - lock.unlock(); - ///////// END OF CACHE LOCKED //////////// - - // Filter out entities that weren't selected by the layer filters - // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, filteredEntities); - - // Set the light sources, with layer filters applied. - for (int i = 0; i < lightSources.count(); ++i) { - if (!filteredEntities.contains(lightSources[i].entity)) - lightSources.removeAt(i--); - } - rv->setLightSources(lightSources); - - if (isDraw) { - // Filter out frustum culled entity for drawable entities - if (rv->frustumCulling()) - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_frustumCullingJob->visibleEntities()); - // Filter out entities which didn't satisfy proximity filtering - if (!rv->proximityFilterIds().empty()) - renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities()); - } - - // Early return in case we have nothing to filter - if (renderableEntities.size() == 0) - return; - - // Filter out Render commands for which the Entity wasn't selected because - // of frustum, proximity or layer filtering - EntityRenderCommandDataPtr filteredCommandData = EntityRenderCommandDataPtr::create(); - filteredCommandData->reserve(renderableEntities.size()); - // Because dataCacheForLeaf.renderableEntities or computeEntities are sorted - // What we get out of EntityRenderCommandData is also sorted by Entity - auto eIt = renderableEntities.cbegin(); - const auto eEnd = renderableEntities.cend(); - int cIt = 0; - const int cEnd = commandData.size(); - - while (eIt != eEnd) { - const Entity *targetEntity = *eIt; - // Advance until we have commands whose Entity has a lower address - // than the selected filtered entity - while (cIt != cEnd && commandData.entities.at(cIt) < targetEntity) - ++cIt; - - // Push pointers to command data for all commands that match the - // entity - while (cIt != cEnd && commandData.entities.at(cIt) == targetEntity) { - filteredCommandData->push_back(commandData.entities.at(cIt), - commandData.commands.at(cIt), - commandData.passesData.at(cIt)); - ++cIt; - } - ++eIt; - } - - // Split among the number of command builders - // The idealPacketSize is at least 100 entities per worker - const int idealPacketSize = std::min(std::max(100, filteredCommandData->size() / RenderViewBuilder::optimalJobCount()), filteredCommandData->size()); - const int m = findIdealNumberOfWorkers(filteredCommandData->size(), idealPacketSize); - - for (int i = 0; i < m; ++i) { - const RenderViewCommandUpdaterJobPtr renderViewCommandBuilder = m_renderViewCommandUpdaterJobs.at(i); - const int count = (i == m - 1) ? filteredCommandData->size() - (i * idealPacketSize) : idealPacketSize; - renderViewCommandBuilder->setRenderables(filteredCommandData, i * idealPacketSize, count); - } - } - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; - FrustumCullingJobPtr m_frustumCullingJob; - FilterProximityDistanceJobPtr m_filterProximityJob; - QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; - bool m_fullRebuild; -}; - -class SetClearDrawBufferIndex -{ -public: - explicit SetClearDrawBufferIndex(const RenderViewInitializerJobPtr &renderViewJob) - : m_renderViewJob(renderViewJob) - {} - - void operator()() - { - RenderView *rv = m_renderViewJob->renderView(); - QVector<ClearBufferInfo> &clearBuffersInfo = rv->specificClearColorBufferInfo(); - const AttachmentPack &attachmentPack = rv->attachmentPack(); - for (ClearBufferInfo &clearBufferInfo : clearBuffersInfo) - clearBufferInfo.drawBufferIndex = attachmentPack.getDrawBufferIndex(clearBufferInfo.attchmentPoint); - - } - -private: - RenderViewInitializerJobPtr m_renderViewJob; -}; - -class SyncFilterEntityByLayer -{ -public: - explicit SyncFilterEntityByLayer(const FilterLayerEntityJobPtr &filterEntityByLayerJob, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_filterEntityByLayerJob(filterEntityByLayerJob) - , m_renderer(renderer) - , m_leafNode(leafNode) - { - } - - void operator()() - { - QMutexLocker lock(m_renderer->cache()->mutex()); - // Save the filtered by layer subset into the cache - const QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities(); - RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; - dataCacheForLeaf.filterEntitiesByLayer = filteredEntities; - } - -private: - FilterLayerEntityJobPtr m_filterEntityByLayerJob; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; -}; - -class SyncMaterialParameterGatherer -{ -public: - explicit SyncMaterialParameterGatherer(const QVector<MaterialParameterGathererJobPtr> &materialParameterGathererJobs, - Renderer *renderer, - FrameGraphNode *leafNode) - : m_materialParameterGathererJobs(materialParameterGathererJobs) - , m_renderer(renderer) - , m_leafNode(leafNode) - { - } - - void operator()() - { - QMutexLocker lock(m_renderer->cache()->mutex()); - RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode]; - dataCacheForLeaf.materialParameterGatherer.clear(); - - for (const auto &materialGatherer : qAsConst(m_materialParameterGathererJobs)) - dataCacheForLeaf.materialParameterGatherer.unite(materialGatherer->materialToPassAndParameter()); - } - -private: - QVector<MaterialParameterGathererJobPtr> m_materialParameterGathererJobs; - Renderer *m_renderer; - FrameGraphNode *m_leafNode; -}; - -} // anonymous - -RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer) - : m_leafNode(leafNode) - , m_renderViewIndex(renderViewIndex) - , m_renderer(renderer) - , m_layerCacheNeedsToBeRebuilt(false) - , m_materialGathererCacheNeedsToBeRebuilt(false) - , m_renderCommandCacheNeedsToBeRebuilt(false) - , m_renderViewJob(RenderViewInitializerJobPtr::create()) - , m_filterEntityByLayerJob() - , m_frustumCullingJob(new Render::FrustumCullingJob()) - , m_syncPreFrustumCullingJob(SynchronizerJobPtr::create(SyncPreFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling)) - , m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex)) - , m_syncFilterEntityByLayerJob() - , m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create()) -{ -} - -RenderViewInitializerJobPtr RenderViewBuilder::renderViewJob() const -{ - return m_renderViewJob; -} - -FilterLayerEntityJobPtr RenderViewBuilder::filterEntityByLayerJob() const -{ - return m_filterEntityByLayerJob; -} - -FrustumCullingJobPtr RenderViewBuilder::frustumCullingJob() const -{ - return m_frustumCullingJob; -} - -QVector<RenderViewCommandUpdaterJobPtr> RenderViewBuilder::renderViewCommandUpdaterJobs() const -{ - return m_renderViewCommandUpdaterJobs; -} - -QVector<RenderViewCommandBuilderJobPtr> RenderViewBuilder::renderViewCommandBuilderJobs() const -{ - return m_renderViewCommandBuilderJobs; -} - -QVector<MaterialParameterGathererJobPtr> RenderViewBuilder::materialGathererJobs() const -{ - return m_materialGathererJobs; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPostInitializationJob() const -{ - return m_syncRenderViewPostInitializationJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncPreFrustumCullingJob() const -{ - return m_syncPreFrustumCullingJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPreCommandBuildingJob() const -{ - return m_syncRenderViewPreCommandBuildingJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPreCommandUpdateJob() const -{ - return m_syncRenderViewPreCommandUpdateJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncRenderViewPostCommandUpdateJob() const -{ - return m_syncRenderViewPostCommandUpdateJob; -} - -SynchronizerJobPtr RenderViewBuilder::setClearDrawBufferIndexJob() const -{ - return m_setClearDrawBufferIndexJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncFilterEntityByLayerJob() const -{ - return m_syncFilterEntityByLayerJob; -} - -SynchronizerJobPtr RenderViewBuilder::syncMaterialGathererJob() const -{ - return m_syncMaterialGathererJob; -} - -FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const -{ - return m_filterProximityJob; -} - -void RenderViewBuilder::prepareJobs() -{ - // Init what we can here - m_filterProximityJob->setManager(m_renderer->nodeManagers()); - m_frustumCullingJob->setRoot(m_renderer->sceneRoot()); - - if (m_renderCommandCacheNeedsToBeRebuilt) { - - m_renderViewCommandBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); - for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { - auto renderViewCommandBuilder = Render::RenderViewCommandBuilderJobPtr::create(); - m_renderViewCommandBuilderJobs.push_back(renderViewCommandBuilder); - } - m_syncRenderViewPreCommandBuildingJob = SynchronizerJobPtr::create(SyncPreCommandBuilding(m_renderViewJob, - m_renderViewCommandBuilderJobs, - m_renderer, - m_leafNode), - JobTypes::SyncRenderViewPreCommandBuilding); - } - - m_renderViewJob->setRenderer(m_renderer); - m_renderViewJob->setFrameGraphLeafNode(m_leafNode); - m_renderViewJob->setSubmitOrderIndex(m_renderViewIndex); - - // RenderCommand building is the most consuming task -> split it - // Estimate the number of jobs to create based on the number of entities - m_renderViewCommandUpdaterJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); - for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { - auto renderViewCommandUpdater = Render::RenderViewCommandUpdaterJobPtr::create(); - renderViewCommandUpdater->setRenderer(m_renderer); - m_renderViewCommandUpdaterJobs.push_back(renderViewCommandUpdater); - } - - if (m_materialGathererCacheNeedsToBeRebuilt) { - // Since Material gathering is an heavy task, we split it - const QVector<HMaterial> materialHandles = m_renderer->nodeManagers()->materialManager()->activeHandles(); - const int elementsPerJob = materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount; - const int lastRemaingElements = materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount; - m_materialGathererJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount); - for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) { - auto materialGatherer = Render::MaterialParameterGathererJobPtr::create(); - materialGatherer->setNodeManagers(m_renderer->nodeManagers()); - if (i == RenderViewBuilder::m_optimalParallelJobCount - 1) - materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob + lastRemaingElements)); - else - materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob)); - m_materialGathererJobs.push_back(materialGatherer); - } - m_syncMaterialGathererJob = SynchronizerJobPtr::create(SyncMaterialParameterGatherer(m_materialGathererJobs, - m_renderer, - m_leafNode), - JobTypes::SyncMaterialGatherer); - } - - if (m_layerCacheNeedsToBeRebuilt) { - m_filterEntityByLayerJob = Render::FilterLayerEntityJobPtr::create(); - m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers()); - m_syncFilterEntityByLayerJob = SynchronizerJobPtr::create(SyncFilterEntityByLayer(m_filterEntityByLayerJob, - m_renderer, - m_leafNode), - JobTypes::SyncFilterEntityByLayer); - } - - m_syncRenderViewPreCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPreCommandUpdate(m_renderViewJob, - m_frustumCullingJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewCommandUpdaterJobs, - m_renderViewCommandBuilderJobs, - m_renderer, - m_leafNode, - m_renderCommandCacheNeedsToBeRebuilt), - JobTypes::SyncRenderViewPreCommandUpdate); - - m_syncRenderViewPostCommandUpdateJob = SynchronizerJobPtr::create(SyncRenderViewPostCommandUpdate(m_renderViewJob, - m_renderViewCommandUpdaterJobs, - m_renderer), - JobTypes::SyncRenderViewPostCommandUpdate); - - m_syncRenderViewPostInitializationJob = SynchronizerJobPtr::create(SyncRenderViewPostInitialization(m_renderViewJob, - m_frustumCullingJob, - m_filterEntityByLayerJob, - m_filterProximityJob, - m_materialGathererJobs, - m_renderViewCommandUpdaterJobs, - m_renderViewCommandBuilderJobs), - JobTypes::SyncRenderViewInitialization); -} - -QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const -{ - QVector<Qt3DCore::QAspectJobPtr> jobs; - - jobs.reserve(m_materialGathererJobs.size() + m_renderViewCommandUpdaterJobs.size() + 11); - - // Set dependencies - - // Finish the skinning palette job before processing renderviews - // TODO: Maybe only update skinning palettes for non-culled entities - m_renderViewJob->addDependency(m_renderer->updateSkinningPaletteJob()); - - m_syncPreFrustumCullingJob->addDependency(m_renderer->updateWorldTransformJob()); - m_syncPreFrustumCullingJob->addDependency(m_renderer->updateShaderDataTransformJob()); - m_syncPreFrustumCullingJob->addDependency(m_syncRenderViewPostInitializationJob); - - m_frustumCullingJob->addDependency(m_renderer->expandBoundingVolumeJob()); - m_frustumCullingJob->addDependency(m_syncPreFrustumCullingJob); - - m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewPostInitializationJob); - - m_syncRenderViewPostInitializationJob->addDependency(m_renderViewJob); - - m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob()); - m_filterProximityJob->addDependency(m_syncRenderViewPostInitializationJob); - - m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncRenderViewPostInitializationJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_filterProximityJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_frustumCullingJob); - - // Ensure the RenderThread won't be able to process dirtyResources - // before they have been completely gathered - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->introspectShadersJob()); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->bufferGathererJob()); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->textureGathererJob()); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_renderer->cacheLightJob()); - - for (const auto &renderViewCommandUpdater : qAsConst(m_renderViewCommandUpdaterJobs)) { - renderViewCommandUpdater->addDependency(m_syncRenderViewPreCommandUpdateJob); - m_syncRenderViewPostCommandUpdateJob->addDependency(renderViewCommandUpdater); - } - - m_renderer->frameCleanupJob()->addDependency(m_syncRenderViewPostCommandUpdateJob); - m_renderer->frameCleanupJob()->addDependency(m_setClearDrawBufferIndexJob); - - // Add jobs - jobs.push_back(m_renderViewJob); // Step 1 - - jobs.push_back(m_syncRenderViewPostInitializationJob); // Step 2 - - if (m_renderCommandCacheNeedsToBeRebuilt) { // Step 3 - m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheComputableEntitiesJob()); - m_syncRenderViewPreCommandBuildingJob->addDependency(m_renderer->cacheRenderableEntitiesJob()); - m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncRenderViewPostInitializationJob); - - if (m_materialGathererCacheNeedsToBeRebuilt) - m_syncRenderViewPreCommandBuildingJob->addDependency(m_syncMaterialGathererJob); - - jobs.push_back(m_syncRenderViewPreCommandBuildingJob); - - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandBuilderJobs)) { - renderViewCommandBuilder->addDependency(m_syncRenderViewPreCommandBuildingJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(renderViewCommandBuilder); - jobs.push_back(renderViewCommandBuilder); - } - } - - if (m_layerCacheNeedsToBeRebuilt) { - m_filterEntityByLayerJob->addDependency(m_renderer->updateEntityLayersJob()); - m_filterEntityByLayerJob->addDependency(m_syncRenderViewPostInitializationJob); - m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob()); - - m_syncFilterEntityByLayerJob->addDependency(m_filterEntityByLayerJob); - m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncFilterEntityByLayerJob); - - jobs.push_back(m_filterEntityByLayerJob); // Step 3 - jobs.push_back(m_syncFilterEntityByLayerJob); // Step 4 - } - jobs.push_back(m_syncPreFrustumCullingJob); // Step 3 - jobs.push_back(m_filterProximityJob); // Step 3 - jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3 - - if (m_materialGathererCacheNeedsToBeRebuilt) { - for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) { - materialGatherer->addDependency(m_syncRenderViewPostInitializationJob); - materialGatherer->addDependency(m_renderer->introspectShadersJob()); - materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob()); - jobs.push_back(materialGatherer); // Step3 - m_syncMaterialGathererJob->addDependency(materialGatherer); - } - m_syncRenderViewPreCommandUpdateJob->addDependency(m_syncMaterialGathererJob); - - jobs.push_back(m_syncMaterialGathererJob); // Step 3 - } - - jobs.push_back(m_frustumCullingJob); // Step 4 - jobs.push_back(m_syncRenderViewPreCommandUpdateJob); // Step 5 - - // Build RenderCommands or Update RenderCommand Uniforms - for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewCommandUpdaterJobs)) // Step 6 - jobs.push_back(renderViewCommandBuilder); - - jobs.push_back(m_syncRenderViewPostCommandUpdateJob); // Step 7 - - return jobs; -} - -Renderer *RenderViewBuilder::renderer() const -{ - return m_renderer; -} - -int RenderViewBuilder::renderViewIndex() const -{ - return m_renderViewIndex; -} - -void RenderViewBuilder::setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt) -{ - m_layerCacheNeedsToBeRebuilt = needsToBeRebuilt; -} - -bool RenderViewBuilder::layerCacheNeedsToBeRebuilt() const -{ - return m_layerCacheNeedsToBeRebuilt; -} - -void RenderViewBuilder::setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt) -{ - m_materialGathererCacheNeedsToBeRebuilt = needsToBeRebuilt; -} - -bool RenderViewBuilder::materialGathererCacheNeedsToBeRebuilt() const -{ - return m_materialGathererCacheNeedsToBeRebuilt; -} - -void RenderViewBuilder::setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt) -{ - m_renderCommandCacheNeedsToBeRebuilt = needsToBeRebuilt; -} - -bool RenderViewBuilder::renderCommandCacheNeedsToBeRebuilt() const -{ - return m_renderCommandCacheNeedsToBeRebuilt; -} - -int RenderViewBuilder::optimalJobCount() -{ - return RenderViewBuilder::m_optimalParallelJobCount; -} - -QVector<Entity *> RenderViewBuilder::entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset) -{ - QVector<Entity *> intersection; - intersection.reserve(qMin(entities.size(), subset.size())); - std::set_intersection(entities.begin(), entities.end(), - subset.begin(), subset.end(), - std::back_inserter(intersection)); - - return intersection; -} - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/renderviewbuilder_p.h b/src/render/renderers/opengl/renderer/renderviewbuilder_p.h deleted file mode 100644 index a2ab80e7e..000000000 --- a/src/render/renderers/opengl/renderer/renderviewbuilder_p.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERVIEWBUILDER_H -#define QT3DRENDER_RENDER_RENDERVIEWBUILDER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <functional> -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/filterlayerentityjob_p.h> -#include <Qt3DRender/private/genericlambdajob_p.h> -#include <Qt3DRender/private/materialparametergathererjob_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/renderviewcommandbuilderjob_p.h> -#include <Qt3DRender/private/renderviewcommandupdaterjob_p.h> -#include <Qt3DRender/private/renderview_p.h> -#include <Qt3DRender/private/frustumcullingjob_p.h> -#include <Qt3DRender/private/filterproximitydistancejob_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class Renderer; - -using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; - -class Q_AUTOTEST_EXPORT RenderViewBuilder -{ -public: - explicit RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer); - - RenderViewInitializerJobPtr renderViewJob() const; - FilterLayerEntityJobPtr filterEntityByLayerJob() const; - FrustumCullingJobPtr frustumCullingJob() const; - QVector<RenderViewCommandBuilderJobPtr> renderViewCommandBuilderJobs() const; - QVector<RenderViewCommandUpdaterJobPtr> renderViewCommandUpdaterJobs() const; - QVector<MaterialParameterGathererJobPtr> materialGathererJobs() const; - SynchronizerJobPtr syncRenderViewPostInitializationJob() const; - SynchronizerJobPtr syncPreFrustumCullingJob() const; - SynchronizerJobPtr syncRenderViewPreCommandBuildingJob() const; - SynchronizerJobPtr syncRenderViewPreCommandUpdateJob() const; - SynchronizerJobPtr syncRenderViewPostCommandUpdateJob() const; - SynchronizerJobPtr setClearDrawBufferIndexJob() const; - SynchronizerJobPtr syncFilterEntityByLayerJob() const; - FilterProximityDistanceJobPtr filterProximityJob() const; - SynchronizerJobPtr syncMaterialGathererJob() const; - - void prepareJobs(); - QVector<Qt3DCore::QAspectJobPtr> buildJobHierachy() const; - - Renderer *renderer() const; - int renderViewIndex() const; - - void setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt); - bool layerCacheNeedsToBeRebuilt() const; - void setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt); - bool materialGathererCacheNeedsToBeRebuilt() const; - void setRenderCommandCacheNeedsToBeRebuilt(bool needsToBeRebuilt); - bool renderCommandCacheNeedsToBeRebuilt() const; - - static int optimalJobCount(); - static QVector<Entity *> entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset); - -private: - Render::FrameGraphNode *m_leafNode; - const int m_renderViewIndex; - Renderer *m_renderer; - bool m_layerCacheNeedsToBeRebuilt; - bool m_materialGathererCacheNeedsToBeRebuilt; - bool m_renderCommandCacheNeedsToBeRebuilt; - - RenderViewInitializerJobPtr m_renderViewJob; - FilterLayerEntityJobPtr m_filterEntityByLayerJob; - FrustumCullingJobPtr m_frustumCullingJob; - QVector<RenderViewCommandBuilderJobPtr> m_renderViewCommandBuilderJobs; - QVector<RenderViewCommandUpdaterJobPtr> m_renderViewCommandUpdaterJobs; - QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs; - - SynchronizerJobPtr m_syncRenderViewPostInitializationJob; - SynchronizerJobPtr m_syncPreFrustumCullingJob; - SynchronizerJobPtr m_syncRenderViewPreCommandBuildingJob; - SynchronizerJobPtr m_syncRenderViewPreCommandUpdateJob; - SynchronizerJobPtr m_syncRenderViewPostCommandUpdateJob; - SynchronizerJobPtr m_setClearDrawBufferIndexJob; - SynchronizerJobPtr m_syncFilterEntityByLayerJob; - SynchronizerJobPtr m_syncMaterialGathererJob; - FilterProximityDistanceJobPtr m_filterProximityJob; - - static const int m_optimalParallelJobCount; -}; - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERVIEWBUILDER_H diff --git a/src/render/renderers/opengl/renderer/shaderparameterpack.cpp b/src/render/renderers/opengl/renderer/shaderparameterpack.cpp deleted file mode 100644 index 1cfb59343..000000000 --- a/src/render/renderers/opengl/renderer/shaderparameterpack.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "shaderparameterpack_p.h" - -#include <Qt3DRender/private/graphicscontext_p.h> -#include <Qt3DRender/private/texture_p.h> - -#include <Qt3DCore/private/qframeallocator_p.h> - -#include <QOpenGLShaderProgram> -#include <QDebug> -#include <QColor> -#include <QQuaternion> -#include <Qt3DRender/private/renderlogging_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -ShaderParameterPack::~ShaderParameterPack() -{ -} - -void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val) -{ - m_uniforms.insert(glslNameId, val); -} - -void ShaderParameterPack::setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId texId) -{ - for (int t=0; t<m_textures.size(); ++t) { - if (m_textures[t].glslNameId != glslNameId || m_textures[t].uniformArrayIndex != uniformArrayIndex) - continue; - - m_textures[t].nodeId = texId; - return; - } - - m_textures.append(NamedResource(glslNameId, texId, uniformArrayIndex, NamedResource::Texture)); -} - -void ShaderParameterPack::setImage(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id) -{ - for (int i=0, m = m_images.size(); i < m; ++i) { - if (m_images[i].glslNameId != glslNameId || m_images[i].uniformArrayIndex != uniformArrayIndex) - continue; - - m_images[i].nodeId = id; - return; - } - - m_images.append(NamedResource(glslNameId, id, uniformArrayIndex, NamedResource::Image)); -} - -// Contains Uniform Block Index and QNodeId of the ShaderData (UBO) -void ShaderParameterPack::setUniformBuffer(BlockToUBO blockToUBO) -{ - m_uniformBuffers.append(std::move(blockToUBO)); -} - -void ShaderParameterPack::setShaderStorageBuffer(BlockToSSBO blockToSSBO) -{ - m_shaderStorageBuffers.push_back(std::move(blockToSSBO)); -} - -void ShaderParameterPack::setSubmissionUniform(const ShaderUniform &uniform) -{ - m_submissionUniforms.push_back(uniform); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h b/src/render/renderers/opengl/renderer/shaderparameterpack_p.h deleted file mode 100644 index cb599124c..000000000 --- a/src/render/renderers/opengl/renderer/shaderparameterpack_p.h +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H -#define QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QVariant> -#include <QByteArray> -#include <QVector> -#include <QOpenGLShaderProgram> -#include <Qt3DCore/qnodeid.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/shadervariables_p.h> -#include <Qt3DRender/private/uniform_p.h> - -QT_BEGIN_NAMESPACE - -class QOpenGLShaderProgram; - -namespace Qt3DCore { -class QFrameAllocator; -} - -namespace Qt3DRender { -namespace Render { - -class GraphicsContext; - -struct BlockToUBO { - int m_blockIndex; - Qt3DCore::QNodeId m_bufferID; - bool m_needsUpdate; - QHash<QString, QVariant> m_updatedProperties; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToUBO, Q_MOVABLE_TYPE) - -struct BlockToSSBO { - int m_blockIndex; - int m_bindingIndex; - Qt3DCore::QNodeId m_bufferID; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToSSBO, Q_PRIMITIVE_TYPE) - - -struct PackUniformHash -{ - QVector<int> keys; - QVector<UniformValue> values; - - PackUniformHash() - { - keys.reserve(10); - values.reserve(10); - } - - void insert(int key, const UniformValue &value) - { - const int idx = keys.indexOf(key); - if (idx != -1) { - values[idx] = value; - } else { - keys.push_back(key); - values.push_back(value); - } - } - - UniformValue value(int key) const - { - const int idx = keys.indexOf(key); - if (idx != -1) - return values.at(idx); - return UniformValue(); - } - - UniformValue& value(int key) - { - const int idx = keys.indexOf(key); - if (idx != -1) - return values[idx]; - insert(key, UniformValue()); - return value(key); - } - - void erase(int idx) - { - keys.removeAt(idx); - values.removeAt(idx); - } - - bool contains(int key) const - { - return keys.contains(key); - } -}; - -class Q_AUTOTEST_EXPORT ShaderParameterPack -{ -public: - ~ShaderParameterPack(); - - void setUniform(const int glslNameId, const UniformValue &val); - void setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id); - void setImage(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id); - - void setUniformBuffer(BlockToUBO blockToUBO); - void setShaderStorageBuffer(BlockToSSBO blockToSSBO); - void setSubmissionUniform(const ShaderUniform &uniform); - - inline PackUniformHash &uniforms() { return m_uniforms; } - inline const PackUniformHash &uniforms() const { return m_uniforms; } - UniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); } - - - struct NamedResource - { - enum Type { - Texture = 0, - Image - }; - - NamedResource() {} - NamedResource(const int glslNameId, Qt3DCore::QNodeId texId, - int uniformArrayIndex, Type type) - : glslNameId(glslNameId) - , nodeId(texId) - , uniformArrayIndex(uniformArrayIndex) - , type(type) - { } - - int glslNameId; - Qt3DCore::QNodeId nodeId; - int uniformArrayIndex; - Type type; - - bool operator==(const NamedResource &other) const - { - return glslNameId == other.glslNameId && - nodeId == other.nodeId && - uniformArrayIndex == other.uniformArrayIndex && - type == other.type; - } - - bool operator!=(const NamedResource &other) const - { - return !(*this == other); - } - }; - - inline QVector<NamedResource> textures() const { return m_textures; } - inline QVector<NamedResource> images() const { return m_images; } - inline QVector<BlockToUBO> uniformBuffers() const { return m_uniformBuffers; } - inline QVector<BlockToSSBO> shaderStorageBuffers() const { return m_shaderStorageBuffers; } - inline QVector<ShaderUniform> submissionUniforms() const { return m_submissionUniforms; } -private: - PackUniformHash m_uniforms; - - QVector<NamedResource> m_textures; - QVector<NamedResource> m_images; - QVector<BlockToUBO> m_uniformBuffers; - QVector<BlockToSSBO> m_shaderStorageBuffers; - QVector<ShaderUniform> m_submissionUniforms; - - friend class RenderView; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderParameterPack::NamedResource, Q_PRIMITIVE_TYPE) - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(Qt3DRender::Render::ShaderParameterPack) - -#endif // QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H diff --git a/src/render/renderers/opengl/renderer/shadervariables_p.h b/src/render/renderers/opengl/renderer/shadervariables_p.h deleted file mode 100644 index e0fa07dff..000000000 --- a/src/render/renderers/opengl/renderer/shadervariables_p.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_SHADERVARIABLES_P_H -#define QT3DRENDER_RENDER_SHADERVARIABLES_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qt3drender_global.h> -#include <QOpenGLContext> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -struct ShaderAttribute -{ - ShaderAttribute() - : m_nameId(-1) - , m_type(0) - , m_size(0) - , m_location(-1) - {} - - QString m_name; - int m_nameId; - GLenum m_type; - int m_size; - int m_location; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderAttribute, Q_MOVABLE_TYPE) - -struct ShaderUniform -{ - ShaderUniform() - : m_nameId(-1) - , m_type(GL_NONE) - , m_size(0) - , m_offset(-1) - , m_location(-1) - , m_blockIndex(-1) - , m_arrayStride(-1) - , m_matrixStride(-1) - , m_rawByteSize(0) - {} - - QString m_name; - int m_nameId; - GLenum m_type; - int m_size; - int m_offset; // -1 default, >= 0 if uniform defined in uniform block - int m_location; // -1 if uniform defined in a uniform block - int m_blockIndex; // -1 is the default, >= 0 if uniform defined in uniform block - int m_arrayStride; // -1 is the default, >= 0 if uniform defined in uniform block and if it's an array - int m_matrixStride; // -1 is the default, >= 0 uniform defined in uniform block and is a matrix - uint m_rawByteSize; // contains byte size (size / type / strides) - // size, offset and strides are in bytes -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderUniform, Q_MOVABLE_TYPE) - -struct ShaderUniformBlock -{ - ShaderUniformBlock() - : m_nameId(-1) - , m_index(-1) - , m_binding(-1) - , m_activeUniformsCount(0) - , m_size(0) - {} - - QString m_name; - int m_nameId; - int m_index; - int m_binding; - int m_activeUniformsCount; - int m_size; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderUniformBlock, Q_MOVABLE_TYPE) - -struct ShaderStorageBlock -{ - ShaderStorageBlock() - : m_nameId(-1) - , m_index(-1) - , m_binding(-1) - , m_size(0) - , m_activeVariablesCount(0) - {} - - QString m_name; - int m_nameId; - int m_index; - int m_binding; - int m_size; - int m_activeVariablesCount; -}; -QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderStorageBlock, Q_MOVABLE_TYPE) - -} // namespace Render - -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_SHADERVARIABLES_P_H diff --git a/src/render/renderers/opengl/renderstates/renderstates.pri b/src/render/renderers/opengl/renderstates/renderstates.pri deleted file mode 100644 index 10f51a0ed..000000000 --- a/src/render/renderers/opengl/renderstates/renderstates.pri +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/renderstateset.cpp - -HEADERS += \ - $$PWD/renderstateset_p.h diff --git a/src/render/renderers/opengl/textures/gltexture.cpp b/src/render/renderers/opengl/textures/gltexture.cpp deleted file mode 100644 index 20e6007a0..000000000 --- a/src/render/renderers/opengl/textures/gltexture.cpp +++ /dev/null @@ -1,772 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qhash.h> -#include "gltexture_p.h" - -#include <private/qdebug_p.h> -#include <private/qopengltexture_p.h> -#include <private/qopengltexturehelper_p.h> -#include <QDebug> -#include <QOpenGLFunctions> -#include <QOpenGLTexture> -#include <QOpenGLPixelTransferOptions> -#include <Qt3DRender/qtexture.h> -#include <Qt3DRender/qtexturedata.h> -#include <Qt3DRender/qtextureimagedata.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/qabstracttexture_p.h> -#include <Qt3DRender/private/renderbuffer_p.h> -#include <Qt3DRender/private/qtextureimagedata_p.h> - -#if !defined(QT_OPENGL_ES_2) -#include <QOpenGLFunctions_3_1> -#include <QOpenGLFunctions_4_5_Core> -#endif - -QT_BEGIN_NAMESPACE - -using namespace Qt3DCore; - -namespace Qt3DRender { -namespace Render { - -namespace { - -// This uploadGLData where the data is a fullsize subimage -// as QOpenGLTexture doesn't allow partial subimage uploads -void uploadGLData(QOpenGLTexture *glTex, - int level, int layer, QOpenGLTexture::CubeMapFace face, - const QByteArray &bytes, const QTextureImageDataPtr &data) -{ - if (data->isCompressed()) { - glTex->setCompressedData(level, layer, face, bytes.size(), bytes.constData()); - } else { - QOpenGLPixelTransferOptions uploadOptions; - uploadOptions.setAlignment(1); - glTex->setData(level, layer, face, data->pixelFormat(), data->pixelType(), bytes.constData(), &uploadOptions); - } -} - -// For partial sub image uploads -void uploadGLData(QOpenGLTexture *glTex, - int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace, - int xOffset, int yOffset, int zOffset, - const QByteArray &bytes, const QTextureImageDataPtr &data) -{ - if (data->isCompressed()) { - qWarning() << Q_FUNC_INFO << "Uploading non full sized Compressed Data not supported yet"; - } else { - QOpenGLPixelTransferOptions uploadOptions; - uploadOptions.setAlignment(1); - glTex->setData(xOffset, yOffset, zOffset, - data->width(), data->height(), data->depth(), - mipLevel, layer, cubeFace, data->layers(), - data->pixelFormat(), data->pixelType(), - bytes.constData(), &uploadOptions); - } -} - -} // anonymous - - -GLTexture::GLTexture() - : m_dirtyFlags(None) - , m_gl(nullptr) - , m_renderBuffer(nullptr) - , m_dataFunctor() - , m_pendingDataFunctor(nullptr) - , m_sharedTextureId(-1) - , m_externalRendering(false) - , m_wasTextureRecreated(false) -{ -} - -GLTexture::~GLTexture() -{ -} - -// Must be called from RenderThread with active GL context -void GLTexture::destroy() -{ - delete m_gl; - m_gl = nullptr; - delete m_renderBuffer; - m_renderBuffer = nullptr; - - m_dirtyFlags = None; - m_sharedTextureId = -1; - m_externalRendering = false; - m_wasTextureRecreated = false; - m_dataFunctor.reset(); - m_pendingDataFunctor = nullptr; - - m_properties = {}; - m_parameters = {}; - m_textureData.reset(); - m_images.clear(); - m_imageData.clear(); - m_pendingTextureDataUpdates.clear(); -} - -bool GLTexture::loadTextureDataFromGenerator() -{ - m_textureData = m_dataFunctor->operator()(); - // if there is a texture generator, most properties will be defined by it - if (m_textureData) { - const QAbstractTexture::Target target = m_textureData->target(); - - // If both target and functor return Automatic we are still - // probably loading the texture, return false - if (m_properties.target == QAbstractTexture::TargetAutomatic && - target == QAbstractTexture::TargetAutomatic) { - m_textureData.reset(); - return false; - } - - if (m_properties.target != QAbstractTexture::TargetAutomatic && - target != QAbstractTexture::TargetAutomatic && - m_properties.target != target) { - qWarning() << Q_FUNC_INFO << "Generator and Properties not requesting the same texture target"; - m_textureData.reset(); - return false; - } - - // We take target type from generator if it wasn't explicitly set by the user - if (m_properties.target == QAbstractTexture::TargetAutomatic) - m_properties.target = target; - m_properties.width = m_textureData->width(); - m_properties.height = m_textureData->height(); - m_properties.depth = m_textureData->depth(); - m_properties.layers = m_textureData->layers(); - m_properties.format = m_textureData->format(); - - const QVector<QTextureImageDataPtr> imageData = m_textureData->imageData(); - - if (imageData.size() > 0) { - // Set the mips level based on the first image if autoMipMapGeneration is disabled - if (!m_properties.generateMipMaps) - m_properties.mipLevels = imageData.first()->mipLevels(); - } - } - return !m_textureData.isNull(); -} - -void GLTexture::loadTextureDataFromImages() -{ - int maxMipLevel = 0; - for (const Image &img : qAsConst(m_images)) { - const QTextureImageDataPtr imgData = img.generator->operator()(); - // imgData may be null in the following cases: - // - Texture is created with TextureImages which have yet to be - // loaded (skybox where you don't yet know the path, source set by - // a property binding, queued connection ...) - // - TextureImage whose generator failed to return a valid data - // (invalid url, error opening file...) - if (imgData.isNull()) - continue; - - m_imageData.push_back(imgData); - maxMipLevel = qMax(maxMipLevel, img.mipLevel); - - // If the texture doesn't have a texture generator, we will - // derive some properties from the first TextureImage (layer=0, miplvl=0, face=0) - if (!m_textureData && img.layer == 0 && img.mipLevel == 0 && img.face == QAbstractTexture::CubeMapPositiveX) { - if (imgData->width() != -1 && imgData->height() != -1 && imgData->depth() != -1) { - m_properties.width = imgData->width(); - m_properties.height = imgData->height(); - m_properties.depth = imgData->depth(); - } - // Set the format of the texture if the texture format is set to Automatic - if (m_properties.format == QAbstractTexture::Automatic) { - m_properties.format = static_cast<QAbstractTexture::TextureFormat>(imgData->format()); - } - setDirtyFlag(Properties, true); - } - } - - // make sure the number of mip levels is set when there is no texture data generator - if (!m_dataFunctor) { - m_properties.mipLevels = maxMipLevel + 1; - setDirtyFlag(Properties, true); - } -} - -// Called from RenderThread -GLTexture::TextureUpdateInfo GLTexture::createOrUpdateGLTexture() -{ - TextureUpdateInfo textureInfo; - m_wasTextureRecreated = false; - - const bool hasSharedTextureId = m_sharedTextureId > 0; - // Only load texture data if we are not using a sharedTextureId - // Check if dataFunctor or images have changed - if (!hasSharedTextureId) { - // If dataFunctor exists and we have no data and it hasn´t run yet - if (m_dataFunctor && !m_textureData && m_dataFunctor.get() != m_pendingDataFunctor ) { - const bool successfullyLoadedTextureData = loadTextureDataFromGenerator(); - // If successful, m_textureData has content - if (successfullyLoadedTextureData) { - setDirtyFlag(Properties, true); - setDirtyFlag(TextureData, true); - } else { - if (m_pendingDataFunctor != m_dataFunctor.get()) { - qWarning() << "[Qt3DRender::GLTexture] No QTextureData generated from Texture Generator yet. Texture will be invalid for this frame"; - m_pendingDataFunctor = m_dataFunctor.get(); - } - textureInfo.properties.status = QAbstractTexture::Loading; - return textureInfo; - } - } - - // If images have changed, clear previous images data - // and regenerate m_imageData for the images - if (testDirtyFlag(TextureImageData)) { - m_imageData.clear(); - loadTextureDataFromImages(); - // Mark for upload if we actually have something to upload - if (!m_imageData.empty()) { - setDirtyFlag(TextureData, true); - } - // Reset image flag - setDirtyFlag(TextureImageData, false); - } - - // Don't try to create the texture if the target or format was still not set - // Format should either be set by user or if Automatic - // by either the dataGenerator of the texture or the first Image - // Target should explicitly be set by the user or the dataGenerator - if (m_properties.target == QAbstractTexture::TargetAutomatic || - m_properties.format == QAbstractTexture::Automatic || - m_properties.format == QAbstractTexture::NoFormat) { - textureInfo.properties.status = QAbstractTexture::Error; - return textureInfo; - } - } - - // If the properties changed or texture has become a shared texture from a - // 3rd party engine, we need to destroy and maybe re-allocate the texture - if (testDirtyFlag(Properties) || testDirtyFlag(SharedTextureId)) { - delete m_gl; - m_gl = nullptr; - textureInfo.wasUpdated = true; - // If we are destroyed because of some property change but still have (some) of - // our content data make sure we are marked for upload - // TO DO: We should actually check if the textureData is still correct - // in regard to the size, target and format of the texture though. - if (!testDirtyFlag(SharedTextureId) && - (m_textureData || !m_imageData.empty() || !m_pendingTextureDataUpdates.empty())) - setDirtyFlag(TextureData, true); - } - - m_properties.status = QAbstractTexture::Ready; - - if (testDirtyFlag(SharedTextureId) || hasSharedTextureId) { - // Update m_properties by doing introspection on the texture - if (hasSharedTextureId) - introspectPropertiesFromSharedTextureId(); - setDirtyFlag(SharedTextureId, false); - } else { - // We only build a QOpenGLTexture if we have no shared textureId set - if (!m_gl) { - m_gl = buildGLTexture(); - if (!m_gl) { - qWarning() << "[Qt3DRender::GLTexture] failed to create texture"; - textureInfo.properties.status = QAbstractTexture::Error; - return textureInfo; - } - - m_gl->allocateStorage(); - if (!m_gl->isStorageAllocated()) { - qWarning() << "[Qt3DRender::GLTexture] failed to allocate texture"; - textureInfo.properties.status = QAbstractTexture::Error; - return textureInfo; - } - m_wasTextureRecreated = true; - } - - textureInfo.texture = m_gl; - - // need to (re-)upload texture data? - const bool needsUpload = testDirtyFlag(TextureData); - if (needsUpload) { - uploadGLTextureData(); - setDirtyFlag(TextureData, false); - } - - // need to set texture parameters? - if (testDirtyFlag(Properties) || testDirtyFlag(Parameters)) { - updateGLTextureParameters(); - setDirtyFlag(Properties, false); - setDirtyFlag(Parameters, false); - } - } - - textureInfo.properties = m_properties; - - return textureInfo; -} - -RenderBuffer *GLTexture::getOrCreateRenderBuffer() -{ - if (m_dataFunctor && !m_textureData) { - m_textureData = m_dataFunctor->operator()(); - if (m_textureData) { - if (m_properties.target != QAbstractTexture::TargetAutomatic) - qWarning() << "[Qt3DRender::GLTexture] [renderbuffer] When a texture provides a generator, it's target is expected to be TargetAutomatic"; - - m_properties.width = m_textureData->width(); - m_properties.height = m_textureData->height(); - m_properties.format = m_textureData->format(); - - setDirtyFlag(Properties); - } else { - if (m_pendingDataFunctor != m_dataFunctor.get()) { - qWarning() << "[Qt3DRender::GLTexture] [renderbuffer] No QTextureData generated from Texture Generator yet. Texture will be invalid for this frame"; - m_pendingDataFunctor = m_dataFunctor.get(); - } - return nullptr; - } - } - - if (testDirtyFlag(Properties)) { - delete m_renderBuffer; - m_renderBuffer = nullptr; - } - - if (!m_renderBuffer) - m_renderBuffer = new RenderBuffer(m_properties.width, m_properties.height, m_properties.format); - - setDirtyFlag(Properties, false); - setDirtyFlag(Parameters, false); - - return m_renderBuffer; -} - -// This must be called from the RenderThread -// So GLTexture release from the manager can only be done from that thread -void GLTexture::cleanup() -{ - destroy(); -} - -void GLTexture::setParameters(const TextureParameters ¶ms) -{ - if (m_parameters != params) { - m_parameters = params; - setDirtyFlag(Parameters); - } -} - -void GLTexture::setProperties(const TextureProperties &props) -{ - if (m_properties != props) { - m_properties = props; - setDirtyFlag(Properties); - } -} - -void GLTexture::setImages(const QVector<Image> &images) -{ - // check if something has changed at all - bool same = (images.size() == m_images.size()); - if (same) { - for (int i = 0; i < images.size(); i++) { - if (images[i] != m_images[i]) { - same = false; - break; - } - } - } - - - if (!same) { - m_images = images; - requestImageUpload(); - } -} - -void GLTexture::setGenerator(const QTextureGeneratorPtr &generator) -{ - m_textureData.reset(); - m_dataFunctor = generator; - m_pendingDataFunctor = nullptr; - requestUpload(); -} - -void GLTexture::setSharedTextureId(int textureId) -{ - if (m_sharedTextureId != textureId) { - m_sharedTextureId = textureId; - setDirtyFlag(SharedTextureId); - } -} - -void GLTexture::addTextureDataUpdates(const QVector<QTextureDataUpdate> &updates) -{ - m_pendingTextureDataUpdates += updates; - requestUpload(); -} - -// Return nullptr if -// - context cannot be obtained -// - texture hasn't yet been loaded -QOpenGLTexture *GLTexture::buildGLTexture() -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (!ctx) { - qWarning() << Q_FUNC_INFO << "requires an OpenGL context"; - return nullptr; - } - - const QAbstractTexture::Target actualTarget = m_properties.target; - if (actualTarget == QAbstractTexture::TargetAutomatic) { - // If the target is automatic at this point, it means that the texture - // hasn't been loaded yet (case of remote urls) and that loading failed - // and that target format couldn't be deduced - return nullptr; - } - - QOpenGLTexture* glTex = new QOpenGLTexture(static_cast<QOpenGLTexture::Target>(actualTarget)); - - // m_format may not be ES2 compatible. Now it's time to convert it, if necessary. - QAbstractTexture::TextureFormat format = m_properties.format; - if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) { - switch (m_properties.format) { - case QAbstractTexture::RGBA8_UNorm: - case QAbstractTexture::RGBAFormat: - format = QAbstractTexture::RGBAFormat; - break; - case QAbstractTexture::RGB8_UNorm: - case QAbstractTexture::RGBFormat: - format = QAbstractTexture::RGBFormat; - break; - case QAbstractTexture::DepthFormat: - format = QAbstractTexture::DepthFormat; - break; - default: - auto warning = qWarning(); - warning << "Could not find a matching OpenGL ES 2.0 texture format:"; - QtDebugUtils::formatQEnum(warning, m_properties.format); - break; - } - } - - // Map ETC1 to ETC2 when supported. This allows using features like - // immutable storage as ETC2 is standard in GLES 3.0, while the ETC1 extension - // is written against GLES 1.0. - if (m_properties.format == QAbstractTexture::RGB8_ETC1) { - if ((ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) - || ctx->hasExtension(QByteArrayLiteral("GL_OES_compressed_ETC2_RGB8_texture")) - || ctx->hasExtension(QByteArrayLiteral("GL_ARB_ES3_compatibility"))) - format = m_properties.format = QAbstractTexture::RGB8_ETC2; - } - - glTex->setFormat(m_properties.format == QAbstractTexture::Automatic ? - QOpenGLTexture::NoFormat : - static_cast<QOpenGLTexture::TextureFormat>(format)); - glTex->setSize(m_properties.width, m_properties.height, m_properties.depth); - // Set layers count if texture array - if (actualTarget == QAbstractTexture::Target1DArray || - actualTarget == QAbstractTexture::Target2DArray || - actualTarget == QAbstractTexture::Target2DMultisampleArray || - actualTarget == QAbstractTexture::TargetCubeMapArray) { - glTex->setLayers(m_properties.layers); - } - - if (actualTarget == QAbstractTexture::Target2DMultisample || - actualTarget == QAbstractTexture::Target2DMultisampleArray) { - // Set samples count if multisampled texture - // (multisampled textures don't have mipmaps) - glTex->setSamples(m_properties.samples); - } else if (m_properties.generateMipMaps) { - glTex->setMipLevels(glTex->maximumMipLevels()); - } else { - glTex->setAutoMipMapGenerationEnabled(false); - if (glTex->hasFeature(QOpenGLTexture::TextureMipMapLevel)) { - glTex->setMipBaseLevel(0); - glTex->setMipMaxLevel(m_properties.mipLevels - 1); - } - glTex->setMipLevels(m_properties.mipLevels); - } - - if (!glTex->create()) { - qWarning() << Q_FUNC_INFO << "creating QOpenGLTexture failed"; - return nullptr; - } - - return glTex; -} - -void GLTexture::uploadGLTextureData() -{ - // Upload all QTexImageData set by the QTextureGenerator - if (m_textureData) { - const QVector<QTextureImageDataPtr> imgData = m_textureData->imageData(); - - for (const QTextureImageDataPtr &data : imgData) { - const int mipLevels = m_properties.generateMipMaps ? 1 : data->mipLevels(); - - for (int layer = 0; layer < data->layers(); layer++) { - for (int face = 0; face < data->faces(); face++) { - for (int level = 0; level < mipLevels; level++) { - // ensure we don't accidentally cause a detach / copy of the raw bytes - const QByteArray bytes(data->data(layer, face, level)); - uploadGLData(m_gl, level, layer, - static_cast<QOpenGLTexture::CubeMapFace>(QOpenGLTexture::CubeMapPositiveX + face), - bytes, data); - } - } - } - } - } - - // Upload all QTexImageData references by the TextureImages - for (int i = 0; i < std::min(m_images.size(), m_imageData.size()); i++) { - const QTextureImageDataPtr &imgData = m_imageData.at(i); - // Here the bytes in the QTextureImageData contain data for a single - // layer, face or mip level, unlike the QTextureGenerator case where - // they are in a single blob. Hence QTextureImageData::data() is not suitable. - const QByteArray bytes(QTextureImageDataPrivate::get(imgData.get())->m_data); - uploadGLData(m_gl, m_images[i].mipLevel, m_images[i].layer, - static_cast<QOpenGLTexture::CubeMapFace>(m_images[i].face), - bytes, imgData); - } - // Free up image data once content has been uploaded - // Note: if data functor stores the data, this won't really free anything though - m_imageData.clear(); - - // Update data from TextureUpdates - const QVector<QTextureDataUpdate> textureDataUpdates = std::move(m_pendingTextureDataUpdates); - for (const QTextureDataUpdate &update : textureDataUpdates) { - const QTextureImageDataPtr imgData = update.data(); - - if (!imgData) { - qWarning() << Q_FUNC_INFO << "QTextureDataUpdate no QTextureImageData set"; - continue; - } - - const int xOffset = update.x(); - const int yOffset = update.y(); - const int zOffset = update.z(); - const int xExtent = xOffset + imgData->width(); - const int yExtent = yOffset + imgData->height(); - const int zExtent = zOffset + imgData->depth(); - - // Check update is compatible with our texture - if (xOffset >= m_gl->width() || - yOffset >= m_gl->height() || - zOffset >= m_gl->depth() || - xExtent > m_gl->width() || - yExtent > m_gl->height() || - zExtent > m_gl->depth() || - update.mipLevel() >= m_gl->mipLevels() || - update.layer() >= m_gl->layers()) { - qWarning() << Q_FUNC_INFO << "QTextureDataUpdate incompatible with texture"; - continue; - } - - const QByteArray bytes = (QTextureImageDataPrivate::get(imgData.get())->m_data); - // Here the bytes in the QTextureImageData contain data for a single - // layer, face or mip level, unlike the QTextureGenerator case where - // they are in a single blob. Hence QTextureImageData::data() is not suitable. - - uploadGLData(m_gl, - update.mipLevel(), update.layer(), - static_cast<QOpenGLTexture::CubeMapFace>(update.face()), - xOffset, yOffset, zOffset, - bytes, imgData); - } -} - -void GLTexture::updateGLTextureParameters() -{ - const QAbstractTexture::Target actualTarget = m_properties.target; - const bool isMultisampledTexture = (actualTarget == QAbstractTexture::Target2DMultisample || - actualTarget == QAbstractTexture::Target2DMultisampleArray); - // Multisampled textures can only be accessed by texelFetch in shaders - // and don't support wrap modes and mig/mag filtes - if (isMultisampledTexture) - return; - - m_gl->setWrapMode(QOpenGLTexture::DirectionS, static_cast<QOpenGLTexture::WrapMode>(m_parameters.wrapModeX)); - if (actualTarget != QAbstractTexture::Target1D && - actualTarget != QAbstractTexture::Target1DArray && - actualTarget != QAbstractTexture::TargetBuffer) - m_gl->setWrapMode(QOpenGLTexture::DirectionT, static_cast<QOpenGLTexture::WrapMode>(m_parameters.wrapModeY)); - if (actualTarget == QAbstractTexture::Target3D) - m_gl->setWrapMode(QOpenGLTexture::DirectionR, static_cast<QOpenGLTexture::WrapMode>(m_parameters.wrapModeZ)); - m_gl->setMinMagFilters(static_cast<QOpenGLTexture::Filter>(m_parameters.minificationFilter), - static_cast<QOpenGLTexture::Filter>(m_parameters.magnificationFilter)); - if (m_gl->hasFeature(QOpenGLTexture::AnisotropicFiltering)) - m_gl->setMaximumAnisotropy(m_parameters.maximumAnisotropy); - if (m_gl->hasFeature(QOpenGLTexture::TextureComparisonOperators)) { - m_gl->setComparisonFunction(static_cast<QOpenGLTexture::ComparisonFunction>(m_parameters.comparisonFunction)); - m_gl->setComparisonMode(static_cast<QOpenGLTexture::ComparisonMode>(m_parameters.comparisonMode)); - } -} - -void GLTexture::introspectPropertiesFromSharedTextureId() -{ - // We know that the context is active when this function is called - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (!ctx) { - qWarning() << Q_FUNC_INFO << "requires an OpenGL context"; - return; - } - QOpenGLFunctions *gl = ctx->functions(); - - // If the user has set the target format himself, we won't try to deduce it - if (m_properties.target != QAbstractTexture::TargetAutomatic) - return; - - const QAbstractTexture::Target targets[] = { - QAbstractTexture::Target2D, - QAbstractTexture::TargetCubeMap, -#ifndef QT_OPENGL_ES_2 - QAbstractTexture::Target1D, - QAbstractTexture::Target1DArray, - QAbstractTexture::Target3D, - QAbstractTexture::Target2DArray, - QAbstractTexture::TargetCubeMapArray, - QAbstractTexture::Target2DMultisample, - QAbstractTexture::Target2DMultisampleArray, - QAbstractTexture::TargetRectangle, - QAbstractTexture::TargetBuffer, -#endif - }; - -#ifndef QT_OPENGL_ES_2 - // Try to find texture target with GL 4.5 functions - const QPair<int, int> ctxGLVersion = ctx->format().version(); - if (ctxGLVersion.first > 4 || (ctxGLVersion.first == 4 && ctxGLVersion.second >= 5)) { - // Only for GL 4.5+ -#ifdef GL_TEXTURE_TARGET - QOpenGLFunctions_4_5_Core *gl5 = ctx->versionFunctions<QOpenGLFunctions_4_5_Core>(); - if (gl5 != nullptr) - gl5->glGetTextureParameteriv(m_sharedTextureId, GL_TEXTURE_TARGET, reinterpret_cast<int *>(&m_properties.target)); -#endif - } -#endif - - // If GL 4.5 function unavailable or not working, try a slower way - if (m_properties.target == QAbstractTexture::TargetAutomatic) { - // // OpenGL offers no proper way of querying for the target of a texture given its id - gl->glActiveTexture(GL_TEXTURE0); - - const GLenum targetBindings[] = { - GL_TEXTURE_BINDING_2D, - GL_TEXTURE_BINDING_CUBE_MAP, -#ifndef QT_OPENGL_ES_2 - GL_TEXTURE_BINDING_1D, - GL_TEXTURE_BINDING_1D_ARRAY, - GL_TEXTURE_BINDING_3D, - GL_TEXTURE_BINDING_2D_ARRAY, - GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, - GL_TEXTURE_BINDING_2D_MULTISAMPLE, - GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, - GL_TEXTURE_BINDING_RECTANGLE, - GL_TEXTURE_BINDING_BUFFER -#endif - }; - - Q_ASSERT(sizeof(targetBindings) / sizeof(targetBindings[0] == sizeof(targets) / sizeof(targets[0]))); - - for (uint i = 0; i < sizeof(targetBindings) / sizeof(targetBindings[0]); ++i) { - const int target = targets[i]; - gl->glBindTexture(target, m_sharedTextureId); - int boundId = 0; - gl->glGetIntegerv(targetBindings[i], &boundId); - gl->glBindTexture(target, 0); - if (boundId == m_sharedTextureId) { - m_properties.target = static_cast<QAbstractTexture::Target>(target); - break; - } - } - } - - // Return early if we weren't able to find texture target - if (std::find(std::begin(targets), std::end(targets), m_properties.target) == std::end(targets)) { - qWarning() << "Unable to determine texture target for shared GL texture"; - return; - } - - // Bind texture once we know its target - gl->glBindTexture(m_properties.target, m_sharedTextureId); - - // TO DO: Improve by using glGetTextureParameters when available which - // support direct state access -#ifndef GL_TEXTURE_MAX_LEVEL -#define GL_TEXTURE_MAX_LEVEL 0x813D -#endif - -#ifndef GL_TEXTURE_WRAP_R -#define GL_TEXTURE_WRAP_R 0x8072 -#endif - - gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MAX_LEVEL, reinterpret_cast<int *>(&m_properties.mipLevels)); - gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MIN_FILTER, reinterpret_cast<int *>(&m_parameters.minificationFilter)); - gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_MAG_FILTER, reinterpret_cast<int *>(&m_parameters.magnificationFilter)); - gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_R, reinterpret_cast<int *>(&m_parameters.wrapModeX)); - gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_S, reinterpret_cast<int *>(&m_parameters.wrapModeY)); - gl->glGetTexParameteriv(int(m_properties.target), GL_TEXTURE_WRAP_T, reinterpret_cast<int *>(&m_parameters.wrapModeZ)); - -#ifndef QT_OPENGL_ES_2 - // Try to retrieve dimensions (not available on ES 2.0) - if (!ctx->isOpenGLES()) { - QOpenGLFunctions_3_1 *gl3 = ctx->versionFunctions<QOpenGLFunctions_3_1>(); - if (!gl3) { - qWarning() << "Failed to retrieve shared texture dimensions"; - return; - } - - gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_WIDTH, reinterpret_cast<int *>(&m_properties.width)); - gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_HEIGHT, reinterpret_cast<int *>(&m_properties.height)); - gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_DEPTH, reinterpret_cast<int *>(&m_properties.depth)); - gl3->glGetTexLevelParameteriv(int(m_properties.target), 0, GL_TEXTURE_INTERNAL_FORMAT, reinterpret_cast<int *>(&m_properties.format)); - } -#endif - - gl->glBindTexture(m_properties.target, 0); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/textures/gltexture_p.h b/src/render/renderers/opengl/textures/gltexture_p.h deleted file mode 100644 index ca851712d..000000000 --- a/src/render/renderers/opengl/textures/gltexture_p.h +++ /dev/null @@ -1,266 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_GLTEXTURE_H -#define QT3DRENDER_RENDER_GLTEXTURE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qtexture.h> -#include <Qt3DRender/qtextureimagedata.h> -#include <Qt3DRender/qtexturegenerator.h> -#include <Qt3DRender/private/backendnode_p.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/texture_p.h> -#include <QOpenGLContext> -#include <QFlags> -#include <QMutex> -#include <QSize> - -QT_BEGIN_NAMESPACE - -class QOpenGLTexture; - -namespace Qt3DRender { -namespace Render { - -class TextureImageManager; -class TextureDataManager; -class TextureImageDataManager; -class RenderBuffer; - -/** - * @brief - * Actual implementation of the OpenGL texture object. Makes sure the - * QOpenGLTexture is up-to-date with the generators, properties and parameters - * that were set for this GLTexture. - * - * Can be shared among multiple QTexture backend nodes through the - * GLTextureManager, which will make sure that there are no two GLTextures - * sharing the same texture data. - * - * A GLTexture can be unique though. In that case, it will not be shared - * between QTextures, but private to one QTexture only. - * - * A GLTexture can also represent an OpenGL renderbuffer object. This is used - * only in certain special cases, mainly to provide a packed depth-stencil - * renderbuffer suitable as an FBO attachment with OpenGL ES 3.1 and earlier. - * Such a GLTexture will have no texture object under the hood, and therefore - * the only valid operation is getOrCreateRenderBuffer(). - */ -class Q_AUTOTEST_EXPORT GLTexture -{ -public: - GLTexture(); - ~GLTexture(); - - enum DirtyFlag { - None = 0, - TextureData = (1 << 0), // texture data needs uploading to GPU - Properties = (1 << 1), // texture needs to be (re-)created - Parameters = (1 << 2), // texture parameters need to be (re-)set - SharedTextureId = (1 << 3), // texture id from shared context - TextureImageData = (1 << 4) // texture image data needs uploading - }; - - /** - * Helper class to hold the defining properties of TextureImages - */ - struct Image { - QTextureImageDataGeneratorPtr generator; - int layer; - int mipLevel; - QAbstractTexture::CubeMapFace face; - - inline bool operator==(const Image &o) const { - bool sameGenerators = (generator == o.generator) - || (!generator.isNull() && !o.generator.isNull() && *generator == *o.generator); - return sameGenerators && layer == o.layer && mipLevel == o.mipLevel && face == o.face; - } - inline bool operator!=(const Image &o) const { return !(*this == o); } - }; - - inline TextureProperties properties() const { return m_properties; } - inline TextureParameters parameters() const { return m_parameters; } - inline QTextureGeneratorPtr textureGenerator() const { return m_dataFunctor; } - inline int sharedTextureId() const { return m_sharedTextureId; } - inline QVector<Image> images() const { return m_images; } - - inline QSize size() const { return QSize(m_properties.width, m_properties.height); } - inline QOpenGLTexture *getGLTexture() const { return m_gl; } - - /** - * @brief - * Returns the QOpenGLTexture for this GLTexture. If necessary, - * the GL texture will be created from the TextureImageDatas associated - * with the texture and image functors. If no functors are provided, - * the texture will be created without images. - * - * If the texture properties or parameters have changed, these changes - * will be applied to the resulting OpenGL texture. - */ - struct TextureUpdateInfo - { - QOpenGLTexture *texture = nullptr; - bool wasUpdated = false; - TextureProperties properties; - }; - - TextureUpdateInfo createOrUpdateGLTexture(); - - /** - * @brief - * Returns the RenderBuffer for this GLTexture. If this is the first - * call, the OpenGL renderbuffer object will be created. - */ - RenderBuffer *getOrCreateRenderBuffer(); - - - void destroy(); - - void cleanup(); - - bool isDirty() const - { - return m_dirtyFlags != None; - } - - bool hasTextureData() const { return !m_textureData.isNull(); } - bool hasImagesData() const { return !m_imageData.isEmpty(); } - - QFlags<DirtyFlag> dirtyFlags() const { return m_dirtyFlags; } - - QMutex *externalRenderingLock() - { - return &m_externalRenderingMutex; - } - - void setExternalRenderingEnabled(bool enable) - { - m_externalRendering = enable; - } - - bool isExternalRenderingEnabled() const - { - return m_externalRendering; - } - - // Purely for unit testing purposes - bool wasTextureRecreated() const - { - return m_wasTextureRecreated; - } - - void setParameters(const TextureParameters ¶ms); - void setProperties(const TextureProperties &props); - void setImages(const QVector<Image> &images); - void setGenerator(const QTextureGeneratorPtr &generator); - void setSharedTextureId(int textureId); - void addTextureDataUpdates(const QVector<QTextureDataUpdate> &updates); - - QVector<QTextureDataUpdate> textureDataUpdates() const { return m_pendingTextureDataUpdates; } - QTextureGeneratorPtr dataGenerator() const { return m_dataFunctor; } - -private: - void requestImageUpload() - { - m_dirtyFlags |= TextureImageData; - } - - void requestUpload() - { - m_dirtyFlags |= TextureData; - } - - bool testDirtyFlag(DirtyFlag flag) - { - return m_dirtyFlags.testFlag(flag); - } - - void setDirtyFlag(DirtyFlag flag, bool value = true) - { - m_dirtyFlags.setFlag(flag, value); - } - - QOpenGLTexture *buildGLTexture(); - bool loadTextureDataFromGenerator(); - void loadTextureDataFromImages(); - void uploadGLTextureData(); - void updateGLTextureParameters(); - void introspectPropertiesFromSharedTextureId(); - void destroyResources(); - - QFlags<DirtyFlag> m_dirtyFlags; - QMutex m_externalRenderingMutex; - QOpenGLTexture *m_gl; - RenderBuffer *m_renderBuffer; - - // target which is actually used for GL texture - TextureProperties m_properties; - TextureParameters m_parameters; - - QTextureGeneratorPtr m_dataFunctor; - QTextureGenerator *m_pendingDataFunctor; - QVector<Image> m_images; - - // cache actual image data generated by the functors - QTextureDataPtr m_textureData; - QVector<QTextureImageDataPtr> m_imageData; - QVector<QTextureDataUpdate> m_pendingTextureDataUpdates; - - int m_sharedTextureId; - bool m_externalRendering; - bool m_wasTextureRecreated; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_GLTEXTURE_H diff --git a/src/render/renderers/opengl/textures/renderbuffer.cpp b/src/render/renderers/opengl/textures/renderbuffer.cpp deleted file mode 100644 index bc5050f73..000000000 --- a/src/render/renderers/opengl/textures/renderbuffer.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderbuffer_p.h" -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLFunctions> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { - -RenderBuffer::RenderBuffer(int width, int height, QAbstractTexture::TextureFormat format) - : m_size(width, height), - m_format(format), - m_renderBuffer(0), - m_context(nullptr) -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (!ctx) { - qWarning("Renderbuffer requires an OpenGL context"); - return; - } - - m_context = ctx; - QOpenGLFunctions *f = ctx->functions(); - f->glGenRenderbuffers(1, &m_renderBuffer); - if (!m_renderBuffer) - return; - - f->glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer); - while (f->glGetError() != GL_NO_ERROR) { } - f->glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); - GLint err = f->glGetError(); - if (err != GL_NO_ERROR) - qWarning("Failed to set renderbuffer storage: error 0x%x", err); - f->glBindRenderbuffer(GL_RENDERBUFFER, 0); -} - -RenderBuffer::~RenderBuffer() -{ - if (m_renderBuffer) { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - - // Ignore the fact that renderbuffers are sharable resources and let's - // just expect that the context is the same as when the resource was - // created. QOpenGLTexture suffers from the same limitation anyway, and - // this is unlikely to become an issue within Qt 3D. - if (ctx == m_context) { - ctx->functions()->glDeleteRenderbuffers(1, &m_renderBuffer); - } else { - qWarning("Wrong current context; renderbuffer not destroyed"); - } - } -} - -void RenderBuffer::bind() -{ - if (!m_renderBuffer) - return; - - m_context->functions()->glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer); -} - -void RenderBuffer::release() -{ - if (!m_context) - return; - - m_context->functions()->glBindRenderbuffer(GL_RENDERBUFFER, 0); -} - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/render/renderers/opengl/textures/renderbuffer_p.h b/src/render/renderers/opengl/textures/renderbuffer_p.h deleted file mode 100644 index 7dc62492a..000000000 --- a/src/render/renderers/opengl/textures/renderbuffer_p.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RENDERBUFFER_P_H -#define QT3DRENDER_RENDER_RENDERBUFFER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DRender/qabstracttexture.h> - -QT_BEGIN_NAMESPACE - -class QOpenGLContext; - -namespace Qt3DRender { -namespace Render { - -class Q_AUTOTEST_EXPORT RenderBuffer -{ -public: - RenderBuffer(int width, int height, QAbstractTexture::TextureFormat format); - ~RenderBuffer(); - - int width() const { return m_size.width(); } - int height() const { return m_size.height(); } - QSize size() const { return m_size; } - QAbstractTexture::TextureFormat format() const { return m_format; } - GLuint renderBufferId() const { return m_renderBuffer; } - - void bind(); - void release(); - -private: - QSize m_size; - QAbstractTexture::TextureFormat m_format; - GLuint m_renderBuffer; - QOpenGLContext *m_context; -}; - -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RENDERBUFFER_P_H diff --git a/src/render/renderers/opengl/textures/textures.pri b/src/render/renderers/opengl/textures/textures.pri deleted file mode 100644 index e17abfbb3..000000000 --- a/src/render/renderers/opengl/textures/textures.pri +++ /dev/null @@ -1,9 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/gltexture.cpp \ - $$PWD/renderbuffer.cpp - -HEADERS += \ - $$PWD/gltexture_p.h \ - $$PWD/renderbuffer_p.h diff --git a/src/render/renderers/renderers.pri b/src/render/renderers/renderers.pri deleted file mode 100644 index 795a6fbdf..000000000 --- a/src/render/renderers/renderers.pri +++ /dev/null @@ -1,7 +0,0 @@ -TEMPLATE = subdirs - -# OpenGL renderer -include($$OUT_PWD/qt3drender-config.pri) -QT_FOR_CONFIG += 3drender-private - -qtConfig(qt3d-opengl-renderer): include(opengl/opengl.pri) diff --git a/src/render/renderstates/genericstate_p.h b/src/render/renderstates/genericstate_p.h index e3ece36f5..1d363e4fe 100644 --- a/src/render/renderstates/genericstate_p.h +++ b/src/render/renderstates/genericstate_p.h @@ -56,6 +56,7 @@ #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> #include <Qt3DCore/private/qresourcemanager_p.h> #include <Qt3DRender/private/statemask_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> //#include <Qt3DRender/private/statevariant_p.h> #include <QList> #include <QVector3D> @@ -73,7 +74,7 @@ class GraphicsContext; typedef quint64 StateMaskSet; -class RenderStateImpl +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderStateImpl { public: virtual ~RenderStateImpl() {} diff --git a/src/render/renderstates/renderstatenode_p.h b/src/render/renderstates/renderstatenode_p.h index e0258112f..604046e00 100644 --- a/src/render/renderstates/renderstatenode_p.h +++ b/src/render/renderstates/renderstatenode_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT RenderStateNode : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderStateNode : public BackendNode { public: RenderStateNode(); @@ -67,7 +67,6 @@ public: StateMask type() const { return m_impl.type; } StateVariant impl() const { return m_impl; } -protected: void cleanup(); private: diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp index 5e238c010..1ab4e0092 100644 --- a/src/render/renderstates/renderstates.cpp +++ b/src/render/renderstates/renderstates.cpp @@ -44,7 +44,6 @@ #include <Qt3DRender/qcullface.h> #include <Qt3DRender/qpointsize.h> -#include <Qt3DRender/private/graphicscontext_p.h> #include <Qt3DRender/private/qstenciloperation_p.h> #include <Qt3DRender/private/qstenciltest_p.h> #include <Qt3DRender/qblendequationarguments.h> diff --git a/src/render/renderstates/renderstates.pri b/src/render/renderstates/renderstates.pri index 06ba53a41..867a8c299 100644 --- a/src/render/renderstates/renderstates.pri +++ b/src/render/renderstates/renderstates.pri @@ -51,7 +51,8 @@ HEADERS += \ $$PWD/statemask_p.h \ $$PWD/statevariant_p.h \ $$PWD/qrastermode.h \ - $$PWD/qrastermode_p.h + $$PWD/qrastermode_p.h \ + $$PWD/renderstateset_p.h SOURCES += \ $$PWD/qalphacoverage.cpp \ @@ -82,4 +83,5 @@ SOURCES += \ $$PWD/renderstatenode.cpp \ $$PWD/statevariant.cpp \ $$PWD/qmultisampleantialiasing.cpp \ - $$PWD/qrastermode.cpp + $$PWD/qrastermode.cpp \ + $$PWD/renderstateset.cpp diff --git a/src/render/renderstates/renderstates_p.h b/src/render/renderstates/renderstates_p.h index 6c8e9d551..8c4c065ee 100644 --- a/src/render/renderstates/renderstates_p.h +++ b/src/render/renderstates/renderstates_p.h @@ -59,128 +59,128 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -class Q_AUTOTEST_EXPORT BlendEquationArguments : public GenericState<BlendEquationArguments, BlendEquationArgumentsMask, GLenum, GLenum, GLenum, GLenum, bool, int> +class Q_3DRENDERSHARED_PRIVATE_EXPORT BlendEquationArguments : public GenericState<BlendEquationArguments, BlendEquationArgumentsMask, GLenum, GLenum, GLenum, GLenum, bool, int> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT BlendEquation : public GenericState<BlendEquation, BlendStateMask, GLenum> +class Q_3DRENDERSHARED_PRIVATE_EXPORT BlendEquation : public GenericState<BlendEquation, BlendStateMask, GLenum> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState<AlphaFunc, AlphaTestMask, GLenum, GLclampf> +class Q_3DRENDERSHARED_PRIVATE_EXPORT AlphaFunc : public GenericState<AlphaFunc, AlphaTestMask, GLenum, GLclampf> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT MSAAEnabled : public GenericState<MSAAEnabled, MSAAEnabledStateMask, GLboolean> +class Q_3DRENDERSHARED_PRIVATE_EXPORT MSAAEnabled : public GenericState<MSAAEnabled, MSAAEnabledStateMask, GLboolean> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT DepthRange : public GenericState<DepthRange, DepthRangeMask, double, double> +class Q_3DRENDERSHARED_PRIVATE_EXPORT DepthRange : public GenericState<DepthRange, DepthRangeMask, double, double> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT DepthTest : public GenericState<DepthTest, DepthTestStateMask, GLenum> +class Q_3DRENDERSHARED_PRIVATE_EXPORT DepthTest : public GenericState<DepthTest, DepthTestStateMask, GLenum> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT RasterMode : public GenericState<RasterMode, RasterModeMask, GLenum, GLenum> +class Q_3DRENDERSHARED_PRIVATE_EXPORT RasterMode : public GenericState<RasterMode, RasterModeMask, GLenum, GLenum> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT NoDepthMask : public GenericState<NoDepthMask, DepthWriteStateMask, GLboolean> +class Q_3DRENDERSHARED_PRIVATE_EXPORT NoDepthMask : public GenericState<NoDepthMask, DepthWriteStateMask, GLboolean> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT CullFace : public GenericState<CullFace, CullFaceStateMask, GLenum> +class Q_3DRENDERSHARED_PRIVATE_EXPORT CullFace : public GenericState<CullFace, CullFaceStateMask, GLenum> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT FrontFace : public GenericState<FrontFace, FrontFaceStateMask, GLenum> +class Q_3DRENDERSHARED_PRIVATE_EXPORT FrontFace : public GenericState<FrontFace, FrontFaceStateMask, GLenum> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT Dithering : public GenericState<Dithering, DitheringStateMask> +class Q_3DRENDERSHARED_PRIVATE_EXPORT Dithering : public GenericState<Dithering, DitheringStateMask> { }; -class Q_AUTOTEST_EXPORT ScissorTest : public GenericState<ScissorTest, ScissorStateMask, int, int, int, int> +class Q_3DRENDERSHARED_PRIVATE_EXPORT ScissorTest : public GenericState<ScissorTest, ScissorStateMask, int, int, int, int> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT StencilTest : public GenericState<StencilTest, StencilTestStateMask, GLenum, int, uint, GLenum, int, uint> +class Q_3DRENDERSHARED_PRIVATE_EXPORT StencilTest : public GenericState<StencilTest, StencilTestStateMask, GLenum, int, uint, GLenum, int, uint> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState<AlphaCoverage, AlphaCoverageStateMask> +class Q_3DRENDERSHARED_PRIVATE_EXPORT AlphaCoverage : public GenericState<AlphaCoverage, AlphaCoverageStateMask> { }; -class Q_AUTOTEST_EXPORT PointSize : public GenericState<PointSize, PointSizeMask, bool, GLfloat> +class Q_3DRENDERSHARED_PRIVATE_EXPORT PointSize : public GenericState<PointSize, PointSizeMask, bool, GLfloat> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT PolygonOffset : public GenericState<PolygonOffset, PolygonOffsetStateMask, GLfloat, GLfloat> +class Q_3DRENDERSHARED_PRIVATE_EXPORT PolygonOffset : public GenericState<PolygonOffset, PolygonOffsetStateMask, GLfloat, GLfloat> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT ColorMask : public GenericState<ColorMask, ColorStateMask, GLboolean, GLboolean, GLboolean, GLboolean> +class Q_3DRENDERSHARED_PRIVATE_EXPORT ColorMask : public GenericState<ColorMask, ColorStateMask, GLboolean, GLboolean, GLboolean, GLboolean> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT ClipPlane : public GenericState<ClipPlane, ClipPlaneMask, int, QVector3D, float> +class Q_3DRENDERSHARED_PRIVATE_EXPORT ClipPlane : public GenericState<ClipPlane, ClipPlaneMask, int, QVector3D, float> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT SeamlessCubemap : public GenericState<SeamlessCubemap, SeamlessCubemapMask> +class Q_3DRENDERSHARED_PRIVATE_EXPORT SeamlessCubemap : public GenericState<SeamlessCubemap, SeamlessCubemapMask> { }; -class Q_AUTOTEST_EXPORT StencilOp : public GenericState<StencilOp, StencilOpMask, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum> +class Q_3DRENDERSHARED_PRIVATE_EXPORT StencilOp : public GenericState<StencilOp, StencilOpMask, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT StencilMask : public GenericState<StencilMask, StencilWriteStateMask, uint, uint> +class Q_3DRENDERSHARED_PRIVATE_EXPORT StencilMask : public GenericState<StencilMask, StencilWriteStateMask, uint, uint> { public: void updateProperties(const QRenderState *node) override; }; -class Q_AUTOTEST_EXPORT LineWidth : public GenericState<LineWidth, LineWidthMask, GLfloat, bool> +class Q_3DRENDERSHARED_PRIVATE_EXPORT LineWidth : public GenericState<LineWidth, LineWidthMask, GLfloat, bool> { public: void updateProperties(const QRenderState *node) override; diff --git a/src/render/renderers/opengl/renderstates/renderstateset.cpp b/src/render/renderstates/renderstateset.cpp index d667d9c76..6b66d2dd7 100644 --- a/src/render/renderers/opengl/renderstates/renderstateset.cpp +++ b/src/render/renderstates/renderstateset.cpp @@ -42,9 +42,6 @@ #include <bitset> -#include <QDebug> -#include <QOpenGLContext> - #include <Qt3DRender/private/renderstates_p.h> #include <Qt3DRender/private/qrenderstate_p.h> diff --git a/src/render/renderers/opengl/renderstates/renderstateset_p.h b/src/render/renderstates/renderstateset_p.h index c2f3a0219..119f1edca 100644 --- a/src/render/renderers/opengl/renderstates/renderstateset_p.h +++ b/src/render/renderstates/renderstateset_p.h @@ -67,7 +67,7 @@ namespace Render { class RenderState; -class RenderStateSet +class Q_3DRENDERSHARED_PRIVATE_EXPORT RenderStateSet { public: RenderStateSet(); @@ -112,7 +112,7 @@ private: }; template<> -void RenderStateSet::addState<StateVariant>(const StateVariant &state); +Q_3DRENDERSHARED_PRIVATE_EXPORT void RenderStateSet::addState<StateVariant>(const StateVariant &state); } // namespace Render } // namespace Qt3DRender diff --git a/src/render/renderstates/statevariant_p.h b/src/render/renderstates/statevariant_p.h index ef6c80744..1926bb937 100644 --- a/src/render/renderstates/statevariant_p.h +++ b/src/render/renderstates/statevariant_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -struct Q_AUTOTEST_EXPORT StateVariant +struct Q_3DRENDERSHARED_PRIVATE_EXPORT StateVariant { StateMask type; diff --git a/src/render/services/vsyncframeadvanceservice_p.h b/src/render/services/vsyncframeadvanceservice_p.h index c57c81a79..81d601e3e 100644 --- a/src/render/services/vsyncframeadvanceservice_p.h +++ b/src/render/services/vsyncframeadvanceservice_p.h @@ -52,6 +52,7 @@ // #include <Qt3DCore/private/qabstractframeadvanceservice_p.h> +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE @@ -61,7 +62,7 @@ namespace Render { class VSyncFrameAdvanceServicePrivate; -class Q_AUTOTEST_EXPORT VSyncFrameAdvanceService final : public Qt3DCore::QAbstractFrameAdvanceService +class Q_3DRENDERSHARED_PRIVATE_EXPORT VSyncFrameAdvanceService final : public Qt3DCore::QAbstractFrameAdvanceService { public: explicit VSyncFrameAdvanceService(bool drivenByRenderThread); diff --git a/src/render/texture/qtexture.cpp b/src/render/texture/qtexture.cpp index 7f662dfc5..6b7b92166 100644 --- a/src/render/texture/qtexture.cpp +++ b/src/render/texture/qtexture.cpp @@ -57,7 +57,7 @@ #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/texture_p.h> #include <Qt3DRender/private/qurlhelper_p.h> -#include <Qt3DRender/private/glresourcemanagers_p.h> +#include <qmath.h> QT_BEGIN_NAMESPACE diff --git a/src/render/texture/qtextureimagedata_p.h b/src/render/texture/qtextureimagedata_p.h index d9a0952de..14095e2eb 100644 --- a/src/render/texture/qtextureimagedata_p.h +++ b/src/render/texture/qtextureimagedata_p.h @@ -52,12 +52,13 @@ // #include "qtextureimagedata.h" +#include <Qt3DRender/private/qt3drender_global_p.h> QT_BEGIN_NAMESPACE namespace Qt3DRender { -class QTextureImageDataPrivate +class Q_3DRENDERSHARED_PRIVATE_EXPORT QTextureImageDataPrivate { public: QTextureImageDataPrivate(); diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp index 795c5844e..dab037568 100644 --- a/src/render/texture/texture.cpp +++ b/src/render/texture/texture.cpp @@ -47,7 +47,7 @@ #include <Qt3DCore/qpropertynoderemovedchange.h> #include <Qt3DRender/private/texture_p.h> -#include <Qt3DRender/private/glresourcemanagers_p.h> +#include <Qt3DRender/private/qabstracttexture_p.h> #include <Qt3DRender/private/managers_p.h> QT_BEGIN_NAMESPACE diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h index 83a05ebcc..61011bb68 100644 --- a/src/render/texture/texture_p.h +++ b/src/render/texture/texture_p.h @@ -128,7 +128,7 @@ struct TextureParameters * Will query the TextureImplManager for an instance of TextureImpl that matches it's * properties. */ -class Q_AUTOTEST_EXPORT Texture : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT Texture : public BackendNode { public: Texture(); diff --git a/src/render/texture/texturedatamanager_p.h b/src/render/texture/texturedatamanager_p.h new file mode 100644 index 000000000..61ebd1125 --- /dev/null +++ b/src/render/texture/texturedatamanager_p.h @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_RENDER_TEXTUREDATAMANAGER_H +#define QT3DRENDER_RENDER_TEXTUREDATAMANAGER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QMutex> +#include <QMutexLocker> +#include <Qt3DRender/qtexture.h> +#include <Qt3DRender/qtextureimagedata.h> +#include <Qt3DRender/qtexturegenerator.h> +#include <Qt3DRender/qtextureimagedatagenerator.h> +#include <Qt3DRender/private/qt3drender_global_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +namespace Render { + +/** + * The texture data managers associates each texture data generator + * with the data objects generated by them. That is, either + * + * QTextureImageDataGenerator -> QTextureImageData, or + * QTextureGenerator -> QTextureData + * + * This way, texture classes only need to refer to the texture functors used. + * Aspect jobs will make sure that at the start of each frame, all generators + * registered with the GeneratorDataManagers have been executed. + * + * This guarantees that no texture data generator is executed twice. + * + * Each Generator is associated with a number of textures that reference it. + * If the last texture disassociates from a generator, the QTextureData will + * be deleted. + */ +template <class GeneratorPtr, class DataPtr, class ReferencedType> +class GeneratorDataManager +{ +public: + GeneratorDataManager() {} + + /*! + * If no data for the given generator exists, make sure that the + * generators are executed the next frame. Reference generator by + * given texture + * + * Returns true if the Entry for a given generator had to be created + */ + bool requestData(const GeneratorPtr &generator, ReferencedType r) + { + QMutexLocker lock(&m_mutex); + + Entry *entry = findEntry(generator); + const bool needsToBeCreated = (entry == nullptr); + if (needsToBeCreated) + entry = createEntry(generator); + Q_ASSERT(entry); + if (!entry->referencingObjects.contains(r)) + entry->referencingObjects.push_back(r); + return needsToBeCreated; + } + + /*! + * Dereference given generator from texture. If no other textures still reference + * the generator, the associated data will be deleted + */ + void releaseData(const GeneratorPtr &generator, ReferencedType r) + { + QMutexLocker lock(&m_mutex); + + const auto end = m_data.end(); + for (auto it = m_data.begin(); it != end; ++it) { + Entry &entry = *it; + if (*entry.generator == *generator) { + entry.referencingObjects.removeAll(r); + // delete, if that was the last reference + if (entry.referencingObjects.empty()) { + m_data.erase(it); + return; + } + } + } + } + + /*! + * Return data associated with given generator, if existent + */ + DataPtr getData(const GeneratorPtr &generator) + { + QMutexLocker lock(&m_mutex); + + const Entry *entry = findEntry(generator); + return entry ? entry->data : DataPtr(); + } + + /*! + * Returns all generators that were not yet executed + */ + QVector<GeneratorPtr> pendingGenerators() + { + QMutexLocker lock(&m_mutex); + + QVector<GeneratorPtr> ret; + for (const Entry &entry : m_data) + if (!entry.data && !ret.contains(entry.generator)) + ret.push_back(entry.generator); + return ret; + } + + /*! + * Assigns a piece of data to the generator that was used to + * create it. + */ + void assignData(const GeneratorPtr &generator, const DataPtr &data) + { + QMutexLocker lock(&m_mutex); + + Entry *entry = findEntry(generator); + if (!entry) { + qWarning() << "[TextureDataManager] assignData() called with non-existent generator"; + return; + } + entry->data = data; + } + + bool contains(const GeneratorPtr &generator) + { + return findEntry(generator) != nullptr; + } + +private: + + struct Entry { + GeneratorPtr generator; + QVector<ReferencedType> referencingObjects; + DataPtr data; + }; + + /*! + * Helper function: return entry for given generator if it exists, nullptr + * otherwise. + */ + Entry* findEntry(const GeneratorPtr &generator) + { + for (int i = 0, sz = m_data.size(); i < sz; ++i) + if (*m_data[i].generator == *generator) + return &m_data[i]; + return nullptr; + } + + Entry *createEntry(const GeneratorPtr &generator) + { + Entry newEntry; + newEntry.generator = generator; + + m_data.push_back(newEntry); + return &m_data.back(); + } + + QMutex m_mutex; + QVector<Entry> m_data; +}; + +class QT3DRENDERSHARED_PRIVATE_EXPORT TextureDataManager + : public GeneratorDataManager<QTextureGeneratorPtr, QTextureDataPtr, void*> +{ +}; + +class QT3DRENDERSHARED_PRIVATE_EXPORT TextureImageDataManager + : public GeneratorDataManager<QTextureImageDataGeneratorPtr, QTextureImageDataPtr, Qt3DCore::QNodeId> +{ +}; + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // TEXTUREDATAMANAGER_H diff --git a/src/render/texture/textureimage_p.h b/src/render/texture/textureimage_p.h index ced8f1ad2..42ef242a7 100644 --- a/src/render/texture/textureimage_p.h +++ b/src/render/texture/textureimage_p.h @@ -70,7 +70,7 @@ class TextureImageDataManager; * Backend class for QAbstractTextureImage. * Will only hold the generator and some info values. */ -class Q_AUTOTEST_EXPORT TextureImage : public BackendNode +class Q_3DRENDERSHARED_PRIVATE_EXPORT TextureImage : public BackendNode { public: TextureImage(); |