summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/Source/render')
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp63
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp491
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderExample.h123
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp188
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h89
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp178
-rw-r--r--src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp104
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp156
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h182
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp57
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderAttribLayout.h90
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderBaseTypes.h2100
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp55
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderComputeShader.h89
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp421
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h248
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderContext.cpp1107
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderContext.h1063
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp158
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDataBuffer.h188
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp91
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h134
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp104
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h152
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderDrawable.h54
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp55
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderFragmentShader.h89
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp300
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h277
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp55
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderGeometryShader.h89
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp103
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderImageTexture.h143
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp100
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h138
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp105
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderInputAssembler.h157
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp82
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h120
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp145
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h165
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp191
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathFontText.h139
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathRender.cpp108
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathRender.h114
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp103
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderPathSpecification.h141
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp134
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h138
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp54
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderQueryBase.h127
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp71
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderRasterizerState.h94
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp114
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h158
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderSampler.cpp84
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderSampler.h124
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderShader.h123
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderShaderConstant.h448
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp1248
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderShaderProgram.h540
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp123
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h158
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderSync.cpp87
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderSync.h132
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp74
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTessellationShader.h132
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp263
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTexture2D.h165
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp123
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h106
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp167
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTextureBase.h177
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp119
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTextureCube.h106
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp75
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderTimerQuery.h129
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp74
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h124
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp54
-rw-r--r--src/Runtime/Source/render/Qt3DSRenderVertexShader.h89
-rw-r--r--src/Runtime/Source/render/backends/Qt3DSRenderBackend.h2245
-rw-r--r--src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp887
-rw-r--r--src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h193
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp170
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h392
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h48
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h408
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h2201
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp784
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h171
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp875
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h205
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp2220
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h530
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h146
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h173
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h105
-rw-r--r--src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp91
-rw-r--r--src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp588
-rw-r--r--src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h46
-rw-r--r--src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h83
102 files changed, 29099 insertions, 0 deletions
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp
new file mode 100644
index 00000000..f67cf717
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderClearColorExample.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSRenderExample.h"
+#include "foundation/Qt3DSVec4.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+namespace {
+class ClearColor : public NVRenderExample
+{
+ NVRenderContext &m_Context;
+
+public:
+ ClearColor(NVRenderContext &ctx)
+ : m_Context(ctx)
+ {
+ }
+ virtual void drawFrame(double currentSeconds)
+ {
+ // Apply this value immediately but track it so that a later pop will in fact
+ // restore this value.
+ if (currentSeconds < 1)
+ m_Context.SetClearColor(QT3DSVec4(.8f, .0f, .0f, 1.f));
+ else if (currentSeconds < 2)
+ m_Context.SetClearColor(QT3DSVec4(0.f, .0f, 1.f, 1.f));
+ else
+ m_Context.SetClearColor(QT3DSVec4(0.f, 1.0f, 1.f, 1.f));
+ m_Context.Clear(NVRenderClearFlags(NVRenderClearValues::Color));
+ }
+ virtual QT3DSU32 getRuntimeInSeconds() { return 2; }
+ virtual void release() { NVDelete(m_Context.GetFoundation(), this); }
+};
+}
+
+// QT3DS_RENDER_REGISTER_EXAMPLE( ClearColor ); \ No newline at end of file
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp
new file mode 100644
index 00000000..d866cda0
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.cpp
@@ -0,0 +1,491 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSRenderExample.h"
+#include "render/NvRenderBaseTypes.h"
+#include "render_util/NVRenderAllocator.h"
+#include "render_util/NVRenderErrorStream.h"
+#include "render_util/NVRenderUtils.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSTime.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/Qt3DSMath.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+static TExampleCreateFunc gCreateFuncs[128];
+
+TExampleCreateFunc *NVRenderExampleFactory::mExampleCreators = gCreateFuncs;
+QT3DSU32 NVRenderExampleFactory::mMaxCreators = 128;
+QT3DSU32 NVRenderExampleFactory::mNumCreators = 0;
+namespace {
+NVRenderErrorStream g_errorStream;
+NVRenderAllocator g_allocator(g_errorStream);
+NVFoundation *g_foundation(NULL);
+NVRenderContext *g_renderContext(NULL);
+NVRenderExample *g_example(NULL);
+QT3DSI32 g_exampleIdx(0);
+Time::Second g_runTime;
+Time g_timer;
+}
+
+bool NVRenderExampleFactory::nextExample()
+{
+ if (g_example)
+ g_example->release();
+ g_example = 0;
+ if (g_exampleIdx < (int)mNumCreators) {
+ g_example = mExampleCreators[g_exampleIdx](*g_renderContext);
+ ++g_exampleIdx;
+ g_runTime = g_example->getRuntimeInSeconds();
+ g_timer = Time();
+ return true;
+ }
+ return false;
+}
+
+void NVRenderExampleFactory::beginExamples()
+{
+ g_foundation = NVCreateFoundation(QT3DS_FOUNDATION_VERSION, g_allocator, g_errorStream);
+ g_renderContext =
+ &NVRenderContext::CreateGL(*g_foundation, NVRenderContextType(NVRenderContextValues::GL2));
+ nextExample();
+}
+bool NVRenderExampleFactory::update()
+{
+ Time::Second currentTime = g_timer.peekElapsedSeconds();
+ if (currentTime > g_runTime)
+ nextExample();
+ if (g_example)
+ g_example->drawFrame(currentTime);
+
+ return g_example != NULL;
+}
+
+void NVRenderExampleFactory::endExamples()
+{
+ g_exampleIdx = mNumCreators;
+ nextExample();
+ if (g_renderContext)
+ g_renderContext->release();
+ if (g_foundation)
+ g_foundation->release();
+
+ g_renderContext = NULL;
+ g_foundation = NULL;
+}
+
+namespace qt3ds {
+namespace render {
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Math stuff
+
+ int eq(float a, float b)
+ {
+ float diff = a - b;
+ if (diff < 0) {
+ diff = -diff;
+ }
+ return diff <= eps;
+ }
+
+ //
+ // Matrix functions, since GLES 2.x doesn't provide them
+ //
+
+ void NvGl2DemoMatrixIdentity(float m[16])
+ {
+ memset(m, 0, sizeof(float) * 16);
+ m[4 * 0 + 0] = m[4 * 1 + 1] = m[4 * 2 + 2] = m[4 * 3 + 3] = 1.0;
+ }
+
+ int NvGl2DemoMatrixEquals(float a[16], float b[16])
+ {
+ int i;
+ for (i = 0; i < 16; ++i)
+ if (!eq(a[i], b[i]))
+ return 0;
+
+ return 1;
+ }
+
+ void NvGl2DemoMatrixTranspose(float m[16])
+ {
+ int i, j;
+ float t;
+ for (i = 1; i < 4; ++i)
+ for (j = 0; j < i; ++j) {
+ t = m[4 * i + j];
+ m[4 * i + j] = m[4 * j + i];
+ m[4 * j + i] = t;
+ }
+ }
+
+ void NvGl2DemoMatrixMultiply(float m0[16], float m1[16])
+ {
+ int r, c, i;
+ for (r = 0; r < 4; r++) {
+ float m[4] = { 0.0, 0.0, 0.0, 0.0 };
+ for (c = 0; c < 4; c++) {
+ for (i = 0; i < 4; i++) {
+ m[c] += m0[4 * i + r] * m1[4 * c + i];
+ }
+ }
+ for (c = 0; c < 4; c++) {
+ m0[4 * c + r] = m[c];
+ }
+ }
+ }
+
+ void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9])
+ {
+ int r, c, i;
+ for (r = 0; r < 4; r++) {
+ float m[3] = { 0.0, 0.0, 0.0 };
+ for (c = 0; c < 3; c++) {
+ for (i = 0; i < 3; i++) {
+ m[c] += m0[4 * i + r] * m1[3 * c + i];
+ }
+ }
+ for (c = 0; c < 3; c++) {
+ m0[4 * c + r] = m[c];
+ }
+ }
+ }
+
+ void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9])
+ {
+ int r, c, i;
+ for (r = 0; r < 3; r++) {
+ float m[3] = { 0.0, 0.0, 0.0 };
+ for (c = 0; c < 3; c++) {
+ for (i = 0; i < 3; i++) {
+ m[c] += m0[3 * i + r] * m1[3 * c + i];
+ }
+ }
+ for (c = 0; c < 3; c++) {
+ m0[3 * c + r] = m[c];
+ }
+ }
+ }
+
+ void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f)
+ {
+ float m1[16];
+ float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv, twoNear;
+
+ rightMinusLeftInv = 1.0f / (r - l);
+ topMinusBottomInv = 1.0f / (t - b);
+ farMinusNearInv = 1.0f / (f - n);
+ twoNear = 2.0f * n;
+
+ m1[0] = twoNear * rightMinusLeftInv;
+ m1[1] = 0.0f;
+ m1[2] = 0.0f;
+ m1[3] = 0.0f;
+
+ m1[4] = 0.0f;
+ m1[5] = twoNear * topMinusBottomInv;
+ m1[6] = 0.0f;
+ m1[7] = 0.0f;
+
+ m1[8] = (r + l) * rightMinusLeftInv;
+ m1[9] = (t + b) * topMinusBottomInv;
+ m1[10] = -(f + n) * farMinusNearInv;
+ m1[11] = -1.0f;
+
+ m1[12] = 0.0f;
+ m1[13] = 0.0f;
+ m1[14] = -(twoNear * f) * farMinusNearInv;
+ m1[15] = 0.0f;
+
+ NvGl2DemoMatrixMultiply(m, m1);
+ }
+
+ void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f)
+ {
+ float m1[16];
+ float rightMinusLeftInv, topMinusBottomInv, farMinusNearInv;
+
+ rightMinusLeftInv = 1.0f / (r - l);
+ topMinusBottomInv = 1.0f / (t - b);
+ farMinusNearInv = 1.0f / (f - n);
+
+ m1[0] = 2.0f * rightMinusLeftInv;
+ m1[1] = 0.0f;
+ m1[2] = 0.0f;
+ m1[3] = 0.0f;
+
+ m1[4] = 0.0f;
+ m1[5] = 2.0f * topMinusBottomInv;
+ m1[6] = 0.0f;
+ m1[7] = 0.0f;
+
+ m1[8] = 0.0f;
+ m1[9] = 0.0f;
+ m1[10] = -2.0f * farMinusNearInv;
+ m1[11] = 0.0f;
+
+ m1[12] = -(r + l) * rightMinusLeftInv;
+ m1[13] = -(t + b) * topMinusBottomInv;
+ m1[14] = -(f + n) * farMinusNearInv;
+ m1[15] = 1.0f;
+
+ NvGl2DemoMatrixMultiply(m, m1);
+ }
+
+ void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z)
+ {
+ float m1[16];
+ NvGl2DemoMatrixIdentity(m1);
+
+ m1[4 * 3 + 0] = x;
+ m1[4 * 3 + 1] = y;
+ m1[4 * 3 + 2] = z;
+
+ NvGl2DemoMatrixMultiply(m, m1);
+ }
+
+ void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z)
+ {
+ float len = (float)sqrtf(x * x + y * y + z * z);
+ float u0 = x / len;
+ float u1 = y / len;
+ float u2 = z / len;
+ float rad = (float)(theta / 180 * NVPi);
+ float c = (float)cosf(rad);
+ float s = (float)sinf(rad);
+ m[3 * 0 + 0] = u0 * u0 + c * (1 - u0 * u0) + s * 0;
+ m[3 * 0 + 1] = u0 * u1 + c * (0 - u0 * u1) + s * u2;
+ m[3 * 0 + 2] = u0 * u2 + c * (0 - u0 * u2) - s * u1;
+
+ m[3 * 1 + 0] = u1 * u0 + c * (0 - u1 * u0) - s * u2;
+ m[3 * 1 + 1] = u1 * u1 + c * (1 - u1 * u1) + s * 0;
+ m[3 * 1 + 2] = u1 * u2 + c * (0 - u1 * u2) + s * u0;
+
+ m[3 * 2 + 0] = u2 * u0 + c * (0 - u2 * u0) + s * u1;
+ m[3 * 2 + 1] = u2 * u1 + c * (0 - u2 * u1) - s * u0;
+ m[3 * 2 + 2] = u2 * u2 + c * (1 - u2 * u2) + s * 0;
+ }
+
+ void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z)
+ {
+ float r[9];
+ NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z);
+ NvGl2DemoMatrixMultiply_4x4_3x3(m, r);
+ }
+
+ void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z)
+ {
+ float r[9];
+ NvGl2DemoMatrixRotate_create3x3(r, theta, x, y, z);
+ NvGl2DemoMatrixMultiply_3x3(m, r);
+ }
+
+ float NvGl2DemoMatrixDeterminant(float m[16])
+ {
+ return m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0]
+ - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0]
+ - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0]
+ + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0]
+ + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0]
+ - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0]
+ - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1]
+ + m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1]
+ + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1]
+ - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1]
+ - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1]
+ + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1]
+ + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2]
+ - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2]
+ - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2]
+ + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2]
+ + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2]
+ - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2]
+ - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3]
+ + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3]
+ + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3]
+ - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3]
+ - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3]
+ + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3];
+ }
+
+ void NvGl2DemoMatrixInverse(float m[16])
+ {
+ float a[16];
+ float det;
+ int i;
+ float b[16], e[16];
+
+ a[4 * 0 + 0] = m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1]
+ - m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1]
+ + m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2]
+ - m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2]
+ - m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3]
+ + m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3];
+ a[4 * 0 + 1] = m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 1]
+ - m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 1]
+ - m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 2]
+ + m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 2]
+ + m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 3]
+ - m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 3];
+ a[4 * 0 + 2] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 1]
+ - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 1]
+ + m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 2]
+ - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 2]
+ - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 3]
+ + m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 3];
+ a[4 * 0 + 3] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 1]
+ - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 1]
+ - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 2]
+ + m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 2]
+ + m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 3]
+ - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 3];
+ a[4 * 1 + 0] = m[4 * 1 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0]
+ - m[4 * 1 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0]
+ - m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2]
+ + m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2]
+ + m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3]
+ - m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3];
+ a[4 * 1 + 1] = m[4 * 0 + 2] * m[4 * 2 + 3] * m[4 * 3 + 0]
+ - m[4 * 0 + 3] * m[4 * 2 + 2] * m[4 * 3 + 0]
+ + m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 2]
+ - m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 2]
+ - m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 3]
+ + m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 3];
+ a[4 * 1 + 2] = m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 3 + 0]
+ - m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 3 + 0]
+ - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 2]
+ + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 2]
+ + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 3]
+ - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 3];
+ a[4 * 1 + 3] = m[4 * 0 + 2] * m[4 * 1 + 3] * m[4 * 2 + 0]
+ - m[4 * 0 + 3] * m[4 * 1 + 2] * m[4 * 2 + 0]
+ + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 2]
+ - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 2]
+ - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 3]
+ + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 3];
+ a[4 * 2 + 0] = m[4 * 1 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0]
+ - m[4 * 1 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0]
+ + m[4 * 1 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1]
+ - m[4 * 1 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1]
+ - m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3]
+ + m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3];
+ a[4 * 2 + 1] = m[4 * 0 + 3] * m[4 * 2 + 1] * m[4 * 3 + 0]
+ - m[4 * 0 + 1] * m[4 * 2 + 3] * m[4 * 3 + 0]
+ - m[4 * 0 + 3] * m[4 * 2 + 0] * m[4 * 3 + 1]
+ + m[4 * 0 + 0] * m[4 * 2 + 3] * m[4 * 3 + 1]
+ + m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 3]
+ - m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 3];
+ a[4 * 2 + 2] = m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 3 + 0]
+ - m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 3 + 0]
+ + m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 3 + 1]
+ - m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 3 + 1]
+ - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 3]
+ + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 3];
+ a[4 * 2 + 3] = m[4 * 0 + 3] * m[4 * 1 + 1] * m[4 * 2 + 0]
+ - m[4 * 0 + 1] * m[4 * 1 + 3] * m[4 * 2 + 0]
+ - m[4 * 0 + 3] * m[4 * 1 + 0] * m[4 * 2 + 1]
+ + m[4 * 0 + 0] * m[4 * 1 + 3] * m[4 * 2 + 1]
+ + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 3]
+ - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 3];
+ a[4 * 3 + 0] = m[4 * 1 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0]
+ - m[4 * 1 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0]
+ - m[4 * 1 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1]
+ + m[4 * 1 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1]
+ + m[4 * 1 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2]
+ - m[4 * 1 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2];
+ a[4 * 3 + 1] = m[4 * 0 + 1] * m[4 * 2 + 2] * m[4 * 3 + 0]
+ - m[4 * 0 + 2] * m[4 * 2 + 1] * m[4 * 3 + 0]
+ + m[4 * 0 + 2] * m[4 * 2 + 0] * m[4 * 3 + 1]
+ - m[4 * 0 + 0] * m[4 * 2 + 2] * m[4 * 3 + 1]
+ - m[4 * 0 + 1] * m[4 * 2 + 0] * m[4 * 3 + 2]
+ + m[4 * 0 + 0] * m[4 * 2 + 1] * m[4 * 3 + 2];
+ a[4 * 3 + 2] = m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 3 + 0]
+ - m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 3 + 0]
+ - m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 3 + 1]
+ + m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 3 + 1]
+ + m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 3 + 2]
+ - m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 3 + 2];
+ a[4 * 3 + 3] = m[4 * 0 + 1] * m[4 * 1 + 2] * m[4 * 2 + 0]
+ - m[4 * 0 + 2] * m[4 * 1 + 1] * m[4 * 2 + 0]
+ + m[4 * 0 + 2] * m[4 * 1 + 0] * m[4 * 2 + 1]
+ - m[4 * 0 + 0] * m[4 * 1 + 2] * m[4 * 2 + 1]
+ - m[4 * 0 + 1] * m[4 * 1 + 0] * m[4 * 2 + 2]
+ + m[4 * 0 + 0] * m[4 * 1 + 1] * m[4 * 2 + 2];
+
+ det = NvGl2DemoMatrixDeterminant(m);
+
+ for (i = 0; i < 16; ++i)
+ a[i] /= det;
+
+ NvGl2DemoMatrixIdentity(e);
+
+ NvGl2DemoMatrixCopy(b, m);
+ NvGl2DemoMatrixMultiply(b, a);
+
+ NvGl2DemoMatrixCopy(m, a);
+ }
+
+ void NvGl2DemoMatrixCopy(float dest[16], float src[16])
+ {
+ memcpy(dest, src, 16 * sizeof(float));
+ }
+
+ void NvGl2DemoMatrixPrint(float a[16])
+ {
+ int i, j;
+
+ for (i = 0; i < 4; ++i)
+ for (j = 0; j < 4; ++j)
+ printf("%f%c", a[4 * i + j], j == 3 ? '\n' : ' ');
+ }
+
+ void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4])
+ {
+ float res[4];
+ int i, j;
+
+ for (i = 0; i < 4; ++i) {
+ res[i] = 0;
+ for (j = 0; j < 4; ++j)
+ res[i] += m[i * 4 + j] * v[j];
+ }
+
+ memcpy(v, res, sizeof(res));
+ }
+}
+} \ No newline at end of file
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h
new file mode 100644
index 00000000..79bfd911
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExample.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_EXAMPLE_H
+#define QT3DS_RENDER_EXAMPLE_H
+#include "foundation/Qt3DS.h"
+#include "foundation/Qt3DSAssert.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/NvRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContext;
+
+ class NVRenderExample
+ {
+ protected:
+ virtual ~NVRenderExample() {}
+ public:
+ virtual void drawFrame(double currentSeconds) = 0;
+ virtual QT3DSU32 getRuntimeInSeconds() { return 5; }
+ virtual void handleKeypress(int /*keypress*/) {}
+ virtual void release() = 0;
+ };
+
+ typedef NVRenderExample *(*TExampleCreateFunc)(NVRenderContext &context);
+
+ struct NVRenderExampleFactory
+ {
+ static TExampleCreateFunc *mExampleCreators;
+ static QT3DSU32 mMaxCreators;
+ static QT3DSU32 mNumCreators;
+
+ static void addCreator(TExampleCreateFunc creator)
+ {
+ if (mNumCreators < mMaxCreators) {
+ mExampleCreators[mNumCreators] = creator;
+ ++mNumCreators;
+ } else
+ QT3DS_ASSERT(false);
+ }
+
+ // Assuming that the render context is egl
+ // Relies on the global structures defined in demo common
+ // to figure out window state.
+ static bool nextExample();
+ static void beginExamples();
+ static bool update();
+ static void endExamples();
+ };
+
+ template <typename TExample>
+ struct NVRenderExampleCreator
+ {
+
+ static NVRenderExample *createExample(NVRenderContext &context)
+ {
+ return QT3DS_NEW(context.GetFoundation().getAllocator(), TExample)(context);
+ }
+ NVRenderExampleCreator() { NVRenderExampleFactory::addCreator(createExample); }
+ };
+
+#define QT3DS_RENDER_REGISTER_EXAMPLE(dtype) static NVRenderExampleCreator<dtype> dtype##Creator
+
+#define eps 1e-4
+
+ int eq(float a, float b);
+
+ // Matrix functions
+ void NvGl2DemoMatrixIdentity(float m[16]);
+ int NvGl2DemoMatrixEquals(float a[16], float b[16]);
+ void NvGl2DemoMatrixTranspose(float m[16]);
+ void NvGl2DemoMatrixMultiply(float m0[16], float m1[16]);
+ void NvGl2DemoMatrixMultiply_4x4_3x3(float m0[16], float m1[9]);
+ void NvGl2DemoMatrixMultiply_3x3(float m0[9], float m1[9]);
+ void NvGl2DemoMatrixFrustum(float m[16], float l, float r, float b, float t, float n, float f);
+ void NvGl2DemoMatrixOrtho(float m[16], float l, float r, float b, float t, float n, float f);
+ void NvGl2DemoMatrixTranslate(float m[16], float x, float y, float z);
+ void NvGl2DemoMatrixRotate_create3x3(float m[9], float theta, float x, float y, float z);
+ void NvGl2DemoMatrixRotate(float m[16], float theta, float x, float y, float z);
+ void NvGl2DemoMatrixRotate_3x3(float m[9], float theta, float x, float y, float z);
+
+ float NvGl2DemoMatrixDeterminant(float m[16]);
+ void NvGl2DemoMatrixInverse(float m[16]);
+ void NvGl2DemoMatrixCopy(float dest[16], float src[16]);
+
+ void NvGl2DemoMatrixPrint(float a[16]);
+
+ void NvGl2DemoMatrixVectorMultiply(float m[16], float v[4]);
+}
+}
+
+#endif \ No newline at end of file
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp
new file mode 100644
index 00000000..efae6f5e
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSRenderExampleTools.h"
+#include "render/Qt3DSRenderIndexBuffer.h"
+#include "render/Qt3DSRenderVertexBuffer.h"
+#include "render_util/NVRenderUtils.h"
+#include "foundation/Qt3DSVec3.h"
+#include "foundation/Qt3DSVec4.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+struct BoxFace
+{
+ QT3DSVec3 positions[4];
+ QT3DSVec3 normal;
+};
+
+static const BoxFace g_BoxFaces[] = {
+ { // Z+
+ QT3DSVec3(-1, -1, 1), QT3DSVec3(-1, 1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(0, 0, 1) },
+ { // X+
+ QT3DSVec3(1, -1, 1), QT3DSVec3(1, 1, 1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, -1, -1), QT3DSVec3(1, 0, 0) },
+ { // Z-
+ QT3DSVec3(1, -1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, -1, -1),
+ QT3DSVec3(0, 0, -1) },
+ { // X-
+ QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, 1, -1), QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, -1, 1),
+ QT3DSVec3(-1, 0, 0) },
+ { // Y+
+ QT3DSVec3(-1, 1, 1), QT3DSVec3(-1, 1, -1), QT3DSVec3(1, 1, -1), QT3DSVec3(1, 1, 1), QT3DSVec3(0, 1, 0) },
+ { // Y-
+ QT3DSVec3(-1, -1, -1), QT3DSVec3(-1, -1, 1), QT3DSVec3(1, -1, 1), QT3DSVec3(1, -1, -1), QT3DSVec3(0, -1, 0) }
+};
+
+static const QT3DSVec3 g_BoxUVs[] = {
+ QT3DSVec3(0, 1, 0), QT3DSVec3(0, 0, 0), QT3DSVec3(1, 0, 0), QT3DSVec3(1, 1, 0),
+};
+
+void NVRenderExampleTools::createBox(NVRenderContext &context,
+ NVRenderVertexBuffer *&outVertexBuffer,
+ NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory)
+{
+ const QT3DSU32 numVerts = 24;
+ const QT3DSU32 numIndices = 36;
+ QT3DSVec3 extents = QT3DSVec3(1, 1, 1);
+
+ NVRenderVertexBufferEntry entries[] = {
+ NVRenderVertexBufferEntry("attr_pos", NVRenderComponentTypes::QT3DSF32, 3, 0),
+ NVRenderVertexBufferEntry("attr_norm", NVRenderComponentTypes::QT3DSF32, 3, 3 * sizeof(QT3DSF32)),
+ NVRenderVertexBufferEntry("attr_uv", NVRenderComponentTypes::QT3DSF32, 2, 6 * sizeof(QT3DSF32)),
+ };
+
+ QT3DSU32 bufStride = 8 * sizeof(QT3DSF32);
+ QT3DSU32 bufSize = bufStride * numVerts;
+ outVertexBuffer = context.CreateVertexBuffer(
+ NVRenderBufferUsageType::Static, NVConstDataRef<NVRenderVertexBufferEntry>(entries, 3), 0,
+ releaseMemory ? 0 : bufSize);
+ QT3DS_ASSERT(bufStride == outVertexBuffer->GetStride());
+ NVDataRef<QT3DSU8> vertData;
+ if (releaseMemory)
+ vertData = NVDataRef<QT3DSU8>(
+ (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "VertexBufferData"),
+ bufSize);
+ else
+ vertData = outVertexBuffer->LockBuffer(bufSize);
+ QT3DSU8 *positions = (QT3DSU8 *)vertData.begin();
+ QT3DSU8 *normals = positions + 3 * sizeof(QT3DSF32);
+ QT3DSU8 *uvs = normals + 3 * sizeof(QT3DSF32);
+
+ for (QT3DSU32 i = 0; i < 6; i++) {
+ const BoxFace &bf = g_BoxFaces[i];
+ for (QT3DSU32 j = 0; j < 4; j++) {
+ QT3DSVec3 &p = *(QT3DSVec3 *)positions;
+ positions = ((QT3DSU8 *)positions) + bufStride;
+ QT3DSVec3 &n = *(QT3DSVec3 *)normals;
+ normals = ((QT3DSU8 *)normals) + bufStride;
+ QT3DSF32 *uv = (QT3DSF32 *)uvs;
+ uvs = ((QT3DSU8 *)uvs) + bufStride;
+ n = bf.normal;
+ p = bf.positions[j].multiply(extents);
+ uv[0] = g_BoxUVs[j].x;
+ uv[1] = g_BoxUVs[j].y;
+ }
+ }
+
+ if (releaseMemory) {
+ outVertexBuffer->SetBuffer(vertData, false);
+ context.GetFoundation().getAllocator().deallocate(vertData.begin());
+ } else
+ outVertexBuffer->UnlockBuffer();
+
+ bufSize = numIndices * sizeof(QT3DSU16);
+ outIndexBuffer =
+ context.CreateIndexBuffer(NVRenderBufferUsageType::Static, NVRenderComponentTypes::QT3DSU16,
+ releaseMemory ? 0 : bufSize);
+ NVDataRef<QT3DSU8> indexData;
+ if (releaseMemory)
+ indexData = NVDataRef<QT3DSU8>(
+ (QT3DSU8 *)QT3DS_ALLOC(context.GetFoundation().getAllocator(), bufSize, "IndexData"),
+ bufSize);
+ else
+ indexData = outIndexBuffer->LockBuffer(bufSize);
+ QT3DSU16 *indices = reinterpret_cast<QT3DSU16 *>(indexData.begin());
+ for (QT3DSU8 i = 0; i < 6; i++) {
+ const QT3DSU16 base = i * 4;
+ *(indices++) = base + 0;
+ *(indices++) = base + 1;
+ *(indices++) = base + 2;
+ *(indices++) = base + 0;
+ *(indices++) = base + 2;
+ *(indices++) = base + 3;
+ }
+ if (releaseMemory) {
+ outIndexBuffer->SetBuffer(indexData, false);
+ context.GetFoundation().getAllocator().deallocate(indexData.begin());
+ } else
+ outIndexBuffer->UnlockBuffer();
+}
+
+namespace {
+
+inline NVConstDataRef<QT3DSI8> toRef(const char *data)
+{
+ size_t len = strlen(data) + 1;
+ return NVConstDataRef<QT3DSI8>((const QT3DSI8 *)data, len);
+}
+
+static void dumpShaderOutput(NVRenderContext &ctx,
+ const NVRenderVertFragCompilationResult &compResult)
+{
+ if (!isTrivial(compResult.mFragCompilationOutput)) {
+ ctx.GetFoundation().error(QT3DS_WARN, "Frag output:\n%s", compResult.mFragCompilationOutput);
+ }
+ if (!isTrivial(compResult.mVertCompilationOutput)) {
+ ctx.GetFoundation().error(QT3DS_WARN, "Vert output:\n%s", compResult.mVertCompilationOutput);
+ }
+ if (!isTrivial(compResult.mLinkOutput)) {
+ ctx.GetFoundation().error(QT3DS_WARN, "Link output:\n%s", compResult.mLinkOutput);
+ }
+}
+
+NVRenderVertFragShader *compileAndDump(NVRenderContext &ctx, const char *name,
+ const char *vertShader, const char *fragShader)
+{
+ NVRenderVertFragCompilationResult compResult =
+ ctx.CompileSource(name, toRef(vertShader), toRef(fragShader));
+ dumpShaderOutput(ctx, compResult);
+ return compResult.mShader;
+}
+}
+
+NVRenderVertFragShader *NVRenderExampleTools::createSimpleShader(NVRenderContext &ctx)
+{
+ return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShader());
+}
+
+NVRenderVertFragShader *NVRenderExampleTools::createSimpleShaderTex(NVRenderContext &ctx)
+{
+ return compileAndDump(ctx, "SimpleShader", getSimpleVertShader(), getSimpleFragShaderTex());
+} \ No newline at end of file
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h
new file mode 100644
index 00000000..5b402868
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderExampleTools.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_EXAMPLE_TOOLS_H
+#define QT3DS_RENDER_EXAMPLE_TOOLS_H
+#include "Qt3DSRenderExample.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderExampleTools
+ {
+ public:
+ static const char *getSimpleVertShader()
+ {
+ return "uniform mat4 mat_mvp;\n"
+ "attribute vec3 attr_pos; // Vertex pos\n"
+ "attribute vec3 attr_norm; // Vertex pos\n"
+ "attribute vec2 attr_uv; // UV coords\n"
+ "varying vec4 color_to_add;\n"
+ "varying vec2 uv_coords;\n"
+ "void main()\n"
+ "{\n"
+ "gl_Position = mat_mvp * vec4(attr_pos, 1.0);\n"
+ "color_to_add.xyz = attr_norm * attr_norm;\n"
+ "color_to_add.a = 1.0;\n"
+ "uv_coords = attr_uv;\n"
+ "}\n";
+ }
+
+ static const char *getSimpleFragShader()
+ {
+ return "precision mediump sampler2D;\n"
+ "precision mediump float;\n"
+ "varying vec4 color_to_add;\n"
+ "void main()\n"
+ "{\n"
+ "gl_FragColor=color_to_add;\n"
+ "}\n";
+ }
+
+ static const char *getSimpleFragShaderTex()
+ {
+ return "precision mediump sampler2D;\n"
+ "precision mediump float;\n"
+ "uniform sampler2D image0;\n"
+ "varying vec2 uv_coords;\n"
+ "void main()\n"
+ "{\n"
+ "gl_FragColor=vec4(texture2D( image0, uv_coords ).xyz, 1.0 );\n"
+ "}\n";
+ }
+
+ static void createBox(NVRenderContext &context, NVRenderVertexBuffer *&outVertexBuffer,
+ NVRenderIndexBuffer *&outIndexBuffer, bool releaseMemory = true);
+ static NVRenderVertFragShader *createSimpleShader(NVRenderContext &context);
+ static NVRenderVertFragShader *createSimpleShaderTex(NVRenderContext &context);
+ };
+}
+}
+
+#endif \ No newline at end of file
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp
new file mode 100644
index 00000000..e2cb4149
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderRenderToTextureExample.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSRenderExample.h"
+#include "Qt3DSRenderExampleTools.h"
+#include "render/Qt3DSRenderFrameBuffer.h"
+#include "render/Qt3DSRenderTexture2D.h"
+#include "render/Qt3DSRenderIndexBuffer.h"
+#include "render/Qt3DSRenderVertexBuffer.h"
+#include "render/Qt3DSRenderFrameBuffer.h"
+#include "render/Qt3DSRenderRenderBuffer.h"
+#include "foundation/Qt3DSVec4.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+namespace {
+struct ShaderArgs
+{
+ float mvp[16];
+ NVRenderTexture2DPtr texture;
+ NVRenderVertFragShaderPtr shader;
+ ShaderArgs() {}
+};
+class RenderToTexture : public NVRenderExample
+{
+ NVRenderContext &m_Context;
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ // Simple shader
+ NVScopedRefCounted<NVRenderVertFragShader> mSimpleShader;
+ // Simple shader with texture lookup.
+ NVScopedRefCounted<NVRenderVertFragShader> mSimpleShaderTex;
+
+ NVScopedRefCounted<NVRenderFrameBuffer> mFrameBuffer;
+ NVScopedRefCounted<NVRenderTexture2D> mColorBuffer;
+ NVScopedRefCounted<NVRenderTexture2D> mDepthBuffer;
+
+ NVRenderHandle mGroupId;
+ QT3DSU32 mFBWidth;
+ QT3DSU32 mFBHeight;
+
+ ShaderArgs mShaderArgs;
+ float frus[16];
+ float model[16];
+ float rot[9];
+
+public:
+ RenderToTexture(NVRenderContext &context)
+ : m_Context(context)
+ , mFBWidth(400)
+ , mFBHeight(400)
+ {
+ NVRenderExampleTools::createBox(m_Context, mVertexBuffer.mPtr, mIndexBuffer.mPtr);
+ mVertexBuffer->addRef();
+ mIndexBuffer->addRef();
+ mSimpleShader = NVRenderExampleTools::createSimpleShader(m_Context);
+ mSimpleShaderTex = NVRenderExampleTools::createSimpleShaderTex(m_Context);
+ // If you don't want the depth buffer information back out of the system, then you can
+ // do this.
+ // mDepthBuffer = m_Context.CreateRenderBuffer( NVRenderRenderBufferFormats::Depth16,
+ // mFBWidth, mFBHeight );
+
+ mDepthBuffer = m_Context.CreateTexture2D();
+ mDepthBuffer->SetTextureData(NVDataRef<QT3DSU8>(), 0, mFBWidth, mFBHeight,
+ NVRenderTextureFormats::Depth16);
+ mColorBuffer = m_Context.CreateTexture2D();
+ mColorBuffer->SetTextureData(NVDataRef<QT3DSU8>(), 0, mFBWidth, mFBHeight,
+ NVRenderTextureFormats::RGBA8);
+ if (mDepthBuffer.mPtr && mColorBuffer.mPtr) {
+ // Creating objects tends to Bind them to their active state hooks.
+ // So to protect the rest of the system against what they are doing (if we care), we
+ // need
+ // to push the current state
+ // Auto-binds the framebuffer.
+ mFrameBuffer = m_Context.CreateFrameBuffer();
+ mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, *mColorBuffer.mPtr);
+ mFrameBuffer->Attach(NVRenderFrameBufferAttachments::Depth, *mDepthBuffer.mPtr);
+ QT3DS_ASSERT(mFrameBuffer->IsComplete());
+
+ m_Context.SetRenderTarget(NULL);
+ }
+ mColorBuffer->SetMinFilter(NVRenderTextureMinifyingOp::Linear);
+ mColorBuffer->SetMagFilter(NVRenderTextureMagnifyingOp::Linear);
+ m_Context.SetVertexBuffer(mVertexBuffer);
+ m_Context.SetIndexBuffer(mIndexBuffer);
+ m_Context.SetDepthTestEnabled(true);
+ m_Context.SetDepthWriteEnabled(true);
+ m_Context.SetClearColor(QT3DSVec4(.3f));
+ // Setup various matrici
+ NvGl2DemoMatrixIdentity(model);
+ NvGl2DemoMatrixIdentity(frus);
+ NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10);
+ NvGl2DemoMatrixTranslate(model, 0, 0, -4);
+ mShaderArgs.texture = mColorBuffer.mPtr;
+ }
+ void setupMVP(QT3DSVec3 translation)
+ {
+ float *mvp(mShaderArgs.mvp);
+ memCopy(mvp, frus, 16 * sizeof(float));
+ NvGl2DemoMatrixMultiply(mvp, model);
+ NvGl2DemoMatrixTranslate(mvp, translation.x, translation.y, translation.z);
+ NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot);
+ }
+ void DrawIndexedArrays(QT3DSVec3 translation)
+ {
+ setupMVP(translation);
+ m_Context.SetActiveShader(mShaderArgs.shader);
+ mShaderArgs.shader->Bind();
+ mShaderArgs.shader->SetPropertyValue("mat_mvp",
+ *reinterpret_cast<QT3DSMat44 *>(mShaderArgs.mvp));
+ mShaderArgs.shader->SetPropertyValue("image0", mShaderArgs.texture);
+ m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0);
+ }
+
+ virtual void drawFrame(double currentSeconds)
+ {
+ NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0);
+ NVRenderClearFlags clearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth);
+ // render to frame buffer
+ {
+ NVRenderContextScopedProperty<NVRenderFrameBufferPtr> __framebuffer(
+ m_Context, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget,
+ mFrameBuffer);
+ NVRenderContextScopedProperty<NVRenderRect> __viewport(
+ m_Context, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport,
+ NVRenderRect(0, 0, mFBWidth, mFBHeight));
+ NVRenderContextScopedProperty<QT3DSVec4> __clearColor(
+ m_Context, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor,
+ QT3DSVec4(.6f));
+ m_Context.Clear(clearFlags);
+ mShaderArgs.shader = mSimpleShader;
+ DrawIndexedArrays(QT3DSVec3(0.f));
+ }
+ m_Context.Clear(clearFlags);
+ mShaderArgs.texture = mColorBuffer;
+ mShaderArgs.shader = mSimpleShaderTex;
+
+ DrawIndexedArrays(QT3DSVec3(-2.f, 0.f, 0.f));
+
+ mShaderArgs.texture = mDepthBuffer;
+ DrawIndexedArrays(QT3DSVec3(2.f, 0.f, 0.f));
+ }
+ virtual QT3DSU32 getRuntimeInSeconds()
+ {
+ return mSimpleShader.mPtr && mSimpleShaderTex.mPtr ? 5 : 0;
+ }
+ virtual void release() { NVDelete(m_Context.GetFoundation(), this); }
+};
+}
+
+QT3DS_RENDER_REGISTER_EXAMPLE(RenderToTexture); \ No newline at end of file
diff --git a/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp b/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp
new file mode 100644
index 00000000..807f0821
--- /dev/null
+++ b/src/Runtime/Source/render/Examples/Qt3DSRenderSpinningCubeExample.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSRenderExample.h"
+#include "render/Qt3DSRenderVertexBuffer.h"
+#include "render/Qt3DSRenderIndexBuffer.h"
+#include "render/NVRenderVertFragShader.h"
+#include "render_util/NVRenderUtils.h"
+#include "Qt3DSRenderExampleTools.h"
+#include "foundation/Qt3DSMat44.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+
+#pragma warning(disable : 4189)
+#pragma warning(disable : 4100)
+
+namespace {
+
+struct ShaderArguments
+{
+ QT3DSMat44 mMatrix;
+};
+
+class SpinningCube : public NVRenderExample
+{
+ NVRenderContext &m_Context;
+ NVScopedRefCounted<NVRenderVertexBuffer> mVertexBuffer;
+ NVScopedRefCounted<NVRenderIndexBuffer> mIndexBuffer;
+ NVScopedRefCounted<NVRenderVertFragShader> mShader;
+ NVRenderHandle mShaderArgGroupId;
+ float frus[16];
+ float model[16];
+ float rot[9];
+
+public:
+ SpinningCube(NVRenderContext &ctx)
+ : m_Context(ctx)
+ {
+ NVRenderExampleTools::createBox(ctx, mVertexBuffer.mPtr, mIndexBuffer.mPtr, false);
+ mVertexBuffer->addRef();
+ mIndexBuffer->addRef();
+ mShader = NVRenderExampleTools::createSimpleShader(ctx);
+ ctx.SetViewport(NVRenderRect(0, 0, 400, 400));
+ // These properties will get applied just before render no matter what
+ // so we can just use the default settings here.
+ ctx.SetVertexBuffer(mVertexBuffer);
+ ctx.SetIndexBuffer(mIndexBuffer);
+ if (mShader) {
+ ctx.SetActiveShader(mShader);
+ }
+ ctx.SetDepthTestEnabled(true);
+ ctx.SetDepthWriteEnabled(true);
+ NvGl2DemoMatrixIdentity(model);
+ NvGl2DemoMatrixIdentity(frus);
+ NvGl2DemoMatrixFrustum(frus, -1, 1, -1, 1, 1, 10);
+ NvGl2DemoMatrixTranslate(model, 0, 0, -4);
+ }
+ virtual void drawFrame(double currentSeconds)
+ {
+ NvGl2DemoMatrixRotate_create3x3(rot, (float)currentSeconds * 50, .707f, .707f, 0);
+ float mvp[16];
+ NvGl2DemoMatrixIdentity(mvp);
+ NvGl2DemoMatrixMultiply(mvp, frus);
+ NvGl2DemoMatrixMultiply(mvp, model);
+ NvGl2DemoMatrixMultiply_4x4_3x3(mvp, rot);
+
+ NVConstDataRef<QT3DSU8> instance((QT3DSU8 *)mvp, 16 * sizeof(float));
+ m_Context.Clear(
+ NVRenderClearFlags(NVRenderClearValues::Color | NVRenderClearValues::Depth));
+ mShader->SetPropertyValue("mat_mvp", *reinterpret_cast<QT3DSMat44 *>(mvp));
+ m_Context.Draw(NVRenderDrawMode::Triangles, mIndexBuffer->GetNumIndices(), 0);
+ }
+ virtual QT3DSU32 getRuntimeInSeconds() { return mShader.mPtr ? 5 : 0; }
+ virtual void release() { NVDelete(m_Context.GetFoundation(), this); }
+};
+}
+QT3DS_RENDER_REGISTER_EXAMPLE(SpinningCube); \ No newline at end of file
diff --git a/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp
new file mode 100644
index 00000000..272c3e8c
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderAtomicCounterBuffer.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+namespace qt3ds {
+namespace render {
+
+ ///< struct handling a constant buffer entry
+ class AtomicCounterBufferEntry
+ {
+ public:
+ CRegisteredString m_Name; ///< parameter Name
+ QT3DSI32 m_Offset; ///< offset into the memory buffer
+
+ AtomicCounterBufferEntry(CRegisteredString name, QT3DSI32 offset)
+ : m_Name(name)
+ , m_Offset(offset)
+ {
+ }
+ };
+
+ NVRenderAtomicCounterBuffer::NVRenderAtomicCounterBuffer(
+ NVRenderContextImpl &context, CRegisteredString bufferName, size_t size,
+ NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data)
+ : NVRenderDataBuffer(context, context.GetFoundation(), size,
+ NVRenderBufferBindValues::Storage, usageType, data)
+ , m_Name(bufferName)
+ , m_AtomicCounterBufferEntryMap(
+ m_Foundation.getAllocator(),
+ "NVRenderAtomicCounterBuffer::m_AtomicCounterBufferEntryMap")
+ , m_Dirty(true)
+ {
+ QT3DS_ASSERT(context.IsStorageBufferSupported());
+ }
+
+ NVRenderAtomicCounterBuffer::~NVRenderAtomicCounterBuffer()
+ {
+ for (TRenderAtomiCounterBufferEntryMap::iterator
+ iter = m_AtomicCounterBufferEntryMap.begin(),
+ end = m_AtomicCounterBufferEntryMap.end();
+ iter != end; ++iter) {
+ NVDelete(m_Foundation.getAllocator(), iter->second);
+ }
+
+ m_AtomicCounterBufferEntryMap.clear();
+
+ m_Context.BufferDestroyed(*this);
+ }
+
+ void NVRenderAtomicCounterBuffer::Bind()
+ {
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ m_Backend->BindBuffer(m_BufferHandle, m_BindFlags);
+ }
+
+ void NVRenderAtomicCounterBuffer::BindToShaderProgram(QT3DSU32 index)
+ {
+ m_Backend->ProgramSetAtomicCounterBuffer(index, m_BufferHandle);
+ }
+
+ void NVRenderAtomicCounterBuffer::Update()
+ {
+ // we only update the buffer if it is dirty and we actually have some data
+ if (m_Dirty && m_BufferData.size()) {
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType,
+ m_BufferData.begin());
+ m_Dirty = false;
+ }
+ }
+
+ void NVRenderAtomicCounterBuffer::UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data)
+ {
+ // we only update the buffer if we something
+ if (data.size())
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType,
+ data.begin() + offset);
+ }
+
+ void NVRenderAtomicCounterBuffer::AddParam(CRegisteredString name, QT3DSU32 offset)
+ {
+ if (m_AtomicCounterBufferEntryMap.find(name) == m_AtomicCounterBufferEntryMap.end()) {
+ AtomicCounterBufferEntry *newEntry =
+ QT3DS_NEW(m_Foundation.getAllocator(), AtomicCounterBufferEntry)(name, offset);
+
+ if (newEntry)
+ m_AtomicCounterBufferEntryMap.insert(eastl::make_pair(name, newEntry));
+ } else {
+ // no duplicated entries
+ return;
+ }
+ }
+
+ bool NVRenderAtomicCounterBuffer::ContainsParam(CRegisteredString name)
+ {
+ if (m_AtomicCounterBufferEntryMap.find(name) != m_AtomicCounterBufferEntryMap.end())
+ return true;
+ else
+ return false;
+ }
+
+ NVRenderAtomicCounterBuffer *
+ NVRenderAtomicCounterBuffer::Create(NVRenderContextImpl &context, const char *bufferName,
+ NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVFoundationBase &fnd(context.GetFoundation());
+ NVRenderAtomicCounterBuffer *retval = NULL;
+
+ if (context.IsAtomicCounterBufferSupported()) {
+ CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName));
+ QT3DSU32 bufSize = sizeof(NVRenderAtomicCounterBuffer);
+ QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "AtomicCounterBuffer");
+ retval = new (newMem) NVRenderAtomicCounterBuffer(
+ context, theBufferName, size, usageType,
+ toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()));
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h
new file mode 100644
index 00000000..5ff449ea
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderAtomicCounterBuffer.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_ATOMIC_COUNTER_BUFFER_H
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Utils.h"
+#include "foundation/StringTable.h"
+#include "render/Qt3DSRenderDataBuffer.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ // forward declaration
+ class NVRenderContextImpl;
+ class AtomicCounterBufferEntry;
+
+ typedef nvhash_map<CRegisteredString, AtomicCounterBufferEntry *>
+ TRenderAtomiCounterBufferEntryMap;
+
+ ///< Constant (uniform) buffer representation
+ class QT3DS_AUTOTEST_EXPORT NVRenderAtomicCounterBuffer : public NVRenderDataBuffer
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] bufferName Name of the buffer. Must match the name used in programs
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return.
+ */
+ NVRenderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString bufferName,
+ size_t size, NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data);
+
+ ///< destructor
+ virtual ~NVRenderAtomicCounterBuffer();
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief bind the buffer to a shader program
+ *
+ * @param[in] index Index of the constant buffer within the program
+ *
+ * @return no return.
+ */
+ virtual void BindToShaderProgram(QT3DSU32 index);
+
+ /**
+ * @brief update the buffer to hardware
+ *
+ * @return no return.
+ */
+ virtual void Update();
+
+ /**
+ * @brief update a piece of memory directly within the storage buffer
+ *
+ * Note: When you use this function you should know what you are doing.
+ * The memory layout within C++ must exactly match the memory layout in the
+ *shader.
+ * We use std140 (430) layout which guarantees a specific layout behavior across
+ *all HW vendors.
+ * How the memory layout is computed can be found in the GL spec.
+ *
+ * @param[in] offset offset into storage buffer
+ * @param[in] data pointer to data
+ *
+ * @return no return
+ */
+ void UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data);
+
+ /**
+ * @brief add a parameter to the atomic counter buffer
+ *
+ * @param[in] name Name of the parameter (must match the name in the shader
+ * program)
+ * @param[in] offset Offset in bytes into the buffer
+ *
+ * @return no return
+ */
+ void AddParam(CRegisteredString name, QT3DSU32 offset);
+
+ /**
+ * @brief Check if the buffer contains this param
+ *
+ * @param[in] name Name of the parameter (must match the name in the shader
+ * program)
+ *
+ * @return no return
+ */
+ bool ContainsParam(CRegisteredString name);
+
+ /**
+ * @brief get the buffer name
+ *
+ * @return the buffer name
+ */
+ CRegisteredString GetBufferName() const { return m_Name; }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+
+ /**
+ * @brief create a NVRenderAtomicCounterBuffer object
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return the buffer object or NULL
+ */
+ static NVRenderAtomicCounterBuffer *Create(NVRenderContextImpl &context,
+ const char *bufferName,
+ NVRenderBufferUsageType::Enum usageType,
+ size_t size, NVConstDataRef<QT3DSU8> bufferData);
+
+ private:
+ CRegisteredString m_Name; ///< buffer name
+ TRenderAtomiCounterBufferEntryMap
+ m_AtomicCounterBufferEntryMap; ///< holds the entries of a atomic counter buffer
+ bool m_Dirty; ///< true if buffer is dirty
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp
new file mode 100644
index 00000000..42641a04
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderAttribLayout.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ ///< constructor
+ NVRenderAttribLayout::NVRenderAttribLayout(NVRenderContextImpl &context,
+ NVConstDataRef<NVRenderVertexBufferEntry> attribs)
+ : m_Context(context)
+ , m_Foundation(context.GetFoundation())
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ {
+ m_AttribLayoutHandle = m_Backend->CreateAttribLayout(attribs);
+ QT3DS_ASSERT(m_AttribLayoutHandle);
+ }
+
+ ///< destructor
+ NVRenderAttribLayout::~NVRenderAttribLayout()
+ {
+ if (m_AttribLayoutHandle) {
+ m_Backend->ReleaseAttribLayout(m_AttribLayoutHandle);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h
new file mode 100644
index 00000000..da801c8e
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderAttribLayout.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_ATTRIB_LAYOUT_H
+#define QT3DS_RENDER_ATTRIB_LAYOUT_H
+
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Utils.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ // forward declarations
+ class NVRenderContextImpl;
+ class NVRenderBackend;
+
+ ///< this class handles the vertex attribute layout setup
+ class NVRenderAttribLayout : public NVRefCounted
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] attribs Pointer to attribute list
+ *
+ * @return No return.
+ */
+ NVRenderAttribLayout(NVRenderContextImpl &context,
+ NVConstDataRef<NVRenderVertexBufferEntry> attribs);
+ ///< destructor
+ ~NVRenderAttribLayout();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendAttribLayoutObject GetAttribLayoutHandle() const
+ {
+ return m_AttribLayoutHandle;
+ }
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+
+ NVRenderBackend::NVRenderBackendAttribLayoutObject
+ m_AttribLayoutHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h b/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h
new file mode 100644
index 00000000..c988b2f1
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderBaseTypes.h
@@ -0,0 +1,2100 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_TYPES_H
+#define QT3DS_RENDER_QT3DS_RENDER_TYPES_H
+#include "foundation/Qt3DS.h"
+#include "foundation/Qt3DSAssert.h"
+#include "foundation/Qt3DSFlags.h"
+#include "foundation/Qt3DSDataRef.h"
+#include "foundation/Qt3DSSimpleTypes.h"
+#include "foundation/Qt3DSMath.h"
+#include "foundation/Qt3DSVec2.h"
+
+namespace qt3ds {
+
+namespace render {
+using namespace foundation;
+
+#define QT3DS_RENDER_ITERATE_COMPONENT_TYPES \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU8) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI8) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU16) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI16) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU32) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI32) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSU64) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSI64) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF16) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF32) \
+ QT3DS_RENDER_HANDLE_COMPONENT_TYPE(QT3DSF64)
+
+struct NVRenderComponentTypes
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) x,
+ QT3DS_RENDER_ITERATE_COMPONENT_TYPES
+#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_COMPONENT_TYPES
+ #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+
+ static qt3ds::QT3DSU32 getSizeofType(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \
+ case x: \
+ return sizeof(qt3ds::x);
+ QT3DS_RENDER_ITERATE_COMPONENT_TYPES
+ #undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+};
+
+/**
+ Define a set of compile-time trait classes that map the enumerations
+ to actual compile time types and sizeof so we can deal with the enumeration
+ in generic ways.
+ */
+template <NVRenderComponentTypes::Enum TraitType>
+struct NVRenderComponentTraits
+{
+ bool force_compile_error;
+};
+
+/**
+ Define a compile time mapping from datatype to enumeration. Not that if you
+ use this with a type that isn't a component type you will get a compilation
+ error.
+ */
+template <typename TDataType>
+struct NVRenderComponentTypeToTypeMap
+{
+ bool force_compile_error;
+};
+
+#define QT3DS_RENDER_HANDLE_COMPONENT_TYPE(x) \
+ template <> \
+ struct NVRenderComponentTraits<NVRenderComponentTypes::x> \
+{ \
+ typedef x TComponentType; \
+ QT3DSU8 mComponentSize; \
+ NVRenderComponentTraits<NVRenderComponentTypes::x>() \
+ : mComponentSize(sizeof(x)) \
+{ \
+} \
+}; \
+ template <> \
+ struct NVRenderComponentTypeToTypeMap<x> \
+{ \
+ NVRenderComponentTypes::Enum m_ComponentType; \
+ NVRenderComponentTypeToTypeMap<x>() \
+ : m_ComponentType(NVRenderComponentTypes::x) \
+{ \
+} \
+};
+
+QT3DS_RENDER_ITERATE_COMPONENT_TYPES;
+
+#undef QT3DS_RENDER_HANDLE_COMPONENT_TYPE
+
+// Map at compile time from component type to datatype;
+template <typename TDataType>
+inline NVRenderComponentTypes::Enum getComponentTypeForType()
+{
+ return NVRenderComponentTypeToTypeMap<TDataType>().m_ComponentType;
+}
+
+struct NVRenderContextValues
+{
+ enum Enum {
+ GLES2 = 1 << 0,
+ GL2 = 1 << 1,
+ GLES3 = 1 << 2,
+ GL3 = 1 << 3,
+ GLES3PLUS = 1 << 4,
+ GL4 = 1 << 5,
+ NullContext = 1 << 6,
+ };
+};
+
+typedef NVFlags<NVRenderContextValues::Enum, QT3DSU32> NVRenderContextType;
+
+struct NVRenderClearValues
+{
+ enum Enum {
+ Color = 1 << 0,
+ Depth = 1 << 1,
+ Stencil = 1 << 3,
+ Coverage = 1 << 4,
+ };
+};
+
+typedef NVFlags<NVRenderClearValues::Enum, QT3DSU32> NVRenderClearFlags;
+
+struct NVRenderQueryType
+{
+ enum Enum {
+ Unknown = 0,
+ Samples, ///< samples query object
+ Timer, ///< timer query object
+ };
+};
+
+struct NVRenderQueryResultType
+{
+ enum Enum {
+ Unknown = 0,
+ ResultAvailable, ///< Check if query result is available
+ Result, ///< Get actual result
+ };
+};
+
+struct NVRenderSyncType
+{
+ enum Enum {
+ Unknown = 0,
+ GpuCommandsComplete, ///< sync to Gpu commands finished
+ };
+};
+
+struct NVRenderSyncValues
+{
+ enum Enum {
+ Unknown = 0, ///< for future usage
+ };
+};
+
+typedef NVFlags<NVRenderSyncValues::Enum, QT3DSU32> NVRenderSyncFlags;
+
+struct NVRenderCommandFlushValues
+{
+ enum Enum {
+ SyncFlushCommands = 0, ///< sync for flushing command
+ };
+};
+
+typedef NVFlags<NVRenderCommandFlushValues::Enum, QT3DSU32> NVRenderCommandFlushFlags;
+
+struct NVRenderBufferBindValues
+{
+ enum Enum {
+ Unknown = 0,
+ Vertex = 1 << 0, ///< Bind as vertex buffer
+ Index = 1 << 1, ///< Bind as index buffer
+ Constant = 1 << 2, ///< Bind as constant buffer
+ Storage = 1 << 3, ///< Bind as shader storage buffer
+ Atomic_Counter = 1 << 4, ///< Bind as atomic counter buffer
+ Draw_Indirect = 1 << 5, ///< Bind as draw indirect buffer
+ };
+};
+
+typedef NVFlags<NVRenderBufferBindValues::Enum, QT3DSU32> NVRenderBufferBindFlags;
+
+struct NVRenderBufferUsageType
+{
+ enum Enum {
+ Unknown = 0,
+ Static, ///< Rarely updated
+ Dynamic, ///< Most likely updated every frame
+ };
+};
+
+struct NVRenderImageAccessType
+{
+ enum Enum {
+ Unknown = 0,
+ Read, ///< Read only access
+ Write, ///< Write only access
+ ReadWrite, ///< Read and write access
+ };
+};
+
+struct NVRenderBufferAccessTypeValues
+{
+ enum Enum {
+ Unknown = 0,
+ Read = 1 << 0, ///< Read access
+ Write = 1 << 1, ///< Write access
+ Invalid = 1 << 2, ///< No sync
+ InvalidRange = 1 << 3, ///< No sync
+
+ };
+};
+
+typedef NVFlags<NVRenderBufferAccessTypeValues::Enum, QT3DSU32> NVRenderBufferAccessFlags;
+
+///< defines a barrier of ordering the memory transactions to a command relative to those issued
+///before the barrier
+struct NVRenderBufferBarrierValues
+{
+ enum Enum {
+ Unknown = 0,
+ VertexAttribArray = 1 << 0, ///< Barrier for vertex attributes sourced from a buffer
+ ElementArray = 1 << 1, ///< Barrier for indices sourced from a buffer
+ UniformBuffer = 1 << 2, ///< Barrier for shader uniforms sourced from a buffer
+ TextureFetch = 1 << 3, ///< Barrier for texture fetches within shaders
+ ShaderImageAccess = 1 << 4, ///< Barrier for image access using load / store
+ CommandBuffer = 1 << 5, ///< Barrier for indirect drawing
+ PixelBuffer = 1 << 6, ///< Barrier for pixel buffer access
+ TextureUpdate = 1 << 7, ///< Barrier for texture writes
+ BufferUpdate = 1 << 8, ///< Barrier for buffer writes
+ Framebuffer = 1 << 9, ///< Barrier for framebuffer writes
+ TransformFeedback = 1 << 10, ///< Barrier for transform feedback writes
+ AtomicCounter = 1 << 11, ///< Barrier for atomic counter writes
+ ShaderStorage = 1 << 12, ///< Barrier for shader storage blocks writes
+ All = 0xFFFF, ///< Barrier for all of the above
+ };
+};
+
+typedef NVFlags<NVRenderBufferBarrierValues::Enum, QT3DSU32> NVRenderBufferBarrierFlags;
+
+#define QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA4) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGB565) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(RGBA5551) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth16) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth24) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(Depth32) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(StencilIndex8) \
+ QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(CoverageNV)
+
+struct NVRenderRenderBufferFormats
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) x,
+ QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS
+#undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_RENDERBUFFER_FORMATS
+ #undef QT3DS_RENDER_HANDLE_RENDERBUFFER_FORMAT
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_TEXTURE_FORMATS \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R16F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32I) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32UI) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R32F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(SRGB8A8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB565) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA5551) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Alpha8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(Luminance16) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(LuminanceAlpha8) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA16F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG16F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RG32F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB32F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGBA32F) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(R11G11B10) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(RGB9E5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT1) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_DXT1) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT3) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_DXT5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC1) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_ETC2) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_ETC2) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB8_PunchThrough_Alpha1_ETC2) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_PunchThrough_Alpha1_ETC2) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_UNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R11_EAC_SNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_UNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG11_EAC_SNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA8_ETC2_EAC) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ETC2_EAC) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_UNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(R_ATI1N_SNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_UNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RG_ATI2N_SNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNSIGNED_FLOAT) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_SIGNED_FLOAT) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGB_BP_UNorm) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_4x4) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x4) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_5x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_6x6) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x6) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_8x8) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x6) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x8) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_10x10) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x10) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(RGBA_ASTC_12x12) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_4x4) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x4) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_5x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_6x6) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x6) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_8x8) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x5) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x6) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x8) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_10x10) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x10) \
+ QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(SRGB8_Alpha8_ASTC_12x12) \
+ QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth16) \
+ QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24) \
+ QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth32) \
+ QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(Depth24Stencil8)
+
+struct NVRenderTextureFormats
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) x,
+#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) x,
+#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) x,
+ QT3DS_RENDER_ITERATE_TEXTURE_FORMATS
+#undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT
+#undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT
+#undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT
+ };
+
+ static bool isUncompressedTextureFormat(NVRenderTextureFormats::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \
+ case NVRenderTextureFormats::x: \
+ return true;
+#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x)
+#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x)
+ QT3DS_RENDER_ITERATE_TEXTURE_FORMATS
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT
+ default:
+ break;
+ }
+ return false;
+ }
+
+ static bool isCompressedTextureFormat(NVRenderTextureFormats::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x)
+#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \
+ case NVRenderTextureFormats::x: \
+ return true;
+#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x)
+ QT3DS_RENDER_ITERATE_TEXTURE_FORMATS
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT
+ default:
+ break;
+ }
+ return false;
+ }
+
+ static bool isDepthTextureFormat(NVRenderTextureFormats::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x)
+#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x)
+#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \
+ case NVRenderTextureFormats::x: \
+ return true;
+ QT3DS_RENDER_ITERATE_TEXTURE_FORMATS
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_GL_QT3DS_DEPTH_TEXTURE_FORMAT
+ default:
+ break;
+ }
+ return false;
+ }
+
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_FORMAT(x) \
+ case x: \
+ return #x;
+#define QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT(x) \
+ case x: \
+ return #x;
+#define QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_TEXTURE_FORMATS
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_COMPRESSED_TEXTURE_FORMAT
+ #undef QT3DS_RENDER_HANDLE_DEPTH_TEXTURE_FORMAT
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+
+ static QT3DSU32 getSizeofFormat(Enum value)
+ {
+ switch (value) {
+ case R8:
+ return 1;
+ case R16F:
+ return 2;
+ case R16:
+ return 2;
+ case R32I:
+ return 4;
+ case R32F:
+ return 4;
+ case RGBA8:
+ return 4;
+ case RGB8:
+ return 3;
+ case RGB565:
+ return 2;
+ case RGBA5551:
+ return 2;
+ case Alpha8:
+ return 1;
+ case Luminance8:
+ return 1;
+ case LuminanceAlpha8:
+ return 1;
+ case Depth16:
+ return 2;
+ case Depth24:
+ return 3;
+ case Depth32:
+ return 4;
+ case Depth24Stencil8:
+ return 4;
+ case RGB9E5:
+ return 4;
+ case SRGB8:
+ return 3;
+ case SRGB8A8:
+ return 4;
+ case RGBA16F:
+ return 8;
+ case RG16F:
+ return 4;
+ case RG32F:
+ return 8;
+ case RGBA32F:
+ return 16;
+ case RGB32F:
+ return 12;
+ case R11G11B10:
+ return 4;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static QT3DSU32 getNumberOfComponent(Enum value)
+ {
+ switch (value) {
+ case R8:
+ return 1;
+ case R16F:
+ return 1;
+ case R16:
+ return 1;
+ case R32I:
+ return 1;
+ case R32F:
+ return 1;
+ case RGBA8:
+ return 4;
+ case RGB8:
+ return 3;
+ case RGB565:
+ return 3;
+ case RGBA5551:
+ return 4;
+ case Alpha8:
+ return 1;
+ case Luminance8:
+ return 1;
+ case LuminanceAlpha8:
+ return 2;
+ case Depth16:
+ return 1;
+ case Depth24:
+ return 1;
+ case Depth32:
+ return 1;
+ case Depth24Stencil8:
+ return 2;
+ case RGB9E5:
+ return 3;
+ case SRGB8:
+ return 3;
+ case SRGB8A8:
+ return 4;
+ case RGBA16F:
+ return 4;
+ case RG16F:
+ return 2;
+ case RG32F:
+ return 2;
+ case RGBA32F:
+ return 4;
+ case RGB32F:
+ return 3;
+ case R11G11B10:
+ return 3;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static void decodeToFloat(void *inPtr, QT3DSU32 byteOfs, float *outPtr,
+ NVRenderTextureFormats::Enum inFmt)
+ {
+ outPtr[0] = 0.0f;
+ outPtr[1] = 0.0f;
+ outPtr[2] = 0.0f;
+ outPtr[3] = 0.0f;
+ QT3DSU8 *src = reinterpret_cast<QT3DSU8 *>(inPtr);
+ // float divisor; // If we want to support RGBD?
+ switch (inFmt) {
+ case Alpha8:
+ outPtr[0] = ((float)src[byteOfs]) / 255.0f;
+ break;
+
+ case Luminance8:
+ case LuminanceAlpha8:
+ case R8:
+ case RG8:
+ case RGB8:
+ case RGBA8:
+ case SRGB8:
+ case SRGB8A8:
+ // NOTE : RGBD Hack here for reference. Not meant for installation.
+ // divisor = (NVRenderTextureFormats::getSizeofFormat(inFmt) == 4) ?
+ // ((float)src[byteOfs+3]) / 255.0f : 1.0f;
+ for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) {
+ float val = ((float)src[byteOfs + i]) / 255.0f;
+ outPtr[i] = (i < 3) ? powf(val, 0.4545454545f) : val;
+ // Assuming RGBA8 actually means RGBD (which is stupid, I know)
+ // if ( NVRenderTextureFormats::getSizeofFormat(inFmt) == 4 ) { outPtr[i] /=
+ // divisor; }
+ }
+ // outPtr[3] = divisor;
+ break;
+
+ case R32F:
+ outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0];
+ break;
+ case RG32F:
+ outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0];
+ outPtr[1] = reinterpret_cast<float *>(src + byteOfs)[1];
+ break;
+ case RGBA32F:
+ outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0];
+ outPtr[1] = reinterpret_cast<float *>(src + byteOfs)[1];
+ outPtr[2] = reinterpret_cast<float *>(src + byteOfs)[2];
+ outPtr[3] = reinterpret_cast<float *>(src + byteOfs)[3];
+ break;
+ case RGB32F:
+ outPtr[0] = reinterpret_cast<float *>(src + byteOfs)[0];
+ outPtr[1] = reinterpret_cast<float *>(src + byteOfs)[1];
+ outPtr[2] = reinterpret_cast<float *>(src + byteOfs)[2];
+ break;
+
+ case R16F:
+ case RG16F:
+ case RGBA16F:
+ for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) {
+ // NOTE : This only works on the assumption that we don't have any denormals,
+ // Infs or NaNs.
+ // Every pixel in our source image should be "regular"
+ QT3DSU16 h = reinterpret_cast<QT3DSU16 *>(src + byteOfs)[i];
+ QT3DSU32 sign = (h & 0x8000) << 16;
+ QT3DSU32 exponent = (((((h & 0x7c00) >> 10) - 15) + 127) << 23);
+ QT3DSU32 mantissa = ((h & 0x3ff) << 13);
+ QT3DSU32 result = sign | exponent | mantissa;
+
+ if (h == 0 || h == 0x8000) {
+ result = 0;
+ } // Special case for zero and negative zero
+ qt3ds::intrinsics::memCopy(reinterpret_cast<QT3DSU32 *>(outPtr) + i, &result, 4);
+ }
+ break;
+
+ case R11G11B10:
+ // place holder
+ QT3DS_ASSERT(false);
+ break;
+
+ default:
+ outPtr[0] = 0.0f;
+ outPtr[1] = 0.0f;
+ outPtr[2] = 0.0f;
+ outPtr[3] = 0.0f;
+ break;
+ }
+ }
+
+ static void encodeToPixel(float *inPtr, void *outPtr, QT3DSU32 byteOfs,
+ NVRenderTextureFormats::Enum inFmt)
+ {
+ QT3DSU8 *dest = reinterpret_cast<QT3DSU8 *>(outPtr);
+ switch (inFmt) {
+ case NVRenderTextureFormats::Alpha8:
+ dest[byteOfs] = QT3DSU8(inPtr[0] * 255.0f);
+ break;
+
+ case Luminance8:
+ case LuminanceAlpha8:
+ case R8:
+ case RG8:
+ case RGB8:
+ case RGBA8:
+ case SRGB8:
+ case SRGB8A8:
+ for (QT3DSU32 i = 0; i < NVRenderTextureFormats::getSizeofFormat(inFmt); ++i) {
+ inPtr[i] = (inPtr[i] > 1.0f) ? 1.0f : inPtr[i];
+ if (i < 3)
+ dest[byteOfs + i] = QT3DSU8(powf(inPtr[i], 2.2f) * 255.0f);
+ else
+ dest[byteOfs + i] = QT3DSU8(inPtr[i] * 255.0f);
+ }
+ break;
+
+ case R32F:
+ reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0];
+ break;
+ case RG32F:
+ reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0];
+ reinterpret_cast<float *>(dest + byteOfs)[1] = inPtr[1];
+ break;
+ case RGBA32F:
+ reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0];
+ reinterpret_cast<float *>(dest + byteOfs)[1] = inPtr[1];
+ reinterpret_cast<float *>(dest + byteOfs)[2] = inPtr[2];
+ reinterpret_cast<float *>(dest + byteOfs)[3] = inPtr[3];
+ break;
+ case RGB32F:
+ reinterpret_cast<float *>(dest + byteOfs)[0] = inPtr[0];
+ reinterpret_cast<float *>(dest + byteOfs)[1] = inPtr[1];
+ reinterpret_cast<float *>(dest + byteOfs)[2] = inPtr[2];
+ break;
+
+ case R16F:
+ case RG16F:
+ case RGBA16F:
+ for (QT3DSU32 i = 0; i < (NVRenderTextureFormats::getSizeofFormat(inFmt) >> 1); ++i) {
+ // NOTE : This also has the limitation of not handling infs, NaNs and
+ // denormals, but it should be
+ // sufficient for our purposes.
+ if (inPtr[i] > 65519.0f) {
+ inPtr[i] = 65519.0f;
+ }
+ if (fabs(inPtr[i]) < 6.10352E-5f) {
+ inPtr[i] = 0.0f;
+ }
+ QT3DSU32 f = reinterpret_cast<QT3DSU32 *>(inPtr)[i];
+ QT3DSU32 sign = (f & 0x80000000) >> 16;
+ QT3DSI32 exponent = (f & 0x7f800000) >> 23;
+ QT3DSU32 mantissa = (f >> 13) & 0x3ff;
+ exponent = exponent - 112;
+ if (exponent > 31) {
+ exponent = 31;
+ }
+ if (exponent < 0) {
+ exponent = 0;
+ }
+ exponent = exponent << 10;
+ reinterpret_cast<QT3DSU16 *>(dest + byteOfs)[i] =
+ QT3DSU16(sign | exponent | mantissa);
+ }
+ break;
+
+ case R11G11B10:
+ // place holder
+ QT3DS_ASSERT(false);
+ break;
+
+ default:
+ dest[byteOfs] = 0;
+ dest[byteOfs + 1] = 0;
+ dest[byteOfs + 2] = 0;
+ dest[byteOfs + 3] = 0;
+ break;
+ }
+ }
+};
+
+struct NVRenderTextureTargetType
+{
+ enum Enum {
+ Unknown = 0,
+ Texture2D,
+ Texture2D_MS,
+ Texture2D_Array,
+ TextureCube,
+ TextureCubePosX,
+ TextureCubeNegX,
+ TextureCubePosY,
+ TextureCubeNegY,
+ TextureCubePosZ,
+ TextureCubeNegZ,
+ };
+};
+
+struct NVRenderTextureUnit
+{
+ enum Enum {
+ TextureUnit_0 = 0,
+ TextureUnit_1,
+ TextureUnit_2,
+ TextureUnit_3,
+ TextureUnit_4,
+ TextureUnit_5,
+ TextureUnit_6,
+ TextureUnit_7,
+ TextureUnit_8,
+ TextureUnit_9,
+ TextureUnit_10,
+ TextureUnit_11,
+ TextureUnit_12,
+ TextureUnit_13,
+ TextureUnit_14,
+ TextureUnit_15,
+ TextureUnit_16,
+ TextureUnit_17,
+ TextureUnit_18,
+ TextureUnit_19,
+ TextureUnit_20,
+ TextureUnit_21,
+ TextureUnit_22,
+ TextureUnit_23,
+ TextureUnit_24,
+ TextureUnit_25,
+ TextureUnit_26,
+ TextureUnit_27,
+ TextureUnit_28,
+ TextureUnit_29,
+ TextureUnit_30,
+ TextureUnit_31
+ };
+};
+
+struct NVRenderTextureCompareMode
+{
+ enum Enum { Unknown = 0, NoCompare, CompareToRef };
+};
+
+struct NVRenderTextureSwizzleMode
+{
+ enum Enum { NoSwizzle = 0, L8toR8, A8toR8, L8A8toRG8, L16toR16 };
+};
+
+#define QT3DS_RENDER_ITERATE_BOOL_OP \
+ QT3DS_RENDER_HANDLE_BOOL_OP(Never) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(Less) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(LessThanOrEqual) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(Equal) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(NotEqual) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(Greater) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(GreaterThanOrEqual) \
+ QT3DS_RENDER_HANDLE_BOOL_OP(AlwaysTrue)
+
+struct NVRenderTextureCompareOp
+{
+ enum Enum {
+#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x,
+ QT3DS_RENDER_ITERATE_BOOL_OP
+#undef QT3DS_RENDER_HANDLE_BOOL_OP
+ };
+};
+
+#define QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP \
+ QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Nearest) \
+ QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(Linear) \
+ QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapNearest) \
+ QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapNearest) \
+ QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(NearestMipmapLinear) \
+ QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(LinearMipmapLinear)
+
+struct NVRenderTextureMinifyingOp
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x,
+#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) x,
+ QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP
+#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP
+#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP
+ };
+ const char *toString(NVRenderTextureMinifyingOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \
+ case x: \
+ return #x;
+#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+struct NVRenderTextureMagnifyingOp
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) x,
+#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x)
+ QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP
+#undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP
+#undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP
+ };
+ const char *toString(NVRenderTextureMinifyingOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP(x) \
+ case x: \
+ return #x;
+#define QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP(x)
+ QT3DS_RENDER_ITERATE_TEXTURE_FILTER_OP
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_MINIFYING_OP
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_FILTER_OP
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP \
+ QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(ClampToEdge) \
+ QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(MirroredRepeat) \
+ QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(Repeat)
+
+struct NVRenderTextureCoordOp
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) x,
+ QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP
+#undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP
+ };
+ const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_TEXTURE_WRAP_OP
+ #undef QT3DS_RENDER_HANDLE_TEXTURE_WRAP_OP
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_HINT \
+ QT3DS_RENDER_HANDLE_HINT(Fastest) \
+ QT3DS_RENDER_HANDLE_HINT(Nicest) \
+ QT3DS_RENDER_HANDLE_HINT(Unspecified)
+
+struct NVRenderHint
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_HINT(x) x,
+ QT3DS_RENDER_ITERATE_HINT
+#undef QT3DS_RENDER_HANDLE_HINT
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_HINT(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_HINT
+ #undef QT3DS_RENDER_HANDLE_HINT
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+class NVRenderImplemented
+{
+protected:
+ virtual ~NVRenderImplemented() {}
+public:
+ // Get the handle that binds us to the implementation.
+ // For instance, return the GLuint that came back from
+ // glGenTextures.
+ virtual const void *GetImplementationHandle() const = 0;
+};
+
+struct NVRenderVertexBufferEntry
+{
+ const char *m_Name;
+ /** Datatype of the this entry points to in the buffer */
+ NVRenderComponentTypes::Enum m_ComponentType;
+ /** Number of components of each data member. 1,2,3, or 4. Don't be stupid.*/
+ QT3DSU32 m_NumComponents;
+ /** Offset from the beginning of the buffer of the first item */
+ QT3DSU32 m_FirstItemOffset;
+ /** Attribute input slot used for this entry*/
+ QT3DSU32 m_InputSlot;
+
+ NVRenderVertexBufferEntry(const char *nm, NVRenderComponentTypes::Enum type,
+ QT3DSU32 numComponents, QT3DSU32 firstItemOffset = 0,
+ QT3DSU32 inputSlot = 0)
+ : m_Name(nm)
+ , m_ComponentType(type)
+ , m_NumComponents(numComponents)
+ , m_FirstItemOffset(firstItemOffset)
+ , m_InputSlot(inputSlot)
+ {
+ }
+
+ NVRenderVertexBufferEntry()
+ : m_Name(NULL)
+ , m_ComponentType(NVRenderComponentTypes::Unknown)
+ , m_NumComponents(0)
+ , m_FirstItemOffset(0)
+ , m_InputSlot(0)
+ {
+ }
+
+ NVRenderVertexBufferEntry(const NVRenderVertexBufferEntry &inOther)
+ : m_Name(inOther.m_Name)
+ , m_ComponentType(inOther.m_ComponentType)
+ , m_NumComponents(inOther.m_NumComponents)
+ , m_FirstItemOffset(inOther.m_FirstItemOffset)
+ , m_InputSlot(inOther.m_InputSlot)
+ {
+ }
+
+ NVRenderVertexBufferEntry &operator=(const NVRenderVertexBufferEntry &inOther)
+ {
+ if (this != &inOther) {
+ m_Name = inOther.m_Name;
+ m_ComponentType = inOther.m_ComponentType;
+ m_NumComponents = inOther.m_NumComponents;
+ m_FirstItemOffset = inOther.m_FirstItemOffset;
+ m_InputSlot = inOther.m_InputSlot;
+ }
+ return *this;
+ }
+};
+
+class NVRenderShaderProgram;
+
+typedef NVConstDataRef<QT3DSI8> TConstI8Ref;
+
+struct NVRenderVertFragCompilationResult
+{
+ const char *mShaderName;
+
+ NVRenderShaderProgram *mShader; ///< contains the program
+
+ NVRenderVertFragCompilationResult()
+ : mShaderName("")
+ , mShader(NULL)
+ {
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color0) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color1) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color2) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color3) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color4) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color5) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color6) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Color7) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Depth) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(Stencil) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(DepthStencil) \
+ QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(CoverageNV)
+
+struct NVRenderFrameBufferAttachments
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT(x) x,
+ QT3DS_RENDER_ITERATE_FRAMEBUFFER_ATTACHMENTS
+#undef QT3DS_RENDER_HANDLE_FRAMEBUFFER_ATTACHMENT
+ LastAttachment,
+ };
+};
+
+struct NVRenderDrawMode
+{
+ enum Enum {
+ Unknown = 0,
+ Points,
+ LineStrip,
+ LineLoop,
+ Lines,
+ TriangleStrip,
+ TriangleFan,
+ Triangles,
+ Patches,
+ };
+};
+
+struct NVRenderTextureCubeFaces
+{
+ enum Enum {
+ InvalidFace = 0,
+ CubePosX = 1,
+ CubeNegX,
+ CubePosY,
+ CubeNegY,
+ CubePosZ,
+ CubeNegZ,
+ };
+};
+
+// enums match the NV path extensions
+struct NVRenderPathCommands
+{
+ enum Enum {
+ Close = 0,
+ MoveTo = 2,
+ CubicCurveTo = 12,
+ };
+};
+
+struct NVRenderPathFontTarget
+{
+ enum Enum {
+ StandardFont = 0,
+ SystemFont = 1,
+ FileFont = 2,
+ };
+};
+
+struct NVRenderPathMissingGlyphs
+{
+ enum Enum {
+ SkipMissing = 0,
+ UseMissing = 1,
+ };
+};
+
+struct NVRenderPathFontStyleValues
+{
+ enum Enum {
+ Bold = 1 << 0,
+ Italic = 1 << 1,
+ };
+};
+
+typedef NVFlags<NVRenderPathFontStyleValues::Enum, QT3DSU32> NVRenderPathFontStyleFlags;
+
+struct NVRenderPathReturnValues
+{
+ enum Enum {
+ FontGlypsAvailable = 0,
+ FontTargetUnavailable = 1,
+ FontUnavailable = 2,
+ FontUnintelligible = 3,
+ InvalidEnum = 4,
+ OutOfMemory = 5,
+ };
+};
+
+struct NVRenderPathFormatType
+{
+ enum Enum {
+ Byte = 1,
+ UByte,
+ Short,
+ UShort,
+ Int,
+ Uint,
+ Float,
+ Utf8,
+ Utf16,
+ Bytes2,
+ Bytes3,
+ Bytes4,
+ };
+};
+
+struct NVRenderPathGlyphFontMetricValues
+{
+ enum Enum {
+ GlyphWidth = 1 << 0,
+ GlyphHeight = 1 << 1,
+ GlyphHorizontalBearingX = 1 << 2,
+ GlyphHorizontalBearingY = 1 << 3,
+ GlyphHorizontalBearingAdvance = 1 << 4,
+ GlyphVerticalBearingX = 1 << 5,
+ GlyphVerticalBearingY = 1 << 6,
+ GlyphVerticalBearingAdvance = 1 << 7,
+ GlyphHasKerning = 1 << 8,
+
+ FontXMinBounds = 1 << 9,
+ FontYMinBounds = 1 << 10,
+ FontXMaxBounds = 1 << 11,
+ FontYMaxBounds = 1 << 12,
+ FontUnitsPerEm = 1 << 13,
+ FontAscender = 1 << 14,
+ FontDescender = 1 << 15,
+ FontHeight = 1 << 16,
+ FontMaxAdvanceWidth = 1 << 17,
+ FontMaxAdvanceHeight = 1 << 18,
+ FontUnderlinePosition = 1 << 19,
+ FontUnderlineThickness = 1 << 20,
+ FontHasKerning = 1 << 21,
+ FontNumGlyphIndices = 1 << 22,
+ };
+};
+
+typedef NVFlags<NVRenderPathGlyphFontMetricValues::Enum, QT3DSU32>
+NVRenderPathGlyphFontMetricFlags;
+
+struct NVRenderPathListMode
+{
+ enum Enum {
+ AccumAdjacentPairs = 1,
+ AdjacentPairs,
+ FirstToRest,
+ };
+};
+
+struct NVRenderPathFillMode
+{
+ enum Enum {
+ Fill = 1,
+ CountUp,
+ CountDown,
+ Invert,
+ };
+};
+
+struct NVRenderPathCoverMode
+{
+ enum Enum {
+ ConvexHull = 1,
+ BoundingBox,
+ BoundingBoxOfBoundingBox,
+ PathFillCover,
+ PathStrokeCover,
+ };
+};
+
+struct NVRenderPathTransformType
+{
+ enum Enum {
+ NoTransform = 0,
+ TranslateX,
+ TranslateY,
+ Translate2D,
+ Translate3D,
+ Affine2D,
+ Affine3D,
+ TransposeAffine2D,
+ TransposeAffine3D,
+ };
+};
+
+#define QT3DS_RENDER_ITERATE_WINDING \
+ QT3DS_RENDER_HANDLE_WINDING(Clockwise) \
+ QT3DS_RENDER_HANDLE_WINDING(CounterClockwise)
+
+struct NVRenderWinding
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_WINDING(x) x,
+ QT3DS_RENDER_ITERATE_WINDING
+#undef QT3DS_RENDER_HANDLE_WINDING
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_WINDING(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_WINDING
+ #undef QT3DS_RENDER_HANDLE_WINDING
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_RENDER_STATE \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(Blend) \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(CullFace) \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(DepthTest) \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(StencilTest) \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(ScissorTest) \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(DepthWrite) \
+ QT3DS_RENDER_HANDLE_RENDER_STATE(Multisample)
+
+struct NVRenderState
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) x,
+ QT3DS_RENDER_ITERATE_RENDER_STATE
+#undef QT3DS_RENDER_HANDLE_RENDER_STATE
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_RENDER_STATE(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_RENDER_STATE
+ #undef QT3DS_RENDER_HANDLE_RENDER_STATE
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_BLEND_FUNC \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(Zero) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(One) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcColor) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcColor) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(DstColor) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstColor) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(SrcAlpha) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusSrcAlpha) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(DstAlpha) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusDstAlpha) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantColor) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantColor) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(ConstantAlpha) \
+ QT3DS_RENDER_HANDLE_BLEND_FUNC(OneMinusConstantAlpha) \
+ QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(SrcAlphaSaturate)
+
+struct NVRenderSrcBlendFunc
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x,
+#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) x,
+ QT3DS_RENDER_ITERATE_BLEND_FUNC
+#undef QT3DS_RENDER_HANDLE_BLEND_FUNC
+#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC
+ };
+
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) \
+ case x: \
+ return #x;
+#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_BLEND_FUNC
+ #undef QT3DS_RENDER_HANDLE_BLEND_FUNC
+ #undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+struct NVRenderDstBlendFunc
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_BLEND_FUNC(x) x,
+#define QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC(x)
+ QT3DS_RENDER_ITERATE_BLEND_FUNC
+#undef QT3DS_RENDER_HANDLE_BLEND_FUNC
+#undef QT3DS_RENDER_HANDLE_SRC_BLEND_FUNC
+ };
+
+ static const char *toString(Enum value)
+ {
+ return NVRenderSrcBlendFunc::toString((NVRenderSrcBlendFunc::Enum)value);
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_BLEND_EQUATION \
+ QT3DS_RENDER_HANDLE_BLEND_EQUATION(Add) \
+ QT3DS_RENDER_HANDLE_BLEND_EQUATION(Subtract) \
+ QT3DS_RENDER_HANDLE_BLEND_EQUATION(ReverseSubtract) \
+ QT3DS_RENDER_HANDLE_BLEND_EQUATION(Overlay) \
+ QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorBurn) \
+ QT3DS_RENDER_HANDLE_BLEND_EQUATION(ColorDodge)
+
+struct NVRenderBlendEquation
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) x,
+ QT3DS_RENDER_ITERATE_BLEND_EQUATION
+#undef QT3DS_RENDER_HANDLE_BLEND_EQUATION
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_BLEND_EQUATION(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_BLEND_EQUATION
+ #undef QT3DS_RENDER_HANDLE_BLEND_EQUATION
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_FACES \
+ QT3DS_RENDER_HANDLE_FACES(Front) \
+ QT3DS_RENDER_HANDLE_FACES(Back) \
+ QT3DS_RENDER_HANDLE_FACES(FrontAndBack)
+
+struct NVRenderFaces
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_FACES(x) x,
+ QT3DS_RENDER_ITERATE_FACES
+#undef QT3DS_RENDER_HANDLE_FACES
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_FACES(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_FACES
+ #undef QT3DS_RENDER_HANDLE_FACES
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_READ_FACES \
+ QT3DS_RENDER_HANDLE_READ_FACES(Front) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Back) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color0) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color1) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color2) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color3) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color4) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color5) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color6) \
+ QT3DS_RENDER_HANDLE_READ_FACES(Color7)
+
+struct NVReadFaces
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_READ_FACES(x) x,
+ QT3DS_RENDER_ITERATE_READ_FACES
+#undef QT3DS_RENDER_HANDLE_READ_FACES
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_READ_FACES(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_READ_FACES
+ #undef QT3DS_RENDER_HANDLE_READ_FACES
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+struct NVRenderBoolOp
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_BOOL_OP(x) x,
+ QT3DS_RENDER_ITERATE_BOOL_OP
+#undef QT3DS_RENDER_HANDLE_BOOL_OP
+ };
+
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_BOOL_OP(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_BOOL_OP
+ #undef QT3DS_RENDER_HANDLE_BOOL_OP
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+#define QT3DS_RENDER_ITERATE_STENCIL_OP \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(Keep) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(Zero) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(Replace) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(Increment) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(IncrementWrap) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(Decrement) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(DecrementWrap) \
+ QT3DS_RENDER_HANDLE_STENCIL_OP(Invert)
+
+struct NVRenderStencilOp
+{
+ enum Enum {
+ Unknown = 0,
+#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) x,
+ QT3DS_RENDER_ITERATE_STENCIL_OP
+#undef QT3DS_RENDER_HANDLE_STENCIL_OP
+ };
+ static const char *toString(Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_STENCIL_OP(x) \
+ case x: \
+ return #x;
+ QT3DS_RENDER_ITERATE_STENCIL_OP
+ #undef QT3DS_RENDER_HANDLE_STENCIL_OP
+ default:
+ break;
+ }
+ return "Unknown";
+ }
+};
+
+struct NVRenderBlendFunctionArgument
+{
+ NVRenderSrcBlendFunc::Enum m_SrcRGB;
+ NVRenderDstBlendFunc::Enum m_DstRGB;
+ NVRenderSrcBlendFunc::Enum m_SrcAlpha;
+ NVRenderDstBlendFunc::Enum m_DstAlpha;
+
+ NVRenderBlendFunctionArgument(NVRenderSrcBlendFunc::Enum srcRGB,
+ NVRenderDstBlendFunc::Enum dstRGB,
+ NVRenderSrcBlendFunc::Enum srcAlpha,
+ NVRenderDstBlendFunc::Enum dstAlpha)
+ : m_SrcRGB(srcRGB)
+ , m_DstRGB(dstRGB)
+ , m_SrcAlpha(srcAlpha)
+ , m_DstAlpha(dstAlpha)
+ {
+ }
+
+ // Default blend system premultiplies values.
+ NVRenderBlendFunctionArgument()
+ : m_SrcRGB(NVRenderSrcBlendFunc::SrcAlpha)
+ , m_DstRGB(NVRenderDstBlendFunc::OneMinusSrcAlpha)
+ , m_SrcAlpha(NVRenderSrcBlendFunc::One)
+ , m_DstAlpha(NVRenderDstBlendFunc::OneMinusSrcAlpha)
+ {
+ }
+};
+
+struct NVRenderBlendEquationArgument
+{
+ NVRenderBlendEquation::Enum m_RGBEquation;
+ NVRenderBlendEquation::Enum m_AlphaEquation;
+
+ NVRenderBlendEquationArgument(NVRenderBlendEquation::Enum rgb,
+ NVRenderBlendEquation::Enum alpha)
+ : m_RGBEquation(rgb)
+ , m_AlphaEquation(alpha)
+ {
+ }
+ NVRenderBlendEquationArgument()
+ : m_RGBEquation(NVRenderBlendEquation::Add)
+ , m_AlphaEquation(NVRenderBlendEquation::Add)
+ {
+ }
+};
+
+struct NVRenderStencilOperationArgument
+{
+ NVRenderStencilOp::Enum m_StencilFail; // What happens when stencil test fails.
+ // These values assume the stencil passed
+ NVRenderStencilOp::Enum
+ m_DepthFail; // What happens when the stencil passes but depth test fail.
+ NVRenderStencilOp::Enum m_DepthPass; // What happens when the stencil and depth tests pass.
+
+ NVRenderStencilOperationArgument(NVRenderStencilOp::Enum fail,
+ NVRenderStencilOp::Enum depthFail,
+ NVRenderStencilOp::Enum depthPass)
+ : m_StencilFail(fail)
+ , m_DepthFail(depthFail)
+ , m_DepthPass(depthPass)
+ {
+ }
+ NVRenderStencilOperationArgument()
+ : m_StencilFail(NVRenderStencilOp::Keep)
+ , m_DepthFail(NVRenderStencilOp::Keep)
+ , m_DepthPass(NVRenderStencilOp::Keep)
+ {
+ }
+ NVRenderStencilOperationArgument(const NVRenderStencilOperationArgument &StencilOp)
+ : m_StencilFail(StencilOp.m_StencilFail)
+ , m_DepthFail(StencilOp.m_DepthFail)
+ , m_DepthPass(StencilOp.m_DepthPass)
+ {
+ }
+
+ NVRenderStencilOperationArgument &operator=(const NVRenderStencilOperationArgument &rhs)
+ {
+ // Check for self-assignment!
+ if (this == &rhs)
+ return *this;
+
+ m_StencilFail = rhs.m_StencilFail;
+ m_DepthFail = rhs.m_DepthFail;
+ m_DepthPass = rhs.m_DepthPass;
+
+ return *this;
+ }
+
+ bool operator==(const NVRenderStencilOperationArgument &other) const
+ {
+ return (m_StencilFail == other.m_StencilFail && m_DepthFail == other.m_DepthFail
+ && m_DepthPass == other.m_DepthPass);
+ }
+};
+
+// see glStencilFuncSeparate
+struct NVRenderStencilFunctionArgument
+{
+ NVRenderBoolOp::Enum m_Function;
+ QT3DSU32 m_ReferenceValue;
+ QT3DSU32 m_Mask;
+
+ NVRenderStencilFunctionArgument(NVRenderBoolOp::Enum function, QT3DSU32 referenceValue,
+ QT3DSU32 mask)
+ : m_Function(function)
+ , m_ReferenceValue(referenceValue)
+ , m_Mask(mask)
+ {
+ }
+ NVRenderStencilFunctionArgument()
+ : m_Function(NVRenderBoolOp::AlwaysTrue)
+ , m_ReferenceValue(0)
+ , m_Mask((QT3DSU32)-1)
+ {
+ }
+ NVRenderStencilFunctionArgument(const NVRenderStencilFunctionArgument &StencilFunc)
+ : m_Function(StencilFunc.m_Function)
+ , m_ReferenceValue(StencilFunc.m_ReferenceValue)
+ , m_Mask(StencilFunc.m_Mask)
+ {
+ }
+
+ NVRenderStencilFunctionArgument &operator=(const NVRenderStencilFunctionArgument &rhs)
+ {
+ // Check for self-assignment!
+ if (this == &rhs)
+ return *this;
+
+ m_Function = rhs.m_Function;
+ m_ReferenceValue = rhs.m_ReferenceValue;
+ m_Mask = rhs.m_Mask;
+
+ return *this;
+ }
+
+ bool operator==(const NVRenderStencilFunctionArgument &other) const
+ {
+ return (m_Function == other.m_Function && m_ReferenceValue == other.m_ReferenceValue
+ && m_Mask == other.m_Mask);
+ }
+};
+
+class NVRenderFrameBuffer;
+class NVRenderVertexBuffer;
+class NVRenderIndexBuffer;
+class NVRenderShaderProgram;
+class NVRenderProgramPipeline;
+class NVRenderTextureBase;
+class NVRenderTexture2D;
+class NVRenderTexture2DArray;
+class NVRenderTextureCube;
+class NVRenderImage2D;
+class NVRenderDataBuffer;
+class NVRenderAttribLayout;
+class NVRenderInputAssembler;
+
+typedef NVRenderFrameBuffer *NVRenderFrameBufferPtr;
+typedef NVRenderVertexBuffer *NVRenderVertexBufferPtr;
+typedef NVRenderIndexBuffer *NVRenderIndexBufferPtr;
+typedef NVRenderTexture2D *NVRenderTexture2DPtr;
+typedef NVRenderTexture2DPtr *NVRenderTexture2DHandle;
+typedef NVRenderTexture2DArray *NVRenderTexture2DArrayPtr;
+typedef NVRenderTextureCube *NVRenderTextureCubePtr;
+typedef NVRenderTextureCubePtr *NVRenderTextureCubeHandle;
+typedef NVRenderImage2D *NVRenderImage2DPtr;
+typedef NVRenderDataBuffer *NVRenderDataBufferPtr;
+typedef const char *NVRenderConstCharPtr;
+typedef bool QT3DSRenderBool;
+typedef NVRenderShaderProgram *NVRenderShaderProgramPtr;
+typedef NVDataRef<QT3DSU32> NVU32List;
+typedef NVDataRef<const char *> NVConstCharPtrList;
+
+template <typename TDataType>
+struct NVRenderRectT
+{
+ typedef TDataType TRectType;
+ TDataType m_X;
+ TDataType m_Y;
+ TDataType m_Width;
+ TDataType m_Height;
+ NVRenderRectT(TDataType x, TDataType y, TDataType w, TDataType h)
+ : m_X(x)
+ , m_Y(y)
+ , m_Width(w)
+ , m_Height(h)
+ {
+ }
+ NVRenderRectT()
+ : m_X(0)
+ , m_Y(0)
+ , m_Width(0)
+ , m_Height(0)
+ {
+ }
+ bool operator==(const NVRenderRectT<TDataType> &inOther) const
+ {
+ return m_X == inOther.m_X && m_Y == inOther.m_Y && m_Width == inOther.m_Width
+ && m_Height == inOther.m_Height;
+ }
+ bool operator!=(const NVRenderRectT<TDataType> &inOther) const
+ {
+ return !(*this == inOther);
+ }
+ TDataType GetRightExtent() const { return m_X + m_Width; }
+ TDataType GetBottomExtent() const { return m_Y + m_Height; }
+ // Ensure this rect is inside the bounds of the other rect
+ void EnsureInBounds(const NVRenderRectT<TDataType> &inOther)
+ {
+ TDataType rightExtent = qt3ds::NVMin(GetRightExtent(), inOther.GetRightExtent());
+ TDataType bottomExtent = qt3ds::NVMin(GetBottomExtent(), inOther.GetBottomExtent());
+ m_X = qt3ds::NVMax(m_X, inOther.m_X);
+ m_Y = qt3ds::NVMax(m_Y, inOther.m_Y);
+ m_Width = NVMax(static_cast<TDataType>(0), rightExtent - m_X);
+ m_Height = NVMax(static_cast<TDataType>(0), bottomExtent - m_Y);
+ }
+};
+
+// Render rects are setup to be in the coordinate space of the gl viewport,
+// so x, y are left, bottom with increasing units going to the right and
+// up respectively.
+struct NVRenderRect : public NVRenderRectT<QT3DSI32>
+{
+ typedef NVRenderRectT<QT3DSI32> TBase;
+ NVRenderRect(QT3DSI32 x, QT3DSI32 y, QT3DSI32 w, QT3DSI32 h)
+ : TBase(x, y, w, h)
+ {
+ }
+ NVRenderRect()
+ : TBase()
+ {
+ }
+};
+
+struct NVRenderRectF : public NVRenderRectT<QT3DSF32>
+{
+ typedef NVRenderRectT<QT3DSF32> TBase;
+ NVRenderRectF(QT3DSF32 x, QT3DSF32 y, QT3DSF32 w, QT3DSF32 h)
+ : TBase(x, y, w, h)
+ {
+ }
+ NVRenderRectF()
+ : TBase()
+ {
+ }
+ NVRenderRectF(const NVRenderRect &inRect)
+ : TBase((QT3DSF32)inRect.m_X, (QT3DSF32)inRect.m_Y, (QT3DSF32)inRect.m_Width,
+ (QT3DSF32)inRect.m_Height)
+ {
+ }
+ NVRenderRect ToIntegerRect() const
+ {
+ return NVRenderRect((QT3DSI32)m_X, (QT3DSI32)m_Y, (QT3DSU32)(m_Width + .5f),
+ (QT3DSU32)(m_Height + .5f));
+ }
+ QT3DSVec2 BottomLeft() const { return QT3DSVec2(m_X, m_Y); }
+ QT3DSVec2 Center() const
+ {
+ QT3DSVec2 halfDims = HalfDims();
+ return QT3DSVec2(m_X + halfDims.x, m_Y + halfDims.y);
+ }
+ QT3DSVec2 HalfDims() const { return QT3DSVec2(m_Width / 2.0f, m_Height / 2.0f); }
+ // Normalized coordinates are in the range of -1,1 where -1 is the left, bottom edges
+ // and 1 is the top,right edges.
+ QT3DSVec2 AbsoluteToNormalizedCoordinates(QT3DSVec2 absoluteCoordinates) const
+ {
+ QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates));
+ return RelativeToNormalizedCoordinates(relativeCoords);
+ };
+
+ QT3DSVec2 RelativeToNormalizedCoordinates(QT3DSVec2 rectRelativeCoords) const
+ {
+ QT3DSVec2 halfDims(HalfDims());
+ QT3DSVec2 retval((rectRelativeCoords.x / halfDims.x) - 1.0f,
+ (rectRelativeCoords.y / halfDims.y) - 1.0f);
+ return retval;
+ }
+
+ // Take coordinates in global space and move local space where 0,0 is the center
+ // of the rect but return value in pixels, not in normalized -1,1 range
+ QT3DSVec2 ToNormalizedRectRelative(QT3DSVec2 absoluteCoordinates) const
+ {
+ // normalize them
+ QT3DSVec2 relativeCoords(ToRectRelative(absoluteCoordinates));
+ QT3DSVec2 halfDims(HalfDims());
+ QT3DSVec2 normalized((relativeCoords.x / halfDims.x) - 1.0f,
+ (relativeCoords.y / halfDims.y) - 1.0f);
+ return QT3DSVec2(normalized.x * halfDims.x, normalized.y * halfDims.y);
+ }
+
+ // Return coordinates in pixels but relative to this rect.
+ QT3DSVec2 ToRectRelative(QT3DSVec2 absoluteCoordinates) const
+ {
+ return QT3DSVec2(absoluteCoordinates.x - m_X, absoluteCoordinates.y - m_Y);
+ }
+
+ QT3DSVec2 ToAbsoluteCoords(QT3DSVec2 inRelativeCoords) const
+ {
+ return QT3DSVec2(inRelativeCoords.x + m_X, inRelativeCoords.y + m_Y);
+ }
+};
+
+template <typename TDataType>
+struct NVRenderGenericVec2
+{
+ TDataType x;
+ TDataType y;
+ NVRenderGenericVec2(TDataType _x, TDataType _y)
+ : x(_x)
+ , y(_y)
+ {
+ }
+ NVRenderGenericVec2() {}
+ bool operator==(const NVRenderGenericVec2 &inOther) const
+ {
+ return x == inOther.x && y == inOther.y;
+ }
+};
+
+template <typename TDataType>
+struct NVRenderGenericVec3
+{
+ TDataType x;
+ TDataType y;
+ TDataType z;
+ NVRenderGenericVec3(TDataType _x, TDataType _y, TDataType _z)
+ : x(_x)
+ , y(_y)
+ , z(_z)
+ {
+ }
+ NVRenderGenericVec3() {}
+ bool operator==(const NVRenderGenericVec3 &inOther) const
+ {
+ return x == inOther.x && y == inOther.y && z == inOther.z;
+ }
+};
+
+template <typename TDataType>
+struct NVRenderGenericVec4
+{
+ TDataType x;
+ TDataType y;
+ TDataType z;
+ TDataType w;
+ NVRenderGenericVec4(TDataType _x, TDataType _y, TDataType _z, TDataType _w)
+ : x(_x)
+ , y(_y)
+ , z(_z)
+ , w(_w)
+ {
+ }
+ NVRenderGenericVec4() {}
+ bool operator==(const NVRenderGenericVec4 &inOther) const
+ {
+ return x == inOther.x && y == inOther.y && z == inOther.z && w == inOther.w;
+ }
+};
+
+#define DECLARE_GENERIC_VECTOR_TYPE(type, numElems) \
+ typedef NVRenderGenericVec##numElems<type> type##_##numElems
+DECLARE_GENERIC_VECTOR_TYPE(bool, 2);
+DECLARE_GENERIC_VECTOR_TYPE(bool, 3);
+DECLARE_GENERIC_VECTOR_TYPE(bool, 4);
+DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 2);
+DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 3);
+DECLARE_GENERIC_VECTOR_TYPE(QT3DSU32, 4);
+DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 2);
+DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 3);
+DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 4);
+
+#define ITERATE_QT3DS_SHADER_DATA_TYPES \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_2) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_3) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSI32_4) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSRenderBool) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(bool_2) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(bool_3) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(bool_4) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSF32) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec2) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec3) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSVec4) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_2) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_3) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSU32_4) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat33) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat44) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DPtr) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DHandle) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DArrayPtr) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubePtr) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubeHandle) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderImage2DPtr) \
+ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderDataBufferPtr)
+
+struct NVRenderShaderDataTypes
+{
+ enum Enum {
+ Unknown = 0,
+#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) type,
+ ITERATE_QT3DS_SHADER_DATA_TYPES
+#undef HANDLE_QT3DS_SHADER_DATA_TYPE
+ };
+};
+
+template <typename TDataType>
+struct NVDataTypeToShaderDataTypeMap
+{
+};
+
+#define HANDLE_QT3DS_SHADER_DATA_TYPE(type) \
+ template <> \
+ struct NVDataTypeToShaderDataTypeMap<type> \
+{ \
+ static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::type; } \
+};
+ITERATE_QT3DS_SHADER_DATA_TYPES
+#undef HANDLE_QT3DS_SHADER_DATA_TYPE
+
+template <>
+struct NVDataTypeToShaderDataTypeMap<NVConstDataRef<QT3DSMat44>>
+{
+ static NVRenderShaderDataTypes::Enum GetType() { return NVRenderShaderDataTypes::QT3DSMat44; }
+};
+
+struct NVRenderShaderTypeValue
+{
+ enum Enum {
+ Unknown = 1 << 0,
+ Vertex = 1 << 1,
+ Fragment = 1 << 2,
+ TessControl = 1 << 3,
+ TessEvaluation = 1 << 4,
+ Geometry = 1 << 5
+ };
+};
+
+typedef NVFlags<NVRenderShaderTypeValue::Enum, QT3DSU32> NVRenderShaderTypeFlags;
+
+struct NVRenderTextureTypeValue
+{
+ enum Enum {
+ Unknown = 0,
+ Diffuse,
+ Specular,
+ Environment,
+ Bump,
+ Normal,
+ Displace,
+ Emissive,
+ Emissive2,
+ Anisotropy,
+ Translucent,
+ LightmapIndirect,
+ LightmapRadiosity,
+ LightmapShadow
+ };
+
+ static const char *toString(NVRenderTextureTypeValue::Enum value)
+ {
+ switch (value) {
+ case Unknown:
+ return "Unknown";
+ case Diffuse:
+ return "Diffuse";
+ case Specular:
+ return "Specular";
+ case Environment:
+ return "Environment";
+ case Bump:
+ return "Bump";
+ case Normal:
+ return "Normal";
+ case Displace:
+ return "Displace";
+ case Emissive:
+ return "Emissive";
+ case Emissive2:
+ return "Emissive2";
+ case Anisotropy:
+ return "Anisotropy";
+ case Translucent:
+ return "Translucent";
+ case LightmapIndirect:
+ return "LightmapIndirect";
+ case LightmapRadiosity:
+ return "LightmapRadiosity";
+ case LightmapShadow:
+ return "LightmapShadow";
+ default:
+ return "Unknown";
+ }
+ }
+};
+
+#define ITERATE_QT3DS_READ_PIXEL_FORMATS \
+ HANDLE_QT3DS_READ_PIXEL_FORMAT(Alpha8) \
+ HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB565) \
+ HANDLE_QT3DS_READ_PIXEL_FORMAT(RGB8) \
+ HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA4444) \
+ HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA5551) \
+ HANDLE_QT3DS_READ_PIXEL_FORMAT(RGBA8)
+
+struct NVRenderReadPixelFormats
+{
+ enum Enum {
+ Unknown = 0,
+#define HANDLE_QT3DS_READ_PIXEL_FORMAT(format) format,
+ ITERATE_QT3DS_READ_PIXEL_FORMATS
+#undef HANDLE_QT3DS_READ_PIXEL_FORMAT
+ };
+};
+
+// Now for scoped property access.
+template <typename TBaseType, typename TDataType>
+struct NVRenderGenericScopedProperty
+{
+ typedef void (TBaseType::*TSetter)(TDataType inType);
+ typedef TDataType (TBaseType::*TGetter)() const;
+
+ TBaseType &m_Context;
+ TSetter m_Setter;
+ TDataType m_InitialValue;
+ NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter)
+ : m_Context(ctx)
+ , m_Setter(setter)
+ , m_InitialValue(((ctx).*getter)())
+ {
+ }
+ NVRenderGenericScopedProperty(TBaseType &ctx, TGetter getter, TSetter setter,
+ const TDataType &inNewValue)
+ : m_Context(ctx)
+ , m_Setter(setter)
+ , m_InitialValue(((ctx).*getter)())
+ {
+ ((m_Context).*m_Setter)(inNewValue);
+ }
+ ~NVRenderGenericScopedProperty() { ((m_Context).*m_Setter)(m_InitialValue); }
+};
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp b/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp
new file mode 100644
index 00000000..01aef473
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderComputeShader.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderComputeShader.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderComputeShader::NVRenderComputeShader(NVRenderContextImpl &context,
+ NVFoundationBase &fnd, NVConstDataRef<QT3DSI8> source,
+ bool binaryProgram)
+ : NVRenderShader(context, fnd, source, binaryProgram)
+ , m_ShaderHandle(NULL)
+ {
+ m_ShaderHandle = m_Backend->CreateComputeShader(source, m_ErrorMessage, binaryProgram);
+ }
+
+ NVRenderComputeShader::~NVRenderComputeShader()
+ {
+ if (m_ShaderHandle) {
+ m_Backend->ReleaseComputeShader(m_ShaderHandle);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderComputeShader.h b/src/Runtime/Source/render/Qt3DSRenderComputeShader.h
new file mode 100644
index 00000000..1ab36bc0
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderComputeShader.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_COMPUTE_SHADER_H
+#define QT3DS_RENDER_COMPUTE_SHADER_H
+
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderShader.h"
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ ///< This class represents a compute shader
+ class NVRenderComputeShader : public NVRenderShader
+ {
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] source Pointer to shader source code
+ * @param[in] binaryProgram true if this is a binary program
+ *
+ * @return No return.
+ */
+ NVRenderComputeShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram);
+
+ /// @brief destructor
+ ~NVRenderComputeShader();
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ bool IsValid() override { return (m_ShaderHandle != NULL); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendComputeShaderObject GetShaderHandle()
+ {
+ return m_ShaderHandle;
+ }
+
+ private:
+ NVRenderBackend::NVRenderBackendComputeShaderObject
+ m_ShaderHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp
new file mode 100644
index 00000000..1b3c43a9
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.cpp
@@ -0,0 +1,421 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderConstantBuffer.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+namespace qt3ds {
+namespace render {
+
+ ///< struct handling a constant buffer entry
+ class ConstantBufferParamEntry
+ {
+ public:
+ CRegisteredString m_Name; ///< parameter Name
+ NVRenderShaderDataTypes::Enum m_Type; ///< parameter type
+ QT3DSI32 m_Count; ///< one or array size
+ QT3DSI32 m_Offset; ///< offset into the memory buffer
+
+ ConstantBufferParamEntry(CRegisteredString name, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 count, QT3DSI32 offset)
+ : m_Name(name)
+ , m_Type(type)
+ , m_Count(count)
+ , m_Offset(offset)
+ {
+ }
+ };
+
+ NVRenderConstantBuffer::NVRenderConstantBuffer(NVRenderContextImpl &context,
+ CRegisteredString bufferName, size_t size,
+ NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data)
+ : NVRenderDataBuffer(context, context.GetFoundation(), size,
+ NVRenderBufferBindValues::Constant, usageType, NVDataRef<QT3DSU8>())
+ , m_Name(bufferName)
+ , m_ConstantBufferEntryMap(m_Foundation.getAllocator(),
+ "NVRenderConstantBuffer::m_ConstantBufferEntryMap")
+ , m_CurrentOffset(0)
+ , m_CurrentSize(0)
+ , m_HWBufferInitialized(false)
+ , m_Dirty(true)
+ , m_RangeStart(0)
+ , m_RangeEnd(0)
+ , m_MaxBlockSize(0)
+ {
+ QT3DS_ASSERT(context.GetConstantBufferSupport());
+
+ m_Backend->GetRenderBackendValue(
+ NVRenderBackend::NVRenderBackendQuery::MaxConstantBufferBlockSize, &m_MaxBlockSize);
+
+ if (size && data.size() && size == data.size()) {
+ QT3DS_ASSERT(size < (QT3DSU32)m_MaxBlockSize);
+ if (allocateShadowBuffer(data.size())) {
+ memcpy(m_ShadowCopy.begin(), data.begin(), data.size());
+ }
+ }
+ }
+
+ NVRenderConstantBuffer::~NVRenderConstantBuffer()
+ {
+ // check if we should release memory
+ if (m_ShadowCopy.size()) {
+ m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin());
+ }
+
+ m_ShadowCopy = NVDataRef<QT3DSU8>();
+
+ for (TRenderConstantBufferEntryMap::iterator iter = m_ConstantBufferEntryMap.begin(),
+ end = m_ConstantBufferEntryMap.end();
+ iter != end; ++iter) {
+ NVDelete(m_Foundation.getAllocator(), iter->second);
+ }
+
+ m_ConstantBufferEntryMap.clear();
+
+ m_Context.BufferDestroyed(*this);
+ }
+
+ void NVRenderConstantBuffer::Bind()
+ {
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ m_Backend->BindBuffer(m_BufferHandle, m_BindFlags);
+ }
+
+ void NVRenderConstantBuffer::BindToShaderProgram(NVRenderShaderProgram *inShader,
+ QT3DSU32 blockIndex, QT3DSU32 binding)
+ {
+ if ((QT3DSI32)binding == -1) {
+ binding = m_Context.GetNextConstantBufferUnit();
+ m_Backend->ProgramSetConstantBlock(inShader->GetShaderProgramHandle(), blockIndex,
+ binding);
+ }
+
+ m_Backend->ProgramSetConstantBuffer(binding, m_BufferHandle);
+ }
+
+ bool NVRenderConstantBuffer::SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index,
+ QT3DSI32 bufSize, QT3DSI32 paramCount)
+ {
+ bool bSuccess = false;
+
+ if (!m_HWBufferInitialized) {
+ // allocate shadow buffer
+ QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate(
+ bufSize, "NVRenderConstantBuffer", __FILE__, __LINE__);
+ if (!newMem)
+ return false;
+
+ // allocate temp buffers to hold constant buffer information
+ QT3DSI32 *theIndices = NULL, *theTypes = NULL, *theSizes = NULL, *theOffsets = NULL;
+ theIndices = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32),
+ "NVRenderConstantBuffer");
+ if (!theIndices)
+ goto fail;
+ theTypes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32),
+ "NVRenderConstantBuffer");
+ if (!theTypes)
+ goto fail;
+ theSizes = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32),
+ "NVRenderConstantBuffer");
+ if (!theSizes)
+ goto fail;
+ theOffsets = (QT3DSI32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), paramCount * sizeof(QT3DSI32),
+ "NVRenderConstantBuffer");
+ if (!theOffsets)
+ goto fail;
+
+ bSuccess = true;
+
+ // get indices for the individal constant buffer entries
+ m_Backend->GetConstantBufferParamIndices(pProgram->GetShaderProgramHandle(), index,
+ theIndices);
+
+ // get constant buffer uniform information
+ m_Backend->GetConstantBufferParamInfoByIndices(pProgram->GetShaderProgramHandle(),
+ paramCount, (QT3DSU32 *)theIndices,
+ theTypes, theSizes, theOffsets);
+
+ // get the names of the uniforms
+ char nameBuf[512];
+ QT3DSI32 elementCount, binding;
+ NVRenderShaderDataTypes::Enum type;
+
+ QT3DS_FOREACH(idx, paramCount)
+ {
+ m_Backend->GetConstantInfoByID(pProgram->GetShaderProgramHandle(), theIndices[idx],
+ 512, &elementCount, &type, &binding, nameBuf);
+ // check if we already have this entry
+ CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf));
+ TRenderConstantBufferEntryMap::iterator entry =
+ m_ConstantBufferEntryMap.find(theName);
+ if (entry != m_ConstantBufferEntryMap.end()) {
+ ConstantBufferParamEntry *pParam = entry->second;
+ // copy content
+ if (m_ShadowCopy.size())
+ memcpy(newMem + theOffsets[idx],
+ m_ShadowCopy.begin() + entry->second->m_Offset,
+ entry->second->m_Count * getUniformTypeSize(pParam->m_Type));
+
+ pParam->m_Offset = theOffsets[idx];
+ QT3DS_ASSERT(type == pParam->m_Type);
+ QT3DS_ASSERT(elementCount == pParam->m_Count);
+ } else {
+ // create one
+ m_ConstantBufferEntryMap.insert(eastl::make_pair(
+ theName,
+ createParamEntry(theName, (NVRenderShaderDataTypes::Enum)theTypes[idx],
+ theSizes[idx], theOffsets[idx])));
+ }
+ }
+
+ // release previous one
+ if (m_ShadowCopy.size()) {
+ m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin());
+ }
+ // set new one
+ m_ShadowCopy = NVDataRef<QT3DSU8>(newMem, bufSize);
+
+ m_HWBufferInitialized = true;
+
+ fail:
+ if (theIndices)
+ QT3DS_FREE(m_Foundation.getAllocator(), theIndices);
+ if (theTypes)
+ QT3DS_FREE(m_Foundation.getAllocator(), theTypes);
+ if (theSizes)
+ QT3DS_FREE(m_Foundation.getAllocator(), theSizes);
+ if (theOffsets)
+ QT3DS_FREE(m_Foundation.getAllocator(), theOffsets);
+
+ } else {
+ // some sanity checks
+ bSuccess = true;
+ bSuccess &= (m_ShadowCopy.size() <= (QT3DSU32)bufSize);
+ }
+
+ return bSuccess;
+ }
+
+ void NVRenderConstantBuffer::Update()
+ {
+ // we only update the buffer if the buffer is already on hardware
+ // and if it is dirty
+ if (m_Dirty && m_HWBufferInitialized) {
+ if (m_RangeEnd == 0)
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_ShadowCopy.size(),
+ m_UsageType, m_ShadowCopy.begin());
+ else
+ UpdateRange();
+
+ m_Dirty = false;
+ m_RangeStart = m_RangeEnd = 0;
+ }
+ }
+
+ void NVRenderConstantBuffer::UpdateRange()
+ {
+ if ((m_RangeStart + m_RangeEnd) > m_ShadowCopy.size()) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ m_Backend->UpdateBufferRange(m_BufferHandle, m_BindFlags, m_RangeStart,
+ m_RangeEnd - m_RangeStart,
+ m_ShadowCopy.begin() + m_RangeStart);
+ }
+
+ void NVRenderConstantBuffer::AddParam(CRegisteredString name,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count)
+ {
+ if (m_ConstantBufferEntryMap.find(name) == m_ConstantBufferEntryMap.end()) {
+ ConstantBufferParamEntry *newEntry =
+ QT3DS_NEW(m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count,
+ m_CurrentOffset);
+
+ if (newEntry)
+ m_ConstantBufferEntryMap.insert(eastl::make_pair(name, newEntry));
+ } else {
+ // no duplicated entries
+ return;
+ }
+
+ // compute new current buffer size and offset
+ QT3DSI32 constantSize = getUniformTypeSize(type) * count;
+ m_CurrentSize += constantSize;
+ m_CurrentOffset += constantSize;
+ }
+
+ void NVRenderConstantBuffer::UpdateParam(const char *inName, NVDataRef<QT3DSU8> value)
+ {
+ // allocate space if not done yet
+ // NOTE this gets reallocated once we get the real constant buffer size from a program
+ if (!m_ShadowCopy.size()) {
+ // allocate shadow buffer
+ if (!allocateShadowBuffer(m_CurrentSize))
+ return;
+ }
+
+ CRegisteredString theName(m_Context.GetStringTable().RegisterStr(inName));
+ TRenderConstantBufferEntryMap::iterator entry = m_ConstantBufferEntryMap.find(theName);
+ if (entry != m_ConstantBufferEntryMap.end()) {
+ if (!memcmp(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(),
+ entry->second->m_Count * getUniformTypeSize(entry->second->m_Type))) {
+ return;
+ }
+ memcpy(m_ShadowCopy.begin() + entry->second->m_Offset, value.begin(),
+ entry->second->m_Count * getUniformTypeSize(entry->second->m_Type));
+ m_Dirty = true;
+ }
+ }
+
+ void NVRenderConstantBuffer::UpdateRaw(QT3DSI32 offset, NVDataRef<QT3DSU8> data)
+ {
+ // allocate space if yet done
+ if (!m_ShadowCopy.size()) {
+ // allocate shadow buffer
+ if (!allocateShadowBuffer(data.size()))
+ return;
+ }
+
+ QT3DS_ASSERT((offset + data.size()) < (QT3DSU32)m_MaxBlockSize);
+
+ // we do not initialize anything when this is used
+ m_HWBufferInitialized = true;
+
+ // we do not allow resize once allocated
+ if ((offset + data.size()) > m_ShadowCopy.size())
+ return;
+
+ // copy data
+ if (!memcmp(m_ShadowCopy.begin() + offset, data.begin(), data.size())) {
+ return;
+ }
+ memcpy(m_ShadowCopy.begin() + offset, data.begin(), data.size());
+
+ // update start
+ m_RangeStart = (m_Dirty) ? (m_RangeStart > (QT3DSU32)offset) ? offset : m_RangeStart : offset;
+ m_RangeEnd = (offset + data.size() > m_RangeEnd) ? offset + data.size() : m_RangeEnd;
+
+ m_Dirty = true;
+ }
+
+ ConstantBufferParamEntry *NVRenderConstantBuffer::createParamEntry(
+ CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count, QT3DSI32 offset)
+ {
+ ConstantBufferParamEntry *newEntry = QT3DS_NEW(
+ m_Foundation.getAllocator(), ConstantBufferParamEntry)(name, type, count, offset);
+
+ return newEntry;
+ }
+
+ QT3DSI32
+ NVRenderConstantBuffer::getUniformTypeSize(NVRenderShaderDataTypes::Enum type)
+ {
+ switch (type) {
+ case NVRenderShaderDataTypes::QT3DSF32:
+ return sizeof(QT3DSF32);
+ case NVRenderShaderDataTypes::QT3DSI32:
+ return sizeof(QT3DSI32);
+ case NVRenderShaderDataTypes::QT3DSI32_2:
+ return sizeof(QT3DSI32) * 2;
+ case NVRenderShaderDataTypes::QT3DSI32_3:
+ return sizeof(QT3DSI32) * 3;
+ case NVRenderShaderDataTypes::QT3DSI32_4:
+ return sizeof(QT3DSI32) * 4;
+ case NVRenderShaderDataTypes::QT3DSU32:
+ return sizeof(QT3DSU32);
+ case NVRenderShaderDataTypes::QT3DSU32_2:
+ return sizeof(QT3DSU32) * 2;
+ case NVRenderShaderDataTypes::QT3DSU32_3:
+ return sizeof(QT3DSU32) * 3;
+ case NVRenderShaderDataTypes::QT3DSU32_4:
+ return sizeof(QT3DSU32) * 4;
+ case NVRenderShaderDataTypes::QT3DSVec2:
+ return sizeof(QT3DSF32) * 2;
+ case NVRenderShaderDataTypes::QT3DSVec3:
+ return sizeof(QT3DSF32) * 3;
+ case NVRenderShaderDataTypes::QT3DSVec4:
+ return sizeof(QT3DSF32) * 4;
+ case NVRenderShaderDataTypes::QT3DSMat33:
+ return sizeof(QT3DSF32) * 9;
+ case NVRenderShaderDataTypes::QT3DSMat44:
+ return sizeof(QT3DSF32) * 16;
+ default:
+ QT3DS_ASSERT(!"Unhandled type in NVRenderConstantBuffer::getUniformTypeSize");
+ break;
+ }
+
+ return 0;
+ }
+
+ bool NVRenderConstantBuffer::allocateShadowBuffer(QT3DSU32 size)
+ {
+ // allocate shadow buffer
+ QT3DSU8 *newMem = (QT3DSU8 *)m_Foundation.getAllocator().allocate(size, "NVRenderConstantBuffer",
+ __FILE__, __LINE__);
+ if (!newMem)
+ return false;
+
+ m_ShadowCopy = NVDataRef<QT3DSU8>(newMem, size);
+
+ m_BufferCapacity = size;
+
+ return true;
+ }
+
+ NVRenderConstantBuffer *NVRenderConstantBuffer::Create(NVRenderContextImpl &context,
+ const char *bufferName,
+ NVRenderBufferUsageType::Enum usageType,
+ size_t size,
+ NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVFoundationBase &fnd(context.GetFoundation());
+ NVRenderConstantBuffer *retval = NULL;
+
+ if (context.GetConstantBufferSupport()) {
+ CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName));
+ QT3DSU32 cbufSize = sizeof(NVRenderConstantBuffer);
+ QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "ConstantBuffer");
+ retval = new (newMem) NVRenderConstantBuffer(
+ context, theBufferName, size, usageType,
+ toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()));
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h
new file mode 100644
index 00000000..5ede23b9
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderConstantBuffer.h
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_CONSTANT_BUFFER_H
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Utils.h"
+#include "foundation/StringTable.h"
+#include "render/Qt3DSRenderDataBuffer.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ // forward declaration
+ class NVRenderContextImpl;
+ class ConstantBufferParamEntry;
+ class NVRenderShaderProgram;
+
+ typedef nvhash_map<CRegisteredString, ConstantBufferParamEntry *> TRenderConstantBufferEntryMap;
+
+ ///< Constant (uniform) buffer representation
+ class QT3DS_AUTOTEST_EXPORT NVRenderConstantBuffer : public NVRenderDataBuffer
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] bufferName Name of the buffer. Must match the name used in programs
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return.
+ */
+ NVRenderConstantBuffer(NVRenderContextImpl &context, CRegisteredString bufferName,
+ size_t size, NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data);
+
+ ///< destructor
+ virtual ~NVRenderConstantBuffer();
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief bind the buffer to a shader program
+ *
+ * @param[in] inShader Pointer to active program
+ * @param[in] blockIndex Index of the constant block within the program
+ * @param[in] binding Binding point of constant buffer
+ *
+ * @return no return.
+ */
+ virtual void BindToShaderProgram(NVRenderShaderProgram *inShader, QT3DSU32 blockIndex,
+ QT3DSU32 binding);
+
+ /**
+ * @brief update the buffer to hardware
+ *
+ * @return no return.
+ */
+ virtual void Update();
+
+ /**
+ * @brief setup constant buffer
+ *
+ * @param[in] pProgram Pointer to the shader program
+ * @param[in] index Index of the constant buffer within the program
+ * @param[in] bufSize Size of the constant buffer
+ * @param[in] paramCount Parameter entry count of the constant buffer
+ *
+ * @return return if successful
+ */
+ bool SetupBuffer(NVRenderShaderProgram *pProgram, QT3DSI32 index, QT3DSI32 bufSize,
+ QT3DSI32 paramCount);
+
+ /**
+ * @brief add a parameter to the constant buffer
+ *
+ * @param[in] name Name of the parameter (must match the name in the shader
+ * program)
+ * @param[in] type Type of the parameter like Mat44
+ * @param[in] count One or size of array
+ *
+ * @return no return
+ */
+ void AddParam(CRegisteredString name, NVRenderShaderDataTypes::Enum type, QT3DSI32 count);
+
+ /**
+ * @brief update a parameter in the constant buffer
+ *
+ * @param[in] name Name of the parameter (must match the name in the shader
+ * program)
+ * @param[in] value New value
+ *
+ * @return no return
+ */
+ void UpdateParam(const char *name, NVDataRef<QT3DSU8> value);
+
+ /**
+ * @brief update a piece of memory directly within the constant buffer
+ *
+ * Note: When you use this function you should know what you are doing.
+ * The memory layout within C++ must exactly match the memory layout in the
+ *shader.
+ * We use std140 layout which guarantees a specific layout behavior across all
+ *HW vendors.
+ * How the memory layout is computed can be found in the GL spec.
+ *
+ * @param[in] offset offset into constant buffer
+ * @param[in] data pointer to new data
+ *
+ * @return no return
+ */
+ void UpdateRaw(QT3DSI32 offset, NVDataRef<QT3DSU8> data);
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+
+ /**
+ * @brief create a NVRenderConstantBuffer object
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return the backend object handle.
+ */
+ static NVRenderConstantBuffer *Create(NVRenderContextImpl &context, const char *bufferName,
+ NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData);
+
+ /**
+ * @brief get the buffer name
+ *
+ * @return the buffer name
+ */
+ CRegisteredString GetBufferName() const { return m_Name; }
+
+ private:
+ /**
+ * @brief Create a parameter entry
+ *
+ * @param[in] name Name of the parameter (must match the name in the shader
+ * program)
+ * @param[in] type Type of the parameter like Mat44
+ * @param[in] count One or size of array
+ * @param[in] offset Offset of the parameter in the memory buffer
+ *
+ * @return return new Entry
+ */
+ ConstantBufferParamEntry *createParamEntry(CRegisteredString name,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count,
+ QT3DSI32 offset);
+
+ /**
+ * @brief get size of a uniform type
+ *
+ * @param[in] type type of uniform
+ *
+ * @return return uniform size
+ */
+ QT3DSI32
+ getUniformTypeSize(NVRenderShaderDataTypes::Enum type);
+
+ /**
+ * @brief allocate the shadow buffer
+ *
+ * @param[in] size size of buffer
+ *
+ * @return return true on success
+ */
+ bool allocateShadowBuffer(QT3DSU32 size);
+
+ /**
+ * @brief update a certain range of the buffer to hardware
+ *
+ * @return no return.
+ */
+ virtual void UpdateRange();
+
+ private:
+ CRegisteredString m_Name; ///< buffer name
+ TRenderConstantBufferEntryMap
+ m_ConstantBufferEntryMap; ///< holds the entries of a constant buffer
+ QT3DSU32 m_CurrentOffset; ///< holds the current offset
+ QT3DSU32 m_CurrentSize; ///< holds the current size
+ bool m_HWBufferInitialized; ///< true if the hardware version of the buffer is initialized
+ bool m_Dirty; ///< true if buffer is dirty
+ QT3DSU32 m_RangeStart; ///< start offset of the range to update
+ QT3DSU32 m_RangeEnd; ///< size of the range to update
+ QT3DSI32 m_MaxBlockSize; ///< maximum size for a single constant buffer
+ NVDataRef<QT3DSU8> m_ShadowCopy; ///< host copy of the data in the GPU
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.cpp b/src/Runtime/Source/render/Qt3DSRenderContext.cpp
new file mode 100644
index 00000000..aa2cb30f
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderContext.cpp
@@ -0,0 +1,1107 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSMat44.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/Utils.h"
+#include "EASTL/set.h"
+#include "EASTL/utility.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+using namespace eastl;
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderContextImpl::NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend,
+ IStringTable &inStrTable)
+ : m_backend(inBackend)
+ , m_DirtyFlags(0)
+ , m_DefaultOffscreenRenderTarget((NVRenderBackend::NVRenderBackendRenderTargetObject)NULL)
+ , m_DephBits(16)
+ , m_StencilBits(8)
+ , mRefCount(0)
+ , m_Foundation(fnd)
+ , m_StringTable(inStrTable)
+ , m_VertToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_VertToImpMap")
+ , m_IndexToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_IndexToImpMap")
+ , m_ConstantToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ConstantToImpMap")
+ , m_StorageToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_StorageToImpMap")
+ , m_AtomicCounterToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_AtomicCounterToImpMap")
+ , m_DrawIndirectToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_DrawIndirectToImpMap")
+ , m_DepthStencilStateToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_DepthStencilStateToImpMap")
+ , m_RasterizerStateToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_RasterizerStateToImpMap")
+ , m_PathFontSpecToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_RasterizerStateToImpMap")
+ , m_Tex2DToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Tex2DToImpMap")
+ , m_Tex2DArrayToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_Tex2DArrayToImpMap")
+ , m_TexCubeToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_TexCubeToImpMap")
+ , m_Image2DtoImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_Image2DtoImpMap")
+ , m_ShaderToImpMap(m_Foundation.getAllocator(), "NVRenderContextImpl::m_ShaderToImpMap")
+ , m_RenderBufferToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_RenderBufferToImpMap")
+ , m_FrameBufferToImpMap(m_Foundation.getAllocator(),
+ "NVRenderContextImpl::m_FrameBufferToImpMap")
+ , m_NextTextureUnit(1)
+ , m_NextConstantBufferUnit(1)
+ , m_PropertyStack(m_Foundation.getAllocator(), "NVRenderContextImpl::m_PropertyStack")
+ {
+
+ m_StringTable.addRef();
+
+ m_MaxTextureUnits = m_backend->GetMaxCombinedTextureUnits();
+ m_MaxConstantBufferUnits = 16; // need backend query
+
+ // get initial state
+ memZero(&m_HardwarePropertyContext, sizeof(m_HardwarePropertyContext));
+
+ // get default blending functions
+ m_backend->GetBlendFunc(&m_HardwarePropertyContext.m_BlendFunction);
+ // set default blend euqation
+ m_HardwarePropertyContext.m_BlendEquation.m_RGBEquation = NVRenderBlendEquation::Add;
+ m_HardwarePropertyContext.m_BlendEquation.m_AlphaEquation = NVRenderBlendEquation::Add;
+ // default state
+ m_HardwarePropertyContext.m_CullingEnabled =
+ m_backend->GetRenderState(NVRenderState::CullFace);
+ m_HardwarePropertyContext.m_DepthFunction = m_backend->GetDepthFunc();
+ m_HardwarePropertyContext.m_BlendingEnabled =
+ m_backend->GetRenderState(NVRenderState::Blend);
+ m_HardwarePropertyContext.m_DepthWriteEnabled = m_backend->GetDepthWrite();
+ m_HardwarePropertyContext.m_DepthTestEnabled =
+ m_backend->GetRenderState(NVRenderState::DepthTest);
+ m_HardwarePropertyContext.m_ScissorTestEnabled =
+ m_backend->GetRenderState(NVRenderState::ScissorTest);
+ m_backend->GetScissorRect(&m_HardwarePropertyContext.m_ScissorRect);
+ m_backend->GetViewportRect(&m_HardwarePropertyContext.m_Viewport);
+
+ DoSetClearColor(m_HardwarePropertyContext.m_ClearColor);
+ }
+
+ NVRenderContextImpl::~NVRenderContextImpl()
+ {
+ m_StringTable.release();
+ QT3DS_ASSERT(m_VertToImpMap.size() == 0);
+ m_VertToImpMap.clear();
+ QT3DS_ASSERT(m_IndexToImpMap.size() == 0);
+ m_IndexToImpMap.clear();
+ QT3DS_ASSERT(m_ConstantToImpMap.size() == 0);
+ m_ConstantToImpMap.clear();
+ QT3DS_ASSERT(m_StorageToImpMap.size() == 0);
+ m_StorageToImpMap.clear();
+ QT3DS_ASSERT(m_DepthStencilStateToImpMap.size() == 0);
+ m_DepthStencilStateToImpMap.clear();
+ QT3DS_ASSERT(m_RasterizerStateToImpMap.size() == 0);
+ m_RasterizerStateToImpMap.clear();
+ QT3DS_ASSERT(m_PathFontSpecToImpMap.size() == 0);
+ m_PathFontSpecToImpMap.clear();
+ QT3DS_ASSERT(m_Tex2DToImpMap.size() == 0);
+ m_Tex2DToImpMap.clear();
+ QT3DS_ASSERT(m_Tex2DArrayToImpMap.size() == 0);
+ m_Tex2DArrayToImpMap.clear();
+ QT3DS_ASSERT(m_Image2DtoImpMap.size() == 0);
+ m_Image2DtoImpMap.clear();
+ QT3DS_ASSERT(m_ShaderToImpMap.size() == 0);
+ m_ShaderToImpMap.clear();
+ QT3DS_ASSERT(m_RenderBufferToImpMap.size() == 0);
+ m_RenderBufferToImpMap.clear();
+ QT3DS_ASSERT(m_FrameBufferToImpMap.size() == 0);
+ m_FrameBufferToImpMap.clear();
+
+ m_backend = NULL;
+ }
+
+ void NVRenderContextImpl::getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight)
+ {
+ QT3DSI32 theMaxTextureSize = 0;
+ m_backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize,
+ &theMaxTextureSize);
+
+ oWidth = (QT3DSU32)theMaxTextureSize;
+ oHeight = (QT3DSU32)theMaxTextureSize;
+ }
+
+ NVRenderDepthStencilState *NVRenderContextImpl::CreateDepthStencilState(
+ bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack)
+ {
+ NVRenderDepthStencilState *state = NVRenderDepthStencilState::Create(
+ *this, enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront,
+ stencilFuncBack, depthStencilOpFront, depthStencilOpBack);
+ if (state)
+ m_DepthStencilStateToImpMap.insert(
+ make_pair(state->GetDepthStencilObjectHandle(), state));
+
+ return state;
+ }
+
+ void NVRenderContextImpl::SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState)
+ {
+ if (inDepthStencilState) {
+ m_backend->SetDepthStencilState(inDepthStencilState->GetDepthStencilObjectHandle());
+ // currently we have a mixture therefore we need to update the context state
+ SetDepthFunction(inDepthStencilState->GetDepthFunc());
+ SetDepthWriteEnabled(inDepthStencilState->GetDepthMask());
+ SetDepthTestEnabled(inDepthStencilState->GetDepthEnabled());
+ SetStencilTestEnabled(inDepthStencilState->GetStencilEnabled());
+ }
+ }
+
+ void NVRenderContextImpl::StateDestroyed(NVRenderDepthStencilState &state)
+ {
+ m_DepthStencilStateToImpMap.erase(state.GetDepthStencilObjectHandle());
+ }
+
+ NVRenderRasterizerState *
+ NVRenderContextImpl::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale,
+ NVRenderFaces::Enum cullFace)
+ {
+ NVRenderRasterizerState *state =
+ NVRenderRasterizerState::Create(*this, depthBias, depthScale, cullFace);
+ if (state)
+ m_RasterizerStateToImpMap.insert(make_pair(state->GetRasterizerObjectHandle(), state));
+
+ return state;
+ }
+
+ void NVRenderContextImpl::SetRasterizerState(NVRenderRasterizerState *inRasterizerState)
+ {
+ if (inRasterizerState)
+ m_backend->SetRasterizerState(inRasterizerState->GetRasterizerObjectHandle());
+ }
+
+ void NVRenderContextImpl::StateDestroyed(NVRenderRasterizerState &state)
+ {
+ m_RasterizerStateToImpMap.erase(state.GetRasterizerObjectHandle());
+ }
+
+ NVRenderVertexBuffer *
+ NVRenderContextImpl::CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size,
+ QT3DSU32 stride, NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVRenderVertexBuffer *buffer =
+ NVRenderVertexBuffer::Create(*this, usageType, size, stride, bufferData);
+ if (buffer)
+ m_VertToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer));
+ return buffer;
+ }
+
+ NVRenderVertexBuffer *NVRenderContextImpl::GetVertexBuffer(const void *implementationHandle)
+ {
+ nvhash_map<const void *, NVRenderVertexBuffer *>::const_iterator entry =
+ m_VertToImpMap.find(implementationHandle);
+ if (entry != m_VertToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::BufferDestroyed(NVRenderVertexBuffer &buffer)
+ {
+ m_VertToImpMap.erase(buffer.GetImplementationHandle());
+ }
+
+ NVRenderIndexBuffer *
+ NVRenderContextImpl::CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType,
+ qt3ds::render::NVRenderComponentTypes::Enum componentType,
+ size_t size, NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVRenderIndexBuffer *buffer =
+ NVRenderIndexBuffer::Create(*this, usageType, componentType, size, bufferData);
+
+ if (buffer) {
+ m_IndexToImpMap.insert(make_pair(buffer->GetImplementationHandle(), buffer));
+ }
+
+ return buffer;
+ }
+
+ NVRenderIndexBuffer *NVRenderContextImpl::GetIndexBuffer(const void *implementationHandle)
+ {
+ const nvhash_map<const void *, NVRenderIndexBuffer *>::iterator entry =
+ m_IndexToImpMap.find(implementationHandle);
+ if (entry != m_IndexToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::BufferDestroyed(NVRenderIndexBuffer &buffer)
+ {
+ m_IndexToImpMap.erase(buffer.GetImplementationHandle());
+ }
+
+ NVRenderConstantBuffer *
+ NVRenderContextImpl::CreateConstantBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType,
+ size_t size, NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVRenderConstantBuffer *buffer =
+ NVRenderConstantBuffer::Create(*this, bufferName, usageType, size, bufferData);
+
+ if (buffer) {
+ m_ConstantToImpMap.insert(make_pair(buffer->GetBufferName(), buffer));
+ }
+
+ return buffer;
+ }
+
+ NVRenderConstantBuffer *NVRenderContextImpl::GetConstantBuffer(CRegisteredString bufferName)
+ {
+ TContextConstantBufferMap::iterator entry = m_ConstantToImpMap.find(bufferName);
+ if (entry != m_ConstantToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::BufferDestroyed(NVRenderConstantBuffer &buffer)
+ {
+ m_ConstantToImpMap.erase(buffer.GetBufferName());
+ }
+
+ QT3DSU32 NVRenderContextImpl::GetNextConstantBufferUnit()
+ {
+ QT3DSU32 retval = m_NextConstantBufferUnit;
+ ++m_NextConstantBufferUnit;
+ // Too many texture units for a single draw call.
+ if (retval >= m_MaxConstantBufferUnits) {
+ QT3DS_ASSERT(false);
+ retval = retval % m_MaxConstantBufferUnits;
+ }
+ return retval;
+ }
+
+ NVRenderStorageBuffer *NVRenderContextImpl::CreateStorageBuffer(
+ const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer)
+ {
+ NVRenderStorageBuffer *buffer =
+ NVRenderStorageBuffer::Create(*this, bufferName, usageType, size, bufferData, pBuffer);
+
+ if (buffer) {
+ m_StorageToImpMap.insert(make_pair(buffer->GetBufferName(), buffer));
+ }
+
+ return buffer;
+ }
+
+ NVRenderStorageBuffer *NVRenderContextImpl::GetStorageBuffer(CRegisteredString bufferName)
+ {
+ TContextStorageBufferMap::iterator entry = m_StorageToImpMap.find(bufferName);
+ if (entry != m_StorageToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::BufferDestroyed(NVRenderStorageBuffer &buffer)
+ {
+ m_StorageToImpMap.erase(buffer.GetBufferName());
+ }
+
+ NVRenderAtomicCounterBuffer *NVRenderContextImpl::CreateAtomicCounterBuffer(
+ const char *bufferName, qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVRenderAtomicCounterBuffer *buffer =
+ NVRenderAtomicCounterBuffer::Create(*this, bufferName, usageType, size, bufferData);
+
+ if (buffer) {
+ m_AtomicCounterToImpMap.insert(make_pair(buffer->GetBufferName(), buffer));
+ }
+
+ return buffer;
+ }
+
+ NVRenderAtomicCounterBuffer *
+ NVRenderContextImpl::GetAtomicCounterBuffer(CRegisteredString bufferName)
+ {
+ TContextAtomicCounterBufferMap::iterator entry = m_AtomicCounterToImpMap.find(bufferName);
+ if (entry != m_AtomicCounterToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ NVRenderAtomicCounterBuffer *
+ NVRenderContextImpl::GetAtomicCounterBufferByParam(CRegisteredString paramName)
+ {
+ // iterate through all atomic counter buffers
+ for (TContextAtomicCounterBufferMap::iterator iter = m_AtomicCounterToImpMap.begin(),
+ end = m_AtomicCounterToImpMap.end();
+ iter != end; ++iter) {
+ if (iter->second && iter->second->ContainsParam(paramName))
+ return iter->second;
+ }
+
+ return NULL;
+ }
+
+ void NVRenderContextImpl::BufferDestroyed(NVRenderAtomicCounterBuffer &buffer)
+ {
+ m_AtomicCounterToImpMap.erase(buffer.GetBufferName());
+ }
+
+ NVRenderDrawIndirectBuffer *NVRenderContextImpl::CreateDrawIndirectBuffer(
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVRenderDrawIndirectBuffer *buffer =
+ NVRenderDrawIndirectBuffer::Create(*this, usageType, size, bufferData);
+
+ if (buffer) {
+ m_DrawIndirectToImpMap.insert(make_pair(buffer->GetBuffertHandle(), buffer));
+ }
+
+ return buffer;
+ }
+
+ NVRenderDrawIndirectBuffer *NVRenderContextImpl::GetDrawIndirectBuffer(
+ NVRenderBackend::NVRenderBackendBufferObject implementationHandle)
+ {
+ TContextDrawIndirectBufferMap::iterator entry =
+ m_DrawIndirectToImpMap.find(implementationHandle);
+ if (entry != m_DrawIndirectToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::BufferDestroyed(NVRenderDrawIndirectBuffer &buffer)
+ {
+ m_DrawIndirectToImpMap.erase(buffer.GetBuffertHandle());
+ }
+
+ void NVRenderContextImpl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers)
+ {
+ m_backend->SetMemoryBarrier(barriers);
+ }
+
+ NVRenderOcclusionQuery *NVRenderContextImpl::CreateOcclusionQuery()
+ {
+ NVRenderOcclusionQuery *theQuery = NVRenderOcclusionQuery::Create(*this);
+
+ return theQuery;
+ }
+
+ NVRenderTimerQuery *NVRenderContextImpl::CreateTimerQuery()
+ {
+ NVRenderTimerQuery *theQuery = NVRenderTimerQuery::Create(*this);
+
+ return theQuery;
+ }
+
+ NVRenderSync *NVRenderContextImpl::CreateSync()
+ {
+ NVRenderSync *theSync = NVRenderSync::Create(*this);
+
+ return theSync;
+ }
+
+ NVRenderTexture2D *NVRenderContextImpl::CreateTexture2D()
+ {
+ NVRenderTexture2D *retval = NVRenderTexture2D::Create(*this);
+ if (retval)
+ m_Tex2DToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval));
+ return retval;
+ }
+
+ NVRenderTexture2DArray *NVRenderContextImpl::CreateTexture2DArray()
+ {
+ NVRenderTexture2DArray *retval = NVRenderTexture2DArray::Create(*this);
+ if (retval)
+ m_Tex2DArrayToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval));
+
+ return retval;
+ }
+
+ NVRenderTextureCube *NVRenderContextImpl::CreateTextureCube()
+ {
+ NVRenderTextureCube *retval = NVRenderTextureCube::Create(*this);
+ if (retval)
+ m_TexCubeToImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval));
+
+ return retval;
+ }
+
+ NVRenderTexture2D *NVRenderContextImpl::GetTexture2D(const void *implementationHandle)
+ {
+ const nvhash_map<const void *, NVRenderTexture2D *>::iterator entry =
+ m_Tex2DToImpMap.find(implementationHandle);
+ if (entry != m_Tex2DToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2D &buffer)
+ {
+ m_Tex2DToImpMap.erase(buffer.GetImplementationHandle());
+ // We would like to find and catch any situations where this texture is being used
+ // but that would require some real work that we don't want to do right now.
+ }
+
+ void NVRenderContextImpl::TextureDestroyed(NVRenderTexture2DArray &buffer)
+ {
+ m_Tex2DArrayToImpMap.erase(buffer.GetTextureObjectHandle());
+ }
+
+ void NVRenderContextImpl::TextureDestroyed(NVRenderTextureCube &buffer)
+ {
+ m_TexCubeToImpMap.erase(buffer.GetTextureObjectHandle());
+ }
+
+ NVRenderImage2D *NVRenderContextImpl::CreateImage2D(NVRenderTexture2D *inTexture,
+ NVRenderImageAccessType::Enum inAccess)
+ {
+ NVRenderImage2D *retval = NVRenderImage2D::Create(*this, inTexture, inAccess);
+ if (retval)
+ m_Image2DtoImpMap.insert(make_pair(retval->GetTextureObjectHandle(), retval));
+
+ return retval;
+ }
+
+ void NVRenderContextImpl::ImageDestroyed(NVRenderImage2D &image)
+ {
+ m_Image2DtoImpMap.erase(image.GetTextureObjectHandle());
+ }
+
+ // IF this texture isn't on a texture unit, put it on one.
+ // If it is on a texture unit, mark it as the most recently used texture.
+ QT3DSU32 NVRenderContextImpl::GetNextTextureUnit()
+ {
+ QT3DSU32 retval = m_NextTextureUnit;
+ ++m_NextTextureUnit;
+ // Too many texture units for a single draw call.
+ if (retval >= m_MaxTextureUnits) {
+ QT3DS_ASSERT(false);
+ retval = retval % m_MaxTextureUnits;
+ }
+ return retval;
+ }
+
+ NVRenderRenderBuffer *
+ NVRenderContextImpl::CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat,
+ QT3DSU32 width, QT3DSU32 height)
+ {
+ NVRenderRenderBuffer *retval =
+ NVRenderRenderBuffer::Create(*this, bufferFormat, width, height);
+ if (retval != NULL)
+ m_RenderBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval));
+ return retval;
+ }
+
+ NVRenderRenderBuffer *NVRenderContextImpl::GetRenderBuffer(const void *implementationHandle)
+ {
+ const nvhash_map<const void *, NVRenderRenderBuffer *>::iterator entry =
+ m_RenderBufferToImpMap.find(implementationHandle);
+ if (entry != m_RenderBufferToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::RenderBufferDestroyed(NVRenderRenderBuffer &buffer)
+ {
+ m_RenderBufferToImpMap.erase(buffer.GetImplementationHandle());
+ }
+
+ NVRenderFrameBuffer *NVRenderContextImpl::CreateFrameBuffer()
+ {
+ NVRenderFrameBuffer *retval = NVRenderFrameBuffer::Create(*this);
+ if (retval != NULL)
+ m_FrameBufferToImpMap.insert(make_pair(retval->GetImplementationHandle(), retval));
+ return retval;
+ }
+
+ NVRenderFrameBuffer *NVRenderContextImpl::GetFrameBuffer(const void *implementationHandle)
+ {
+ const nvhash_map<const void *, NVRenderFrameBuffer *>::iterator entry =
+ m_FrameBufferToImpMap.find(implementationHandle);
+ if (entry != m_FrameBufferToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::FrameBufferDestroyed(NVRenderFrameBuffer &fb)
+ {
+ m_FrameBufferToImpMap.erase(fb.GetImplementationHandle());
+ if (m_HardwarePropertyContext.m_FrameBuffer == &fb)
+ m_HardwarePropertyContext.m_FrameBuffer = NULL;
+ }
+
+ NVRenderAttribLayout *
+ NVRenderContextImpl::CreateAttributeLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs)
+ {
+ return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderAttribLayout)(*this, attribs);
+ }
+
+ NVRenderInputAssembler *NVRenderContextImpl::CreateInputAssembler(
+ NVRenderAttribLayout *attribLayout, NVConstDataRef<NVRenderVertexBuffer *> buffers,
+ const NVRenderIndexBuffer *indexBuffer, NVConstDataRef<QT3DSU32> strides,
+ NVConstDataRef<QT3DSU32> offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount)
+ {
+ return QT3DS_NEW(GetFoundation().getAllocator(),
+ NVRenderInputAssembler)(*this, attribLayout, buffers, indexBuffer, strides,
+ offsets, primType, patchVertexCount);
+ }
+
+ void NVRenderContextImpl::SetInputAssembler(NVRenderInputAssembler *inputAssembler)
+ {
+ if (m_HardwarePropertyContext.m_InputAssembler != inputAssembler) {
+ DoSetInputAssembler(inputAssembler);
+ }
+ }
+
+ NVRenderVertFragCompilationResult NVRenderContextImpl::CompileSource(
+ const char *shaderName, NVConstDataRef<QT3DSI8> vertShader, NVConstDataRef<QT3DSI8> fragShader,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource,
+ NVConstDataRef<QT3DSI8> tessEvaluationShaderSource, NVConstDataRef<QT3DSI8> geometryShaderSource,
+ bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram)
+ {
+ NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create(
+ *this, shaderName, vertShader, fragShader, tessControlShaderSource,
+ tessEvaluationShaderSource, geometryShaderSource, separateProgram, type, binaryProgram);
+
+ if (result.mShader != NULL)
+ m_ShaderToImpMap.insert(
+ make_pair(result.mShader->GetShaderProgramHandle(), result.mShader));
+
+ return result;
+ }
+
+ NVRenderVertFragCompilationResult NVRenderContextImpl::CompileBinary(
+ const char *shaderName, NVRenderShaderProgramBinaryType::Enum type,
+ NVDataRef<QT3DSI8> vertShader, NVDataRef<QT3DSI8> fragShader,
+ NVDataRef<QT3DSI8> tessControlShaderSource, NVDataRef<QT3DSI8> tessEvaluationShaderSource,
+ NVConstDataRef<QT3DSI8> geometryShaderSource)
+ {
+#ifndef _MACOSX
+ NVRenderVertFragCompilationResult result = NVRenderShaderProgram::Create(
+ *this, shaderName, vertShader, fragShader, tessControlShaderSource,
+ tessEvaluationShaderSource, geometryShaderSource, false, type, true);
+
+ if (result.mShader != NULL)
+ m_ShaderToImpMap.insert(
+ make_pair(result.mShader->GetShaderProgramHandle(), result.mShader));
+
+ return result;
+#else
+ QT3DS_ASSERT(false);
+ return NVRenderVertFragCompilationResult();
+#endif
+ }
+
+ NVRenderVertFragCompilationResult
+ NVRenderContextImpl::CompileComputeSource(const char *shaderName,
+ NVConstDataRef<QT3DSI8> computeShaderSource)
+ {
+ NVRenderVertFragCompilationResult result =
+ NVRenderShaderProgram::CreateCompute(*this, shaderName, computeShaderSource);
+
+ if (result.mShader != NULL)
+ m_ShaderToImpMap.insert(
+ make_pair(result.mShader->GetShaderProgramHandle(), result.mShader));
+
+ return result;
+ }
+
+ NVRenderShaderProgram *NVRenderContextImpl::GetShaderProgram(const void *implementationHandle)
+ {
+ const nvhash_map<const void *, NVRenderShaderProgram *>::iterator entry =
+ m_ShaderToImpMap.find(implementationHandle);
+ if (entry != m_ShaderToImpMap.end())
+ return entry->second;
+ return NULL;
+ }
+
+ void NVRenderContextImpl::ShaderDestroyed(NVRenderShaderProgram &shader)
+ {
+ m_ShaderToImpMap.erase(shader.GetShaderProgramHandle());
+ if (m_HardwarePropertyContext.m_ActiveShader == &shader)
+ SetActiveShader(NULL);
+ }
+
+ NVRenderProgramPipeline *NVRenderContextImpl::CreateProgramPipeline()
+ {
+ return QT3DS_NEW(GetFoundation().getAllocator(), NVRenderProgramPipeline)(*this,
+ GetFoundation());
+ }
+
+ NVRenderPathSpecification *NVRenderContextImpl::CreatePathSpecification()
+ {
+ return NVRenderPathSpecification::CreatePathSpecification(*this);
+ }
+
+ NVRenderPathRender *NVRenderContextImpl::CreatePathRender(size_t range)
+ {
+ return NVRenderPathRender::Create(*this, range);
+ }
+
+ void NVRenderContextImpl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection)
+ {
+ m_backend->SetPathProjectionMatrix(inPathProjection);
+ }
+
+ void NVRenderContextImpl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview)
+ {
+ m_backend->SetPathModelViewMatrix(inPathModelview);
+ }
+
+ void NVRenderContextImpl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias)
+ {
+ m_backend->SetPathStencilDepthOffset(inSlope, inBias);
+ }
+ void NVRenderContextImpl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc)
+ {
+ m_backend->SetPathCoverDepthFunc(inFunc);
+ }
+
+ NVRenderPathFontSpecification *
+ NVRenderContextImpl::CreatePathFontSpecification(CRegisteredString fontName)
+ {
+ // first check if it already exists
+ nvhash_map<CRegisteredString, NVRenderPathFontSpecification *>::const_iterator entry =
+ m_PathFontSpecToImpMap.find(fontName);
+ if (entry != m_PathFontSpecToImpMap.end())
+ return entry->second;
+
+ // if not create new one
+ NVRenderPathFontSpecification *pPathFontSpec =
+ NVRenderPathFontSpecification::CreatePathFontSpecification(*this, fontName);
+
+ if (pPathFontSpec)
+ m_PathFontSpecToImpMap.insert(make_pair(fontName, pPathFontSpec));
+
+ return pPathFontSpec;
+ }
+
+ void
+ NVRenderContextImpl::ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec)
+ {
+ m_PathFontSpecToImpMap.erase(inPathSpec.GetFontName());
+ }
+
+ NVRenderPathFontItem *NVRenderContextImpl::CreatePathFontItem()
+ {
+ // if not create new one
+ return NVRenderPathFontItem::CreatePathFontItem(*this);
+ }
+
+ void NVRenderContextImpl::SetClearColor(QT3DSVec4 inClearColor)
+ {
+ if (m_HardwarePropertyContext.m_ClearColor != inClearColor)
+ DoSetClearColor(inClearColor);
+ }
+
+ void NVRenderContextImpl::SetBlendFunction(NVRenderBlendFunctionArgument inFunctions)
+ {
+ if (memcmp(&inFunctions, &m_HardwarePropertyContext.m_BlendFunction,
+ sizeof(NVRenderBlendFunctionArgument))) {
+ DoSetBlendFunction(inFunctions);
+ }
+ }
+
+ void NVRenderContextImpl::SetBlendEquation(NVRenderBlendEquationArgument inEquations)
+ {
+ if (memcmp(&inEquations, &m_HardwarePropertyContext.m_BlendEquation,
+ sizeof(NVRenderBlendEquationArgument))) {
+ DoSetBlendEquation(inEquations);
+ }
+ }
+
+ void NVRenderContextImpl::SetCullingEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_CullingEnabled) {
+ DoSetCullingEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction)
+ {
+ if (inFunction != m_HardwarePropertyContext.m_DepthFunction) {
+ DoSetDepthFunction(inFunction);
+ }
+ }
+
+ void NVRenderContextImpl::SetBlendingEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_BlendingEnabled) {
+ DoSetBlendingEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetColorWritesEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_ColorWritesEnabled) {
+ DoSetColorWritesEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetDepthWriteEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_DepthWriteEnabled) {
+ m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled;
+ m_backend->SetRenderState(inEnabled, NVRenderState::DepthWrite);
+ }
+ }
+
+ void NVRenderContextImpl::SetDepthTestEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_DepthTestEnabled) {
+ DoSetDepthTestEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetMultisampleEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_MultisampleEnabled) {
+ DoSetMultisampleEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetStencilTestEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_StencilTestEnabled) {
+ DoSetStencilTestEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetScissorTestEnabled(bool inEnabled)
+ {
+ if (inEnabled != m_HardwarePropertyContext.m_ScissorTestEnabled) {
+ DoSetScissorTestEnabled(inEnabled);
+ }
+ }
+
+ void NVRenderContextImpl::SetScissorRect(NVRenderRect inRect)
+ {
+ if (memcmp(&inRect, &m_HardwarePropertyContext.m_ScissorRect, sizeof(NVRenderRect))) {
+ DoSetScissorRect(inRect);
+ }
+ }
+
+ void NVRenderContextImpl::SetViewport(NVRenderRect inViewport)
+ {
+ if (memcmp(&inViewport, &m_HardwarePropertyContext.m_Viewport, sizeof(NVRenderRect))) {
+ DoSetViewport(inViewport);
+ }
+ }
+
+ void NVRenderContextImpl::SetActiveShader(NVRenderShaderProgram *inShader)
+ {
+ if (inShader != m_HardwarePropertyContext.m_ActiveShader)
+ DoSetActiveShader(inShader);
+ }
+
+ void NVRenderContextImpl::SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline)
+ {
+ if (inProgramPipeline != m_HardwarePropertyContext.m_ActiveProgramPipeline)
+ DoSetActiveProgramPipeline(inProgramPipeline);
+ }
+
+ void NVRenderContextImpl::DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX,
+ QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ)
+ {
+ QT3DS_ASSERT(inShader);
+
+ if (inShader != m_HardwarePropertyContext.m_ActiveShader)
+ DoSetActiveShader(inShader);
+
+ m_backend->DispatchCompute(inShader->GetShaderProgramHandle(), numGroupsX, numGroupsY,
+ numGroupsZ);
+
+ OnPostDraw();
+ }
+
+ void NVRenderContextImpl::SetDrawBuffers(NVConstDataRef<QT3DSI32> inDrawBufferSet)
+ {
+ m_backend->SetDrawBuffers(
+ (m_HardwarePropertyContext.m_FrameBuffer)
+ ? m_HardwarePropertyContext.m_FrameBuffer->GetFrameBuffertHandle()
+ : NULL,
+ inDrawBufferSet);
+ }
+
+ void NVRenderContextImpl::SetReadBuffer(NVReadFaces::Enum inReadFace)
+ {
+ // currently NULL which means the read target must be set with setReadTarget
+ m_backend->SetReadBuffer(NULL, inReadFace);
+ }
+
+ void NVRenderContextImpl::ReadPixels(NVRenderRect inRect,
+ NVRenderReadPixelFormats::Enum inFormat,
+ NVDataRef<QT3DSU8> inWriteBuffer)
+ {
+ // NULL means read from current render target
+ m_backend->ReadPixel(NULL, inRect.m_X, inRect.m_Y, inRect.m_Width, inRect.m_Height,
+ inFormat, (void *)inWriteBuffer.begin());
+ }
+
+ void NVRenderContextImpl::SetRenderTarget(NVRenderFrameBuffer *inBuffer)
+ {
+ if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) {
+ DoSetRenderTarget(inBuffer);
+ }
+ }
+
+ void NVRenderContextImpl::SetReadTarget(NVRenderFrameBuffer *inBuffer)
+ {
+ if (inBuffer != m_HardwarePropertyContext.m_FrameBuffer) {
+ DoSetReadTarget(inBuffer);
+ }
+ }
+
+ void NVRenderContextImpl::ResetBlendState()
+ {
+ QT3DSI32_4 values;
+
+ m_backend->SetRenderState(m_HardwarePropertyContext.m_BlendingEnabled,
+ NVRenderState::Blend);
+ const NVRenderBlendFunctionArgument &theBlendArg(m_HardwarePropertyContext.m_BlendFunction);
+ m_backend->SetBlendFunc(theBlendArg);
+ }
+
+ // Pop the entire set of properties, potentially forcing the values
+ // to opengl.
+ void NVRenderContextImpl::PopPropertySet(bool inForceSetProperties)
+ {
+ if (!m_PropertyStack.empty()) {
+ SNVGLHardPropertyContext &theTopContext(m_PropertyStack.back());
+ if (inForceSetProperties) {
+#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \
+ DoSet##setterName(theTopContext.m_##propName);
+
+ ITERATE_HARDWARE_CONTEXT_PROPERTIES
+
+#undef HANDLE_CONTEXT_HARDWARE_PROPERTY
+ } else {
+#define HANDLE_CONTEXT_HARDWARE_PROPERTY(setterName, propName) \
+ Set##setterName(theTopContext.m_##propName);
+
+ ITERATE_HARDWARE_CONTEXT_PROPERTIES
+
+#undef HANDLE_CONTEXT_HARDWARE_PROPERTY
+ }
+ m_PropertyStack.pop_back();
+ }
+ }
+
+ void NVRenderContextImpl::Clear(NVRenderClearFlags flags)
+ {
+ if ((flags & NVRenderClearValues::Depth)
+ && m_HardwarePropertyContext.m_DepthWriteEnabled == false) {
+ QT3DS_ASSERT(false);
+ SetDepthWriteEnabled(true);
+ }
+ m_backend->Clear(flags);
+ }
+
+ void NVRenderContextImpl::Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags)
+ {
+ NVRenderFrameBuffer *previous = m_HardwarePropertyContext.m_FrameBuffer;
+ if (previous != &fb)
+ SetRenderTarget(&fb);
+
+ Clear(flags);
+
+ if (previous != &fb)
+ SetRenderTarget(previous);
+ }
+
+ void NVRenderContextImpl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter)
+ {
+ m_backend->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, flags,
+ filter);
+ }
+
+ bool
+ NVRenderContextImpl::BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler,
+ NVRenderShaderProgram *shader)
+ {
+ // setup the input assembler object
+ return m_backend->SetInputAssembler(inputAssembler->GetInputAssemblerHandle(),
+ shader->GetShaderProgramHandle());
+ }
+
+ bool NVRenderContextImpl::ApplyPreDrawProperties()
+ {
+ // Get the currently bound vertex and shader
+ NVRenderInputAssembler *inputAssembler = this->m_HardwarePropertyContext.m_InputAssembler;
+ NVRenderShaderProgram *shader = this->m_HardwarePropertyContext.m_ActiveShader;
+
+ // we could render through a program pipline
+ if (shader == NULL && this->m_HardwarePropertyContext.m_ActiveProgramPipeline)
+ shader = this->m_HardwarePropertyContext.m_ActiveProgramPipeline->GetVertexStage();
+
+ if (inputAssembler == NULL || shader == NULL) {
+ qCCritical(INVALID_OPERATION,
+ "Attempting to render no valid shader or input assembler setup");
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ return BindShaderToInputAssembler(inputAssembler, shader);
+ }
+
+ void NVRenderContextImpl::OnPostDraw()
+ {
+ // reset input assembler binding
+ m_backend->SetInputAssembler(NULL, 0);
+ // Texture unit 0 is used for setting up and loading textures.
+ // Bugs happen if we load a texture then setup the sampler.
+ // Then we load another texture. Because when loading we use texture unit 0,
+ // the render bindings for the first texture are blown away.
+ // Again, for this reason, texture unit 0 is reserved for loading textures.
+ m_NextTextureUnit = 1;
+ m_NextConstantBufferUnit = 0;
+ }
+
+ void NVRenderContextImpl::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset)
+ {
+ if (!ApplyPreDrawProperties())
+ return;
+
+ NVRenderIndexBuffer *theIndexBuffer = const_cast<NVRenderIndexBuffer *>(
+ m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer());
+ if (theIndexBuffer == NULL)
+ m_backend->Draw(drawMode, offset, count);
+ else
+ theIndexBuffer->Draw(drawMode, count, offset);
+
+ OnPostDraw();
+ }
+
+ void NVRenderContextImpl::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset)
+ {
+ if (!ApplyPreDrawProperties())
+ return;
+
+ NVRenderIndexBuffer *theIndexBuffer = const_cast<NVRenderIndexBuffer *>(
+ m_HardwarePropertyContext.m_InputAssembler->GetIndexBuffer());
+ if (theIndexBuffer == NULL)
+ m_backend->DrawIndirect(drawMode, (const void *)offset);
+ else
+ theIndexBuffer->DrawIndirect(drawMode, offset);
+
+ OnPostDraw();
+ }
+
+ QT3DSMat44
+ NVRenderContext::ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection,
+ const NVRenderRectF &inViewport,
+ const NVRenderRectF &inVirtualViewport)
+ {
+ if (inVirtualViewport == inViewport)
+ return inProjection;
+ // Run conversion to floating point once.
+ NVRenderRectF theVirtualViewport(inVirtualViewport);
+ NVRenderRectF theViewport(inViewport);
+ if (theVirtualViewport.m_Width == 0 || theVirtualViewport.m_Height == 0
+ || theViewport.m_Width == 0 || theViewport.m_Height == 0) {
+ QT3DS_ASSERT(false);
+ return inProjection;
+ }
+ QT3DSMat44 theScaleTransMat(QT3DSMat44::createIdentity());
+ QT3DSF32 theHeightDiff = theViewport.m_Height - theVirtualViewport.m_Height;
+ QT3DSF32 theViewportOffY = theVirtualViewport.m_Y - theViewport.m_Y;
+ QT3DSVec2 theCameraOffsets = QT3DSVec2(theVirtualViewport.m_Width - theViewport.m_Width
+ + (theVirtualViewport.m_X - theViewport.m_X) * 2.0f,
+ theHeightDiff + (theViewportOffY - theHeightDiff) * 2.0f);
+ QT3DSVec2 theCameraScale = QT3DSVec2(theVirtualViewport.m_Width / theViewport.m_Width,
+ theVirtualViewport.m_Height / theViewport.m_Height);
+
+ QT3DSVec3 theTranslation(theCameraOffsets.x / theViewport.m_Width,
+ theCameraOffsets.y / theViewport.m_Height, 0);
+ theScaleTransMat.column3[0] = theTranslation.x;
+ theScaleTransMat.column3[1] = theTranslation.y;
+ theScaleTransMat.column0[0] = theCameraScale.x;
+ theScaleTransMat.column1[1] = theCameraScale.y;
+
+ return theScaleTransMat * inProjection;
+ }
+
+ NVRenderVertFragCompilationResult NVRenderContext::CompileSource(
+ const char *shaderName, const char *vertShader, QT3DSU32 inVertLen, const char *fragShader,
+ QT3DSU32 inFragLen, const char *tessControlShaderSource, QT3DSU32 inTCLen,
+ const char *tessEvaluationShaderSource, QT3DSU32 inTELen, const char *geometryShaderSource,
+ QT3DSU32 inGSLen, bool separableProgram)
+ {
+ return CompileSource(
+ shaderName, NVConstDataRef<QT3DSI8>((const QT3DSI8 *)vertShader, inVertLen),
+ NVConstDataRef<QT3DSI8>((const QT3DSI8 *)fragShader, inFragLen),
+ NVConstDataRef<QT3DSI8>((const QT3DSI8 *)tessControlShaderSource, inTCLen),
+ NVConstDataRef<QT3DSI8>((const QT3DSI8 *)tessEvaluationShaderSource, inTELen),
+ NVConstDataRef<QT3DSI8>((const QT3DSI8 *)geometryShaderSource, inGSLen), separableProgram);
+ }
+
+ void NVRenderContextImpl::DoSetActiveShader(NVRenderShaderProgram *inShader)
+ {
+ m_HardwarePropertyContext.m_ActiveShader = NULL;
+ if (inShader)
+ m_backend->SetActiveProgram(inShader->GetShaderProgramHandle());
+ else {
+ m_backend->SetActiveProgram(NULL);
+ }
+ m_HardwarePropertyContext.m_ActiveShader = inShader;
+ }
+
+ void NVRenderContextImpl::DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline)
+ {
+ if (inProgramPipeline) {
+ // invalid any bound shader
+ DoSetActiveShader(NULL);
+ inProgramPipeline->Bind();
+ } else
+ m_backend->SetActiveProgramPipeline(NULL);
+
+ m_HardwarePropertyContext.m_ActiveProgramPipeline = inProgramPipeline;
+ }
+
+ NVRenderContext &NVRenderContext::CreateNULL(NVFoundationBase &foundation,
+ IStringTable &inStringTable)
+ {
+ NVRenderContext *retval = NULL;
+
+ // create backend
+ NVScopedRefCounted<IStringTable> theStringTable(inStringTable);
+ NVScopedRefCounted<NVRenderBackend> theBackend =
+ NVRenderBackendNULL::CreateBackend(foundation);
+ retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend,
+ *theStringTable);
+ return *retval;
+ }
+}
+} // end namespace
diff --git a/src/Runtime/Source/render/Qt3DSRenderContext.h b/src/Runtime/Source/render/Qt3DSRenderContext.h
new file mode 100644
index 00000000..e5b51341
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderContext.h
@@ -0,0 +1,1063 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_CONTEXT_H
+#define QT3DS_RENDER_CONTEXT_H
+#include "foundation/Qt3DS.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSDataRef.h"
+#include "foundation/Qt3DSMemoryBuffer.h"
+#include "render/glg/Qt3DSGLImplObjects.h"
+#include "render/backends/gl/Q3DSRenderBackendGLES2.h"
+#include "render/backends/gl/Qt3DSRenderBackendGL3.h"
+#include "render/backends/gl/Qt3DSRenderBackendGL4.h"
+#include "render/backends/software/Qt3DSRenderBackendNULL.h"
+#include "render/Qt3DSRenderVertexBuffer.h"
+#include "render/Qt3DSRenderIndexBuffer.h"
+#include "render/Qt3DSRenderConstantBuffer.h"
+#include "render/Qt3DSRenderFrameBuffer.h"
+#include "render/Qt3DSRenderRenderBuffer.h"
+#include "render/Qt3DSRenderDepthStencilState.h"
+#include "render/Qt3DSRenderRasterizerState.h"
+#include "render/Qt3DSRenderDrawable.h"
+#include "render/Qt3DSRenderInputAssembler.h"
+#include "render/Qt3DSRenderAttribLayout.h"
+#include "render/Qt3DSRenderImageTexture.h"
+#include "render/Qt3DSRenderOcclusionQuery.h"
+#include "render/Qt3DSRenderTimerQuery.h"
+#include "render/Qt3DSRenderSync.h"
+#include "render/Qt3DSRenderTexture2DArray.h"
+#include "render/Qt3DSRenderTextureCube.h"
+#include "render/Qt3DSRenderStorageBuffer.h"
+#include "render/Qt3DSRenderAtomicCounterBuffer.h"
+#include "render/Qt3DSRenderDrawIndirectBuffer.h"
+#include "render/Qt3DSRenderProgramPipeline.h"
+#include "render/Qt3DSRenderPathRender.h"
+#include "render/Qt3DSRenderPathSpecification.h"
+#include "render/Qt3DSRenderPathFontSpecification.h"
+#include "render/Qt3DSRenderPathFontText.h"
+
+#include <QSurfaceFormat>
+
+// When SW fallback is defined we can support (some) object/layer advanced blend modes. If defined,
+// the HW implementation is still preperred if available through extensions. SW fallback can't be
+// used in custom shaders.
+#define ADVANCED_BLEND_SW_FALLBACK
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ struct NVRenderShaderProgramBinaryType
+ {
+ enum Enum {
+ Unknown = 0,
+ NVBinary = 1,
+ };
+ };
+
+ // context dirty flags
+ struct NVRenderContextDirtyValues
+ {
+ enum Enum {
+ InputAssembler = 1 << 0,
+ };
+ };
+
+ typedef NVFlags<NVRenderContextDirtyValues::Enum, QT3DSU32> NVRenderContextDirtyFlags;
+ typedef nvhash_map<CRegisteredString, NVRenderConstantBuffer *> TContextConstantBufferMap;
+ typedef nvhash_map<CRegisteredString, NVRenderStorageBuffer *> TContextStorageBufferMap;
+ typedef nvhash_map<CRegisteredString, NVRenderAtomicCounterBuffer *>
+ TContextAtomicCounterBufferMap;
+ typedef nvhash_map<NVRenderBackend::NVRenderBackendBufferObject, NVRenderDrawIndirectBuffer *>
+ TContextDrawIndirectBufferMap;
+ typedef nvhash_map<NVRenderBackend::NVRenderBackendDepthStencilStateObject,
+ NVRenderDepthStencilState *>
+ TContextDepthStencilStateMap;
+ typedef nvhash_map<NVRenderBackend::NVRenderBackendRasterizerStateObject,
+ NVRenderRasterizerState *>
+ TContextRasterizerStateMap;
+ typedef nvhash_map<NVRenderBackend::NVRenderBackendTextureObject, NVRenderTexture2DArray *>
+ TContextTex2DArrayToImpMap;
+ typedef nvhash_map<NVRenderBackend::NVRenderBackendTextureObject, NVRenderTextureCube *>
+ TContextTexCubeToImpMap;
+ typedef nvhash_map<NVRenderBackend::NVRenderBackendTextureObject, NVRenderImage2D *>
+ TContextImage2DToImpMap;
+ typedef nvhash_map<CRegisteredString, NVRenderPathFontSpecification *>
+ TContextPathFontSpecificationMap;
+
+ class QT3DS_AUTOTEST_EXPORT NVRenderContext : public NVRefCounted, public NVRenderDrawable
+ {
+ public:
+ virtual NVRenderContextType GetRenderContextType() const = 0;
+ virtual bool AreMultisampleTexturesSupported() const = 0;
+ virtual bool GetConstantBufferSupport() const = 0;
+ virtual void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) = 0;
+ virtual const char *GetShadingLanguageVersion() = 0;
+ // Get the bit depth of the currently bound depth buffer.
+ virtual QT3DSU32 GetDepthBits() const = 0;
+ virtual QT3DSU32 GetStencilBits() const = 0;
+ virtual bool
+ GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const = 0;
+ virtual bool AreDXTImagesSupported() const = 0;
+ virtual bool IsDepthStencilSupported() const = 0;
+ virtual bool IsFpRenderTargetSupported() const = 0;
+ virtual bool IsTessellationSupported() const = 0;
+ virtual bool IsGeometryStageSupported() const = 0;
+ virtual bool IsComputeSupported() const = 0;
+ virtual bool IsSampleQuerySupported() const = 0;
+ virtual bool IsTimerQuerySupported() const = 0;
+ virtual bool IsCommandSyncSupported() const = 0;
+ virtual bool IsTextureArraySupported() const = 0;
+ virtual bool IsStorageBufferSupported() const = 0;
+ virtual bool IsAtomicCounterBufferSupported() const = 0;
+ virtual bool IsShaderImageLoadStoreSupported() const = 0;
+ virtual bool IsProgramPipelineSupported() const = 0;
+ virtual bool IsPathRenderingSupported() const = 0;
+ virtual bool IsBlendCoherencySupported() const = 0;
+ virtual bool IsAdvancedBlendHwSupported() const = 0;
+ virtual bool IsAdvancedBlendHwSupportedKHR() const = 0;
+ virtual bool IsStandardDerivativesSupported() const = 0;
+ virtual bool IsTextureLodSupported() const = 0;
+
+ virtual void SetDefaultRenderTarget(QT3DSU64 targetID) = 0;
+ virtual void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) = 0;
+
+ virtual NVRenderDepthStencilState *
+ CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc,
+ bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack) = 0;
+
+ virtual NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale,
+ NVRenderFaces::Enum cullFace) = 0;
+
+ virtual NVRenderVertexBuffer *
+ CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType, size_t size, QT3DSU32 stride = 0,
+ NVConstDataRef<QT3DSU8> bufferData = NVConstDataRef<QT3DSU8>()) = 0;
+ virtual NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) = 0;
+
+ virtual NVRenderIndexBuffer *
+ CreateIndexBuffer(NVRenderBufferUsageType::Enum usageType,
+ NVRenderComponentTypes::Enum componentType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData = NVConstDataRef<QT3DSU8>()) = 0;
+ virtual NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) = 0;
+
+ virtual NVRenderConstantBuffer *
+ CreateConstantBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) = 0;
+ virtual NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) = 0;
+
+ virtual NVRenderStorageBuffer *
+ CreateStorageBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer) = 0;
+ virtual NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) = 0;
+
+ virtual NVRenderAtomicCounterBuffer *
+ CreateAtomicCounterBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) = 0;
+ virtual NVRenderAtomicCounterBuffer *
+ GetAtomicCounterBuffer(CRegisteredString bufferName) = 0;
+ virtual NVRenderAtomicCounterBuffer *
+ GetAtomicCounterBufferByParam(CRegisteredString paramName) = 0;
+
+ virtual NVRenderDrawIndirectBuffer *
+ CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) = 0;
+ virtual NVRenderDrawIndirectBuffer *GetDrawIndirectBuffer(
+ NVRenderBackend::NVRenderBackendBufferObject implementationHandle) = 0;
+
+ virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0;
+
+ virtual NVRenderOcclusionQuery *CreateOcclusionQuery() = 0;
+ virtual NVRenderTimerQuery *CreateTimerQuery() = 0;
+ virtual NVRenderSync *CreateSync() = 0;
+
+ virtual NVRenderTexture2D *CreateTexture2D() = 0;
+ virtual NVRenderTexture2D *GetTexture2D(const void *implementationHandle) = 0;
+ virtual NVRenderBackend *GetBackend() = 0;
+
+ virtual NVRenderTexture2DArray *CreateTexture2DArray() = 0;
+
+ virtual NVRenderTextureCube *CreateTextureCube() = 0;
+
+ virtual NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture,
+ NVRenderImageAccessType::Enum inAccess) = 0;
+
+ virtual NVRenderRenderBuffer *
+ CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width,
+ QT3DSU32 height) = 0;
+ virtual NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) = 0;
+ // Create a new frame buffer and set the current render target to that frame buffer.
+ virtual NVRenderFrameBuffer *CreateFrameBuffer() = 0;
+ virtual NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) = 0;
+
+ virtual NVRenderAttribLayout *
+ CreateAttributeLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) = 0;
+
+ virtual NVRenderInputAssembler *
+ CreateInputAssembler(NVRenderAttribLayout *attribLayout,
+ NVConstDataRef<NVRenderVertexBuffer *> buffers,
+ const NVRenderIndexBuffer *indexBuffer, NVConstDataRef<QT3DSU32> strides,
+ NVConstDataRef<QT3DSU32> offsets,
+ NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles,
+ QT3DSU32 patchVertexCount = 1) = 0;
+ virtual void SetInputAssembler(NVRenderInputAssembler *inputAssembler) = 0;
+
+ virtual NVRenderVertFragCompilationResult CompileSource(
+ const char *shaderName, NVConstDataRef<QT3DSI8> vertShader,
+ NVConstDataRef<QT3DSI8> fragShader,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource = NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> tessEvaluationShaderSource = NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>(),
+ bool separateProgram = false,
+ NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown,
+ bool binaryProgram = false) = 0;
+
+ // You must figure out inVertLen and inFragLen yourself, this object doesn't do that.
+ NVRenderVertFragCompilationResult
+ CompileSource(const char *shaderName, const char *vertShader, QT3DSU32 inVertLen,
+ const char *fragShader, QT3DSU32 inFragLen, const char * = NULL,
+ QT3DSU32 inTCLen = 0, const char *tessEvaluationShaderSource = NULL,
+ QT3DSU32 inTELen = 0, const char *geometryShaderSource = NULL, QT3DSU32 inGSLen = 0,
+ bool separableProgram = false);
+
+ virtual NVRenderVertFragCompilationResult
+ CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type,
+ NVDataRef<QT3DSI8> vertShader, NVDataRef<QT3DSI8> fragShader,
+ NVDataRef<QT3DSI8> tessControlShaderSource = NVDataRef<QT3DSI8>(),
+ NVDataRef<QT3DSI8> tessEvaluationShaderSource = NVDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>()) = 0;
+
+ virtual NVRenderVertFragCompilationResult
+ CompileComputeSource(const char *shaderName, NVConstDataRef<QT3DSI8> computeShaderSource) = 0;
+
+ virtual NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) = 0;
+
+ virtual NVRenderProgramPipeline *CreateProgramPipeline() = 0;
+
+ virtual NVRenderPathSpecification *CreatePathSpecification() = 0;
+ virtual NVRenderPathRender *CreatePathRender(size_t range = 1) = 0;
+ virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0;
+ virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0;
+ virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0;
+ virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) = 0;
+
+ virtual NVRenderPathFontSpecification *
+ CreatePathFontSpecification(CRegisteredString fontName) = 0;
+ virtual NVRenderPathFontItem *CreatePathFontItem() = 0;
+
+ // Specific setters for the guaranteed-to-exist context properties to set them as fast as
+ // possible.
+ // Note that this bypasses the property manage so push/pop will have no effect (unless you
+ // set these already
+ // once after a push using the property manager.
+ virtual void SetClearColor(QT3DSVec4 inClearColor) = 0;
+ virtual QT3DSVec4 GetClearColor() const = 0;
+
+ virtual void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) = 0;
+ virtual NVRenderBlendFunctionArgument GetBlendFunction() const = 0;
+
+ virtual void SetBlendEquation(NVRenderBlendEquationArgument inEquations) = 0;
+ virtual NVRenderBlendEquationArgument GetBlendEquation() const = 0;
+
+ virtual void SetCullingEnabled(bool inEnabled) = 0;
+ virtual bool IsCullingEnabled() const = 0;
+
+ virtual void SetDepthFunction(NVRenderBoolOp::Enum inFunction) = 0;
+ virtual qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const = 0;
+
+ virtual void SetBlendingEnabled(bool inEnabled) = 0;
+ virtual bool IsBlendingEnabled() const = 0;
+
+ virtual void SetDepthWriteEnabled(bool inEnabled) = 0;
+ virtual bool IsDepthWriteEnabled() const = 0;
+
+ virtual void SetDepthTestEnabled(bool inEnabled) = 0;
+ virtual bool IsDepthTestEnabled() const = 0;
+
+ virtual void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) = 0;
+ virtual void SetStencilTestEnabled(bool inEnabled) = 0;
+ virtual bool IsStencilTestEnabled() const = 0;
+
+ virtual void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) = 0;
+
+ virtual void SetScissorTestEnabled(bool inEnabled) = 0;
+ virtual bool IsScissorTestEnabled() const = 0;
+
+ virtual void SetScissorRect(NVRenderRect inRect) = 0;
+ virtual NVRenderRect GetScissorRect() const = 0;
+
+ virtual void SetViewport(NVRenderRect inViewport) = 0;
+ virtual NVRenderRect GetViewport() const = 0;
+
+ virtual void SetColorWritesEnabled(bool inEnabled) = 0;
+ virtual bool IsColorWritesEnabled() const = 0;
+
+ virtual void SetMultisampleEnabled(bool inEnabled) = 0;
+ virtual bool IsMultisampleEnabled() const = 0;
+
+ // Used during layer rendering because we can't set the *actual* viewport to what it should
+ // be due to hardware problems.
+ // Set during begin render.
+ static QT3DSMat44
+ ApplyVirtualViewportToProjectionMatrix(const QT3DSMat44 &inProjection,
+ const NVRenderRectF &inViewport,
+ const NVRenderRectF &inVirtualViewport);
+
+ virtual void SetRenderTarget(NVRenderFrameBuffer *inBuffer) = 0;
+ virtual void SetReadTarget(NVRenderFrameBuffer *inBuffer) = 0;
+ virtual NVRenderFrameBuffer *GetRenderTarget() const = 0;
+
+ virtual void SetActiveShader(NVRenderShaderProgram *inShader) = 0;
+ virtual NVRenderShaderProgram *GetActiveShader() const = 0;
+
+ virtual void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) = 0;
+ virtual NVRenderProgramPipeline *GetActiveProgramPipeline() const = 0;
+
+ virtual void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX,
+ QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0;
+
+ // Push the entire set of properties.
+ virtual void PushPropertySet() = 0;
+ // Pop the entire set of properties, potentially forcing the values
+ // to opengl. Will set the hardware state to whatever at the time of push.
+ virtual void PopPropertySet(bool inForceSetProperties) = 0;
+
+ // Ensure the hardware state matches the state we expect.
+ virtual void ResetBlendState() = 0;
+
+ // Draw buffers are what the system will render to.. Applies to the current render context.
+ //-1 means none, else the integer is assumed to be an index past the draw buffer index.
+ // This applies only to the currently bound framebuffer.
+ virtual void SetDrawBuffers(NVConstDataRef<QT3DSI32> inDrawBufferSet) = 0;
+ virtual void SetReadBuffer(NVReadFaces::Enum inReadFace) = 0;
+
+ virtual void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat,
+ NVDataRef<QT3DSU8> inWriteBuffer) = 0;
+
+ // Return the property manager for this render context
+ // virtual NVRenderPropertyManager& GetPropertyManager() = 0;
+ // Clear the current render target
+ virtual void Clear(NVRenderClearFlags flags) = 0;
+ // Clear this framebuffer without changing the active frame buffer
+ virtual void Clear(NVRenderFrameBuffer &framebuffer, NVRenderClearFlags flags) = 0;
+ // copy framebuffer content between read target and render target
+ virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter) = 0;
+
+ // Render, applying these immediate property values just before render. The hardware
+ // properties are tracked for push/pop
+ // but the shader properties are just set on the active shader *after* the hardware
+ // properties have been set. The shader properties are not tracked for push/pop.
+ // This call is meant to come directly before each draw call to setup the last bit of state
+ // before the draw operation. Note that there isn't another way to set the immedate
+ // property values for a given shader because it isn't clear which shader is active
+ // when the properties are getting set.
+ void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override = 0;
+
+ /**
+ * @brief Draw the current active vertex buffer using an indirect buffer
+ * This means the setup of the draw call is stored in a buffer bound to
+ * NVRenderBufferBindValues::Draw_Indirect
+ *
+ * @param[in] drawMode Draw mode (Triangles, ....)
+ * @param[in] indirect Offset into a indirect drawing setup buffer
+ *
+ * @return no return.
+ */
+ virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) = 0;
+
+ virtual NVFoundationBase &GetFoundation() = 0;
+ virtual qt3ds::foundation::IStringTable &GetStringTable() = 0;
+ virtual NVAllocatorCallback &GetAllocator() = 0;
+
+ virtual QSurfaceFormat format() const = 0;
+
+ virtual void resetStates() = 0;
+
+ static NVRenderContext &CreateGL(NVFoundationBase &foundation, IStringTable &inStringTable,
+ const QSurfaceFormat &format);
+
+ static NVRenderContext &CreateNULL(NVFoundationBase &foundation,
+ IStringTable &inStringTable);
+ };
+
+ // Now for scoped property access.
+ template <typename TDataType>
+ struct NVRenderContextScopedProperty
+ : public NVRenderGenericScopedProperty<NVRenderContext, TDataType>
+ {
+ typedef typename NVRenderGenericScopedProperty<NVRenderContext, TDataType>::TGetter TGetter;
+ typedef typename NVRenderGenericScopedProperty<NVRenderContext, TDataType>::TSetter TSetter;
+ NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter)
+ : NVRenderGenericScopedProperty<NVRenderContext, TDataType>(ctx, getter, setter)
+ {
+ }
+ NVRenderContextScopedProperty(NVRenderContext &ctx, TGetter getter, TSetter setter,
+ const TDataType &inNewValue)
+ : NVRenderGenericScopedProperty<NVRenderContext, TDataType>(ctx, getter, setter,
+ inNewValue)
+ {
+ }
+ };
+
+/**
+ * A Render Context implementation class
+ *
+ */
+
+#define ITERATE_HARDWARE_CONTEXT_PROPERTIES \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(RenderTarget, FrameBuffer) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveShader, ActiveShader) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(ActiveProgramPipeline, ActiveProgramPipeline) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(InputAssembler, InputAssembler) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendFunction, BlendFunction) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(CullingEnabled, CullingEnabled) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthFunction, DepthFunction) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(BlendingEnabled, BlendingEnabled) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthWriteEnabled, DepthWriteEnabled) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(DepthTestEnabled, DepthTestEnabled) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(StencilTestEnabled, StencilTestEnabled) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorTestEnabled, ScissorTestEnabled) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(ScissorRect, ScissorRect) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(Viewport, Viewport) \
+ HANDLE_CONTEXT_HARDWARE_PROPERTY(ClearColor, ClearColor)
+
+ // forward declarations
+
+ class NVRenderContextImpl : public NVRenderContext, public NoCopy
+ {
+ public:
+ // these variables represent the current hardware state of the render context.
+ SNVGLHardPropertyContext m_HardwarePropertyContext;
+
+ private:
+ NVScopedRefCounted<NVRenderBackend> m_backend; ///< pointer to our render backend
+ NVRenderContextDirtyFlags m_DirtyFlags; ///< context dirty flags
+
+ NVRenderBackend::NVRenderBackendRenderTargetObject
+ m_DefaultOffscreenRenderTarget; ///< this is a special target set from outside if we
+ ///never render to a window directly (GL only)
+ QT3DSI32 m_DephBits; ///< this is the depth bits count of the default window render target
+ QT3DSI32 m_StencilBits; ///< this is the stencil bits count of the default window render target
+
+ protected:
+ volatile QT3DSI32 mRefCount;
+ NVFoundationBase &m_Foundation;
+ qt3ds::foundation::IStringTable &m_StringTable;
+
+ nvhash_map<const void *, NVRenderVertexBuffer *> m_VertToImpMap;
+ nvhash_map<const void *, NVRenderIndexBuffer *> m_IndexToImpMap;
+ TContextConstantBufferMap m_ConstantToImpMap;
+ TContextStorageBufferMap m_StorageToImpMap;
+ TContextAtomicCounterBufferMap m_AtomicCounterToImpMap;
+ TContextDrawIndirectBufferMap m_DrawIndirectToImpMap;
+ TContextDepthStencilStateMap m_DepthStencilStateToImpMap;
+ TContextRasterizerStateMap m_RasterizerStateToImpMap;
+ TContextPathFontSpecificationMap m_PathFontSpecToImpMap;
+
+ nvhash_map<const void *, NVRenderTexture2D *> m_Tex2DToImpMap;
+ TContextTex2DArrayToImpMap m_Tex2DArrayToImpMap;
+ TContextTexCubeToImpMap m_TexCubeToImpMap;
+ TContextImage2DToImpMap m_Image2DtoImpMap;
+ nvhash_map<const void *, NVRenderShaderProgram *> m_ShaderToImpMap;
+ nvhash_map<const void *, NVRenderRenderBuffer *> m_RenderBufferToImpMap;
+ nvhash_map<const void *, NVRenderFrameBuffer *> m_FrameBufferToImpMap;
+ QT3DSU32 m_MaxTextureUnits;
+ QT3DSU32 m_NextTextureUnit;
+ QT3DSU32 m_MaxConstantBufferUnits;
+ QT3DSU32 m_NextConstantBufferUnit;
+
+ nvvector<SNVGLHardPropertyContext> m_PropertyStack;
+
+ void DoSetClearColor(QT3DSVec4 inClearColor)
+ {
+ m_HardwarePropertyContext.m_ClearColor = inClearColor;
+ m_backend->SetClearColor(&inClearColor);
+ }
+
+ void DoSetBlendFunction(NVRenderBlendFunctionArgument inFunctions)
+ {
+ QT3DSI32_4 values;
+ m_HardwarePropertyContext.m_BlendFunction = inFunctions;
+
+ m_backend->SetBlendFunc(inFunctions);
+ }
+
+ void DoSetBlendEquation(NVRenderBlendEquationArgument inEquations)
+ {
+ QT3DSI32_4 values;
+ m_HardwarePropertyContext.m_BlendEquation = inEquations;
+
+ m_backend->SetBlendEquation(inEquations);
+ }
+
+ void DoSetCullingEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_CullingEnabled = inEnabled;
+ m_backend->SetRenderState(inEnabled, NVRenderState::CullFace);
+ }
+
+ void DoSetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction)
+ {
+ m_HardwarePropertyContext.m_DepthFunction = inFunction;
+ m_backend->SetDepthFunc(inFunction);
+ }
+
+ void DoSetBlendingEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_BlendingEnabled = inEnabled;
+ m_backend->SetRenderState(inEnabled, NVRenderState::Blend);
+ }
+
+ void DoSetColorWritesEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_ColorWritesEnabled = inEnabled;
+ m_backend->SetColorWrites(inEnabled, inEnabled, inEnabled, inEnabled);
+ }
+
+ void DoSetMultisampleEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_MultisampleEnabled = inEnabled;
+ m_backend->SetMultisample(inEnabled);
+ }
+
+ void DoSetDepthWriteEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_DepthWriteEnabled = inEnabled;
+ m_backend->SetDepthWrite(inEnabled);
+ }
+
+ void DoSetDepthTestEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_DepthTestEnabled = inEnabled;
+ m_backend->SetRenderState(inEnabled, NVRenderState::DepthTest);
+ }
+
+ void DoSetStencilTestEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_StencilTestEnabled = inEnabled;
+ m_backend->SetRenderState(inEnabled, NVRenderState::StencilTest);
+ }
+
+ void DoSetScissorTestEnabled(bool inEnabled)
+ {
+ m_HardwarePropertyContext.m_ScissorTestEnabled = inEnabled;
+ m_backend->SetRenderState(inEnabled, NVRenderState::ScissorTest);
+ }
+
+ void DoSetScissorRect(NVRenderRect inRect)
+ {
+ m_HardwarePropertyContext.m_ScissorRect = inRect;
+ m_backend->SetScissorRect(inRect);
+ }
+
+ void DoSetViewport(NVRenderRect inViewport)
+ {
+ m_HardwarePropertyContext.m_Viewport = inViewport;
+ m_backend->SetViewportRect(inViewport);
+ }
+
+ // Circular dependencies between shader constants and shader programs preclude
+ // implementation in header
+ void DoSetActiveShader(NVRenderShaderProgram *inShader);
+ void DoSetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline);
+
+ void DoSetInputAssembler(NVRenderInputAssembler *inAssembler)
+ {
+ m_HardwarePropertyContext.m_InputAssembler = inAssembler;
+ m_DirtyFlags |= NVRenderContextDirtyValues::InputAssembler;
+ }
+
+ void DoSetRenderTarget(NVRenderFrameBuffer *inBuffer)
+ {
+ if (inBuffer)
+ m_backend->SetRenderTarget(inBuffer->GetFrameBuffertHandle());
+ else
+ m_backend->SetRenderTarget(m_DefaultOffscreenRenderTarget);
+
+ m_HardwarePropertyContext.m_FrameBuffer = inBuffer;
+ }
+
+ void DoSetReadTarget(NVRenderFrameBuffer *inBuffer)
+ {
+ if (inBuffer)
+ m_backend->SetReadTarget(inBuffer->GetFrameBuffertHandle());
+ else
+ m_backend->SetReadTarget(NVRenderBackend::NVRenderBackendRenderTargetObject(NULL));
+ }
+
+ bool BindShaderToInputAssembler(const NVRenderInputAssembler *inputAssembler,
+ NVRenderShaderProgram *shader);
+ bool ApplyPreDrawProperties();
+ void OnPostDraw();
+
+ public:
+ NVRenderContextImpl(NVFoundationBase &fnd, NVRenderBackend &inBackend,
+ IStringTable &inStrTable);
+ virtual ~NVRenderContextImpl();
+
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation);
+
+ NVRenderBackend *GetBackend() override { return m_backend; }
+
+ void getMaxTextureSize(QT3DSU32 &oWidth, QT3DSU32 &oHeight) override;
+
+ const char *GetShadingLanguageVersion() override
+ {
+ return m_backend->GetShadingLanguageVersion();
+ }
+
+ NVRenderContextType GetRenderContextType() const override
+ {
+ return m_backend->GetRenderContextType();
+ }
+
+ QT3DSU32 GetDepthBits() const override
+ {
+ // only query this if a framebuffer is bound
+ if (m_HardwarePropertyContext.m_FrameBuffer)
+ return m_backend->GetDepthBits();
+ else
+ return m_DephBits;
+ }
+
+ QT3DSU32 GetStencilBits() const override
+ {
+ // only query this if a framebuffer is bound
+ if (m_HardwarePropertyContext.m_FrameBuffer)
+ return m_backend->GetStencilBits();
+ else
+ return m_StencilBits;
+ }
+
+ bool GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Enum inCap) const override
+ {
+ return m_backend->GetRenderBackendCap(inCap);
+ }
+
+ bool AreMultisampleTexturesSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::MsTexture);
+ }
+
+ bool GetConstantBufferSupport() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ConstantBuffer);
+ }
+
+ bool AreDXTImagesSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DxtImages);
+ }
+
+ bool IsDepthStencilSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::DepthStencilTexture);
+ }
+
+ bool IsFpRenderTargetSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::FpRenderTarget);
+ }
+
+ bool IsTessellationSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Tessellation);
+ }
+
+ bool IsGeometryStageSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Geometry);
+ }
+
+ bool IsComputeSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::Compute);
+ }
+
+ bool IsSampleQuerySupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::SampleQuery);
+ }
+
+ bool IsTimerQuerySupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TimerQuery);
+ }
+
+ bool IsCommandSyncSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::CommandSync);
+ }
+ bool IsTextureArraySupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureArray);
+ }
+ bool IsStorageBufferSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StorageBuffer);
+ }
+ bool IsAtomicCounterBufferSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AtomicCounterBuffer);
+ }
+ bool IsShaderImageLoadStoreSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ShaderImageLoadStore);
+ }
+ bool IsProgramPipelineSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::ProgramPipeline);
+ }
+ bool IsPathRenderingSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::PathRendering);
+ }
+ // Are blend modes really supported in HW?
+ bool IsAdvancedBlendHwSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlend);
+ }
+ bool IsAdvancedBlendHwSupportedKHR() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::AdvancedBlendKHR);
+ }
+ bool IsBlendCoherencySupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::BlendCoherency);
+ }
+ bool IsStandardDerivativesSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StandardDerivatives);
+ }
+ bool IsTextureLodSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureLod);
+ }
+
+ void SetDefaultRenderTarget(QT3DSU64 targetID) override
+ {
+ m_DefaultOffscreenRenderTarget =
+ (NVRenderBackend::NVRenderBackendRenderTargetObject)targetID;
+ }
+
+ void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) override { m_DephBits = depthBits; }
+
+ virtual NVRenderDepthStencilState *
+ CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc,
+ bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack) override;
+ void SetDepthStencilState(NVRenderDepthStencilState *inDepthStencilState) override;
+ virtual void StateDestroyed(NVRenderDepthStencilState &state);
+
+ NVRenderRasterizerState *CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale,
+ NVRenderFaces::Enum cullFace) override;
+ void SetRasterizerState(NVRenderRasterizerState *inRasterizerState) override;
+ virtual void StateDestroyed(NVRenderRasterizerState &state);
+
+ NVRenderVertexBuffer *CreateVertexBuffer(NVRenderBufferUsageType::Enum usageType,
+ size_t size, QT3DSU32 stride,
+ NVConstDataRef<QT3DSU8> bufferData) override;
+ NVRenderVertexBuffer *GetVertexBuffer(const void *implementationHandle) override;
+ virtual void BufferDestroyed(NVRenderVertexBuffer &buffer);
+
+ virtual NVRenderIndexBuffer *
+ CreateIndexBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType,
+ qt3ds::render::NVRenderComponentTypes::Enum componentType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) override;
+ NVRenderIndexBuffer *GetIndexBuffer(const void *implementationHandle) override;
+ virtual void BufferDestroyed(NVRenderIndexBuffer &buffer);
+
+ virtual NVRenderConstantBuffer *
+ CreateConstantBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) override;
+ NVRenderConstantBuffer *GetConstantBuffer(CRegisteredString bufferName) override;
+ virtual void BufferDestroyed(NVRenderConstantBuffer &buffer);
+
+ virtual QT3DSU32 GetNextConstantBufferUnit();
+
+ virtual NVRenderStorageBuffer *
+ CreateStorageBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer) override;
+ NVRenderStorageBuffer *GetStorageBuffer(CRegisteredString bufferName) override;
+ virtual void BufferDestroyed(NVRenderStorageBuffer &buffer);
+
+ virtual NVRenderAtomicCounterBuffer *
+ CreateAtomicCounterBuffer(const char *bufferName,
+ qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) override;
+ NVRenderAtomicCounterBuffer *GetAtomicCounterBuffer(CRegisteredString bufferName) override;
+ virtual NVRenderAtomicCounterBuffer *
+ GetAtomicCounterBufferByParam(CRegisteredString paramName) override;
+ virtual void BufferDestroyed(NVRenderAtomicCounterBuffer &buffer);
+
+ virtual NVRenderDrawIndirectBuffer *
+ CreateDrawIndirectBuffer(qt3ds::render::NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData) override;
+ virtual NVRenderDrawIndirectBuffer *
+ GetDrawIndirectBuffer(NVRenderBackend::NVRenderBackendBufferObject implementationHandle) override;
+ virtual void BufferDestroyed(NVRenderDrawIndirectBuffer &buffer);
+
+ void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override;
+
+ NVRenderOcclusionQuery *CreateOcclusionQuery() override;
+ NVRenderTimerQuery *CreateTimerQuery() override;
+ NVRenderSync *CreateSync() override;
+
+ NVRenderTexture2D *CreateTexture2D() override;
+ NVRenderTexture2D *GetTexture2D(const void *implementationHandle) override;
+ virtual void TextureDestroyed(NVRenderTexture2D &buffer);
+
+ NVRenderTexture2DArray *CreateTexture2DArray() override;
+ virtual void TextureDestroyed(NVRenderTexture2DArray &buffer);
+
+ NVRenderTextureCube *CreateTextureCube() override;
+ virtual void TextureDestroyed(NVRenderTextureCube &buffer);
+
+ virtual QT3DSU32 GetNextTextureUnit();
+
+ NVRenderImage2D *CreateImage2D(NVRenderTexture2D *inTexture,
+ NVRenderImageAccessType::Enum inAccess) override;
+ virtual void ImageDestroyed(NVRenderImage2D &buffer);
+
+ virtual NVRenderRenderBuffer *
+ CreateRenderBuffer(NVRenderRenderBufferFormats::Enum bufferFormat, QT3DSU32 width,
+ QT3DSU32 height) override;
+ NVRenderRenderBuffer *GetRenderBuffer(const void *implementationHandle) override;
+ virtual void RenderBufferDestroyed(NVRenderRenderBuffer &buffer);
+
+ NVRenderFrameBuffer *CreateFrameBuffer() override;
+ NVRenderFrameBuffer *GetFrameBuffer(const void *implementationHandle) override;
+ virtual void FrameBufferDestroyed(NVRenderFrameBuffer &fb);
+
+ virtual NVRenderAttribLayout *
+ CreateAttributeLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) override;
+ NVRenderInputAssembler *CreateInputAssembler(
+ NVRenderAttribLayout *attribLayout, NVConstDataRef<NVRenderVertexBuffer *> buffers,
+ const NVRenderIndexBuffer *indexBuffer, NVConstDataRef<QT3DSU32> strides,
+ NVConstDataRef<QT3DSU32> offsets, NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount) override;
+ void SetInputAssembler(NVRenderInputAssembler *inputAssembler) override;
+
+ NVRenderVertFragCompilationResult CompileSource(
+ const char *shaderName, NVConstDataRef<QT3DSI8> vertShader,
+ NVConstDataRef<QT3DSI8> fragShader,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource = NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> tessEvaluationShaderSource = NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>(),
+ bool separateProgram = false,
+ NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown,
+ bool binaryProgram = false) override;
+
+ virtual NVRenderVertFragCompilationResult
+ CompileBinary(const char *shaderName, NVRenderShaderProgramBinaryType::Enum type,
+ NVDataRef<QT3DSI8> vertShader, NVDataRef<QT3DSI8> fragShader,
+ NVDataRef<QT3DSI8> tessControlShaderSource = NVDataRef<QT3DSI8>(),
+ NVDataRef<QT3DSI8> tessEvaluationShaderSource = NVDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>()) override;
+
+ virtual NVRenderVertFragCompilationResult
+ CompileComputeSource(const char *shaderName, NVConstDataRef<QT3DSI8> computeShaderSource) override;
+
+ NVRenderShaderProgram *GetShaderProgram(const void *implementationHandle) override;
+ virtual void ShaderDestroyed(NVRenderShaderProgram &shader);
+
+ NVRenderProgramPipeline *CreateProgramPipeline() override;
+ NVRenderPathSpecification *CreatePathSpecification() override;
+ NVRenderPathRender *CreatePathRender(size_t range = 1) override;
+ void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override;
+ void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override;
+ void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override;
+ void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inFunc) override;
+
+ virtual NVRenderPathFontSpecification *
+ CreatePathFontSpecification(CRegisteredString fontName) override;
+ virtual void ReleasePathFontSpecification(NVRenderPathFontSpecification &inPathSpec);
+ NVRenderPathFontItem *CreatePathFontItem() override;
+
+ void SetClearColor(QT3DSVec4 inClearColor) override;
+ QT3DSVec4 GetClearColor() const override { return m_HardwarePropertyContext.m_ClearColor; }
+
+ void SetBlendFunction(NVRenderBlendFunctionArgument inFunctions) override;
+ NVRenderBlendFunctionArgument GetBlendFunction() const override
+ {
+ return m_HardwarePropertyContext.m_BlendFunction;
+ }
+
+ void SetBlendEquation(NVRenderBlendEquationArgument inEquations) override;
+ NVRenderBlendEquationArgument GetBlendEquation() const override
+ {
+ return m_HardwarePropertyContext.m_BlendEquation;
+ };
+
+ void SetCullingEnabled(bool inEnabled) override;
+ bool IsCullingEnabled() const override { return m_HardwarePropertyContext.m_CullingEnabled; }
+
+ void SetDepthFunction(qt3ds::render::NVRenderBoolOp::Enum inFunction) override;
+ qt3ds::render::NVRenderBoolOp::Enum GetDepthFunction() const override
+ {
+ return m_HardwarePropertyContext.m_DepthFunction;
+ }
+
+ void SetBlendingEnabled(bool inEnabled) override;
+ bool IsBlendingEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_BlendingEnabled;
+ }
+
+ void SetDepthWriteEnabled(bool inEnabled) override;
+ bool IsDepthWriteEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_DepthWriteEnabled;
+ }
+ void SetDepthTestEnabled(bool inEnabled) override;
+ bool IsDepthTestEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_DepthTestEnabled;
+ }
+
+ void SetStencilTestEnabled(bool inEnabled) override;
+ bool IsStencilTestEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_StencilTestEnabled;
+ }
+
+ void SetScissorTestEnabled(bool inEnabled) override;
+ bool IsScissorTestEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_ScissorTestEnabled;
+ }
+ void SetScissorRect(NVRenderRect inRect) override;
+ NVRenderRect GetScissorRect() const override
+ {
+ return m_HardwarePropertyContext.m_ScissorRect;
+ }
+
+ void SetViewport(NVRenderRect inViewport) override;
+ NVRenderRect GetViewport() const override { return m_HardwarePropertyContext.m_Viewport; }
+
+ void SetColorWritesEnabled(bool inEnabled) override;
+ bool IsColorWritesEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_ColorWritesEnabled;
+ }
+
+ void SetMultisampleEnabled(bool inEnabled) override;
+ bool IsMultisampleEnabled() const override
+ {
+ return m_HardwarePropertyContext.m_MultisampleEnabled;
+ }
+
+ void SetActiveShader(NVRenderShaderProgram *inShader) override;
+ NVRenderShaderProgram *GetActiveShader() const override
+ {
+ return m_HardwarePropertyContext.m_ActiveShader;
+ }
+
+ void SetActiveProgramPipeline(NVRenderProgramPipeline *inProgramPipeline) override;
+ NVRenderProgramPipeline *GetActiveProgramPipeline() const override
+ {
+ return m_HardwarePropertyContext.m_ActiveProgramPipeline;
+ }
+
+ void DispatchCompute(NVRenderShaderProgram *inShader, QT3DSU32 numGroupsX,
+ QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override;
+
+ void SetDrawBuffers(NVConstDataRef<QT3DSI32> inDrawBufferSet) override;
+ void SetReadBuffer(NVReadFaces::Enum inReadFace) override;
+
+ void ReadPixels(NVRenderRect inRect, NVRenderReadPixelFormats::Enum inFormat,
+ NVDataRef<QT3DSU8> inWriteBuffer) override;
+
+ void SetRenderTarget(NVRenderFrameBuffer *inBuffer) override;
+ void SetReadTarget(NVRenderFrameBuffer *inBuffer) override;
+ NVRenderFrameBuffer *GetRenderTarget() const override
+ {
+ return m_HardwarePropertyContext.m_FrameBuffer;
+ }
+
+ void ResetBlendState() override;
+
+ // Push the entire set of properties.
+ void PushPropertySet() override { m_PropertyStack.push_back(m_HardwarePropertyContext); }
+
+ // Pop the entire set of properties, potentially forcing the values
+ // to opengl.
+ void PopPropertySet(bool inForceSetProperties) override;
+
+ // clear current bound render target
+ void Clear(NVRenderClearFlags flags) override;
+ // clear passed in rendertarget
+ void Clear(NVRenderFrameBuffer &fb, NVRenderClearFlags flags) override;
+
+ // copy framebuffer content between read target and render target
+ void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter) override;
+
+ void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override;
+ void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset) override;
+
+ NVFoundationBase &GetFoundation() override { return m_Foundation; }
+ qt3ds::foundation::IStringTable &GetStringTable() override { return m_StringTable; }
+ NVAllocatorCallback &GetAllocator() override { return m_Foundation.getAllocator(); }
+ QSurfaceFormat format() const override
+ {
+ return m_backend->format();
+ }
+ virtual void resetStates()
+ {
+ PushPropertySet();
+ PopPropertySet(true);
+ }
+ };
+}
+}
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp
new file mode 100644
index 00000000..b00b0af0
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderDataBuffer.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSFoundation.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderDataBuffer::NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ size_t size, NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_UsageType(usageType)
+ , m_BindFlags(bindFlags)
+ , m_BufferData(data)
+ , m_BufferCapacity(data.size())
+ , m_BufferSize(size)
+ , m_OwnsData(false)
+ , m_Mapped(false)
+ {
+ m_BufferHandle =
+ m_Backend->CreateBuffer(size, bindFlags, usageType, (const void *)m_BufferData.begin());
+ }
+
+ NVRenderDataBuffer::~NVRenderDataBuffer()
+ {
+ if (m_BufferHandle) {
+ m_Backend->ReleaseBuffer(m_BufferHandle);
+ }
+ m_BufferHandle = 0;
+
+ releaseMemory();
+ }
+
+ void NVRenderDataBuffer::releaseMemory()
+ {
+ // chekc if we should release memory
+ if (m_BufferData.size() && m_OwnsData) {
+ m_Foundation.getAllocator().deallocate(m_BufferData.begin());
+ }
+
+ m_BufferData = NVDataRef<QT3DSU8>();
+ m_OwnsData = false;
+ }
+
+ NVDataRef<QT3DSU8> NVRenderDataBuffer::MapBuffer()
+ {
+ // don't map twice
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ QT3DSU8 *pData = (QT3DSU8 *)m_Backend->MapBuffer(
+ m_BufferHandle, m_BindFlags, 0, m_BufferSize,
+ NVRenderBufferAccessFlags(NVRenderBufferAccessTypeValues::Read
+ | NVRenderBufferAccessTypeValues::Write));
+
+ releaseMemory();
+ m_BufferData = toDataRef(const_cast<QT3DSU8 *>(pData), (QT3DSU32)m_BufferSize);
+ m_BufferCapacity = (QT3DSU32)m_BufferSize;
+ m_OwnsData = false;
+
+ // currently we return a reference to the system memory
+ m_Mapped = true;
+ return m_BufferData;
+ }
+
+ NVDataRef<QT3DSU8> NVRenderDataBuffer::MapBufferRange(size_t offset, size_t size,
+ NVRenderBufferAccessFlags flags)
+ {
+ // don't map twice
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to map a mapped buffer");
+ QT3DS_ASSERT(false);
+ }
+ // don't map out of range
+ if ((m_BufferSize < (offset + size)) || (size == 0)) {
+ qCCritical(INVALID_OPERATION, "Attempting to map out of buffer range");
+ QT3DS_ASSERT(false);
+ }
+
+ QT3DSU8 *pData =
+ (QT3DSU8 *)m_Backend->MapBuffer(m_BufferHandle, m_BindFlags, offset, size, flags);
+
+ releaseMemory();
+ m_BufferData = toDataRef(const_cast<QT3DSU8 *>(pData), (QT3DSU32)size);
+ m_BufferCapacity = (QT3DSU32)size;
+ m_OwnsData = false;
+
+ // currently we return a reference to the system memory
+ m_Mapped = true;
+ return m_BufferData;
+ }
+
+ void NVRenderDataBuffer::UnmapBuffer()
+ {
+ if (m_Mapped) {
+ // update hardware
+ m_Backend->UnmapBuffer(m_BufferHandle, m_BindFlags);
+ m_Mapped = false;
+ releaseMemory();
+ }
+ }
+
+ void NVRenderDataBuffer::UpdateBuffer(NVConstDataRef<QT3DSU8> data, bool ownsMemory)
+ {
+ // don't update a mapped buffer
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to update a mapped buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ releaseMemory();
+
+ m_BufferData = toDataRef(const_cast<QT3DSU8 *>(data.begin()), data.size());
+ m_BufferCapacity = data.mSize;
+ m_OwnsData = ownsMemory;
+ // update hardware
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferCapacity, m_UsageType,
+ (const void *)m_BufferData.begin());
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h
new file mode 100644
index 00000000..579e2361
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDataBuffer.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_DATA_BUFFER_H
+#define QT3DS_RENDER_DATA_BUFFER_H
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+ class NVRenderBackend;
+
+ ///< Base class
+ class NVRenderDataBuffer : public NVRefCounted, public NVRenderImplemented
+ {
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBufferUsageType::Enum m_UsageType; ///< usage type
+ NVRenderBufferBindFlags m_BindFlags; ///< bind flags
+ NVDataRef<QT3DSU8> m_BufferData; ///< buffer data pointer
+ QT3DSU32 m_BufferCapacity; ///< size of internal backup buffer (m_BufferData)
+ size_t m_BufferSize; ///< size of buffer
+ bool m_OwnsData; ///< true when we own m_BufferData
+ bool m_Mapped; ///< true when locked for reading or writing to m_BufferData
+ NVRenderBackend::NVRenderBackendBufferObject m_BufferHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ *application.
+ *
+ * @return No return.
+ */
+ NVRenderDataBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t size,
+ NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data);
+
+ virtual ~NVRenderDataBuffer();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ /**
+ * @brief Get Buffer usage type
+ *
+ * @return Return usage tyoe
+ */
+ virtual NVRenderBufferUsageType::Enum GetBufferUsageType() const
+ {
+ return m_UsageType;
+ }
+
+ /**
+ * @brief Get Buffer usage type
+ * Should be overwritten
+ *
+ * @return Return usage tyoe
+ */
+ virtual NVRenderBufferBindFlags GetBufferBindings() const { return m_BindFlags; }
+
+ /**
+ * @brief Return buffer size in byte
+ *
+ * @return Return size
+ */
+ virtual QT3DSU32 Size() { return (QT3DSU32)m_BufferSize; }
+
+ /**
+ * @brief Get a pointer to the foundation
+ *
+ * @return pointer to foundation
+ */
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ virtual void Bind() = 0;
+
+ /**
+ * @brief Map the buffer
+ * Mapped buffers cannot be used for rendering
+ *
+ * @return Return mapped pointer to data
+ */
+ virtual NVDataRef<QT3DSU8> MapBuffer();
+
+ /**
+ * @brief Map a range of a buffer
+ * Mapped buffers cannot be used for rendering
+ *
+ * @param[in] offset Offset in bytes into the buffer
+ * @param[in] size Range in bytes to map
+ * @param[in] flags Buffer access flags
+ *
+ * @return Return mapped pointer to data
+ */
+ virtual NVDataRef<QT3DSU8> MapBufferRange(size_t offset, size_t size,
+ NVRenderBufferAccessFlags flags);
+
+ /**
+ * @brief Unmap the buffer
+ * This updates the data to the hardware
+ *
+ * @return no return
+ */
+ virtual void UnmapBuffer();
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ * @param[in] ownsMemory If true data will be owned by this object and can therefore be
+ * released
+ *
+ * @return No return.
+ */
+ virtual void UpdateBuffer(NVConstDataRef<QT3DSU8> data, bool ownsMemory = false);
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const = 0;
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override = 0;
+
+ private:
+ void releaseMemory();
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp
new file mode 100644
index 00000000..3ea47e23
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderDepthStencilState.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderDepthStencilState::NVRenderDepthStencilState(
+ NVRenderContextImpl &context, NVFoundationBase &fnd, bool enableDepth, bool depthMask,
+ NVRenderBoolOp::Enum depthFunc, bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_DepthEnabled(enableDepth)
+ , m_DepthMask(depthMask)
+ , m_DepthFunc(depthFunc)
+ , m_StencilEnabled(enableStencil)
+ , m_StencilFuncFront(stencilFuncFront)
+ , m_StencilFuncBack(stencilFuncBack)
+ , m_DepthStencilOpFront(depthStencilOpFront)
+ , m_DepthStencilOpBack(depthStencilOpBack)
+ {
+ // create backend handle
+ m_StateHandle = m_Backend->CreateDepthStencilState(
+ enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack,
+ depthStencilOpFront, depthStencilOpBack);
+ }
+
+ NVRenderDepthStencilState::~NVRenderDepthStencilState()
+ {
+ if (m_StateHandle) {
+ m_Context.StateDestroyed(*this);
+ m_Backend->ReleaseDepthStencilState(m_StateHandle);
+ }
+ }
+
+ NVRenderDepthStencilState *
+ NVRenderDepthStencilState::Create(NVRenderContextImpl &context, bool enableDepth,
+ bool depthMask, NVRenderBoolOp::Enum depthFunc,
+ bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack)
+ {
+ return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderDepthStencilState)(
+ context, context.GetFoundation(), enableDepth, depthMask, depthFunc, enableStencil,
+ stencilFuncFront, stencilFuncBack, depthStencilOpFront, depthStencilOpBack);
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h
new file mode 100644
index 00000000..e6b31981
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDepthStencilState.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_DEPTH_STENCIL_STATE_H
+#define QT3DS_RENDER_DEPTH_STENCIL_STATE_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+
+ // currently this handles only stencil state
+ class NVRenderDepthStencilState : public NVRefCounted
+ {
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBackend::NVRenderBackendDepthStencilStateObject
+ m_StateHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] enableDepth enable depth test
+ * @param[in] depthMask enable depth writes
+ * @param[in] depthFunc depth compare function
+ * @param[in] enableStencil enable stencil test
+ * @param[in] stencilFuncFront stencil setup front faces
+ * @param[in] stencilFuncBack stencil setup back faces
+ * @param[in] depthStencilOpFront depth/stencil operations front faces
+ * @param[in] depthStencilOpBack depth/stencil operations back faces
+ *
+ * @return No return.
+ */
+ NVRenderDepthStencilState(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc,
+ bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack);
+
+ virtual ~NVRenderDepthStencilState();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ ///< various get functions
+ const NVRenderStencilFunctionArgument GetStencilFunc(NVRenderFaces::Enum face) const
+ {
+ return (face == NVRenderFaces::Back) ? m_StencilFuncBack : m_StencilFuncFront;
+ }
+ const NVRenderStencilOperationArgument GetStencilOp(NVRenderFaces::Enum face) const
+ {
+ return (face == NVRenderFaces::Back) ? m_DepthStencilOpBack : m_DepthStencilOpFront;
+ }
+ NVRenderBoolOp::Enum GetDepthFunc() const { return m_DepthFunc; }
+ bool GetDepthEnabled() const { return m_DepthEnabled; }
+ bool GetStencilEnabled() const { return m_StencilEnabled; }
+ bool GetDepthMask() const { return m_DepthMask; }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendDepthStencilStateObject
+ GetDepthStencilObjectHandle()
+ {
+ return m_StateHandle;
+ }
+
+ static NVRenderDepthStencilState *
+ Create(NVRenderContextImpl &context, bool enableDepth, bool depthMask,
+ NVRenderBoolOp::Enum depthFunc, bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack);
+
+ private:
+ bool m_DepthEnabled; ///< depth test enabled
+ bool m_DepthMask; ///< depth writes enabled
+ NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func
+ bool m_StencilEnabled; ///< stencil test enabled
+ NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup front faces
+ NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup back faces
+ NVRenderStencilOperationArgument
+ m_DepthStencilOpFront; ///< depth stencil operation front faces
+ NVRenderStencilOperationArgument
+ m_DepthStencilOpBack; ///< depth stencil operation back faces
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp
new file mode 100644
index 00000000..9940003f
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderDrawIndirectBuffer.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderDrawIndirectBuffer::NVRenderDrawIndirectBuffer(NVRenderContextImpl &context,
+ size_t size,
+ NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data)
+ : NVRenderDataBuffer(context, context.GetFoundation(), size,
+ NVRenderBufferBindValues::Draw_Indirect, usageType, data)
+ , m_Dirty(true)
+ {
+ }
+
+ NVRenderDrawIndirectBuffer::~NVRenderDrawIndirectBuffer() { m_Context.BufferDestroyed(*this); }
+
+ void NVRenderDrawIndirectBuffer::Bind()
+ {
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ m_Backend->BindBuffer(m_BufferHandle, m_BindFlags);
+ }
+
+ void NVRenderDrawIndirectBuffer::Update()
+ {
+ // we only update the buffer if it is dirty and we actually have some data
+ if (m_Dirty && m_BufferData.size()) {
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType,
+ m_BufferData.begin());
+ m_Dirty = false;
+ }
+ }
+
+ void NVRenderDrawIndirectBuffer::UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data)
+ {
+ // we only update the buffer if we something
+ if (data.size())
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType,
+ data.begin() + offset);
+ }
+
+ NVRenderDrawIndirectBuffer *
+ NVRenderDrawIndirectBuffer::Create(NVRenderContextImpl &context,
+ NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVFoundationBase &fnd(context.GetFoundation());
+ NVRenderDrawIndirectBuffer *retval = NULL;
+
+ // these are the context flags which do not support this drawing mode
+ NVRenderContextType noDrawIndirectSupported(
+ NVRenderContextValues::GL2 | NVRenderContextValues::GLES2 | NVRenderContextValues::GL3
+ | NVRenderContextValues::GLES3);
+ NVRenderContextType ctxType = context.GetRenderContextType();
+
+ if (!(ctxType & noDrawIndirectSupported)) {
+ QT3DSU32 bufSize = sizeof(NVRenderDrawIndirectBuffer);
+ QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), bufSize, "DrawIndirectBuffer");
+ retval = new (newMem) NVRenderDrawIndirectBuffer(
+ context, size, usageType,
+ toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()));
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h
new file mode 100644
index 00000000..81cd59d1
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDrawIndirectBuffer.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_DRAW_INDIRECT_BUFFER_H
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Utils.h"
+#include "foundation/StringTable.h"
+#include "render/Qt3DSRenderDataBuffer.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ // forward declaration
+ class NVRenderContextImpl;
+
+ struct DrawArraysIndirectCommand
+ {
+ QT3DSU32 count;
+ QT3DSU32 primCount;
+ QT3DSU32 first;
+ QT3DSU32 baseInstance;
+ };
+
+ struct DrawElementsIndirectCommand
+ {
+ QT3DSU32 count;
+ QT3DSU32 primCount;
+ QT3DSU32 firstIndex;
+ QT3DSU32 baseVertex;
+ QT3DSU32 baseInstance;
+ };
+
+ ///< Constant (uniform) buffer representation
+ class NVRenderDrawIndirectBuffer : public NVRenderDataBuffer
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return.
+ */
+ NVRenderDrawIndirectBuffer(NVRenderContextImpl &context, size_t size,
+ NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data);
+
+ ///< destructor
+ virtual ~NVRenderDrawIndirectBuffer();
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief update the buffer to hardware
+ *
+ * @return no return.
+ */
+ virtual void Update();
+
+ /**
+ * @brief update a piece of memory directly within the storage buffer
+ *
+ * Note: When you use this function you should know what you are doing.
+ * The memory layout within C++ must exactly match the memory layout in the
+ *shader.
+ * We use std140 (430) layout which guarantees a specific layout behavior across
+ *all HW vendors.
+ * How the memory layout is computed can be found in the GL spec.
+ *
+ * @param[in] offset offset into storage buffer
+ * @param[in] data pointer to data
+ *
+ * @return no return
+ */
+ void UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data);
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+
+ /**
+ * @brief create a NVRenderDrawIndirectBuffer object
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return the buffer object or NULL
+ */
+ static NVRenderDrawIndirectBuffer *Create(NVRenderContextImpl &context,
+ NVRenderBufferUsageType::Enum usageType,
+ size_t size, NVConstDataRef<QT3DSU8> bufferData);
+
+ private:
+ bool m_Dirty; ///< true if buffer is dirty
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderDrawable.h b/src/Runtime/Source/render/Qt3DSRenderDrawable.h
new file mode 100644
index 00000000..0f78aacc
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderDrawable.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H
+#define QT3DS_RENDER_QT3DS_RENDER_DRAWABLE_H
+#include "Qt3DSRenderBaseTypes.h"
+
+namespace qt3ds {
+namespace render {
+ class NVRenderDrawable
+ {
+ protected:
+ virtual ~NVRenderDrawable() {}
+
+ public:
+ /**
+ * Draw using this object.
+ * offset is in num elements, not in number of bytes
+ * because the various different draw functions differ in what datatype
+ * offset is (gl drawarrays vs gl drawindexedarras).
+ */
+ virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) = 0;
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp
new file mode 100644
index 00000000..e2f31f1b
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderFragmentShader.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderFragmentShader::NVRenderFragmentShader(NVRenderContextImpl &context,
+ NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram)
+ : NVRenderShader(context, fnd, source, binaryProgram)
+ , m_ShaderHandle(NULL)
+ {
+ m_ShaderHandle = m_Backend->CreateFragmentShader(source, m_ErrorMessage, binaryProgram);
+ }
+
+ NVRenderFragmentShader::~NVRenderFragmentShader()
+ {
+ if (m_ShaderHandle) {
+ m_Backend->ReleaseFragmentShader(m_ShaderHandle);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h
new file mode 100644
index 00000000..f661605c
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderFragmentShader.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_FRAGMENT_SHADER_H
+#define QT3DS_RENDER_FRAGMENT_SHADER_H
+
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderShader.h"
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ ///< This class represents a fragment shader
+ class NVRenderFragmentShader : public NVRenderShader
+ {
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] source Pointer to shader source code
+ * @param[in] binaryProgram true if this is a binary program
+ *
+ * @return No return.
+ */
+ NVRenderFragmentShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram);
+
+ /// @brief destructor
+ ~NVRenderFragmentShader();
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ bool IsValid() override { return (m_ShaderHandle != NULL); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendFragmentShaderObject GetShaderHandle()
+ {
+ return m_ShaderHandle;
+ }
+
+ private:
+ NVRenderBackend::NVRenderBackendFragmentShaderObject
+ m_ShaderHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp
new file mode 100644
index 00000000..0ab38428
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "render/Qt3DSRenderFrameBuffer.h"
+#include "render/Qt3DSRenderRenderBuffer.h"
+#include "render/Qt3DSRenderTexture2D.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderFrameBuffer::NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_BufferHandle(NULL)
+ , m_AttachmentBits(0)
+ {
+ m_BufferHandle = m_Backend->CreateRenderTarget();
+ QT3DS_ASSERT(m_BufferHandle);
+ }
+
+ NVRenderFrameBuffer::~NVRenderFrameBuffer()
+ {
+ m_Context.FrameBufferDestroyed(*this);
+ m_Backend->ReleaseRenderTarget(m_BufferHandle);
+ m_BufferHandle = 0;
+ m_AttachmentBits = 0;
+
+ // release attachments
+ QT3DS_FOREACH(idx, (QT3DSU32)NVRenderFrameBufferAttachments::LastAttachment)
+ {
+ if ((NVRenderFrameBufferAttachments::Enum)idx
+ != NVRenderFrameBufferAttachments::DepthStencil
+ || m_Context.IsDepthStencilSupported())
+ releaseAttachment((NVRenderFrameBufferAttachments::Enum)idx);
+ }
+ }
+
+ inline void CheckAttachment(NVRenderContext &ctx,
+ NVRenderFrameBufferAttachments::Enum attachment)
+ {
+#ifdef _DEBUG
+ QT3DS_ASSERT(attachment != NVRenderFrameBufferAttachments::DepthStencil
+ || ctx.IsDepthStencilSupported());
+#endif
+ (void)ctx;
+ (void)attachment;
+ }
+
+ NVRenderTextureTargetType::Enum
+ NVRenderFrameBuffer::releaseAttachment(NVRenderFrameBufferAttachments::Enum idx)
+ {
+ NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Unknown;
+
+ NVRenderTextureOrRenderBuffer Attach = m_Attachments[idx];
+ if (Attach.HasTexture2D()) {
+ target = (Attach.GetTexture2D()->IsMultisampleTexture())
+ ? NVRenderTextureTargetType::Texture2D_MS
+ : NVRenderTextureTargetType::Texture2D;
+ Attach.GetTexture2D()->release();
+ } else if (Attach.HasTexture2DArray()) {
+ target = (Attach.GetTexture2DArray()->IsMultisampleTexture())
+ ? NVRenderTextureTargetType::Texture2D_MS
+ : NVRenderTextureTargetType::Texture2D_Array;
+ Attach.GetTexture2DArray()->release();
+ } else if (Attach.HasTextureCube()) {
+ target = (Attach.GetTextureCube()->IsMultisampleTexture())
+ ? NVRenderTextureTargetType::Texture2D_MS
+ : NVRenderTextureTargetType::TextureCube;
+ Attach.GetTextureCube()->release();
+ } else if (Attach.HasRenderBuffer())
+ Attach.GetRenderBuffer()->release();
+
+ CheckAttachment(m_Context, idx);
+ m_Attachments[idx] = NVRenderTextureOrRenderBuffer();
+
+ m_AttachmentBits &= ~(1 << idx);
+
+ return target;
+ }
+
+ NVRenderTextureOrRenderBuffer
+ NVRenderFrameBuffer::GetAttachment(NVRenderFrameBufferAttachments::Enum attachment)
+ {
+ if (attachment == NVRenderFrameBufferAttachments::Unknown
+ || attachment > NVRenderFrameBufferAttachments::LastAttachment) {
+ qCCritical(INVALID_PARAMETER, "Attachment out of range");
+ return NVRenderTextureOrRenderBuffer();
+ }
+ CheckAttachment(m_Context, attachment);
+ return m_Attachments[attachment];
+ }
+
+ void NVRenderFrameBuffer::Attach(NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderTextureOrRenderBuffer buffer,
+ NVRenderTextureTargetType::Enum target)
+ {
+ if (attachment == NVRenderFrameBufferAttachments::Unknown
+ || attachment > NVRenderFrameBufferAttachments::LastAttachment) {
+ qCCritical(INVALID_PARAMETER, "Attachment out of range");
+ return;
+ }
+
+ // early out
+ // if there is nothing to detach
+ if (!buffer.HasTexture2D() && !buffer.HasRenderBuffer() && !buffer.HasTexture2DArray()
+ && !(m_AttachmentBits & (1 << attachment)))
+ return;
+
+ CheckAttachment(m_Context, attachment);
+ // Ensure we are the bound framebuffer
+ m_Context.SetRenderTarget(this);
+
+ // release previous attachments
+ NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment);
+
+ if (buffer.HasTexture2D()) {
+ // On the same attachment point there could be a something attached with a different
+ // target MSAA <--> NoMSAA
+ if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target)
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ NVRenderBackend::NVRenderBackendTextureObject(NULL),
+ theRelTarget);
+
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ buffer.GetTexture2D()->GetTextureObjectHandle(), target);
+ buffer.GetTexture2D()->addRef();
+ m_AttachmentBits |= (1 << attachment);
+ } else if (buffer.HasTexture2DArray()) {
+ // On the same attachment point there could be a something attached with a different
+ // target MSAA <--> NoMSAA
+ if (theRelTarget != NVRenderTextureTargetType::Unknown && theRelTarget != target)
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ NVRenderBackend::NVRenderBackendTextureObject(NULL),
+ theRelTarget);
+
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ buffer.GetTexture2D()->GetTextureObjectHandle(), target);
+ buffer.GetTexture2DArray()->addRef();
+ m_AttachmentBits |= (1 << attachment);
+ } else if (buffer.HasRenderBuffer()) {
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ buffer.GetRenderBuffer()->GetRenderBuffertHandle());
+ buffer.GetRenderBuffer()->addRef();
+ m_AttachmentBits |= (1 << attachment);
+ } else if (theRelTarget == NVRenderTextureTargetType::Unknown) {
+ // detach renderbuffer
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ NVRenderBackend::NVRenderBackendRenderbufferObject(NULL));
+ } else {
+ // detach texture
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ NVRenderBackend::NVRenderBackendTextureObject(NULL),
+ theRelTarget);
+ }
+ m_Attachments[attachment] = buffer;
+ }
+
+ void NVRenderFrameBuffer::AttachLayer(NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer,
+ QT3DSI32 level)
+ {
+ if (attachment == NVRenderFrameBufferAttachments::Unknown
+ || attachment > NVRenderFrameBufferAttachments::LastAttachment) {
+ qCCritical(INVALID_PARAMETER, "Attachment out of range");
+ return;
+ }
+
+ // This function is only used for attaching a layer
+ // If texture exists probably something is wrong
+ if (!buffer.HasTexture2DArray()) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ CheckAttachment(m_Context, attachment);
+ // Ensure we are the bound framebuffer
+ m_Context.SetRenderTarget(this);
+
+ // release previous attachments
+ NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment);
+
+ // On the same attachment point there could be a something attached with a different target
+ // MSAA <--> NoMSAA
+ if (theRelTarget != NVRenderTextureTargetType::Unknown
+ && theRelTarget != NVRenderTextureTargetType::Texture2D_Array)
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ NVRenderBackend::NVRenderBackendTextureObject(NULL),
+ theRelTarget);
+
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ buffer.GetTexture2DArray()->GetTextureObjectHandle(), level,
+ layer);
+ buffer.GetTexture2DArray()->addRef();
+ m_AttachmentBits |= (1 << attachment);
+
+ m_Attachments[attachment] = buffer;
+ }
+
+ void NVRenderFrameBuffer::AttachFace(NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderTextureOrRenderBuffer buffer,
+ NVRenderTextureCubeFaces::Enum face)
+ {
+ if (attachment == NVRenderFrameBufferAttachments::Unknown
+ || attachment > NVRenderFrameBufferAttachments::LastAttachment) {
+ qCCritical(INVALID_PARAMETER, "Attachment out of range");
+ return;
+ }
+
+ if (face == NVRenderTextureCubeFaces::InvalidFace) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ CheckAttachment(m_Context, attachment);
+ // Ensure we are the bound framebuffer
+ m_Context.SetRenderTarget(this);
+
+ // release previous attachments
+ NVRenderTextureTargetType::Enum attachTarget = static_cast<NVRenderTextureTargetType::Enum>(
+ (int)NVRenderTextureTargetType::TextureCube + (int)face);
+ NVRenderTextureTargetType::Enum theRelTarget = releaseAttachment(attachment);
+
+ // If buffer has no texture cube, this call is used to detach faces.
+ // If release target is not cube, there is something else attached to that
+ // attachment point, so we want to release that first. E.g (MSAA <--> NoMSAA)
+ if (theRelTarget == NVRenderTextureTargetType::TextureCube && !buffer.HasTextureCube()) {
+ theRelTarget = attachTarget;
+ attachTarget = NVRenderTextureTargetType::Unknown;
+ } else if (theRelTarget == NVRenderTextureTargetType::TextureCube) {
+ theRelTarget = NVRenderTextureTargetType::Unknown;
+ }
+ if (theRelTarget != NVRenderTextureTargetType::Unknown) {
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ NVRenderBackend::NVRenderBackendTextureObject(NULL),
+ theRelTarget);
+ }
+
+ if (attachTarget != NVRenderTextureTargetType::Unknown) {
+ m_Backend->RenderTargetAttach(m_BufferHandle, attachment,
+ buffer.GetTextureCube()->GetTextureObjectHandle(),
+ attachTarget);
+ buffer.GetTextureCube()->addRef();
+ m_AttachmentBits |= (1 << attachment);
+ }
+
+ m_Attachments[attachment] = buffer;
+ }
+
+ bool NVRenderFrameBuffer::IsComplete()
+ {
+ // Ensure we are the bound framebuffer
+ m_Context.SetRenderTarget(this);
+
+ return m_Backend->RenderTargetIsValid(m_BufferHandle);
+ }
+}
+}
+
+qt3ds::render::NVRenderFrameBuffer *
+qt3ds::render::NVRenderFrameBuffer::Create(NVRenderContextImpl &context)
+{
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderFrameBuffer)(context, context.GetFoundation());
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h
new file mode 100644
index 00000000..1882a27d
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderFrameBuffer.h
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_FRAME_BUFFER_H
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSAssert.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+ class NVRenderTexture2D;
+ class NVRenderRenderBuffer;
+ class NVRenderTexture2DArray;
+ class NVRenderTextureCube;
+
+ class NVRenderTextureOrRenderBuffer
+ {
+ NVRenderTexture2D *m_Texture2D;
+ NVRenderTexture2DArray *m_Texture2DArray;
+ NVRenderTextureCube *m_TextureCube;
+ NVRenderRenderBuffer *m_RenderBuffer;
+
+ public:
+ NVRenderTextureOrRenderBuffer(NVRenderTexture2D &texture)
+ : m_Texture2D(&texture)
+ , m_Texture2DArray(NULL)
+ , m_TextureCube(NULL)
+ , m_RenderBuffer(NULL)
+ {
+ }
+ NVRenderTextureOrRenderBuffer(NVRenderRenderBuffer &render)
+ : m_Texture2D(NULL)
+ , m_Texture2DArray(NULL)
+ , m_TextureCube(NULL)
+ , m_RenderBuffer(&render)
+ {
+ }
+ NVRenderTextureOrRenderBuffer(NVRenderTexture2DArray &textureArray)
+ : m_Texture2D(NULL)
+ , m_Texture2DArray(&textureArray)
+ , m_TextureCube(NULL)
+ , m_RenderBuffer(NULL)
+ {
+ }
+ NVRenderTextureOrRenderBuffer(NVRenderTextureCube &textureCube)
+ : m_Texture2D(NULL)
+ , m_Texture2DArray(NULL)
+ , m_TextureCube(&textureCube)
+ , m_RenderBuffer(NULL)
+ {
+ }
+ NVRenderTextureOrRenderBuffer()
+ : m_Texture2D(NULL)
+ , m_Texture2DArray(NULL)
+ , m_TextureCube(NULL)
+ , m_RenderBuffer(NULL)
+ {
+ }
+ NVRenderTextureOrRenderBuffer(const NVRenderTextureOrRenderBuffer &other)
+ : m_Texture2D(other.m_Texture2D)
+ , m_Texture2DArray(other.m_Texture2DArray)
+ , m_TextureCube(other.m_TextureCube)
+ , m_RenderBuffer(other.m_RenderBuffer)
+ {
+ }
+ NVRenderTextureOrRenderBuffer &operator=(const NVRenderTextureOrRenderBuffer &other)
+ {
+ if (this != &other) {
+ m_Texture2D = const_cast<NVRenderTexture2D *>(other.m_Texture2D);
+ m_Texture2DArray = const_cast<NVRenderTexture2DArray *>(other.m_Texture2DArray);
+ m_RenderBuffer = const_cast<NVRenderRenderBuffer *>(other.m_RenderBuffer);
+ m_TextureCube = const_cast<NVRenderTextureCube *>(other.m_TextureCube);
+ }
+ return *this;
+ }
+
+ bool HasTexture2D() const { return m_Texture2D != NULL; }
+ bool HasTexture2DArray() const { return m_Texture2DArray != NULL; }
+ bool HasTextureCube() const { return m_TextureCube != NULL; }
+ bool HasRenderBuffer() const { return m_RenderBuffer != NULL; }
+
+ NVRenderTexture2D *GetTexture2D() const
+ {
+ QT3DS_ASSERT(HasTexture2D());
+ return m_Texture2D;
+ }
+ NVRenderTexture2DArray *GetTexture2DArray() const
+ {
+ QT3DS_ASSERT(HasTexture2DArray());
+ return m_Texture2DArray;
+ }
+ NVRenderTextureCube *GetTextureCube() const
+ {
+ QT3DS_ASSERT(HasTextureCube());
+ return m_TextureCube;
+ }
+ NVRenderRenderBuffer *GetRenderBuffer() const
+ {
+ QT3DS_ASSERT(HasRenderBuffer());
+ return m_RenderBuffer;
+ }
+ };
+
+ class NVRenderFrameBuffer : public NVRefCounted, public NVRenderImplemented
+ {
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+
+ NVRenderTextureOrRenderBuffer
+ m_Attachments[NVRenderFrameBufferAttachments::LastAttachment]; ///< attachments array
+ NVRenderBackend::NVRenderBackendRenderTargetObject
+ m_BufferHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderFrameBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ /// destructor
+ virtual ~NVRenderFrameBuffer();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ /**
+ * @brief query attachment
+ *
+ *
+ * @return buffer format
+ */
+ virtual NVRenderTextureOrRenderBuffer
+ GetAttachment(NVRenderFrameBufferAttachments::Enum attachment);
+
+ /**
+ * @brief Attach a render or texture buffer to a render target
+ * For texture attachments we use always level 0
+ *
+ * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...)
+ * @param[in] buffer Contains a pointer to the attachment
+ * @param[in] target Attachment texture target
+ *
+ * @return no return
+ */
+ virtual void
+ Attach(NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderTextureOrRenderBuffer buffer,
+ NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D);
+
+ /**
+ * @brief Attach a particular layer of the texture 2D array to a render target
+ *
+ * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...)
+ * @param[in] buffer Pointer to the Texture Array which contains the
+ * layers
+ * @param[in] layer The index to the layer that will be attached to the
+ * target
+ * @param[in] level Mip level of the texture that will be attached
+ * (default 0)
+ *
+ * @return no return
+ */
+ virtual void AttachLayer(NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderTextureOrRenderBuffer buffer, QT3DSI32 layer,
+ QT3DSI32 level = 0);
+
+ /**
+ * @brief Attach a particular face of the texture cubemap to a render target
+ *
+ * @param[in] attachment Attachment point (e.g. COLOR0, DEPTH...)
+ * @param[in] buffer Pointer to the Texture Array which contains the
+ * layers
+ * @param[in] face The face of the cubemap that will be attached to the
+ * target
+ * @param[in] level Mip level of the texture that will be attached
+ * (default 0)
+ *
+ * @return no return
+ */
+ virtual void AttachFace(NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderTextureOrRenderBuffer buffer,
+ NVRenderTextureCubeFaces::Enum face);
+
+ /**
+ * @brief Check that this framebuffer is complete and can be rendered to.
+ *
+ *
+ * @return true if complete
+ */
+ virtual bool IsComplete();
+
+ /**
+ * @brief query if framebuffer has any attachment
+ *
+ * @return true if any attachment
+ */
+ virtual bool HasAnyAttachment() { return (m_AttachmentBits != 0); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendRenderTargetObject GetFrameBuffertHandle()
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<const void *>(m_BufferHandle);
+ }
+
+ /**
+ * @brief static creator function
+ *
+ * @param[in] context Pointer to context
+ *
+ * @return a pointer to framebuffer object.
+ */
+ static NVRenderFrameBuffer *Create(NVRenderContextImpl &context);
+
+ private:
+ /**
+ * @brief releaes an attached object
+ *
+ * @return which target we released
+ */
+ NVRenderTextureTargetType::Enum releaseAttachment(NVRenderFrameBufferAttachments::Enum idx);
+
+ QT3DSU32 m_AttachmentBits; ///< holds flags for current attached buffers
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp
new file mode 100644
index 00000000..50567287
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderGeometryShader.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderGeometryShader::NVRenderGeometryShader(NVRenderContextImpl &context,
+ NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram)
+ : NVRenderShader(context, fnd, source, binaryProgram)
+ , m_ShaderHandle(NULL)
+ {
+ m_ShaderHandle = m_Backend->CreateGeometryShader(source, m_ErrorMessage, binaryProgram);
+ }
+
+ NVRenderGeometryShader::~NVRenderGeometryShader()
+ {
+ if (m_ShaderHandle) {
+ m_Backend->ReleaseGeometryShader(m_ShaderHandle);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h
new file mode 100644
index 00000000..2a643cfc
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderGeometryShader.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_GEOMETRY_SHADER_H
+#define QT3DS_RENDER_GEOMETRY_SHADER_H
+
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderShader.h"
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ ///< This class represents a vertex shader
+ class NVRenderGeometryShader : public NVRenderShader
+ {
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] source Pointer to shader source code
+ * @param[in] binaryProgram true if this is a binary program
+ *
+ * @return No return.
+ */
+ NVRenderGeometryShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram);
+
+ /// @brief destructor
+ ~NVRenderGeometryShader();
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ bool IsValid() override { return (m_ShaderHandle != NULL); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendGeometryShaderObject GetShaderHandle()
+ {
+ return m_ShaderHandle;
+ }
+
+ private:
+ NVRenderBackend::NVRenderBackendGeometryShaderObject
+ m_ShaderHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp b/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp
new file mode 100644
index 00000000..e987cc31
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderImageTexture.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderImageTexture.h"
+#include "render/Qt3DSRenderTexture2D.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderImage2D::NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTexture2D *inTexture,
+ NVRenderImageAccessType::Enum inAccess)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_Texture2D(inTexture)
+ , m_TextureUnit(QT3DS_MAX_U32)
+ , m_AccessType(inAccess)
+ , m_TextureLevel(0)
+ {
+ inTexture->addRef();
+ }
+
+ NVRenderImage2D::~NVRenderImage2D()
+ {
+ m_Context.ImageDestroyed(*this);
+ m_Texture2D->release();
+ }
+
+ void NVRenderImage2D::SetTextureLevel(QT3DSI32 inLevel)
+ {
+ if (m_Texture2D && m_Texture2D->GetNumMipmaps() >= (QT3DSU32)inLevel) {
+ m_TextureLevel = inLevel;
+ }
+ }
+
+ void NVRenderImage2D::Bind(QT3DSU32 unit)
+ {
+ if (unit == -1)
+ m_TextureUnit = m_Context.GetNextTextureUnit();
+ else
+ m_TextureUnit = unit;
+
+ STextureDetails theDetails(m_Texture2D->GetTextureDetails());
+
+ // note it is the callers responsibility that the texture format is supported by the compute
+ // shader
+ m_Backend->BindImageTexture(m_Texture2D->GetTextureObjectHandle(), m_TextureUnit,
+ m_TextureLevel, false, 0, m_AccessType, theDetails.m_Format);
+ }
+
+ NVRenderBackend::NVRenderBackendTextureObject NVRenderImage2D::GetTextureObjectHandle()
+ {
+ return m_Texture2D->GetTextureObjectHandle();
+ }
+
+ NVRenderImage2D *NVRenderImage2D::Create(NVRenderContextImpl &context,
+ NVRenderTexture2D *inTexture,
+ NVRenderImageAccessType::Enum inAccess)
+ {
+ if (inTexture)
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderImage2D)(context, context.GetFoundation(), inTexture, inAccess);
+ else
+ return NULL;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderImageTexture.h b/src/Runtime/Source/render/Qt3DSRenderImageTexture.h
new file mode 100644
index 00000000..8b3469b0
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderImageTexture.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H
+#define QT3DS_RENDER_QT3DS_RENDER_IMAGE_TEXTURE_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+ class NVRenderTexture2D;
+
+ // a wrapper class for NVRenderTexture2D
+ // to use with compute shaders and load / store image shaders
+
+ class NVRenderImage2D : public NVRefCounted
+ {
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderTexture2D *m_Texture2D; ///< pointer to texture
+ QT3DSI32 m_TextureUnit; ///< texture unit this texture should use
+ NVRenderImageAccessType::Enum
+ m_AccessType; ///< texture / image access type ( read, write, read_write )
+ QT3DSU32 m_TextureLevel; ///< texture level we use for this image
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] inTexture Pointer to a NVRenderTexture2D object
+ * @param[in] inAccess Image access type ( read, write, read_write )
+ *
+ * @return No return.
+ */
+ NVRenderImage2D(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTexture2D *inTexture, NVRenderImageAccessType::Enum inAccess);
+
+ virtual ~NVRenderImage2D();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief Set the access rights within the shader.
+ * Can be read, write or read_write.
+ *
+ * @param[in] inAccess Image access type ( read, write, read_write )
+ *
+ * @return No return.
+ */
+ virtual void SetAccessType(NVRenderImageAccessType::Enum inAccess)
+ {
+ m_AccessType = inAccess;
+ }
+
+ /**
+ * @brief Set the texture level we use for this image
+ *
+ * @param[in] inLevel texture level ( must be in range of max levels )
+ *
+ * @return No return.
+ */
+ virtual void SetTextureLevel(QT3DSI32 inLevel);
+
+ /**
+ * @brief Get texture unit used
+ *
+ *
+ * @return texture unit bound to.
+ */
+ virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; }
+
+ /**
+ * @brief Bind a texture for shader access
+ *
+ * @param[in] unit The binding point
+ *
+ * @return No return.
+ */
+ virtual void Bind(QT3DSU32 unit);
+
+ /**
+ * @brief get the backend object handle
+ * here we return the handle from the wrapped texture
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle();
+
+ /**
+ * @brief static creation function
+ *
+ * @param[in] context Pointer to context
+ * @param[in] inTexture Pointer to a NVRenderTexture2D object
+ * @param[in] inAccess Image access type ( read, write, read_write )
+ *
+ * @return No return.
+ */
+ static NVRenderImage2D *Create(NVRenderContextImpl &context, NVRenderTexture2D *inTexture,
+ NVRenderImageAccessType::Enum inAccess);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp
new file mode 100644
index 00000000..37f56bd2
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderIndexBuffer.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/StringTable.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderIndexBuffer::NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size,
+ NVRenderComponentTypes::Enum componentType,
+ NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data)
+ : NVRenderDataBuffer(context, context.GetFoundation(), size,
+ NVRenderBufferBindValues::Index, usageType, data)
+ , m_ComponentType(componentType)
+ {
+ }
+
+ NVRenderIndexBuffer::~NVRenderIndexBuffer() { m_Context.BufferDestroyed(*this); }
+
+ QT3DSU32 NVRenderIndexBuffer::GetNumIndices() const
+ {
+ QT3DSU32 dtypeSize = NVRenderComponentTypes::getSizeofType(m_ComponentType);
+ return m_BufferCapacity / dtypeSize;
+ }
+
+ void NVRenderIndexBuffer::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset)
+ {
+ m_Backend->DrawIndexed(
+ drawMode, count, m_ComponentType,
+ (const void *)(offset * NVRenderComponentTypes::getSizeofType(m_ComponentType)));
+ }
+
+ void NVRenderIndexBuffer::DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset)
+ {
+ m_Backend->DrawIndexedIndirect(drawMode, m_ComponentType, (const void *)offset);
+ }
+
+ void NVRenderIndexBuffer::Bind()
+ {
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ m_Backend->BindBuffer(m_BufferHandle, m_BindFlags);
+ }
+
+ NVRenderIndexBuffer *NVRenderIndexBuffer::Create(NVRenderContextImpl &context,
+ NVRenderBufferUsageType::Enum usageType,
+ NVRenderComponentTypes::Enum componentType,
+ size_t size, NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVFoundationBase &fnd(context.GetFoundation());
+ if (componentType != NVRenderComponentTypes::QT3DSU32
+ && componentType != NVRenderComponentTypes::QT3DSU16
+ && componentType != NVRenderComponentTypes::QT3DSU8) {
+ qCCritical(INVALID_PARAMETER, "Invalid component type for index buffer");
+ QT3DS_ASSERT(false);
+ return NULL;
+ }
+
+ QT3DSU32 ibufSize = sizeof(NVRenderIndexBuffer);
+ QT3DSU8 *baseMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), ibufSize, "IndexBuffer");
+ NVRenderIndexBuffer *retval = new (baseMem) NVRenderIndexBuffer(
+ context, size, componentType, usageType,
+ toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()));
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h
new file mode 100644
index 00000000..6b9c4711
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderIndexBuffer.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_INDEX_BUFFER_H
+#define QT3DS_RENDER_INDEX_BUFFER_H
+#include "render/Qt3DSRenderDataBuffer.h"
+#include "render/Qt3DSRenderDrawable.h"
+
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+
+ class NVRenderIndexBuffer : public NVRenderDataBuffer, public NVRenderDrawable
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] componentType Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return.
+ */
+ NVRenderIndexBuffer(NVRenderContextImpl &context, size_t size,
+ NVRenderComponentTypes::Enum componentType,
+ NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data);
+
+ ///< destruvtor
+ ~NVRenderIndexBuffer();
+
+ /**
+ * @brief get the component type (QT3DSU8, QT3DSU16)
+ *
+ * @return the component type
+ */
+ virtual NVRenderComponentTypes::Enum GetComponentType() const { return m_ComponentType; }
+
+ /**
+ * @brief get the index count
+ *
+ * @return actual index count
+ */
+ virtual QT3DSU32 GetNumIndices() const;
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief draw the buffer
+ *
+ * @param[in] drawMode draw mode (e.g Triangles...)
+ * @param[in] count vertex count
+ * @param[in] offset start offset in byte
+ *
+ * @return no return.
+ */
+ void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 count, QT3DSU32 offset) override;
+
+ /**
+ * @brief draw the buffer via indirec draw buffer setup
+ *
+ * @param[in] drawMode draw mode (e.g Triangles...)
+ * @param[in] offset byte offset into the bound drawIndirectBuffer see
+ * NVRenderDrawIndirectBuffer
+ *
+ * @return no return.
+ */
+ virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, QT3DSU32 offset);
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+
+ static NVRenderIndexBuffer *Create(NVRenderContextImpl &context,
+ NVRenderBufferUsageType::Enum usageType,
+ NVRenderComponentTypes::Enum componentType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData);
+
+ private:
+ NVRenderComponentTypes::Enum m_ComponentType; ///< component type (QT3DSU8, QT3DSU16)
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp
new file mode 100644
index 00000000..e4d38b9d
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderInputAssembler.h"
+#include "render/Qt3DSRenderAttribLayout.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ ///< constructor
+ NVRenderInputAssembler::NVRenderInputAssembler(
+ NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout,
+ NVConstDataRef<NVRenderVertexBuffer *> buffers, const NVRenderIndexBuffer *indexBuffer,
+ NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets,
+ NVRenderDrawMode::Enum primType, QT3DSU32 patchVertexCount)
+ : m_Context(context)
+ , m_Foundation(context.GetFoundation())
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_AttribLayout(attribLayout)
+ , m_VertexBuffers(context.GetAllocator(), "m_VertexBuffers")
+ , m_IndexBuffer(indexBuffer)
+ , m_PrimitiveType(primType)
+ , m_PatchVertexCount(patchVertexCount)
+ {
+ // we cannot currently attach more than 16 vertex buffers
+ QT3DS_ASSERT(buffers.size() < 16);
+ // if primitive is "Patch" we need a patch per vertex count > 0
+ QT3DS_ASSERT(m_PrimitiveType != NVRenderDrawMode::Patches || m_PatchVertexCount > 1);
+
+ QT3DSU32 entrySize = sizeof(NVRenderBackend::NVRenderBackendBufferObject) * buffers.size();
+ NVRenderBackend::NVRenderBackendBufferObject *bufferHandle =
+ (NVRenderBackend::NVRenderBackendBufferObject *)QT3DS_ALLOC(
+ m_Foundation.getAllocator(), entrySize, "NVRenderInputAssembler");
+ // setup vertex buffer backend handle array
+ QT3DS_FOREACH(idx, buffers.size())
+ {
+ m_VertexBuffers.push_back(buffers.mData[idx]);
+ bufferHandle[idx] = buffers.mData[idx]->GetBuffertHandle();
+ };
+
+ m_VertexbufferHandles = toConstDataRef(bufferHandle, buffers.size());
+
+ m_InputAssemblertHandle = m_Backend->CreateInputAssembler(
+ m_AttribLayout->GetAttribLayoutHandle(), m_VertexbufferHandles,
+ (m_IndexBuffer) ? m_IndexBuffer->GetBuffertHandle() : NULL, strides, offsets,
+ patchVertexCount);
+
+ attribLayout->addRef();
+ }
+
+ ///< destructor
+ NVRenderInputAssembler::~NVRenderInputAssembler()
+ {
+ m_AttribLayout->release();
+
+ if (m_InputAssemblertHandle) {
+ m_Backend->ReleaseInputAssembler(m_InputAssemblertHandle);
+ }
+
+ QT3DS_FREE(m_Foundation.getAllocator(), (void *)m_VertexbufferHandles.mData);
+ }
+
+ QT3DSU32 NVRenderInputAssembler::GetIndexCount() const
+ {
+ return (m_IndexBuffer) ? m_IndexBuffer->GetNumIndices() : 0;
+ }
+
+ QT3DSU32 NVRenderInputAssembler::GetVertexCount() const
+ {
+ // makes only sense if we have a single vertex buffer
+ QT3DS_ASSERT(m_VertexBuffers.size() == 1);
+
+ return m_VertexBuffers[0]->GetNumVertexes();
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h
new file mode 100644
index 00000000..adac4c42
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderInputAssembler.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_INPUT_ASSEMBLER_H
+#define QT3DS_RENDER_INPUT_ASSEMBLER_H
+
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Utils.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ // forward declarations
+ class NVRenderContextImpl;
+ class NVRenderBackend;
+ class NVRenderAttribLayout;
+
+ ///< this class handles the vertex attribute layout setup
+ class NVRenderInputAssembler : public NVRefCounted
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * NOTE: The limit for buffers count is currently 16
+ *
+ * @param[in] context Pointer to context
+ * @param[in] attribLayout Pointer to NVRenderAttribLayout object
+ * @param[in] buffers list of vertex buffers
+ * @param[in] indexBuffer pointer to index buffer. Can be NULL
+ * @param[in] strides list of strides of the buffer
+ * @param[in] offsets list of offsets into the buffer
+ * @param[in] primType primitive type used for drawing
+ * @param[in] patchVertexCount if primitive is "Patch" this is the vertex count for a
+ *single patch
+ *
+ * @return No return.
+ */
+ NVRenderInputAssembler(NVRenderContextImpl &context, NVRenderAttribLayout *attribLayout,
+ NVConstDataRef<NVRenderVertexBuffer *> buffers,
+ const NVRenderIndexBuffer *indexBuffer,
+ NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets,
+ NVRenderDrawMode::Enum primType = NVRenderDrawMode::Triangles,
+ QT3DSU32 patchVertexCount = 1);
+ ///< destructor
+ ~NVRenderInputAssembler();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendInputAssemblerObject GetInputAssemblerHandle() const
+ {
+ return m_InputAssemblertHandle;
+ }
+
+ /**
+ * @brief get the attached index buffer
+ *
+ * @return the index buffer
+ */
+ const NVRenderIndexBuffer *GetIndexBuffer() { return m_IndexBuffer; }
+
+ /**
+ * @brief get the index count of the attached index buffer (if any)
+ *
+ * @return the index buffer count
+ */
+ QT3DSU32 GetIndexCount() const;
+
+ /**
+ * @brief get the vertex count of the buffer
+ * Note this makes only sense if we have a single
+ * interleaved buffer
+ *
+ * @return the vertex buffer count
+ */
+ QT3DSU32 GetVertexCount() const;
+
+ /**
+ * @brief get the primitive type used for drawing
+ *
+ * @return primitive type
+ */
+ NVRenderDrawMode::Enum GetPrimitiveType() const { return m_PrimitiveType; }
+
+ /**
+ * @brief set the per vertex patch count
+ *
+ * @return none
+ */
+ void SetPatchVertexCount(QT3DSU32 count)
+ {
+ if (count != m_PatchVertexCount) {
+ // clamp to 1;
+ m_PatchVertexCount = (count == 0) ? 1 : count;
+ ;
+ m_Backend->SetPatchVertexCount(m_InputAssemblertHandle, m_PatchVertexCount);
+ }
+ }
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+
+ NVRenderAttribLayout *m_AttribLayout; ///< pointer to attribute layout
+ nvvector<NVRenderVertexBuffer *> m_VertexBuffers; ///< vertex buffers
+ const NVRenderIndexBuffer *m_IndexBuffer; ///< index buffer
+ NVConstDataRef<NVRenderBackend::NVRenderBackendBufferObject>
+ m_VertexbufferHandles; ///< opaque vertex buffer backend handles
+
+ NVRenderBackend::NVRenderBackendInputAssemblerObject
+ m_InputAssemblertHandle; ///< opaque backend handle
+ NVRenderDrawMode::Enum m_PrimitiveType; ///< primitive type used for drawing
+ QT3DSU32 m_PatchVertexCount; ///< vertex count if primitive type is patch
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp
new file mode 100644
index 00000000..d1b62d4c
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderOcclusionQuery.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/StringTable.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderOcclusionQuery::NVRenderOcclusionQuery(NVRenderContextImpl &context,
+ NVFoundationBase &fnd)
+ : NVRenderQueryBase(context, fnd)
+ {
+ }
+
+ NVRenderOcclusionQuery::~NVRenderOcclusionQuery() {}
+
+ void NVRenderOcclusionQuery::Begin()
+ {
+ m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Samples);
+ }
+
+ void NVRenderOcclusionQuery::End()
+ {
+ m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Samples);
+ }
+
+ void NVRenderOcclusionQuery::GetResult(QT3DSU32 *params)
+ {
+ m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params);
+ }
+
+ bool NVRenderOcclusionQuery::GetResultAvailable()
+ {
+ QT3DSU32 param;
+
+ m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::ResultAvailable, &param);
+
+ return (param == 1);
+ }
+
+ NVRenderOcclusionQuery *NVRenderOcclusionQuery::Create(NVRenderContextImpl &context)
+ {
+ if (!context.IsSampleQuerySupported())
+ return NULL;
+
+ NVRenderOcclusionQuery *retval =
+ QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderOcclusionQuery)(context, context.GetFoundation());
+
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h
new file mode 100644
index 00000000..04f64e97
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderOcclusionQuery.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_OCCLUSION_QUERY_H
+#define QT3DS_RENDER_OCCLUSION_QUERY_H
+
+#include "render/Qt3DSRenderQueryBase.h"
+
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+
+ class NVRenderOcclusionQuery : public NVRenderQueryBase
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderOcclusionQuery(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ ///< destructor
+ ~NVRenderOcclusionQuery();
+
+ /**
+ * @brief Get query type
+ *
+ * @return Return query type
+ */
+ NVRenderQueryType::Enum GetQueryType() const override
+ {
+ return NVRenderQueryType::Samples;
+ }
+
+ /**
+ * @brief Get a pointer to the foundation
+ *
+ * @return pointer to foundation
+ */
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ /**
+ * @brief begin a query
+ *
+ * @return no return.
+ */
+ void Begin() override;
+
+ /**
+ * @brief end a query
+ *
+ * @return no return.
+ */
+ void End() override;
+
+ /**
+ * @brief Get the result of a query
+ *
+ * @param[out] params Contains result of query regarding query type
+ *
+ * @return no return.
+ */
+ void GetResult(QT3DSU32 *params) override;
+
+ /**
+ * @brief query if a result is available
+ *
+ *
+ * @return true if available.
+ */
+ virtual bool GetResultAvailable();
+
+ /*
+ * @brief static creation function
+ *
+ * * @return a occlusion query object on success
+ */
+ static NVRenderOcclusionQuery *Create(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp
new file mode 100644
index 00000000..3e9276aa
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderPathFontSpecification.h"
+#include "render/Qt3DSRenderPathFontText.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderPathFontSpecification::NVRenderPathFontSpecification(NVRenderContextImpl &context,
+ NVFoundationBase &fnd,
+ CRegisteredString fontName)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , m_Backend(context.GetBackend())
+ , mRefCount(0)
+ , m_NumFontGlyphs(0)
+ , m_EmScale(2048) // 2048 is default true type scale
+ , m_Type(NVRenderPathFormatType::UByte)
+ , m_TransformType(NVRenderPathTransformType::Translate2D)
+ , m_FontName(fontName)
+ {
+ }
+
+ NVRenderPathFontSpecification::~NVRenderPathFontSpecification()
+ {
+ m_Context.ReleasePathFontSpecification(*this);
+ }
+
+ void NVRenderPathFontSpecification::LoadPathGlyphs(const char *fontName,
+ NVRenderPathFormatType::Enum type)
+ {
+ // check if we already created it
+ if (m_NumFontGlyphs)
+ return;
+
+ m_Type = type;
+
+ // create fonts based on the input
+ m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange(
+ NVRenderPathFontTarget::FileFont, fontName, NVRenderPathFontStyleFlags(), 0, m_EmScale,
+ &m_NumFontGlyphs);
+
+ // Fallback in case the previuos call fails
+ // This is a no-op if the previous call succeeds
+ // Note that sans is an inbuild driver font
+ if (!m_PathRenderHandle) {
+ m_PathRenderHandle = m_Backend->LoadPathGlyphsIndexedRange(
+ NVRenderPathFontTarget::SystemFont, "Arial", NVRenderPathFontStyleFlags(), 0,
+ m_EmScale, &m_NumFontGlyphs);
+ }
+
+ // we should have some glyphs
+ QT3DS_ASSERT(m_NumFontGlyphs);
+ }
+
+ void
+ NVRenderPathFontSpecification::StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem)
+ {
+ const void *glyphIDs = inPathFontItem.GetGlyphIDs();
+ const QT3DSF32 *spacing = inPathFontItem.GetSpacing();
+ if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) {
+ QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount());
+ return;
+ }
+
+ m_Backend->StencilFillPathInstanced(m_PathRenderHandle, inPathFontItem.GetGlyphsCount(),
+ m_Type, glyphIDs, NVRenderPathFillMode::Fill, 0xFF,
+ m_TransformType, spacing);
+ }
+
+ void NVRenderPathFontSpecification::CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem)
+ {
+ const void *glyphIDs = inPathFontItem.GetGlyphIDs();
+ const QT3DSF32 *spacing = inPathFontItem.GetSpacing();
+ if (!glyphIDs || !spacing || !inPathFontItem.GetGlyphsCount()) {
+ QT3DS_ASSERT(false || !inPathFontItem.GetGlyphsCount());
+ return;
+ }
+
+ m_Backend->CoverFillPathInstanced(
+ m_PathRenderHandle, inPathFontItem.GetGlyphsCount(), m_Type, glyphIDs,
+ NVRenderPathCoverMode::BoundingBoxOfBoundingBox, m_TransformType, spacing);
+ }
+
+ QT3DSU32
+ NVRenderPathFontSpecification::getSizeofType(NVRenderPathFormatType::Enum type)
+ {
+ switch (type) {
+ case NVRenderPathFormatType::Byte:
+ return sizeof(QT3DSI8);
+ case NVRenderPathFormatType::UByte:
+ return sizeof(QT3DSU8);
+ case NVRenderPathFormatType::Bytes2:
+ return sizeof(QT3DSU16);
+ case NVRenderPathFormatType::Uint:
+ return sizeof(QT3DSU32);
+ case NVRenderPathFormatType::Utf8:
+ return sizeof(QT3DSU32);
+ default:
+ QT3DS_ASSERT(false);
+ return 1;
+ }
+ }
+
+ NVRenderPathFontSpecification *
+ NVRenderPathFontSpecification::CreatePathFontSpecification(NVRenderContextImpl &context,
+ CRegisteredString fontName)
+ {
+ QT3DS_ASSERT(context.IsPathRenderingSupported());
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderPathFontSpecification)(context, context.GetFoundation(), fontName);
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h
new file mode 100644
index 00000000..dad3f6bb
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathFontSpecification.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/ #pragma once
+#ifndef QT3DS_RENDER_PATH_FONT_SPECIFICATION_H
+#define QT3DS_RENDER_PATH_FONT_SPECIFICATION_H
+#include "foundation/Qt3DSVec2.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSContainers.h"
+#include "foundation/Qt3DSAllocatorCallback.h"
+#include "foundation/StringTable.h"
+#include "EASTL/string.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+ namespace qt3ds
+{
+ namespace render {
+
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+ class NVRenderPathRender;
+ class NVRenderPathFontItem;
+
+ class NVRenderPathFontSpecification : public NVRefCounted
+ {
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ volatile QT3DSI32
+ mRefCount; ///< Using foundations' naming convention to ease implementation
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] fontName Name of font ( may include path
+ * )
+ *
+ * @return No return.
+ */
+ NVRenderPathFontSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ CRegisteredString fontName);
+
+ /// @NVRenderPathSpecification destructor
+ ~NVRenderPathFontSpecification();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief Load numGlyphs glyphs from specified font file
+ *
+ * @param[in] pathBase Base of path objects
+ * @param[in] fontName Name of font ( may include path
+ * )
+ * @param[in] numGlyphs Glyph count
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes character string
+ *
+ * @return No return
+ */
+ virtual void LoadPathGlyphs(const char *fontName, NVRenderPathFormatType::Enum type);
+
+ /**
+ * @brief Render a stencil fill pass for fonts
+ *
+ * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification
+ *
+ * @return no return
+ */
+ void StencilFillPathInstanced(NVRenderPathFontItem &inPathFontItem);
+
+ /**
+ * @brief Render a cover fill pass for fonts
+ *
+ * @param[in] inPathFontSpec Pointer to NVRenderPathFontSpecification
+ *
+ * @return no return
+ */
+ void CoverFillPathInstanced(NVRenderPathFontItem &inPathFontItem);
+
+ /**
+ * @brief get type for font path set
+ *
+ * @return path font type
+ */
+ NVRenderPathFormatType::Enum GetPathFontType() { return m_Type; }
+
+ /**
+ * @brief get font glyph count
+ *
+ * @return get glyph count
+ */
+ QT3DSU32 GetFontGlyphsCount() { return m_NumFontGlyphs; }
+
+ /**
+ * @brief get spacing for char set
+ *
+ * @return spacing array
+ */
+ QT3DSF32 GetEmScale() const { return m_EmScale; }
+
+ /**
+ * @brief Get font name
+ *
+ * @return name set
+ */
+ CRegisteredString GetFontName() const { return m_FontName; }
+
+ private:
+ QT3DSU32 m_NumFontGlyphs; ///< glyph count of the entire font set
+ QT3DSF32 m_EmScale; ///< true type scale
+ NVRenderPathFormatType::Enum m_Type; ///< type ( byte, int,... )
+ NVRenderPathTransformType::Enum m_TransformType; ///< transform type default 2D
+ CRegisteredString m_FontName; ///< Name of Font
+ NVRenderBackend::NVRenderBackendPathObject
+ m_PathRenderHandle; ///< opaque backend handle
+
+ private:
+ /**
+ * @brief Get size of type
+ *
+ * @param[in] type type ( byte, int,... )
+ *
+ * @return true if successful
+ */
+ QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type);
+
+ public:
+ static NVRenderPathFontSpecification *
+ CreatePathFontSpecification(NVRenderContextImpl &context, CRegisteredString fontName);
+ };
+ }
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp b/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp
new file mode 100644
index 00000000..aeaad13c
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathFontText.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderPathFontText.h"
+#include "render/Qt3DSRenderPathFontSpecification.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderPathRender.h"
+
+namespace qt3ds {
+namespace render {
+
+ // see NVprSDK for explanation
+ // Math from page 54-56 of "Digital Image Warping" by George Wolberg,
+ // though credited to Paul Heckert's "Fundamentals of Texture
+ // Mapping and Image Warping" 1989 Master's thesis.
+ static QT3DSMat33 mapSquareToQuad(QT3DSVec2 inSquare[4])
+ {
+ QT3DSMat33 ret;
+
+ QT3DSVec2 d1(inSquare[1] - inSquare[2]);
+ QT3DSVec2 d2(inSquare[3] - inSquare[2]);
+ QT3DSVec2 d3(inSquare[0] - inSquare[1] + inSquare[2] - inSquare[3]);
+
+ QT3DSF32 denom = d1.x * d2.y - d2.x * d1.y;
+ if (denom == 0.0) {
+ return QT3DSMat33::createIdentity();
+ }
+
+ ret[2][0] = (d3.x * d2.y - d2.x * d3.y) / denom;
+ ret[2][1] = (d1.x * d3.y - d3.x * d1.y) / denom;
+ ret[2][2] = 1.0;
+ ret[0][0] = inSquare[1].x - inSquare[0].x + ret[2][0] * inSquare[1].x;
+ ret[1][0] = inSquare[1].y - inSquare[0].y + ret[2][0] * inSquare[1].y;
+ ret[0][1] = inSquare[3].x - inSquare[0].x + ret[2][1] * inSquare[3].x;
+ ret[1][1] = inSquare[3].y - inSquare[0].y + ret[2][1] * inSquare[3].y;
+ ret[0][2] = inSquare[0].x;
+ ret[1][2] = inSquare[0].y;
+
+ return ret;
+ }
+
+ static QT3DSMat33 mapQuadToSquare(QT3DSVec2 inSquare[4])
+ {
+ return mapSquareToQuad(inSquare).getInverse();
+ }
+
+ static QT3DSMat33 mapQuadToQuad(QT3DSVec2 fromSquare[4], QT3DSVec2 toSquare[4])
+ {
+ return (mapSquareToQuad(toSquare) * mapQuadToSquare(fromSquare));
+ }
+
+ static QT3DSMat44 mapBoxToQuad(QT3DSVec4 inBox, QT3DSVec2 inSquare[4])
+ {
+ QT3DSVec2 fromSquare[4] = { QT3DSVec2(inBox.x, inBox.y), QT3DSVec2(inBox.z, inBox.y),
+ QT3DSVec2(inBox.z, inBox.w), QT3DSVec2(inBox.x, inBox.w) };
+
+ QT3DSMat33 ret = mapQuadToQuad(fromSquare, inSquare);
+
+ return QT3DSMat44(ret.column0, ret.column1, ret.column2, QT3DSVec3(0.0, 0.0, 0.0));
+ }
+
+ NVRenderPathFontItem::NVRenderPathFontItem(NVFoundationBase &fnd)
+ : m_Foundation(fnd)
+ , mRefCount(0)
+ , m_NumGlyphs(0)
+ , m_GlyphIDs(NULL)
+ , m_TranslateXY(NULL)
+ {
+ }
+
+ NVRenderPathFontItem::~NVRenderPathFontItem()
+ {
+ if (m_TranslateXY)
+ QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY);
+ if (m_GlyphIDs)
+ QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs);
+ }
+
+ void NVRenderPathFontItem::InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs,
+ NVRenderPathFormatType::Enum type, QT3DSF32 *posArray,
+ QT3DSVec2 pixelBound, QT3DSVec2 logicalBound, QT3DSF32 emScale)
+ {
+ m_NumGlyphs = glyphCount;
+
+ // allocate glyphs array
+ if (m_GlyphIDs)
+ QT3DS_FREE(m_Foundation.getAllocator(), m_GlyphIDs);
+
+ // allocate position array
+ if (m_TranslateXY)
+ QT3DS_FREE(m_Foundation.getAllocator(), m_TranslateXY);
+
+ m_GlyphIDs = (QT3DSU32 *)QT3DS_ALLOC(m_Foundation.getAllocator(),
+ glyphCount * getSizeofType(type), "NVRenderPathFontItem");
+ m_TranslateXY =
+ (QT3DSF32 *)QT3DS_ALLOC(m_Foundation.getAllocator(), 2 * (glyphCount + 1) * sizeof(QT3DSF32),
+ "NVRenderPathFontItem");
+
+ if (!m_GlyphIDs || !m_TranslateXY)
+ return;
+
+ QT3DSU32 *pTheGlyphIDs = (QT3DSU32 *)m_GlyphIDs;
+ QT3DSU32 *pInGlyphs = (QT3DSU32 *)glyphIDs;
+
+ /// copy glyphs array
+ for (size_t i = 0; i < glyphCount; i++) {
+ pTheGlyphIDs[i] = pInGlyphs[i];
+ }
+
+ // copy position array
+ // we copy what we got from our layout system
+ if (posArray != NULL) {
+ for (size_t i = 0, k = 0; i < glyphCount * 2; i += 2, k++) {
+ m_TranslateXY[i] = posArray[i] * emScale;
+ m_TranslateXY[i + 1] = posArray[i + 1] * emScale;
+ }
+ }
+
+ // setup transform
+ QT3DSVec2 square[4] = { QT3DSVec2(0.0, 0.0), QT3DSVec2(pixelBound.x, 0.0),
+ QT3DSVec2(pixelBound.x, pixelBound.y), QT3DSVec2(0.0, pixelBound.y) };
+ QT3DSVec4 box(0.0, 0.0, logicalBound.x * emScale, logicalBound.y * emScale);
+
+ m_ModelMatrix = mapBoxToQuad(box, square);
+ }
+
+ const QT3DSMat44 NVRenderPathFontItem::GetTransform()
+ {
+ return QT3DSMat44(QT3DSVec4(m_ModelMatrix[0][0], m_ModelMatrix[1][0], 0.0, m_ModelMatrix[2][0]),
+ QT3DSVec4(m_ModelMatrix[0][1], m_ModelMatrix[1][1], 0.0, m_ModelMatrix[2][1]),
+ QT3DSVec4(0.0, 0.0, 1.0, 0.0),
+ QT3DSVec4(m_ModelMatrix[0][2], m_ModelMatrix[1][2], 0.0, m_ModelMatrix[2][2]));
+ }
+
+ QT3DSU32
+ NVRenderPathFontItem::getSizeofType(NVRenderPathFormatType::Enum type)
+ {
+ switch (type) {
+ case NVRenderPathFormatType::Byte:
+ return sizeof(QT3DSI8);
+ case NVRenderPathFormatType::UByte:
+ return sizeof(QT3DSU8);
+ case NVRenderPathFormatType::Bytes2:
+ return sizeof(QT3DSU16);
+ case NVRenderPathFormatType::Uint:
+ return sizeof(QT3DSU32);
+ case NVRenderPathFormatType::Utf8:
+ return sizeof(QT3DSU32);
+ default:
+ QT3DS_ASSERT(false);
+ return 1;
+ }
+ }
+
+ NVRenderPathFontItem *NVRenderPathFontItem::CreatePathFontItem(NVRenderContextImpl &context)
+ {
+ QT3DS_ASSERT(context.IsPathRenderingSupported());
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderPathFontItem)(context.GetFoundation());
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathFontText.h b/src/Runtime/Source/render/Qt3DSRenderPathFontText.h
new file mode 100644
index 00000000..a1d103ac
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathFontText.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/ #pragma once
+#ifndef QT3DS_RENDER_PATH_FONT_TEXT_H
+#define QT3DS_RENDER_PATH_FONT_TEXT_H
+#include "foundation/Qt3DSVec2.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSContainers.h"
+#include "foundation/Qt3DSAllocatorCallback.h"
+#include "EASTL/string.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+ namespace qt3ds
+{
+ namespace render {
+
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+ class NVRenderPathFontSpecification;
+
+ class NVRenderPathFontItem : public NVRefCounted
+ {
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32
+ mRefCount; ///< Using foundations' naming convention to ease implementation
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderPathFontItem(NVFoundationBase &fnd);
+
+ /// @NVRenderPathFontItem destructor
+ ~NVRenderPathFontItem();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief Setup text
+ *
+ * @param[in] glyphCount number of glyphs
+ * @param[in] glyphIDs array of glyhp ID's
+ * @param[in] type type ( byte, int,... )
+ * @param[in] posArray array of glyhp positions
+ * @param[in] pixelBound pixel boundary
+ * @param[in] logicalBound logical boundary
+ * @param[in] emScale true type scale
+ *
+ * @return No return.
+ */
+ void InitTextItem(size_t glyphCount, const QT3DSU32 *glyphIDs,
+ NVRenderPathFormatType::Enum type, QT3DSF32 *posArray, QT3DSVec2 pixelBound,
+ QT3DSVec2 logicalBound, QT3DSF32 emScale);
+
+ /**
+ * @brief get glyph count
+ *
+ * @return get glyph count
+ */
+ size_t GetGlyphsCount() { return m_NumGlyphs; }
+
+ /**
+ * @brief get spacing for char set
+ *
+ * @return spacing array
+ */
+ const QT3DSF32 *GetSpacing() { return m_TranslateXY; }
+
+ /**
+ * @brief get name set
+ *
+ * @return name set
+ */
+ const void *GetGlyphIDs() { return (void *)m_GlyphIDs; }
+
+ /**
+ * @brief Get Y bound of font metric
+ *
+ * @return transform matrix
+ */
+ const QT3DSMat44 GetTransform();
+
+ private:
+ /**
+ * @brief Get size of type
+ *
+ * @param[in] type type ( byte, int,... )
+ *
+ * @return true if successful
+ */
+ QT3DSU32 getSizeofType(NVRenderPathFormatType::Enum type);
+
+ private:
+ size_t m_NumGlyphs; ///< glyph count
+ QT3DSU32 *m_GlyphIDs; ///< array glyph ID's
+ QT3DSF32 *
+ m_TranslateXY; ///< pointer to arrray for character advance information like kerning
+ QT3DSMat44 m_ModelMatrix; ///< Matrix which converts from font space to box space
+
+ public:
+ static NVRenderPathFontItem *CreatePathFontItem(NVRenderContextImpl &context);
+ };
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp b/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp
new file mode 100644
index 00000000..42982498
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathRender.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderPathRender.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderPathSpecification.h"
+#include "render/Qt3DSRenderPathFontSpecification.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderPathRender::NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ size_t range)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , m_Backend(context.GetBackend())
+ , mRefCount(0)
+ , m_StrokeWidth(0.0f)
+ {
+ m_Range = range;
+ m_PathRenderHandle = m_Backend->CreatePathNVObject(range);
+ }
+
+ NVRenderPathRender::~NVRenderPathRender()
+ {
+ if (m_PathRenderHandle) {
+ m_Backend->ReleasePathNVObject(m_PathRenderHandle, m_Range);
+ }
+ }
+
+ void NVRenderPathRender::SetPathSpecification(NVRenderPathSpecification &inCommandBuffer)
+ {
+ m_Backend->SetPathSpecification(m_PathRenderHandle, inCommandBuffer.GetPathCommands(),
+ inCommandBuffer.GetPathCoords());
+ }
+
+ NVBounds3 NVRenderPathRender::GetPathObjectBoundingBox()
+ {
+ return m_Backend->GetPathObjectBoundingBox(m_PathRenderHandle);
+ }
+
+ NVBounds3 NVRenderPathRender::GetPathObjectFillBox()
+ {
+ return m_Backend->GetPathObjectFillBox(m_PathRenderHandle);
+ }
+
+ NVBounds3 NVRenderPathRender::GetPathObjectStrokeBox()
+ {
+ return m_Backend->GetPathObjectStrokeBox(m_PathRenderHandle);
+ }
+
+ void NVRenderPathRender::SetStrokeWidth(QT3DSF32 inStrokeWidth)
+ {
+ if (inStrokeWidth != m_StrokeWidth) {
+ m_StrokeWidth = inStrokeWidth;
+ m_Backend->SetStrokeWidth(m_PathRenderHandle, inStrokeWidth);
+ }
+ }
+
+ QT3DSF32 NVRenderPathRender::GetStrokeWidth() const { return m_StrokeWidth; }
+
+ void NVRenderPathRender::StencilStroke() { m_Backend->StencilStrokePath(m_PathRenderHandle); }
+
+ void NVRenderPathRender::StencilFill() { m_Backend->StencilFillPath(m_PathRenderHandle); }
+
+ NVRenderPathRender *NVRenderPathRender::Create(NVRenderContextImpl &context, size_t range)
+ {
+ if (!context.IsPathRenderingSupported())
+ return NULL;
+
+ NVRenderPathRender *retval =
+ QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderPathRender)(context, context.GetFoundation(), range);
+
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathRender.h b/src/Runtime/Source/render/Qt3DSRenderPathRender.h
new file mode 100644
index 00000000..c261ca31
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathRender.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_PATH_RENDER_H
+#define QT3DS_RENDER_PATH_RENDER_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include "foundation/Qt3DSBounds3.h"
+#include <EASTL/string.h>
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+ class NVRenderPathSpecification;
+ class NVRenderPathFontSpecification;
+
+ ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....)
+ class NVRenderPathRender : public NVRefCounted
+ {
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] range Number of internal objects
+ *
+ * @return No return.
+ */
+ NVRenderPathRender(NVRenderContextImpl &context, NVFoundationBase &fnd, size_t range);
+
+ /// @brief destructor
+ ~NVRenderPathRender();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendPathObject GetPathHandle() { return m_PathRenderHandle; }
+
+ // The render context can create a path specification object.
+ void SetPathSpecification(NVRenderPathSpecification &inCommandBuffer);
+
+ NVBounds3 GetPathObjectBoundingBox();
+ NVBounds3 GetPathObjectFillBox();
+ NVBounds3 GetPathObjectStrokeBox();
+
+ void SetStrokeWidth(QT3DSF32 inStrokeWidth);
+ QT3DSF32 GetStrokeWidth() const;
+
+ void StencilStroke();
+ void StencilFill();
+
+ /**
+ * @brief static create function
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] range Number of internal objects
+ *
+ * @return the backend object handle.
+ */
+ static NVRenderPathRender *Create(NVRenderContextImpl &context, size_t range);
+
+ private:
+ NVRenderBackend::NVRenderBackendPathObject m_PathRenderHandle; ///< opaque backend handle
+ size_t m_Range; ///< range of internal objects
+ QT3DSF32 m_StrokeWidth;
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp
new file mode 100644
index 00000000..f4b26f11
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderPathSpecification.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderPathSpecification::NVRenderPathSpecification(NVRenderContextImpl &context,
+ NVFoundationBase &fnd)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , m_Backend(context.GetBackend())
+ , mRefCount(0)
+ , m_PathCommands(fnd.getAllocator(), "m_PathCommands")
+ , m_PathCoords(fnd.getAllocator(), "m_PathCoords")
+ {
+ }
+
+ NVRenderPathSpecification::~NVRenderPathSpecification() {}
+
+ void NVRenderPathSpecification::Reset()
+ {
+ m_PathCommands.clear();
+ m_PathCoords.clear();
+ }
+
+ void NVRenderPathSpecification::P(QT3DSVec2 inData)
+ {
+ m_PathCoords.push_back(inData.x);
+ m_PathCoords.push_back(inData.y);
+ }
+
+ void NVRenderPathSpecification::MoveTo(QT3DSVec2 inPoint)
+ {
+ // we should actually query the backend for command converesion
+ // but will we support any other pather render system than nv path?
+ StaticAssert<NVRenderPathCommands::MoveTo == 0x02>::valid_expression();
+
+ m_PathCommands.push_back(NVRenderPathCommands::MoveTo);
+ P(inPoint);
+ }
+
+ void NVRenderPathSpecification::CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest)
+ {
+ // we should actually query the backend for command converesion
+ // but will we support any other pather render system than nv path?
+ StaticAssert<NVRenderPathCommands::CubicCurveTo == 0x0C>::valid_expression();
+
+ m_PathCommands.push_back(NVRenderPathCommands::CubicCurveTo);
+ P(inC1);
+ P(inC2);
+ P(inDest);
+ }
+
+ void NVRenderPathSpecification::ClosePath()
+ {
+ // we should actually query the backend for command converesion
+ // but will we support any other pather render system than nv path?
+ StaticAssert<NVRenderPathCommands::Close == 0x00>::valid_expression();
+
+ m_PathCommands.push_back(NVRenderPathCommands::Close);
+ }
+
+ NVRenderPathSpecification *
+ NVRenderPathSpecification::CreatePathSpecification(NVRenderContextImpl &context)
+ {
+ QT3DS_ASSERT(context.IsPathRenderingSupported());
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderPathSpecification)(context, context.GetFoundation());
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h
new file mode 100644
index 00000000..7c6faeda
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderPathSpecification.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_PATH_SPECIFICATION_H
+#define QT3DS_RENDER_PATH_SPECIFICATION_H
+#include "foundation/Qt3DSVec2.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSContainers.h"
+#include "foundation/Qt3DSAllocatorCallback.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ class NVRenderPathSpecification : public NVRefCounted
+ {
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderPathSpecification(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ /// @NVRenderPathSpecification destructor
+ ~NVRenderPathSpecification();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief reset commands and coordiantes
+ *
+ * @return No return.
+ */
+ virtual void Reset();
+
+ /**
+ * @brief add new move to command
+ *
+ * @param[in] inPoint Coordinate
+ *
+ * @return No return.
+ */
+ virtual void MoveTo(QT3DSVec2 inPoint);
+
+ /**
+ * @brief add new cubic curve command
+ *
+ * @param[in] inC1 control point 1
+ * @param[in] inC2 control point 2
+ * @param[in] inDest final point
+ *
+ * @return No return.
+ */
+ virtual void CubicCurveTo(QT3DSVec2 inC1, QT3DSVec2 inC2, QT3DSVec2 inDest);
+
+ /**
+ * @brief add new close command
+ *
+ *
+ * @return No return.
+ */
+ virtual void ClosePath();
+
+ /**
+ * @brief Get path command list
+ *
+ *
+ * @return path commands
+ */
+ virtual NVConstDataRef<QT3DSU8> GetPathCommands() { return m_PathCommands; }
+
+ /**
+ * @brief Get path coordinates list
+ *
+ *
+ * @return path coordinates
+ */
+ virtual NVConstDataRef<QT3DSF32> GetPathCoords() { return m_PathCoords; }
+
+ private:
+ nvvector<QT3DSU8> m_PathCommands;
+ nvvector<QT3DSF32> m_PathCoords;
+
+ /**
+ * @brief add a new point to the coordinates
+ *
+ * @param[in] inPoint Coordinate
+ *
+ * @return No return.
+ */
+ void P(QT3DSVec2 inData);
+
+ public:
+ static NVRenderPathSpecification *CreatePathSpecification(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif \ No newline at end of file
diff --git a/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp
new file mode 100644
index 00000000..b0a9f271
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderProgramPipeline.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderProgramPipeline::NVRenderProgramPipeline(NVRenderContextImpl &context,
+ NVFoundationBase &fnd)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , m_Backend(context.GetBackend())
+ , mRefCount(0)
+ , m_Program(NULL)
+ , m_VertexProgram(NULL)
+ , m_FragmentProgram(NULL)
+ , m_TessControlProgram(NULL)
+ , m_TessEvalProgram(NULL)
+ , m_GeometryProgram(NULL)
+ , m_ComputProgram(NULL)
+ {
+ m_ProgramPipelineHandle = m_Backend->CreateProgramPipeline();
+ }
+
+ NVRenderProgramPipeline::~NVRenderProgramPipeline()
+ {
+ if (m_ProgramPipelineHandle) {
+ m_Backend->ReleaseProgramPipeline(m_ProgramPipelineHandle);
+ }
+
+ if (m_VertexProgram)
+ m_VertexProgram->release();
+ if (m_FragmentProgram)
+ m_FragmentProgram->release();
+ if (m_TessControlProgram)
+ m_TessControlProgram->release();
+ if (m_TessEvalProgram)
+ m_TessEvalProgram->release();
+ if (m_GeometryProgram)
+ m_GeometryProgram->release();
+ }
+
+ bool NVRenderProgramPipeline::IsValid() { return (m_ProgramPipelineHandle != NULL); }
+
+ void NVRenderProgramPipeline::SetProgramStages(NVRenderShaderProgram *inProgram,
+ NVRenderShaderTypeFlags flags)
+ {
+ bool bDirty = false;
+
+ if (flags & NVRenderShaderTypeValue::Vertex && inProgram != m_VertexProgram) {
+ if (m_VertexProgram)
+ m_VertexProgram->release();
+ if (inProgram)
+ inProgram->addRef();
+ m_VertexProgram = inProgram;
+ bDirty = true;
+ }
+ if (flags & NVRenderShaderTypeValue::Fragment && inProgram != m_FragmentProgram) {
+ if (m_FragmentProgram)
+ m_FragmentProgram->release();
+ if (inProgram)
+ inProgram->addRef();
+ m_FragmentProgram = inProgram;
+ bDirty = true;
+ }
+ if (flags & NVRenderShaderTypeValue::TessControl && inProgram != m_TessControlProgram) {
+ if (m_TessControlProgram)
+ m_TessControlProgram->release();
+ if (inProgram)
+ inProgram->addRef();
+ m_TessControlProgram = inProgram;
+ bDirty = true;
+ }
+ if (flags & NVRenderShaderTypeValue::TessEvaluation && inProgram != m_TessEvalProgram) {
+ if (m_TessEvalProgram)
+ m_TessEvalProgram->release();
+ if (inProgram)
+ inProgram->addRef();
+ m_TessEvalProgram = inProgram;
+ bDirty = true;
+ }
+ if (flags & NVRenderShaderTypeValue::Geometry && inProgram != m_GeometryProgram) {
+ if (m_GeometryProgram)
+ m_GeometryProgram->release();
+ if (inProgram)
+ inProgram->addRef();
+ m_GeometryProgram = inProgram;
+ bDirty = true;
+ }
+
+ if (bDirty) {
+ m_Backend->SetProgramStages(m_ProgramPipelineHandle, flags,
+ (inProgram) ? inProgram->GetShaderProgramHandle() : NULL);
+ }
+ }
+
+ void NVRenderProgramPipeline::Bind()
+ {
+ m_Backend->SetActiveProgramPipeline(m_ProgramPipelineHandle);
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h
new file mode 100644
index 00000000..ce47146a
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderProgramPipeline.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_PROGRAM_PIPLINE_H
+#define QT3DS_RENDER_PROGRAM_PIPLINE_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include <EASTL/string.h>
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+ class NVRenderShaderProgram;
+
+ ///< A program pipeline is a collection of a multiple programs (vertex, fragment, geometry,....)
+ class QT3DS_AUTOTEST_EXPORT NVRenderProgramPipeline : public NVRefCounted
+ {
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderProgramPipeline(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ /// @brief destructor
+ ~NVRenderProgramPipeline();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief Query if pipeline is valid
+ *
+ * @return True if valid.
+ */
+ bool IsValid();
+
+ /**
+ * @brief enable / disable a program stage in the pipeline
+ *
+ * @param[in] pProgram Pointer to program. If NULL stage will be disabled
+ * @param[in] flags Flags to which stage this program is bound to. Can more than
+ * one stage
+ *
+ * @return no return.
+ */
+ void SetProgramStages(NVRenderShaderProgram *pProgram, NVRenderShaderTypeFlags flags);
+
+ /**
+ * @brief Make the program pipeline active
+ *
+ * @return True if valid.
+ */
+ void Bind();
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendProgramPipeline GetShaderHandle()
+ {
+ return m_ProgramPipelineHandle;
+ }
+
+ /**
+ * @brief get the vertex stage program
+ *
+ * @return the backend object handle.
+ */
+ NVRenderShaderProgram *GetVertexStage() { return m_VertexProgram; }
+
+ private:
+ NVRenderBackend::NVRenderBackendProgramPipeline
+ m_ProgramPipelineHandle; ///< opaque backend handle
+
+ NVRenderShaderProgram
+ *m_Program; ///< for non separable programs this contains the entire program
+ NVRenderShaderProgram
+ *m_VertexProgram; ///< for separable programs this contains the vertex program
+ NVRenderShaderProgram
+ *m_FragmentProgram; ///< for separable programs this contains the fragment program
+ NVRenderShaderProgram *m_TessControlProgram; ///< for separable programs this contains the
+ ///tessellation control program
+ NVRenderShaderProgram *m_TessEvalProgram; ///< for separable programs this contains the
+ ///tessellation evaluation program
+ NVRenderShaderProgram
+ *m_GeometryProgram; ///< for separable programs this contains the geometry program
+ NVRenderShaderProgram
+ *m_ComputProgram; ///< for separable programs this contains the compute program
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp b/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp
new file mode 100644
index 00000000..f13bc499
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderQueryBase.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderQueryBase.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSFoundation.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderQueryBase::NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ {
+ m_QueryHandle = m_Backend->CreateQuery();
+ }
+
+ NVRenderQueryBase::~NVRenderQueryBase()
+ {
+ if (m_QueryHandle)
+ m_Backend->ReleaseQuery(m_QueryHandle);
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderQueryBase.h b/src/Runtime/Source/render/Qt3DSRenderQueryBase.h
new file mode 100644
index 00000000..7a7ead87
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderQueryBase.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QUERY_BASE_H
+#define QT3DS_RENDER_QUERY_BASE_H
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+ class NVRenderBackend;
+
+ ///< Base class
+ class NVRenderQueryBase : public NVRefCounted
+ {
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBackend::NVRenderBackendQueryObject m_QueryHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderQueryBase(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ virtual ~NVRenderQueryBase();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief Get query type
+ *
+ * @return Return query type
+ */
+ virtual NVRenderQueryType::Enum GetQueryType() const = 0;
+
+ /**
+ * @brief Get a pointer to the foundation
+ *
+ * @return pointer to foundation
+ */
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ /**
+ * @brief begin a query
+ *
+ * @return no return.
+ */
+ virtual void Begin() = 0;
+
+ /**
+ * @brief end a query
+ *
+ * @return no return.
+ */
+ virtual void End() = 0;
+
+ /**
+ * @brief Get the result of a query
+ *
+ * @param[out] params Contains result of query regarding query type
+ *
+ * @return no return.
+ */
+ virtual void GetResult(QT3DSU32 *params) = 0;
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendQueryObject GetQuerytHandle() const
+ {
+ return m_QueryHandle;
+ }
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp
new file mode 100644
index 00000000..e7daf7f4
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderRasterizerState.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderRasterizerState::NVRenderRasterizerState(NVRenderContextImpl &context,
+ NVFoundationBase &fnd, QT3DSF32 depthBias,
+ QT3DSF32 depthScale, NVRenderFaces::Enum cullFace)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ {
+ // create backend handle
+ m_StateHandle = m_Backend->CreateRasterizerState(depthBias, depthScale, cullFace);
+ }
+
+ NVRenderRasterizerState::~NVRenderRasterizerState()
+ {
+ if (m_StateHandle) {
+ m_Backend->ReleaseRasterizerState(m_StateHandle);
+ m_Context.StateDestroyed(*this);
+ }
+ }
+
+ NVRenderRasterizerState *NVRenderRasterizerState::Create(NVRenderContextImpl &context,
+ QT3DSF32 depthBias, QT3DSF32 depthScale,
+ NVRenderFaces::Enum cullFace)
+ {
+ return QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderRasterizerState)(
+ context, context.GetFoundation(), depthBias, depthScale, cullFace);
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h
new file mode 100644
index 00000000..9b71ae42
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderRasterizerState.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_RASTERIZER_STATE_H
+#define QT3DS_RENDER_RASTERIZER_STATE_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+
+ // currently this handles only stencil state
+ class NVRenderRasterizerState : public NVRefCounted
+ {
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBackend::NVRenderBackendRasterizerStateObject
+ m_StateHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] depthBias depth bias
+ * @param[in] depthScale depth multiplicator
+ * @param[in] cullFace which face to cull front or back
+ *
+ * @return No return.
+ */
+ NVRenderRasterizerState(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace);
+
+ virtual ~NVRenderRasterizerState();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendRasterizerStateObject GetRasterizerObjectHandle()
+ {
+ return m_StateHandle;
+ }
+
+ static NVRenderRasterizerState *Create(NVRenderContextImpl &context, QT3DSF32 depthBias,
+ QT3DSF32 depthScale, NVRenderFaces::Enum cullFace);
+
+ private:
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp
new file mode 100644
index 00000000..b682bc1b
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderRenderBuffer.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/Qt3DSFoundation.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderRenderBuffer::NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderRenderBufferFormats::Enum format,
+ QT3DSU32 width, QT3DSU32 height)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_Width(width)
+ , m_Height(height)
+ , m_StorageFormat(format)
+ , m_BufferHandle(NULL)
+ {
+ SetDimensions(NVRenderRenderBufferDimensions(width, height));
+ }
+
+ NVRenderRenderBuffer::~NVRenderRenderBuffer()
+ {
+ m_Context.RenderBufferDestroyed(*this);
+ m_Backend->ReleaseRenderbuffer(m_BufferHandle);
+ m_BufferHandle = 0;
+ }
+
+ void NVRenderRenderBuffer::SetDimensions(const NVRenderRenderBufferDimensions &inDimensions)
+ {
+ QT3DSU32 maxWidth, maxHeight;
+ m_Width = inDimensions.m_Width;
+ m_Height = inDimensions.m_Height;
+
+ // get max size and clamp to max value
+ m_Context.getMaxTextureSize(maxWidth, maxHeight);
+ if (m_Width > maxWidth || m_Height > maxHeight) {
+ qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)",
+ maxWidth, maxHeight);
+ m_Width = NVMin(m_Width, maxWidth);
+ m_Height = NVMin(m_Height, maxHeight);
+ }
+
+ bool success = true;
+
+ if (m_BufferHandle == NULL)
+ m_BufferHandle = m_Backend->CreateRenderbuffer(m_StorageFormat, m_Width, m_Height);
+ else
+ success =
+ m_Backend->ResizeRenderbuffer(m_BufferHandle, m_StorageFormat, m_Width, m_Height);
+
+ if (m_BufferHandle == NULL || !success) {
+ // We could try smaller sizes
+ QT3DS_ASSERT(false);
+ qCCritical(INTERNAL_ERROR, "Unable to create render buffer %s, %dx%d",
+ NVRenderRenderBufferFormats::toString(m_StorageFormat), m_Width,
+ m_Height);
+ }
+ }
+}
+}
+
+qt3ds::render::NVRenderRenderBuffer *
+qt3ds::render::NVRenderRenderBuffer::Create(NVRenderContextImpl &context,
+ NVRenderRenderBufferFormats::Enum format, QT3DSU32 width,
+ QT3DSU32 height)
+{
+ NVRenderRenderBuffer *retval = NULL;
+ if (width == 0 || height == 0) {
+ qCCritical(INVALID_PARAMETER, "Invalid renderbuffer width or height");
+ return retval;
+ }
+
+ retval = QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderRenderBuffer)(context, context.GetFoundation(), format, width, height);
+
+ return retval;
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h
new file mode 100644
index 00000000..41f4068a
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderRenderBuffer.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_RENDER_BUFFER_H
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+ class NVRenderContextImpl;
+
+ struct NVRenderRenderBufferDimensions
+ {
+ QT3DSU32 m_Width; ///< buffer width
+ QT3DSU32 m_Height; ///< buffer height
+
+ NVRenderRenderBufferDimensions(QT3DSU32 w, QT3DSU32 h)
+ : m_Width(w)
+ , m_Height(h)
+ {
+ }
+ NVRenderRenderBufferDimensions()
+ : m_Width(0)
+ , m_Height(0)
+ {
+ }
+ };
+
+ class NVRenderRenderBuffer : public NVRefCounted, public NVRenderImplemented
+ {
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ QT3DSU32 m_Width; ///< buffer width
+ QT3DSU32 m_Height; ///< buffer height
+ NVRenderRenderBufferFormats::Enum m_StorageFormat; ///< buffer storage format
+
+ NVRenderBackend::NVRenderBackendRenderbufferObject
+ m_BufferHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] format Renderbuffer format
+ * @param[in] width Renderbuffer width
+ * @param[in] height Renderbuffer height
+ *
+ * @return No return.
+ */
+ NVRenderRenderBuffer(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderRenderBufferFormats::Enum format, QT3DSU32 width, QT3DSU32 height);
+
+ /// destructor
+ virtual ~NVRenderRenderBuffer();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ /**
+ * @brief query buffer format
+ *
+ *
+ * @return buffer format
+ */
+ virtual NVRenderRenderBufferFormats::Enum GetStorageFormat() const
+ {
+ return m_StorageFormat;
+ }
+
+ /**
+ * @brief query buffer dimension
+ *
+ *
+ * @return NVRenderRenderBufferDimensions object
+ */
+ virtual NVRenderRenderBufferDimensions GetDimensions() const
+ {
+ return NVRenderRenderBufferDimensions(m_Width, m_Height);
+ }
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] inDimensions A dimension object
+ *
+ * @return buffer format
+ */
+ virtual void SetDimensions(const NVRenderRenderBufferDimensions &inDimensions);
+
+ /**
+ * @brief static creator function
+ *
+ * @param[in] context Pointer to context
+ * @param[in] format Renderbuffer format
+ * @param[in] width Renderbuffer width
+ * @param[in] height Renderbuffer height
+ *
+ * @return No return.
+ */
+ static NVRenderRenderBuffer *Create(NVRenderContextImpl &context,
+ NVRenderRenderBufferFormats::Enum format, QT3DSU32 width,
+ QT3DSU32 height);
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendRenderbufferObject GetRenderBuffertHandle()
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderSampler.cpp b/src/Runtime/Source/render/Qt3DSRenderSampler.cpp
new file mode 100644
index 00000000..b02fc615
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderSampler.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSDataRef.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderSampler.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTextureSampler::NVRenderTextureSampler(
+ NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter,
+ NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT,
+ NVRenderTextureCoordOp::Enum wrapR, NVRenderTextureSwizzleMode::Enum swizzleMode,
+ QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias, NVRenderTextureCompareMode::Enum compareMode,
+ NVRenderTextureCompareOp::Enum compareFunc, QT3DSF32 anisotropy, QT3DSF32 *borderColor)
+ : m_MinFilter(minFilter)
+ , m_MagFilter(magFilter)
+ , m_WrapS(wrapS)
+ , m_WrapT(wrapT)
+ , m_WrapR(wrapR)
+ , m_SwizzleMode(swizzleMode)
+ , m_MinLod(minLod)
+ , m_MaxLod(maxLod)
+ , m_LodBias(lodBias)
+ , m_CompareMode(compareMode)
+ , m_CompareOp(compareFunc)
+ , m_Anisotropy(anisotropy)
+ , m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_SamplerHandle(NULL)
+ {
+ // create backend handle
+ m_SamplerHandle = m_Backend->CreateSampler();
+
+ if (borderColor) {
+ m_BorderColor[0] = borderColor[0];
+ m_BorderColor[1] = borderColor[1];
+ m_BorderColor[2] = borderColor[2];
+ m_BorderColor[3] = borderColor[3];
+ }
+ }
+
+ NVRenderTextureSampler::~NVRenderTextureSampler()
+ {
+ if (m_SamplerHandle)
+ m_Backend->ReleaseSampler(m_SamplerHandle);
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderSampler.h b/src/Runtime/Source/render/Qt3DSRenderSampler.h
new file mode 100644
index 00000000..77d3f008
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderSampler.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H
+#define QT3DS_RENDER_QT3DS_RENDER_SAMPLER_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+
+ class NVRenderTextureSampler
+ {
+ public:
+ NVRenderTextureMinifyingOp::Enum m_MinFilter;
+ NVRenderTextureMagnifyingOp::Enum m_MagFilter;
+ NVRenderTextureCoordOp::Enum m_WrapS;
+ NVRenderTextureCoordOp::Enum m_WrapT;
+ NVRenderTextureCoordOp::Enum m_WrapR;
+ NVRenderTextureSwizzleMode::Enum m_SwizzleMode;
+ QT3DSF32 m_MinLod;
+ QT3DSF32 m_MaxLod;
+ QT3DSF32 m_LodBias;
+ NVRenderTextureCompareMode::Enum m_CompareMode;
+ NVRenderTextureCompareOp::Enum m_CompareOp;
+ QT3DSF32 m_Anisotropy;
+ QT3DSF32 m_BorderColor[4];
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] minFilter Texture min filter
+ * @param[in] magFilter Texture mag filter
+ * @param[in] wrapS Texture coord generation for S
+ * @param[in] wrapT Texture coord generation for T
+ * @param[in] wrapR Texture coord generation for R
+ * @param[in] swizzleMode Texture swizzle mode
+ * @param[in] minLod Texture min level of detail
+ * @param[in] maxLod Texture max level of detail
+ * @param[in] lodBias Texture level of detail bias (unused)
+ * @param[in] compareMode Texture compare mode
+ * @param[in] compareFunc Texture compare function
+ * @param[in] anisoFilter Aniso filter value [1.0, 16.0]
+ * @param[in] borderColor Texture border color float[4] (unused)
+ *
+ * @return No return.
+ */
+ NVRenderTextureSampler(
+ NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle,
+ QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL);
+
+ /**
+ * @brief destructor
+ *
+ */
+ virtual ~NVRenderTextureSampler();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendSamplerObject GetSamplerHandle() const
+ {
+ return m_SamplerHandle;
+ }
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBackend::NVRenderBackendSamplerObject m_SamplerHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderShader.h b/src/Runtime/Source/render/Qt3DSRenderShader.h
new file mode 100644
index 00000000..8d0a62c4
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderShader.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_SHADER_H
+#define QT3DS_RENDER_SHADER_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include <EASTL/string.h>
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ ///< A shader program is an object composed of a multiple shaders (vertex, fragment,
+ ///geometry,....)
+ class NVRenderShader
+ {
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVConstDataRef<QT3DSI8> m_Source; ///< shader source code
+ bool m_Binary; ///< true for binary programs
+ eastl::string m_ErrorMessage; ///< contains the error message if linking fails
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , m_Backend(context.GetBackend())
+ , m_Source(source)
+ , m_Binary(binaryProgram)
+ {
+ }
+
+ /// @brief destructor
+ ~NVRenderShader(){}
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ virtual bool IsValid() = 0;
+
+ /**
+ * @brief Get Error Message
+ *
+ * @param[out] messageLength Pointer to error string
+ * @param[out] messageLength Size of error meesage
+ *
+ * @return no return
+ */
+ virtual void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage)
+ {
+ // Since we do not have any error message just generate a generic one
+ if (m_Binary)
+ m_ErrorMessage = "Binary shader compilation failed";
+
+ *messageLength = m_ErrorMessage.size();
+ errorMessage = m_ErrorMessage.c_str();
+ }
+
+ /**
+ * @brief Get Error Message
+ *
+ *
+ * @return error message.
+ */
+ virtual const char *GetErrorMessage()
+ {
+ if (m_Binary)
+ m_ErrorMessage = "Binary shader compilation failed";
+
+ return m_ErrorMessage.c_str();
+ }
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h b/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h
new file mode 100644
index 00000000..7fb57ffe
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderShaderConstant.h
@@ -0,0 +1,448 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_SHADER_CONSTANT_H
+#define QT3DS_RENDER_SHADER_CONSTANT_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSMat33.h"
+#include "foundation/Qt3DSMat44.h"
+#include "EASTL/string.h"
+#include "EASTL/utility.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ ///< forward declarations
+ class NVRenderContextImpl;
+ class NVRenderConstantBuffer;
+
+ ///< A shader constant belongs to a program
+ class QT3DS_AUTOTEST_EXPORT NVRenderShaderConstantBase
+ {
+ public:
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ CRegisteredString m_Name; ///< register constant name
+ QT3DSI32 m_Location; ///< constant index
+ QT3DSI32 m_ElementCount; ///< constant element count for arrays
+ NVRenderShaderDataTypes::Enum m_Type; ///< constant type
+ QT3DSI32 m_Binding; ///< sampler/imnage binding point
+
+ public:
+ NVRenderShaderConstantBase(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding)
+ : m_Backend(backend)
+ , m_Name(name)
+ , m_Location(location)
+ , m_ElementCount(elementCount)
+ , m_Type(type)
+ , m_Binding(binding)
+ {
+ }
+
+ NVRenderShaderDataTypes::Enum GetShaderConstantType() const { return m_Type; }
+
+ virtual void Release() = 0;
+ };
+
+ ///< A general class for shader types
+ template <typename TDataType>
+ class NVRenderShaderConstant : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ TDataType m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ memset(&m_Value, 0, sizeof(TDataType));
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< A specialized class for textures
+ template <>
+ class NVRenderShaderConstant<NVRenderTexture2DPtr> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSU32 m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ m_Value = QT3DS_MAX_U32;
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< A specialized class for textures
+ template <>
+ class NVRenderShaderConstant<NVRenderTexture2DHandle> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QVector<QT3DSU32> m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ m_Value.resize(elementCount);
+ m_Value.fill(QT3DS_MAX_U32);
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< A specialized class for texture arrays
+ template <>
+ class NVRenderShaderConstant<NVRenderTexture2DArrayPtr> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSU32 m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ m_Value = QT3DS_MAX_U32;
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< A specialized class for cubemap textures
+ template <>
+ class NVRenderShaderConstant<NVRenderTextureCubePtr> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSU32 m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ m_Value = QT3DS_MAX_U32;
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< A specialized class for cubemap textures
+ template <>
+ class NVRenderShaderConstant<NVRenderTextureCubeHandle> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QVector<QT3DSU32> m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ m_Value.resize(elementCount);
+ m_Value.fill(QT3DS_MAX_U32);
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< A specialized class for texture image buffer
+ template <>
+ class NVRenderShaderConstant<NVRenderImage2DPtr> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSU32 m_Value; ///< constant value
+
+ public:
+ NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location,
+ QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type,
+ QT3DSI32 binding, NVFoundationBase &allocator)
+ : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding)
+ , m_Foundation(allocator)
+ {
+ m_Value = QT3DS_MAX_U32;
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
+ };
+
+ ///< Base for any buffer ( constant, texture, ... ) which is used by this program
+ class NVRenderShaderBufferBase
+ {
+ public:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ CRegisteredString m_Name; ///< buffer name
+ QT3DSU32 m_Location; ///< program buffer block location
+ QT3DSU32 m_Binding; ///< program buffer binding
+ QT3DSI32 m_Size; ///< buffer size
+
+ public:
+ NVRenderShaderBufferBase(NVRenderContextImpl &context, CRegisteredString name,
+ QT3DSI32 location, QT3DSI32 binding, QT3DSI32 size)
+ : m_Context(context)
+ , m_Name(name)
+ , m_Location(location)
+ , m_Binding(binding)
+ , m_Size(size)
+ {
+ }
+
+ virtual void Release() = 0;
+
+ virtual void Validate(NVRenderShaderProgram *inShader) = 0;
+ virtual void BindToProgram(NVRenderShaderProgram *inShader) = 0;
+ virtual void Update() = 0;
+ };
+
+ class NVRenderShaderConstantBuffer : public NVRenderShaderBufferBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer
+ NVRenderConstantBuffer *m_pCB; ///< pointer to constant buffer
+
+ public:
+ NVRenderShaderConstantBuffer(NVRenderContextImpl &context, CRegisteredString name,
+ QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count,
+ NVRenderConstantBuffer *pCB, NVFoundationBase &allocator)
+ : NVRenderShaderBufferBase(context, name, location, binding, size)
+ , m_Foundation(allocator)
+ , m_ParamCount(count)
+ , m_pCB(pCB)
+ {
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override
+ {
+ if (m_pCB)
+ m_pCB->release();
+
+ NVDelete(GetFoundation().getAllocator(), this);
+ }
+
+ void Validate(NVRenderShaderProgram *inShader) override
+ {
+ // A constant buffer might not be set at first call
+ // due to the fact that they are compiled from a cache file
+ // Now it must exists.
+ if (m_pCB)
+ return;
+
+ NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(m_Name);
+ if (cb) {
+ cb->SetupBuffer(inShader, m_Location, m_Size, m_ParamCount);
+ cb->addRef();
+ m_pCB = cb;
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ void Update() override
+ {
+ if (m_pCB)
+ m_pCB->Update();
+ }
+
+ void BindToProgram(NVRenderShaderProgram *inShader) override
+ {
+ if (m_pCB)
+ m_pCB->BindToShaderProgram(inShader, m_Location, m_Binding);
+ }
+ };
+
+ class NVRenderShaderStorageBuffer : public NVRenderShaderBufferBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer
+ NVRenderStorageBuffer *m_pSB; ///< pointer to storage buffer
+
+ public:
+ NVRenderShaderStorageBuffer(NVRenderContextImpl &context, CRegisteredString name,
+ QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count,
+ NVRenderStorageBuffer *pSB, NVFoundationBase &allocator)
+ : NVRenderShaderBufferBase(context, name, location, binding, size)
+ , m_Foundation(allocator)
+ , m_ParamCount(count)
+ , m_pSB(pSB)
+ {
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override
+ {
+ if (m_pSB)
+ m_pSB->release();
+
+ NVDelete(GetFoundation().getAllocator(), this);
+ }
+
+ void Validate(NVRenderShaderProgram * /*inShader*/) override
+ {
+ // A constant buffer might not be set at first call
+ // due to the fact that they are compile from a cache file
+ // Now it must exists.
+ if (m_pSB)
+ return;
+
+ NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(m_Name);
+ if (sb) {
+ sb->addRef();
+ m_pSB = sb;
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ void Update() override
+ {
+ if (m_pSB)
+ m_pSB->Update();
+ }
+
+ void BindToProgram(NVRenderShaderProgram * /*inShader*/) override
+ {
+ if (m_pSB)
+ m_pSB->BindToShaderProgram(m_Location);
+ }
+ };
+
+ class NVRenderShaderAtomicCounterBuffer : public NVRenderShaderBufferBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QT3DSI32 m_ParamCount; ///< count of parameters contained in the constant buffer
+ NVRenderAtomicCounterBuffer *m_pAcB; ///< pointer to atomic counter buffer
+
+ public:
+ NVRenderShaderAtomicCounterBuffer(NVRenderContextImpl &context, CRegisteredString name,
+ QT3DSU32 location, QT3DSI32 binding, QT3DSI32 size, QT3DSI32 count,
+ NVRenderAtomicCounterBuffer *pAcB,
+ NVFoundationBase &allocator)
+ : NVRenderShaderBufferBase(context, name, location, binding, size)
+ , m_Foundation(allocator)
+ , m_ParamCount(count)
+ , m_pAcB(pAcB)
+ {
+ }
+
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ void Release() override
+ {
+ if (m_pAcB)
+ m_pAcB->release();
+
+ NVDelete(GetFoundation().getAllocator(), this);
+ }
+
+ void Validate(NVRenderShaderProgram * /*inShader*/) override
+ {
+ // A constant buffer might not be set at first call
+ // due to the fact that they are compile from a cache file
+ // Now it must exists.
+ if (m_pAcB)
+ return;
+
+ NVRenderAtomicCounterBuffer *acb = m_Context.GetAtomicCounterBuffer(m_Name);
+ if (acb) {
+ acb->addRef();
+ m_pAcB = acb;
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ void Update() override
+ {
+ if (m_pAcB)
+ m_pAcB->Update();
+ }
+
+ void BindToProgram(NVRenderShaderProgram * /*inShader*/) override
+ {
+ if (m_pAcB)
+ m_pAcB->BindToShaderProgram(m_Location);
+ }
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp
new file mode 100644
index 00000000..09f1094b
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.cpp
@@ -0,0 +1,1248 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+#include "render/Qt3DSRenderVertexShader.h"
+#include "render/Qt3DSRenderFragmentShader.h"
+#include "render/Qt3DSRenderTessellationShader.h"
+#include "render/Qt3DSRenderGeometryShader.h"
+#include "render/Qt3DSRenderComputeShader.h"
+#include "render/Qt3DSRenderImageTexture.h"
+
+namespace qt3ds {
+namespace render {
+
+ template <typename TDataType>
+ struct ShaderConstantApplier
+ {
+ bool force_compile_error;
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSI32>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32 &inValue,
+ QT3DSI32 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSI32_2>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_2 &inValue,
+ QT3DSI32_2 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue.x);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSI32_3>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_3 &inValue,
+ QT3DSI32_3 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue.x);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSI32_4>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSI32_4 &inValue,
+ QT3DSI32_4 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue.x);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSRenderBool>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ const QT3DSRenderBool inValue, QT3DSRenderBool &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<bool_2>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_2 &inValue,
+ bool_2 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<bool_3>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_3 &inValue,
+ bool_3 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<bool_4>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const bool_4 &inValue,
+ bool_4 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSF32>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSF32 &inValue,
+ QT3DSF32 &oldValue)
+ {
+ if (count > 1 || !(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSVec2>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec2 &inValue,
+ QT3DSVec2 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSVec3>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec3 &inValue,
+ QT3DSVec3 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSVec4>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSVec4 &inValue,
+ QT3DSVec4 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSU32>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32 &inValue,
+ QT3DSU32 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSU32_2>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_2 &inValue,
+ QT3DSU32_2 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue.x);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSU32_3>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_3 &inValue,
+ QT3DSU32_3 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue.x);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSU32_4>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSU32_4 &inValue,
+ QT3DSU32_4 &oldValue)
+ {
+ if (!(inValue == oldValue)) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ &inValue.x);
+ oldValue = inValue;
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSMat33>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat33 inValue,
+ QT3DSMat33 &, bool inTranspose)
+ {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ inValue.front(), inTranspose);
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<QT3DSMat44>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type, const QT3DSMat44 inValue,
+ QT3DSMat44 &, bool inTranspose)
+ {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ inValue.front(), inTranspose);
+ }
+
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVConstDataRef<QT3DSMat44> inValue, QT3DSMat44 &, bool inTranspose)
+ {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type, count,
+ reinterpret_cast<const GLfloat *>(inValue.begin()),
+ inTranspose);
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<NVRenderTexture2DPtr>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTexture2DPtr inValue, QT3DSU32 &oldValue)
+ {
+ if (inValue) {
+ NVRenderTexture2D *texObj = reinterpret_cast<NVRenderTexture2D *>(inValue);
+ texObj->Bind();
+ QT3DSU32 texUnit = texObj->GetTextureUnit();
+ if (texUnit != oldValue) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type,
+ count, &texUnit);
+ oldValue = texUnit;
+ }
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<NVRenderTexture2DHandle>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend,
+ QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTexture2DHandle inValue, QVector<QT3DSU32> &oldValue)
+ {
+ Q_UNUSED(type)
+ if (inValue) {
+ bool update = false;
+ for (int i = 0; i < count; i++) {
+ NVRenderTexture2D *texObj = reinterpret_cast<NVRenderTexture2D *>(inValue[i]);
+ QT3DSU32 texUnit = QT3DS_MAX_U32;
+ if (texObj) {
+ texObj->Bind();
+ texUnit = texObj->GetTextureUnit();
+ }
+ if (texUnit != oldValue[i]) {
+ update = true;
+ oldValue[i] = texUnit;
+ }
+ }
+ if (update)
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location,
+ NVRenderShaderDataTypes::NVRenderTexture2DPtr,
+ count, oldValue.data());
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<NVRenderTexture2DArrayPtr>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTexture2DArrayPtr inValue, QT3DSU32 &oldValue)
+ {
+ if (inValue) {
+ NVRenderTexture2DArray *texObj =
+ reinterpret_cast<NVRenderTexture2DArray *>(inValue);
+ texObj->Bind();
+ QT3DSU32 texUnit = texObj->GetTextureUnit();
+ if (texUnit != oldValue) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type,
+ count, &texUnit);
+ oldValue = texUnit;
+ }
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<NVRenderTextureCubePtr>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTextureCubePtr inValue, QT3DSU32 &oldValue)
+ {
+ if (inValue) {
+ NVRenderTextureCube *texObj = reinterpret_cast<NVRenderTextureCube *>(inValue);
+ texObj->Bind();
+ QT3DSU32 texUnit = texObj->GetTextureUnit();
+ if (texUnit != oldValue) {
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type,
+ count, &texUnit);
+ oldValue = texUnit;
+ }
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<NVRenderTextureCubeHandle>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend,
+ QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTextureCubeHandle inValue, QVector<QT3DSU32> &oldValue)
+ {
+ Q_UNUSED(type)
+ if (inValue) {
+ bool update = false;
+ for (int i = 0; i < count; i++) {
+ NVRenderTextureCube *texObj = reinterpret_cast<NVRenderTextureCube *>(inValue[i]);
+ QT3DSU32 texUnit = QT3DS_MAX_U32;
+ if (texObj) {
+ texObj->Bind();
+ texUnit = texObj->GetTextureUnit();
+ }
+ if (texUnit != oldValue[i]) {
+ update = true;
+ oldValue[i] = texUnit;
+ }
+ }
+ if (update)
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location,
+ NVRenderShaderDataTypes::NVRenderTextureCubePtr,
+ count, oldValue.data());
+ }
+ }
+ };
+
+ template <>
+ struct ShaderConstantApplier<NVRenderImage2DPtr>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
+ QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderImage2DPtr inValue, QT3DSU32 &oldValue, QT3DSI32 binding)
+ {
+ if (inValue) {
+ NVRenderImage2D *imgObj = reinterpret_cast<NVRenderImage2D *>(inValue);
+ imgObj->Bind(binding);
+ QT3DSU32 texUnit = imgObj->GetTextureUnit();
+ if (texUnit != oldValue) {
+ // on ES we need a explicit binding value
+ QT3DS_ASSERT(backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS
+ || binding != -1);
+ // this is not allowed on ES 3+ for image types
+ if (backend->GetRenderContextType() != NVRenderContextValues::GLES3PLUS)
+ backend->SetConstantValue(program->GetShaderProgramHandle(), location, type,
+ count, &texUnit);
+
+ oldValue = texUnit;
+ }
+ }
+ }
+ };
+
+ NVRenderShaderProgram::NVRenderShaderProgram(NVRenderContextImpl &context,
+ NVFoundationBase &fnd, const char *programName,
+ bool separableProgram)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_ProgramName(programName)
+ , m_ProgramHandle(NULL)
+ , m_Constants(context.GetFoundation().getAllocator(), "NVRenderShaderProgram::m_Constants")
+ , m_ShaderBuffers(context.GetFoundation().getAllocator(),
+ "NVRenderShaderProgram::m_ShaderBuffers")
+ , m_ProgramType(ProgramType::Graphics)
+ {
+ m_ProgramHandle = m_Backend->CreateShaderProgram(separableProgram);
+
+ QT3DS_ASSERT(m_ProgramHandle);
+ }
+
+ NVRenderShaderProgram::~NVRenderShaderProgram()
+ {
+ m_Context.ShaderDestroyed(*this);
+
+ if (m_ProgramHandle)
+ m_Backend->ReleaseShaderProgram(m_ProgramHandle);
+
+ for (TShaderConstantMap::iterator iter = m_Constants.begin(), end = m_Constants.end();
+ iter != end; ++iter) {
+ iter->second->Release();
+ }
+
+ m_Constants.clear();
+
+ for (TShaderBufferMap::iterator iter = m_ShaderBuffers.begin(), end = m_ShaderBuffers.end();
+ iter != end; ++iter) {
+ iter->second->Release();
+ }
+
+ m_ShaderBuffers.clear();
+
+ m_ProgramHandle = NULL;
+ }
+
+ template <typename TShaderObject>
+ void NVRenderShaderProgram::Attach(TShaderObject *pShader)
+ {
+ m_Backend->AttachShader(m_ProgramHandle, pShader->GetShaderHandle());
+ }
+
+ template <typename TShaderObject>
+ void NVRenderShaderProgram::Detach(TShaderObject *pShader)
+ {
+ m_Backend->DetachShader(m_ProgramHandle, pShader->GetShaderHandle());
+ }
+
+ static NVRenderShaderConstantBase *
+ ShaderConstantFactory(NVRenderBackend *backend, CRegisteredString inName,
+ NVFoundationBase &alloc, QT3DSI32 uniLoc, QT3DSI32 elementCount,
+ NVRenderShaderDataTypes::Enum inConstantType, QT3DSI32 binding)
+ {
+ switch (inConstantType) {
+#define HANDLE_QT3DS_SHADER_DATA_TYPE(nv) \
+ case NVRenderShaderDataTypes::nv: \
+ return QT3DS_NEW(alloc.getAllocator(), NVRenderShaderConstant<nv>)( \
+ backend, inName, uniLoc, elementCount, inConstantType, binding, alloc);
+ ITERATE_QT3DS_SHADER_DATA_TYPES
+#undef HANDLE_QT3DS_SHADER_DATA_TYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NULL;
+ }
+
+ template <typename TShaderBufferType, typename TBufferDataType>
+ static NVRenderShaderBufferBase *
+ ShaderBufferFactory(NVRenderContextImpl &context, CRegisteredString inName,
+ NVFoundationBase &alloc, QT3DSI32 cbLoc, QT3DSI32 cbBinding, QT3DSI32 cbSize,
+ QT3DSI32 cbCount, TBufferDataType *pBuffer)
+ {
+ return QT3DS_NEW(alloc.getAllocator(), TShaderBufferType)(context, inName, cbLoc, cbBinding,
+ cbSize, cbCount, pBuffer, alloc);
+ }
+
+ bool NVRenderShaderProgram::Link()
+ {
+ bool success = m_Backend->LinkProgram(m_ProgramHandle, m_ErrorMessage);
+
+ if (success) {
+ char nameBuf[512];
+ QT3DSI32 location, elementCount, binding;
+ NVRenderShaderDataTypes::Enum type;
+
+ QT3DSI32 constantCount = m_Backend->GetConstantCount(m_ProgramHandle);
+
+ QT3DS_FOREACH(idx, constantCount)
+ {
+ location = m_Backend->GetConstantInfoByID(m_ProgramHandle, idx, 512, &elementCount,
+ &type, &binding, nameBuf);
+
+ // sampler arrays have different type
+ if (type == NVRenderShaderDataTypes::NVRenderTexture2DPtr && elementCount > 1) {
+ type = NVRenderShaderDataTypes::NVRenderTexture2DHandle;
+ } else if (type == NVRenderShaderDataTypes::NVRenderTextureCubePtr
+ && elementCount > 1) {
+ type = NVRenderShaderDataTypes::NVRenderTextureCubeHandle;
+ }
+ if (location != -1) {
+ CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf));
+ m_Constants.insert(eastl::make_pair(
+ theName,
+ ShaderConstantFactory(m_Backend, theName, m_Context.GetFoundation(),
+ location, elementCount, type, binding)));
+ }
+ }
+
+ // next query constant buffers info
+ QT3DSI32 length, bufferSize, paramCount;
+ QT3DSI32 constantBufferCount = m_Backend->GetConstantBufferCount(m_ProgramHandle);
+ QT3DS_FOREACH(idx, constantBufferCount)
+ {
+ location = m_Backend->GetConstantBufferInfoByID(
+ m_ProgramHandle, idx, 512, &paramCount, &bufferSize, &length, nameBuf);
+
+ if (location != -1) {
+ CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf));
+
+ // find constant buffer in our DB
+ NVRenderConstantBuffer *cb = m_Context.GetConstantBuffer(theName);
+ if (cb) {
+ cb->SetupBuffer(this, location, bufferSize, paramCount);
+ cb->addRef();
+ }
+
+ m_ShaderBuffers.insert(eastl::make_pair(
+ theName,
+ ShaderBufferFactory<NVRenderShaderConstantBuffer, NVRenderConstantBuffer>(
+ m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize,
+ paramCount, cb)));
+ }
+ }
+
+ // next query storage buffers
+ QT3DSI32 storageBufferCount = m_Backend->GetStorageBufferCount(m_ProgramHandle);
+ QT3DS_FOREACH(idx, storageBufferCount)
+ {
+ location = m_Backend->GetStorageBufferInfoByID(
+ m_ProgramHandle, idx, 512, &paramCount, &bufferSize, &length, nameBuf);
+
+ if (location != -1) {
+ CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf));
+
+ // find constant buffer in our DB
+ NVRenderStorageBuffer *sb = m_Context.GetStorageBuffer(theName);
+ if (sb) {
+ sb->addRef();
+ }
+
+ m_ShaderBuffers.insert(eastl::make_pair(
+ theName,
+ ShaderBufferFactory<NVRenderShaderStorageBuffer, NVRenderStorageBuffer>(
+ m_Context, theName, m_Context.GetFoundation(), location, -1, bufferSize,
+ paramCount, sb)));
+ }
+ }
+
+ // next query atomic counter buffers
+ QT3DSI32 atomicBufferCount = m_Backend->GetAtomicCounterBufferCount(m_ProgramHandle);
+ QT3DS_FOREACH(idx, atomicBufferCount)
+ {
+ location = m_Backend->GetAtomicCounterBufferInfoByID(
+ m_ProgramHandle, idx, 512, &paramCount, &bufferSize, &length, nameBuf);
+
+ if (location != -1) {
+ CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf));
+
+ // find atomic counter buffer in our DB
+ // The buffer itself is not used in the program itself.
+ // Instead uniform variables are used but the interface to set the value is like
+ // for buffers.
+ // This is a bit insane but that is how it is.
+ // The theName variable contains the uniform name associated with an atomic
+ // counter buffer.
+ // We get the actual buffer name by searching for this uniform name
+ // See NVRenderTestAtomicCounterBuffer.cpp how the setup works
+ NVRenderAtomicCounterBuffer *acb =
+ m_Context.GetAtomicCounterBufferByParam(theName);
+ if (acb) {
+ acb->addRef();
+
+ m_ShaderBuffers.insert(eastl::make_pair(
+ acb->GetBufferName(),
+ ShaderBufferFactory<NVRenderShaderAtomicCounterBuffer,
+ NVRenderAtomicCounterBuffer>(
+ m_Context, acb->GetBufferName(), m_Context.GetFoundation(),
+ location, -1, bufferSize, paramCount, acb)));
+ }
+ }
+ }
+ }
+
+ return success;
+ }
+
+ void NVRenderShaderProgram::GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage)
+ {
+ *messageLength = m_ErrorMessage.size();
+ errorMessage = m_ErrorMessage.c_str();
+ }
+
+ const char *NVRenderShaderProgram::GetErrorMessage() { return m_ErrorMessage.c_str(); }
+
+ NVRenderShaderConstantBase *NVRenderShaderProgram::GetShaderConstant(const char *constantName)
+ {
+ TShaderConstantMap::iterator theIter =
+ m_Constants.find(m_Context.GetStringTable().RegisterStr(constantName));
+
+ if (theIter != m_Constants.end()) {
+ NVRenderShaderConstantBase *theConstant =
+ static_cast<NVRenderShaderConstantBase *>(theIter->second);
+ return theConstant;
+ }
+
+ return NULL;
+ }
+
+ NVRenderShaderBufferBase *NVRenderShaderProgram::GetShaderBuffer(const char *bufferName)
+ {
+ TShaderBufferMap::iterator theIter =
+ m_ShaderBuffers.find(m_Context.GetStringTable().RegisterStr(bufferName));
+
+ if (theIter != m_ShaderBuffers.end()) {
+ return theIter->second;
+ }
+
+ return NULL;
+ }
+
+ NVRenderContextImpl &NVRenderShaderProgram::GetRenderContext() { return m_Context; }
+
+ template <typename TDataType>
+ void SetConstantValueOfType(NVRenderShaderProgram *program,
+ NVRenderShaderConstantBase *inConstantBase,
+ const TDataType &inValue, const QT3DSI32 inCount)
+ {
+ if (inConstantBase == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount);
+
+ if (inConstantBase->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ NVRenderShaderConstant<TDataType> *inConstant =
+ static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase);
+ ShaderConstantApplier<TDataType>().ApplyConstant(
+ program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type,
+ inValue, inConstant->m_Value);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ template <typename TDataType>
+ void SetSamplerConstantValueOfType(NVRenderShaderProgram *program,
+ NVRenderShaderConstantBase *inConstantBase,
+ const TDataType &inValue, const QT3DSI32 inCount)
+ {
+ if (inConstantBase == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount);
+
+ if (inConstantBase->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ NVRenderShaderConstant<TDataType> *inConstant =
+ static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase);
+ ShaderConstantApplier<TDataType>().ApplyConstant(
+ program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type,
+ inValue, inConstant->m_Value, inConstant->m_Binding);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ template <typename TDataType>
+ void SetMatrixConstantValueOfType(NVRenderShaderProgram *program,
+ NVRenderShaderConstantBase *inConstantBase,
+ const TDataType &inValue, const QT3DSI32 inCount,
+ bool inTranspose)
+ {
+ if (inConstantBase == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ QT3DS_ASSERT(inConstantBase->m_ElementCount >= inCount);
+
+ if (inConstantBase->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ NVRenderShaderConstant<TDataType> *inConstant =
+ static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase);
+ ShaderConstantApplier<TDataType>().ApplyConstant(
+ program, inConstant->m_Backend, inConstant->m_Location, inCount, inConstant->m_Type,
+ inValue, inConstant->m_Value, inTranspose);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ template <typename TDataType>
+ void SetMatrixConstantValueOfType(NVRenderShaderProgram *program,
+ NVRenderShaderConstantBase *inConstantBase,
+ const NVConstDataRef<TDataType> inValue,
+ const QT3DSI32 /*inCount*/, bool inTranspose)
+ {
+ if (inConstantBase == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ QT3DS_ASSERT(inConstantBase->m_ElementCount >= (QT3DSI32)inValue.size());
+
+ if (inConstantBase->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ NVRenderShaderConstant<TDataType> *inConstant =
+ static_cast<NVRenderShaderConstant<TDataType> *>(inConstantBase);
+ ShaderConstantApplier<TDataType>().ApplyConstant(
+ program, inConstant->m_Backend, inConstant->m_Location, inValue.size(),
+ inConstant->m_Type, inValue, inConstant->m_Value, inTranspose);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ QT3DSI32 inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSI32_2 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSI32_3 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSI32_4 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ QT3DSRenderBool inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const bool_2 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const bool_3 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const bool_4 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSF32 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSVec2 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSVec3 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSVec4 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSU32 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSU32_2 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSU32_3 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSU32_4 &inValue, const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSMat33 &inValue, const QT3DSI32 inCount,
+ bool inTranspose)
+ {
+ SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const QT3DSMat44 &inValue, const QT3DSI32 inCount,
+ bool inTranspose)
+ {
+ SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, inTranspose);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const NVConstDataRef<QT3DSMat44> inValue,
+ const QT3DSI32 inCount)
+ {
+ SetMatrixConstantValueOfType(this, inConstant, inValue, inCount, false);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderTexture2D *inValue, const QT3DSI32 inCount)
+ {
+ Q_UNUSED(inCount)
+ SetConstantValueOfType(this, inConstant, inValue, 1);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderTexture2D **inValue,
+ const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderTexture2DArray *inValue,
+ const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderTextureCube *inValue, const QT3DSI32 inCount)
+ {
+ Q_UNUSED(inCount)
+ SetConstantValueOfType(this, inConstant, inValue, 1);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderTextureCube **inValue,
+ const QT3DSI32 inCount)
+ {
+ SetConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderImage2D *inValue, const QT3DSI32 inCount)
+ {
+ SetSamplerConstantValueOfType(this, inConstant, inValue, inCount);
+ }
+ void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *, NVRenderDataBuffer *,
+ const QT3DSI32)
+ {
+ // this is merely a dummy right now
+ }
+
+ void NVRenderShaderProgram::BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex)
+ {
+ NVRenderBackend::NVRenderBackendBufferObject obj(NULL);
+ if (inBuffer)
+ obj = inBuffer->GetBuffertHandle();
+ m_Backend->ProgramSetStorageBuffer(inIndex, obj);
+ }
+
+ namespace {
+ void WriteErrorMessage(NVFoundationBase &fnd, const char *tag, const char *message)
+ {
+ Q_UNUSED(fnd)
+ eastl::string messageData(nonNull(message));
+ eastl::vector<eastl::string> lines;
+ for (eastl::string::size_type pos = messageData.find('\n'); pos != eastl::string::npos;
+ pos = messageData.find('\n')) {
+ eastl::string line = messageData.substr(0, pos);
+ messageData.erase(messageData.begin(), messageData.begin() + pos + 1);
+ if (line.size())
+ qCCritical(INVALID_OPERATION, "%s: %s", tag, line.c_str());
+ }
+ }
+ }
+
+ Option<NVRenderVertexShader *> NVRenderShaderProgram::createVertexShader(
+ NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> vertexShaderSource, bool binaryProgram)
+ {
+ if (vertexShaderSource.size() == 0)
+ return Empty();
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderVertexShader(context, context.GetFoundation(), vertexShaderSource,
+ binaryProgram));
+ }
+
+ Option<NVRenderFragmentShader *> NVRenderShaderProgram::createFragmentShader(
+ NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> fragmentShaderSource, bool binaryProgram)
+ {
+ if (fragmentShaderSource.size() == 0)
+ return Empty();
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderFragmentShader(context, context.GetFoundation(), fragmentShaderSource,
+ binaryProgram));
+ }
+
+ Option<NVRenderTessControlShader *>
+ NVRenderShaderProgram::createTessControlShader(NVRenderContextImpl &context,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource,
+ bool binaryProgram)
+ {
+ if (tessControlShaderSource.size() == 0)
+ return Empty();
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderTessControlShader(context, context.GetFoundation(),
+ tessControlShaderSource, binaryProgram));
+ }
+
+ Option<NVRenderTessEvaluationShader *>
+ NVRenderShaderProgram::createTessEvaluationShader(NVRenderContextImpl &context,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource,
+ bool binaryProgram)
+ {
+ if (tessControlShaderSource.size() == 0)
+ return Empty();
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderTessEvaluationShader(context, context.GetFoundation(),
+ tessControlShaderSource, binaryProgram));
+ }
+
+ Option<NVRenderGeometryShader *> NVRenderShaderProgram::createGeometryShader(
+ NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> geometryShaderSource, bool binaryProgram)
+ {
+ if (geometryShaderSource.size() == 0)
+ return Empty();
+
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderGeometryShader(context, context.GetFoundation(), geometryShaderSource,
+ binaryProgram));
+ }
+
+ NVRenderVertFragCompilationResult NVRenderShaderProgram::Create(
+ NVRenderContextImpl &context, const char *programName,
+ NVConstDataRef<QT3DSI8> vertShaderSource, NVConstDataRef<QT3DSI8> fragShaderSource,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource,
+ NVConstDataRef<QT3DSI8> tessEvaluationShaderSource, NVConstDataRef<QT3DSI8> geometryShaderSource,
+ bool separateProgram, NVRenderShaderProgramBinaryType::Enum type, bool binaryProgram)
+ {
+ NVRenderVertFragCompilationResult result;
+ NVRenderShaderProgram *pProgram = NULL;
+ bool bProgramIsValid = false;
+
+ result.mShaderName = programName;
+
+ // our minimum requirement is a vertex and a fragment shader or geometry shader
+ // if we should treat it as a separate program we don't care
+ if (!separateProgram
+ && (vertShaderSource.size() == 0
+ || (fragShaderSource.size() == 0 && geometryShaderSource.size() == 0))) {
+ qCCritical(INVALID_PARAMETER,
+ "Vertex or fragment (geometry) source have 0 length");
+ QT3DS_ASSERT(false);
+ return result;
+ }
+
+ if (binaryProgram && type != NVRenderShaderProgramBinaryType::NVBinary) {
+ qCCritical(INVALID_PARAMETER, "Unrecoginzed binary format");
+ QT3DS_ASSERT(false);
+ return result;
+ }
+
+ // first create and compile shader
+ Option<NVRenderVertexShader *> vtxShader =
+ createVertexShader(context, vertShaderSource, binaryProgram);
+ Option<NVRenderFragmentShader *> fragShader =
+ createFragmentShader(context, fragShaderSource, binaryProgram);
+ Option<NVRenderTessControlShader *> tcShader =
+ createTessControlShader(context, tessControlShaderSource, binaryProgram);
+ Option<NVRenderTessEvaluationShader *> teShader =
+ createTessEvaluationShader(context, tessEvaluationShaderSource, binaryProgram);
+ Option<NVRenderGeometryShader *> geShader =
+ createGeometryShader(context, geometryShaderSource, binaryProgram);
+
+ bool vertexValid = (vtxShader.hasValue()) ? vtxShader.getValue()->IsValid() : true;
+ bool fragValid = (fragShader.hasValue()) ? fragShader.getValue()->IsValid() : true;
+ bool tcValid = (tcShader.hasValue()) ? tcShader.getValue()->IsValid() : true;
+ bool teValid = (teShader.hasValue()) ? teShader.getValue()->IsValid() : true;
+ bool geValid = (geShader.hasValue()) ? geShader.getValue()->IsValid() : true;
+
+ if (vertexValid && fragValid && tcValid && teValid && geValid) {
+ // shaders were succesfuly created
+ pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)(
+ context, context.GetFoundation(), programName, separateProgram);
+
+ if (pProgram) {
+ // attach programs
+ if (vtxShader.hasValue() && vtxShader.getValue()->IsValid())
+ pProgram->Attach(vtxShader.getValue());
+ if (fragShader.hasValue() && fragShader.getValue()->IsValid())
+ pProgram->Attach(fragShader.getValue());
+ if (tcShader.hasValue() && tcShader.getValue()->IsValid())
+ pProgram->Attach(tcShader.getValue());
+ if (teShader.hasValue() && teShader.getValue()->IsValid())
+ pProgram->Attach(teShader.getValue());
+ if (geShader.hasValue() && geShader.getValue()->IsValid())
+ pProgram->Attach(geShader.getValue());
+
+ // link program
+ bProgramIsValid = pProgram->Link();
+ }
+ }
+
+ // if anything went wrong print out
+ if (!vertexValid || !fragValid || !tcValid || !teValid || !geValid || !bProgramIsValid) {
+ NVFoundationBase &foundation(context.GetFoundation());
+
+ if (!vertexValid) {
+ qCCritical(INTERNAL_ERROR, "Failed to generate vertex shader!!");
+ qCCritical(INTERNAL_ERROR, "Vertex source:\n%s",
+ nonNull((const char *)vertShaderSource.begin()));
+ WriteErrorMessage(foundation, "Vertex compilation output:",
+ vtxShader.getValue()->GetErrorMessage());
+ }
+
+ if (!fragValid) {
+ qCCritical(INTERNAL_ERROR, "Failed to generate fragment shader!!");
+ qCCritical(INTERNAL_ERROR, "Fragment source:\n%s",
+ nonNull((const char *)fragShaderSource.begin()));
+ WriteErrorMessage(foundation, "Fragment compilation output:",
+ fragShader.getValue()->GetErrorMessage());
+ }
+
+ if (!tcValid) {
+ qCCritical(INTERNAL_ERROR,
+ "Failed to generate tessellation control shader!!");
+ qCCritical(INTERNAL_ERROR, "Tessellation control source:\n%s",
+ nonNull((const char *)tessControlShaderSource.begin()));
+ WriteErrorMessage(foundation, "Tessellation control compilation output:",
+ tcShader.getValue()->GetErrorMessage());
+ }
+
+ if (!teValid) {
+ qCCritical(INTERNAL_ERROR,
+ "Failed to generate tessellation evaluation shader!!");
+ qCCritical(INTERNAL_ERROR, "Tessellation evaluation source:\n%s",
+ nonNull((const char *)tessEvaluationShaderSource.begin()));
+ WriteErrorMessage(foundation, "Tessellation evaluation compilation output:",
+ teShader.getValue()->GetErrorMessage());
+ }
+
+ if (!geValid) {
+ qCCritical(INTERNAL_ERROR, "Failed to generate geometry shader!!");
+ qCCritical(INTERNAL_ERROR, "Geometry source:\n%s",
+ nonNull((const char *)geometryShaderSource.begin()));
+ WriteErrorMessage(foundation, "Geometry compilation output:",
+ geShader.getValue()->GetErrorMessage());
+ }
+
+ if (!bProgramIsValid && pProgram) {
+ qCCritical(INTERNAL_ERROR, "Failed to link program!!");
+ WriteErrorMessage(foundation, "Program link output:", pProgram->GetErrorMessage());
+
+ // delete program
+ QT3DS_FREE(context.GetFoundation().getAllocator(), pProgram);
+ pProgram = NULL;
+ }
+ }
+
+ // clean up
+ if (vtxShader.hasValue()) {
+ if (bProgramIsValid && vtxShader.getValue()->IsValid())
+ pProgram->Detach(vtxShader.getValue());
+ QT3DS_FREE(context.GetFoundation().getAllocator(), vtxShader.getValue());
+ }
+ if (fragShader.hasValue()) {
+ if (bProgramIsValid && fragShader.getValue()->IsValid())
+ pProgram->Detach(fragShader.getValue());
+ QT3DS_FREE(context.GetFoundation().getAllocator(), fragShader.getValue());
+ }
+ if (tcShader.hasValue()) {
+ if (bProgramIsValid && tcShader.getValue()->IsValid())
+ pProgram->Detach(tcShader.getValue());
+ QT3DS_FREE(context.GetFoundation().getAllocator(), tcShader.getValue());
+ }
+ if (teShader.hasValue()) {
+ if (bProgramIsValid && teShader.getValue()->IsValid())
+ pProgram->Detach(teShader.getValue());
+ QT3DS_FREE(context.GetFoundation().getAllocator(), teShader.getValue());
+ }
+ if (geShader.hasValue()) {
+ if (bProgramIsValid && geShader.getValue()->IsValid())
+ pProgram->Detach(geShader.getValue());
+ QT3DS_FREE(context.GetFoundation().getAllocator(), geShader.getValue());
+ }
+
+ // set program
+ result.mShader = pProgram;
+
+ return result;
+ }
+
+ NVRenderVertFragCompilationResult
+ NVRenderShaderProgram::CreateCompute(NVRenderContextImpl &context, const char *programName,
+ NVConstDataRef<QT3DSI8> computeShaderSource)
+ {
+ NVRenderVertFragCompilationResult result;
+ NVRenderShaderProgram *pProgram = NULL;
+ bool bProgramIsValid = true;
+
+ result.mShaderName = programName;
+
+ // check source
+ if (computeShaderSource.size() == 0) {
+ qCCritical(INVALID_PARAMETER, "compute source has 0 length");
+ QT3DS_ASSERT(false);
+ return result;
+ }
+
+ NVRenderComputeShader computeShader(context, context.GetFoundation(), computeShaderSource,
+ false);
+
+ if (computeShader.IsValid()) {
+ // shaders were succesfuly created
+ pProgram = QT3DS_NEW(context.GetFoundation().getAllocator(), NVRenderShaderProgram)(
+ context, context.GetFoundation(), programName, false);
+
+ if (pProgram) {
+ // attach programs
+ pProgram->Attach(&computeShader);
+
+ // link program
+ bProgramIsValid = pProgram->Link();
+
+ // set program type
+ pProgram->SetProgramType(ProgramType::Compute);
+ }
+ }
+
+ // if anything went wrong print out
+ if (!computeShader.IsValid() || !bProgramIsValid) {
+ NVFoundationBase &foundation(context.GetFoundation());
+
+ if (!computeShader.IsValid()) {
+ qCCritical(INTERNAL_ERROR, "Failed to generate compute shader!!");
+ qCCritical(INTERNAL_ERROR, "Vertex source:\n%s",
+ nonNull((const char *)computeShaderSource.begin()));
+ WriteErrorMessage(foundation, "Compute shader compilation output:",
+ computeShader.GetErrorMessage());
+ }
+ }
+
+ // set program
+ result.mShader = pProgram;
+
+ return result;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h
new file mode 100644
index 00000000..054db64b
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderShaderProgram.h
@@ -0,0 +1,540 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_SHADER_PROGRAM_H
+#define QT3DS_RENDER_SHADER_PROGRAM_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderShaderConstant.h"
+#include "EASTL/string.h"
+#include "EASTL/utility.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ ///< forward declarations
+ class NVRenderContextImpl;
+ class NVRenderVertexShader;
+ class NVRenderFragmentShader;
+ class NVRenderTessControlShader;
+ class NVRenderTessEvaluationShader;
+ class NVRenderGeometryShader;
+ class NVRenderShaderConstantBase;
+ class NVRenderShaderBufferBase;
+ class NVRenderComputeShader;
+
+ typedef nvhash_map<CRegisteredString, NVRenderShaderConstantBase *> TShaderConstantMap;
+ typedef nvhash_map<CRegisteredString, NVRenderShaderBufferBase *> TShaderBufferMap;
+
+ ///< A shader program is an object composed of a multiple shaders (vertex, fragment,
+ ///geometry,....)
+ class QT3DS_AUTOTEST_EXPORT NVRenderShaderProgram : public NVRefCounted
+ {
+ public:
+ struct ProgramType
+ {
+ enum Enum { Graphics, Compute };
+ };
+
+ private:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ const char *m_ProgramName; /// Name of the program
+ NVRenderBackend::NVRenderBackendShaderProgramObject
+ m_ProgramHandle; ///< opaque backend handle
+ TShaderConstantMap m_Constants; ///< map of shader constants
+ TShaderBufferMap m_ShaderBuffers; ///< map of shader buffers
+ ProgramType::Enum m_ProgramType; ///< shader type
+ eastl::string m_ErrorMessage; ///< contains the error message if linking fails
+
+ /**
+ * @brief create vertex shader
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] vertexShaderSource Fragment shader source code
+ * @param[in] binaryProgram True if binary program
+ *
+ * @return pointer to vertex shader object
+ */
+ static Option<NVRenderVertexShader *>
+ createVertexShader(NVRenderContextImpl &context, NVConstDataRef<QT3DSI8> vertexShaderSource,
+ bool binaryProgram = false);
+
+ /**
+ * @brief create fragment shader
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fragmentShaderSource Fragment shader source code
+ * @param[in] binaryProgram True if binary program
+ *
+ * @return pointer to fragment shader object
+ */
+ static Option<NVRenderFragmentShader *>
+ createFragmentShader(NVRenderContextImpl &context,
+ NVConstDataRef<QT3DSI8> fragmentShaderSource, bool binaryProgram = false);
+
+ /**
+ * @brief create tesselation control shader
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] tessControlShaderSource Tessellation control shader source code
+ * @param[in] binaryProgram True if binary program
+ *
+ * @return pointer to tessellation control shader
+ */
+ static Option<NVRenderTessControlShader *>
+ createTessControlShader(NVRenderContextImpl &context,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource,
+ bool binaryProgram = false);
+
+ /**
+ * @brief create tesselation evaluation shader
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] tessEvaluationShaderSource Tessellation evaluation shader source code
+ * @param[in] binaryProgram True if binary program
+ *
+ * @return pointer to tessellation evaluation shader
+ */
+ static Option<NVRenderTessEvaluationShader *>
+ createTessEvaluationShader(NVRenderContextImpl &context,
+ NVConstDataRef<QT3DSI8> tessEvaluationShaderSource,
+ bool binaryProgram = false);
+
+ /**
+ * @brief create geometry shader
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] geometryShaderSource Geometry shader source code
+ * @param[in] binaryProgram True if binary program
+ *
+ * @return pointer to geometry shader
+ */
+ static Option<NVRenderGeometryShader *>
+ createGeometryShader(NVRenderContextImpl &context,
+ NVConstDataRef<QT3DSI8> geometryShaderSource, bool binaryProgram = false);
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] programName Pointer to string of program name
+ * @param[in] separableProgram True if this is a separable program
+ *
+ * @return No return.
+ */
+ NVRenderShaderProgram(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ const char *programName, bool separableProgram);
+
+ /// destructor
+ ~NVRenderShaderProgram();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief attach a shader to the program
+ *
+ * @param[in] pShader Pointer to shader object
+ *
+ * @return No return.
+ */
+ template <typename TShaderObject>
+ void Attach(TShaderObject *pShader);
+
+ /**
+ * @brief detach a shader from the program
+ *
+ * @param[in] pShader Pointer to shader object
+ *
+ * @return No return.
+ */
+ template <typename TShaderObject>
+ void Detach(TShaderObject *pShader);
+
+ /**
+ * @brief link a program
+ *
+ *
+ * @return true if succesfuly linked.
+ */
+ bool Link();
+
+ /**
+ * @brief set a shader type
+ *
+ * @param[in] type shader type ( graphics or compute )
+ *
+ * @return No return.
+ */
+ void SetProgramType(ProgramType::Enum type) { m_ProgramType = type; }
+ ProgramType::Enum GetProgramType() const { return m_ProgramType; }
+
+ /**
+ * @brief Get Error Message
+ *
+ * @param[out] messageLength Pointer to error string
+ * @param[out] messageLength Size of error meesage
+ *
+ * @return no return.
+ */
+ void GetErrorMessage(QT3DSI32 *messageLength, const char *errorMessage);
+
+ /**
+ * @brief Get Error Message
+ *
+ *
+ * @return error message.
+ */
+ const char *GetErrorMessage();
+
+ /**
+ * @brief Query constant class
+ *
+ * @param[in] constantName Pointer to constant name
+ *
+ * @return return a pointer to a constant class.
+ */
+ NVRenderShaderConstantBase *GetShaderConstant(const char *constantName);
+
+ /**
+ * @brief Query a shader buffer (constant, ... )
+ *
+ * @param[in] bufferName Pointer to constant name
+ *
+ * @return return a pointer to a constant class.
+ */
+ NVRenderShaderBufferBase *GetShaderBuffer(const char *bufferName);
+
+ // concrete set functions
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSI32 inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_2 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_3 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSI32_4 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, QT3DSRenderBool inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_2 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_3 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const bool_4 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSF32 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec2 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec3 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSVec4 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_2 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_3 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSU32_4 &inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat33 &inValue,
+ const QT3DSI32 inCount, bool inTranspose = false);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, const QT3DSMat44 &inValue,
+ const QT3DSI32 inCount, bool inTranspose = false);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ const NVConstDataRef<QT3DSMat44> inValue, const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D *inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D **inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant,
+ NVRenderTexture2DArray *inValue, const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube *inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube **inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderImage2D *inValue,
+ const QT3DSI32 inCount);
+ void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderDataBuffer *inValue,
+ const QT3DSI32 inCount);
+
+ /**
+ * @brief Template to set constant value via name
+ *
+ * @param[in] inConstantName Pointer to constant name
+ * @param[in] inValue Pointer to data
+ * @param[in] inCount Number of elements (array count)
+ *
+ * @return return a pointer to a constant class.
+ */
+ template <typename TDataType>
+ void SetPropertyValue(const char *inConstantName, const TDataType &inValue,
+ const QT3DSI32 inCount = 1)
+ {
+ NVRenderShaderConstantBase *theConstant = GetShaderConstant(inConstantName);
+
+ if (theConstant) {
+ if (theConstant->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ SetConstantValue(theConstant, inValue, inCount);
+ } else {
+ // Types don't match or property not found
+ QT3DS_ASSERT(false);
+ }
+ }
+ }
+
+ /**
+ * @brief Template to set constant value shader constant object
+ *
+ * @param[in] inConstant Pointer shader constant object
+ * @param[in] inValue Pointer to data
+ * @param[in] inCount Number of elements (array count)
+ *
+ * @return return a pointer to a constant class.
+ */
+ template <typename TDataType>
+ void SetPropertyValue(NVRenderShaderConstantBase *inConstant, const TDataType &inValue,
+ const QT3DSI32 inCount = 1)
+ {
+ if (inConstant) {
+ if (inConstant->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ SetConstantValue(inConstant, inValue, inCount);
+ } else {
+ // Types don't match or property not found
+ QT3DS_ASSERT(false);
+ }
+ }
+ }
+
+ virtual void BindComputeInput(NVRenderDataBuffer *inBuffer, QT3DSU32 inIndex);
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendShaderProgramObject GetShaderProgramHandle() const
+ {
+ return m_ProgramHandle;
+ }
+
+ /**
+ * @brief get the context object
+ *
+ * @return context which this shader belongs to.
+ */
+ NVRenderContextImpl &GetRenderContext();
+
+ /**
+ * @brief Create a shader program
+ *
+ * @param[in] context Pointer to context
+ * @param[in] programName Name of the program
+ * @param[in] vertShaderSource Vertex shader source code
+ * @param[in] fragShaderSource Fragment shader source code
+ * @param[in] tessControlShaderSource tessellation control shader source code
+ * @param[in] tessEvaluationShaderSource tessellation evaluation shader source code
+ * @param[in] separateProgram True if this will we a separate
+ * program
+ * @param[in] type Binary program type
+ * @param[in] binaryProgram True if program is binary
+ *
+ * @return a render result
+ */
+ static NVRenderVertFragCompilationResult Create(
+ NVRenderContextImpl &context, const char *programName,
+ NVConstDataRef<QT3DSI8> vertShaderSource, NVConstDataRef<QT3DSI8> fragShaderSource,
+ NVConstDataRef<QT3DSI8> tessControlShaderSource = NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> tessEvaluationShaderSource = NVConstDataRef<QT3DSI8>(),
+ NVConstDataRef<QT3DSI8> geometryShaderSource = NVConstDataRef<QT3DSI8>(),
+ bool separateProgram = false,
+ NVRenderShaderProgramBinaryType::Enum type = NVRenderShaderProgramBinaryType::Unknown,
+ bool binaryProgram = false);
+
+ /**
+ * @brief Create a compute shader program
+ *
+ * @param[in] context Pointer to context
+ * @param[in] programName Name of the program
+ * @param[in] computeShaderSource Compute shader source code
+ *
+ * @return a render result
+ */
+ static NVRenderVertFragCompilationResult
+ CreateCompute(NVRenderContextImpl &context, const char *programName,
+ NVConstDataRef<QT3DSI8> computeShaderSource);
+ };
+
+ // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe
+ // way.
+ template <typename TDataType>
+ struct NVRenderCachedShaderProperty
+ {
+ NVRenderShaderProgram *m_Shader; ///< pointer to shader program
+ NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object
+
+ NVRenderCachedShaderProperty(const QString &inConstantName, NVRenderShaderProgram &inShader)
+ : NVRenderCachedShaderProperty(qPrintable(inConstantName), inShader)
+ {
+ }
+
+ NVRenderCachedShaderProperty(const char *inConstantName, NVRenderShaderProgram &inShader)
+ : m_Shader(&inShader)
+ , m_Constant(NULL)
+ {
+ NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName);
+ if (theConstant) {
+ if (theConstant->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType>::GetType()) {
+ m_Constant = theConstant;
+ } else {
+ // Property types do not match, this probably indicates that the shader changed
+ // while the
+ // code creating this object did not change.
+ QT3DS_ASSERT(false);
+ }
+ }
+ }
+
+ NVRenderCachedShaderProperty()
+ : m_Shader(NULL)
+ , m_Constant(NULL)
+ {
+ }
+
+ void Set(const TDataType &inValue)
+ {
+ if (m_Constant)
+ m_Shader->SetPropertyValue(m_Constant, inValue);
+ }
+
+ bool IsValid() const { return m_Constant != 0; }
+ };
+
+ template <typename TDataType, int size>
+ struct NVRenderCachedShaderPropertyArray
+ {
+ NVRenderShaderProgram *m_Shader; ///< pointer to shader program
+ NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object
+ TDataType m_array[size];
+
+ NVRenderCachedShaderPropertyArray(const QString &inConstantName,
+ NVRenderShaderProgram &inShader)
+ : NVRenderCachedShaderPropertyArray(qPrintable(inConstantName), inShader)
+ {
+
+ }
+
+ NVRenderCachedShaderPropertyArray(const char *inConstantName,
+ NVRenderShaderProgram &inShader)
+ : m_Shader(&inShader)
+ , m_Constant(nullptr)
+ {
+ memset(m_array, 0, sizeof(m_array));
+ NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName);
+ if (theConstant) {
+ if (theConstant->m_ElementCount > 1 && theConstant->m_ElementCount <= size &&
+ theConstant->GetShaderConstantType()
+ == NVDataTypeToShaderDataTypeMap<TDataType*>::GetType()) {
+ m_Constant = theConstant;
+ } else {
+ // Property types do not match, this probably indicates that the shader changed
+ // while the code creating this object did not change.
+ QT3DS_ASSERT(false);
+ }
+ }
+ }
+
+ NVRenderCachedShaderPropertyArray()
+ : m_Shader(nullptr)
+ , m_Constant(nullptr)
+ {
+ memset(m_array, 0, sizeof(m_array));
+ }
+
+ void Set(int count)
+ {
+ if (m_Constant)
+ m_Shader->SetPropertyValue(m_Constant, (TDataType*)m_array, qMin(size, count));
+ }
+
+ bool IsValid() const { return m_Constant != 0; }
+ };
+
+ // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe
+ // way.
+ template <typename TDataType>
+ struct NVRenderCachedShaderBuffer
+ {
+ NVRenderShaderProgram *m_Shader; ///< pointer to shader program
+ TDataType m_ShaderBuffer; ///< poiner to shader buffer object
+
+ NVRenderCachedShaderBuffer(const char *inShaderBufferName, NVRenderShaderProgram &inShader)
+ : m_Shader(&inShader)
+ , m_ShaderBuffer(NULL)
+ {
+ TDataType theShaderBuffer =
+ static_cast<TDataType>(inShader.GetShaderBuffer(inShaderBufferName));
+ if (theShaderBuffer) {
+ m_ShaderBuffer = theShaderBuffer;
+ }
+ }
+ NVRenderCachedShaderBuffer()
+ : m_Shader(NULL)
+ , m_ShaderBuffer(NULL)
+ {
+ }
+
+ void Set()
+ {
+ if (m_ShaderBuffer) {
+ m_ShaderBuffer->Validate(m_Shader);
+ m_ShaderBuffer->Update();
+ m_ShaderBuffer->BindToProgram(m_Shader);
+ }
+ }
+
+ bool IsValid() const { return m_ShaderBuffer != 0; }
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp
new file mode 100644
index 00000000..ab632189
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderStorageBuffer.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderStorageBuffer::NVRenderStorageBuffer(NVRenderContextImpl &context,
+ CRegisteredString bufferName, size_t size,
+ NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data, NVRenderDataBuffer *pBuffer)
+ : NVRenderDataBuffer(context, context.GetFoundation(), size,
+ NVRenderBufferBindValues::Storage, usageType, data)
+ , m_Name(bufferName)
+ , m_WrappedBuffer(pBuffer)
+ , m_Dirty(true)
+ {
+ QT3DS_ASSERT(context.IsStorageBufferSupported());
+
+ if (pBuffer)
+ pBuffer->addRef();
+ }
+
+ NVRenderStorageBuffer::~NVRenderStorageBuffer()
+ {
+ if (m_WrappedBuffer)
+ m_WrappedBuffer->release();
+
+ m_Context.BufferDestroyed(*this);
+ }
+
+ void NVRenderStorageBuffer::Bind()
+ {
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ if (m_WrappedBuffer)
+ m_WrappedBuffer->Bind();
+ else
+ m_Backend->BindBuffer(m_BufferHandle, m_BindFlags);
+ }
+
+ void NVRenderStorageBuffer::BindToShaderProgram(QT3DSU32 index)
+ {
+ m_Backend->ProgramSetStorageBuffer(
+ index, (m_WrappedBuffer) ? m_WrappedBuffer->GetBuffertHandle() : m_BufferHandle);
+ }
+
+ void NVRenderStorageBuffer::Update()
+ {
+ // we only update the buffer if it is dirty and we actually have some data
+ if (m_Dirty && m_BufferData.size()) {
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, m_BufferData.size(), m_UsageType,
+ m_BufferData.begin());
+ m_Dirty = false;
+ }
+ }
+
+ void NVRenderStorageBuffer::UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data)
+ {
+ // we only update the buffer if it is not just a wrapper
+ if (!m_WrappedBuffer)
+ m_Backend->UpdateBuffer(m_BufferHandle, m_BindFlags, data.size(), m_UsageType,
+ data.begin() + offset);
+ }
+
+ NVRenderStorageBuffer *
+ NVRenderStorageBuffer::Create(NVRenderContextImpl &context, const char *bufferName,
+ NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData, NVRenderDataBuffer *pBuffer)
+ {
+ NVFoundationBase &fnd(context.GetFoundation());
+ NVRenderStorageBuffer *retval = NULL;
+
+ if (context.IsStorageBufferSupported()) {
+ CRegisteredString theBufferName(context.GetStringTable().RegisterStr(bufferName));
+ QT3DSU32 cbufSize = sizeof(NVRenderStorageBuffer);
+ QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), cbufSize, "StorageBuffer");
+ retval = new (newMem) NVRenderStorageBuffer(
+ context, theBufferName, size, usageType,
+ toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()), pBuffer);
+ } else {
+ QString errorMsg = QObject::tr("Shader storage buffers are not supported: %1")
+ .arg(bufferName);
+ qCCritical(INVALID_OPERATION) << errorMsg;
+ QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8());
+ }
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h
new file mode 100644
index 00000000..fefe6b08
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderStorageBuffer.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_STORAGE_BUFFER_H
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Utils.h"
+#include "foundation/StringTable.h"
+#include "render/Qt3DSRenderDataBuffer.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ // forward declaration
+ class NVRenderContextImpl;
+ class NVRenderVertexBuffer;
+
+ ///< Constant (uniform) buffer representation
+ class NVRenderStorageBuffer : public NVRenderDataBuffer
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] bufferName Name of the buffer. Must match the name used in programs
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ * @param[in] pBuffer Pointer to the buffer
+ *
+ * @return No return.
+ */
+ NVRenderStorageBuffer(NVRenderContextImpl &context, CRegisteredString bufferName,
+ size_t size, NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data, NVRenderDataBuffer *pBuffer = NULL);
+
+ ///< destructor
+ virtual ~NVRenderStorageBuffer();
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief bind the buffer to a shader program
+ *
+ * @param[in] index Index of the constant buffer within the program
+ *
+ * @return no return.
+ */
+ virtual void BindToShaderProgram(QT3DSU32 index);
+
+ /**
+ * @brief update the buffer to hardware
+ *
+ * @return no return.
+ */
+ virtual void Update();
+
+ /**
+ * @brief update a piece of memory directly within the storage buffer
+ *
+ * Note: When you use this function you should know what you are doing.
+ * The memory layout within C++ must exactly match the memory layout in the
+ *shader.
+ * We use std140 (430) layout which guarantees a specific layout behavior across
+ *all HW vendors.
+ * How the memory layout is computed can be found in the GL spec.
+ *
+ * @param[in] offset offset into storage buffer
+ * @param[in] data pointer to data
+ *
+ * @return no return
+ */
+ void UpdateData(QT3DSI32 offset, NVDataRef<QT3DSU8> data);
+
+ /**
+ * @brief get the buffer name
+ *
+ * @return the buffer name
+ */
+ CRegisteredString GetBufferName() const { return m_Name; }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+
+ /**
+ * @brief create a NVRenderStorageBuffer object
+ *
+ * @param[in] context Pointer to context
+ * @param[in] size Size of the buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return the buffer object or NULL
+ */
+ static NVRenderStorageBuffer *Create(NVRenderContextImpl &context, const char *bufferName,
+ NVRenderBufferUsageType::Enum usageType, size_t size,
+ NVConstDataRef<QT3DSU8> bufferData,
+ NVRenderDataBuffer *pBuffer);
+
+ private:
+ CRegisteredString m_Name; ///< buffer name
+ NVRenderDataBuffer *m_WrappedBuffer; ///< pointer to wrapped buffer
+ bool m_Dirty; ///< true if buffer is dirty
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderSync.cpp b/src/Runtime/Source/render/Qt3DSRenderSync.cpp
new file mode 100644
index 00000000..02d153a6
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderSync.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderSync.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSFoundation.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderSync::NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_SyncHandle(NULL)
+ {
+ }
+
+ NVRenderSync::~NVRenderSync()
+ {
+ if (m_SyncHandle)
+ m_Backend->ReleaseSync(m_SyncHandle);
+ }
+
+ void NVRenderSync::Sync()
+ {
+ // On every sync call we need to create a new sync object
+ // A sync object can only be used once
+
+ // First delete the old object
+ // We can safely do this because it is actually not deleted until
+ // it is unused
+ if (m_SyncHandle)
+ m_Backend->ReleaseSync(m_SyncHandle);
+
+ m_SyncHandle =
+ m_Backend->CreateSync(NVRenderSyncType::GpuCommandsComplete, NVRenderSyncFlags());
+ }
+
+ void NVRenderSync::Wait()
+ {
+ // wait until the sync object is signaled or a timeout happens
+ if (m_SyncHandle)
+ m_Backend->WaitSync(m_SyncHandle, NVRenderCommandFlushFlags(), 0);
+ }
+
+ NVRenderSync *NVRenderSync::Create(NVRenderContextImpl &context)
+ {
+ if (!context.IsCommandSyncSupported())
+ return NULL;
+
+ NVRenderSync *retval = QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderSync)(context, context.GetFoundation());
+
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderSync.h b/src/Runtime/Source/render/Qt3DSRenderSync.h
new file mode 100644
index 00000000..9dfeb28a
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderSync.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_SYNC_H
+#define QT3DS_RENDER_SYNC_H
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+ class NVRenderBackend;
+
+ ///< Base class
+ class NVRenderSync : public NVRefCounted
+ {
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBackend::NVRenderBackendSyncObject m_SyncHandle; ///< opaque backend handle
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderSync(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ virtual ~NVRenderSync();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ /**
+ * @brief Get sync type
+ *
+ * @return Return query type
+ */
+ virtual NVRenderSyncType::Enum GetSyncType() const
+ {
+ return NVRenderSyncType::GpuCommandsComplete;
+ }
+
+ /**
+ * @brief Get a pointer to the foundation
+ *
+ * @return pointer to foundation
+ */
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ /**
+ * @brief Create a sync object and place it in command stream.
+ * Note every syncobject can only be used once.
+ * This function creates a new sync object on ever call
+ * and deletes the previous one
+ *
+ * @return no return.
+ */
+ virtual void Sync();
+
+ /**
+ * @brief Wait for a sync to be signaled
+ * Note this blocks until the sync is signaled
+ *
+ * @return no return.
+ */
+ virtual void Wait();
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendSyncObject GetSyncHandle() const
+ {
+ return m_SyncHandle;
+ }
+
+ /*
+ * @brief static creation function
+ *
+ * @return a sync object on success
+ */
+ static NVRenderSync *Create(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp
new file mode 100644
index 00000000..7a0fd897
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderTessellationShader.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTessControlShader::NVRenderTessControlShader(NVRenderContextImpl &context,
+ NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source,
+ bool binaryProgram)
+ : NVRenderShader(context, fnd, source, binaryProgram)
+ , m_ShaderHandle(NULL)
+ {
+ m_ShaderHandle = m_Backend->CreateTessControlShader(source, m_ErrorMessage, binaryProgram);
+ }
+
+ NVRenderTessControlShader::~NVRenderTessControlShader()
+ {
+ if (m_ShaderHandle) {
+ m_Backend->ReleaseTessControlShader(m_ShaderHandle);
+ }
+ }
+
+ NVRenderTessEvaluationShader::NVRenderTessEvaluationShader(NVRenderContextImpl &context,
+ NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source,
+ bool binaryProgram)
+ : NVRenderShader(context, fnd, source, binaryProgram)
+ , m_ShaderHandle(NULL)
+ {
+ m_ShaderHandle =
+ m_Backend->CreateTessEvaluationShader(source, m_ErrorMessage, binaryProgram);
+ }
+
+ NVRenderTessEvaluationShader::~NVRenderTessEvaluationShader()
+ {
+ if (m_ShaderHandle) {
+ m_Backend->ReleaseTessEvaluationShader(m_ShaderHandle);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h
new file mode 100644
index 00000000..b69e56b1
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTessellationShader.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_TESSELLATION_SHADER_H
+#define QT3DS_RENDER_TESSELLATION_SHADER_H
+
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderShader.h"
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ ///< This class represents a tessellation control shader
+ class NVRenderTessControlShader : public NVRenderShader
+ {
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] source Pointer to shader source code
+ * @param[in] binaryProgram true if this is a binary program
+ *
+ * @return No return.
+ */
+ NVRenderTessControlShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram);
+
+ /// @brief destructor
+ ~NVRenderTessControlShader();
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ bool IsValid() override { return (m_ShaderHandle != NULL); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendTessControlShaderObject GetShaderHandle()
+ {
+ return m_ShaderHandle;
+ }
+
+ private:
+ NVRenderBackend::NVRenderBackendTessControlShaderObject
+ m_ShaderHandle; ///< opaque backend handle
+ };
+
+ ///< This class represents a tessellation evaluation shader
+ class NVRenderTessEvaluationShader : public NVRenderShader
+ {
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] source Pointer to shader source code
+ * @param[in] binaryProgram true if this is a binary program
+ *
+ * @return No return.
+ */
+ NVRenderTessEvaluationShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram);
+
+ /// @brief destructor
+ ~NVRenderTessEvaluationShader();
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ bool IsValid() override { return (m_ShaderHandle != NULL); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendTessEvaluationShaderObject GetShaderHandle()
+ {
+ return m_ShaderHandle;
+ }
+
+ private:
+ NVRenderBackend::NVRenderBackendTessEvaluationShaderObject
+ m_ShaderHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp b/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp
new file mode 100644
index 00000000..c5ea4750
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTexture2D.cpp
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderSampler.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTexture2D::NVRenderTexture2D(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget)
+ : NVRenderTextureBase(context, fnd, texTarget)
+ , m_Width(0)
+ , m_Height(0)
+ {
+ }
+
+ NVRenderTexture2D::~NVRenderTexture2D() { m_Context.TextureDestroyed(*this); }
+
+ STextureDetails NVRenderTexture2D::GetTextureDetails() const
+ {
+ return STextureDetails(m_Width, m_Height, 0, m_SampleCount, m_Format);
+ }
+
+ void NVRenderTexture2D::SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width,
+ QT3DSU32 height, NVRenderTextureFormats::Enum format,
+ NVRenderTextureFormats::Enum formatDest)
+ {
+ QT3DS_ASSERT(m_TextureHandle);
+
+ // check if we should compress this texture
+
+ if (inMipLevel == 0) {
+ m_Width = width;
+ m_Height = height;
+ m_Format = format;
+
+ // We re-use textures and this might have been a MSAA texture before
+ // for resue we must completely destroy the texture object and create a new one
+ // The same is true for immutable textures
+ if (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS || m_Immutable) {
+ m_Backend->ReleaseTexture(m_TextureHandle);
+ m_TexTarget = NVRenderTextureTargetType::Texture2D;
+ m_SampleCount = 1;
+ m_TextureHandle = m_Backend->CreateTexture();
+ }
+
+ if (NVRenderTextureFormats::isCompressedTextureFormat(formatDest)) {
+ bool compress = NVRenderTextureFormats::isUncompressedTextureFormat(format);
+ bool appropriateSizes = ((width % 4) || (height % 4)) == false;
+
+ // we only compress multiple of 4 textures
+ if (compress && !appropriateSizes)
+ compress = false;
+
+ if (compress) {
+ // This seems like a very dubious line here. If we are compressing then the
+ // image
+ // is really 1/4 the width and height? - CN
+ m_Width = width / 4;
+ m_Height = height / 4;
+ m_Format = formatDest;
+ }
+ } else if (NVRenderTextureFormats::isUncompressedTextureFormat(formatDest)) {
+ m_Format = formatDest;
+ }
+ }
+
+ if (m_MaxMipLevel < inMipLevel) {
+ m_MaxMipLevel = inMipLevel;
+ }
+
+ // get max size and check value
+ QT3DSU32 maxWidth, maxHeight;
+ m_Context.getMaxTextureSize(maxWidth, maxHeight);
+ if (width > maxWidth || height > maxHeight) {
+ qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)",
+ maxWidth, maxHeight);
+ }
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(format)
+ || NVRenderTextureFormats::isDepthTextureFormat(format)) {
+ m_Backend->SetTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width,
+ height, 0, format, newBuffer.begin());
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) {
+ m_Backend->SetCompressedTextureData2D(m_TextureHandle, m_TexTarget, inMipLevel, format,
+ width, height, 0, newBuffer.size(),
+ newBuffer.begin());
+ }
+ // Set our texture parameters to a default that will look the best
+ if (inMipLevel > 0)
+ SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear);
+ }
+
+ void NVRenderTexture2D::SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height,
+ NVRenderTextureFormats::Enum formaInternal,
+ NVRenderTextureFormats::Enum format,
+ NVDataRef<QT3DSU8> dataBuffer)
+ {
+ QT3DS_ASSERT(m_TextureHandle);
+
+ if (!m_Context.IsShaderImageLoadStoreSupported()) {
+ qCCritical(INVALID_OPERATION, "The extension Shader_Image_Load_Store is not supported");
+ return;
+ }
+
+ m_Width = width;
+ m_Height = height;
+ m_Format = formaInternal;
+ if (format == NVRenderTextureFormats::Unknown)
+ format = formaInternal;
+
+ // get max size and check value
+ QT3DSU32 maxWidth, maxHeight;
+ m_Context.getMaxTextureSize(maxWidth, maxHeight);
+ if (width > maxWidth || height > maxHeight) {
+ qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)",
+ maxWidth, maxHeight);
+ }
+
+ if (inLevels < 1) {
+ qCCritical(INVALID_PARAMETER, "inLevels is less than 1 (%d)", inLevels);
+ }
+
+ m_MaxMipLevel = inLevels - 1; // we count from 0
+
+ // only uncompressed formats are supported and no depth
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(formaInternal)) {
+ m_Backend->CreateTextureStorage2D(m_TextureHandle, m_TexTarget, inLevels, formaInternal,
+ width, height);
+
+ m_Immutable = true;
+ m_TexTarget = NVRenderTextureTargetType::Texture2D;
+
+ if (dataBuffer.size() > 0)
+ m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, 0, 0, 0, width, height,
+ format, dataBuffer.begin());
+
+ if (inLevels > 1)
+ SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear);
+ }
+ }
+
+ void NVRenderTexture2D::SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height,
+ NVRenderTextureFormats::Enum format)
+ {
+ QT3DS_ASSERT(m_TextureHandle);
+ QT3DS_ASSERT(m_MaxMipLevel == 0);
+
+ m_TexTarget = NVRenderTextureTargetType::Texture2D_MS;
+
+ QT3DSU32 maxWidth, maxHeight;
+ m_Context.getMaxTextureSize(maxWidth, maxHeight);
+ if (width > maxWidth || height > maxHeight) {
+ qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)",
+ maxWidth, maxHeight);
+ }
+
+ QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format)
+ || NVRenderTextureFormats::isDepthTextureFormat(format));
+
+ m_Backend->SetMultisampledTextureData2D(m_TextureHandle, m_TexTarget, sampleCount, format,
+ width, height, true);
+
+ m_Width = width;
+ m_Height = height;
+ m_SampleCount = sampleCount;
+ m_Format = format;
+ }
+
+ void NVRenderTexture2D::SetTextureSubData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel,
+ QT3DSU32 inXOffset, QT3DSU32 inYOffset, QT3DSU32 width,
+ QT3DSU32 height, NVRenderTextureFormats::Enum format)
+ {
+ QT3DS_ASSERT(m_TextureHandle);
+
+ if (!NVRenderTextureFormats::isUncompressedTextureFormat(format)) {
+ qCCritical(INVALID_PARAMETER, "Cannot set sub data for depth or compressed formats");
+ QT3DS_ASSERT(false);
+ return;
+ }
+ QT3DSU32 subRectStride = width * NVRenderTextureFormats::getSizeofFormat(format);
+ if (newBuffer.size() < subRectStride * height) {
+ qCCritical(INVALID_PARAMETER, "Invalid sub rect buffer size");
+ QT3DS_ASSERT(false);
+ return;
+ }
+ // nop
+ if (width == 0 || height == 0)
+ return;
+
+ if (inXOffset + width > m_Width || inYOffset + height > m_Height) {
+ qCCritical(INVALID_PARAMETER, "Sub rect outside existing image bounds");
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ // not handled yet
+ QT3DS_ASSERT(!NVRenderTextureFormats::isDepthTextureFormat(format));
+
+ m_Backend->SetTextureSubData2D(m_TextureHandle, m_TexTarget, inMipLevel, inXOffset,
+ inYOffset, width, height, format, newBuffer.begin());
+ }
+
+ void NVRenderTexture2D::GenerateMipmaps(NVRenderHint::Enum genType)
+ {
+ applyTexParams();
+ m_Backend->GenerateMipMaps(m_TextureHandle, m_TexTarget, genType);
+ QT3DSU32 maxDim = (m_Width >= m_Height) ? m_Width : m_Height;
+ m_MaxMipLevel = static_cast<QT3DSU32>(logf((float)maxDim) / logf(2.0f));
+ // we never create more level than m_MaxLevel
+ m_MaxMipLevel = qt3ds::NVMin(m_MaxMipLevel, (QT3DSU32)m_MaxLevel);
+ }
+
+ void NVRenderTexture2D::Bind()
+ {
+ m_TextureUnit = m_Context.GetNextTextureUnit();
+
+ m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit);
+
+ applyTexParams();
+ applyTexSwizzle();
+ }
+
+ NVRenderTexture2D *NVRenderTexture2D::Create(NVRenderContextImpl &context)
+ {
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderTexture2D)(context, context.GetFoundation());
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2D.h b/src/Runtime/Source/render/Qt3DSRenderTexture2D.h
new file mode 100644
index 00000000..29c7c1b4
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTexture2D.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H
+#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include "render/Qt3DSRenderTextureBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+ class NVRenderTextureSampler;
+
+ class NVRenderTexture2D : public NVRenderTextureBase, public NVRenderImplemented
+ {
+
+ private:
+ QT3DSU32 m_Width; ///< texture width
+ QT3DSU32 m_Height; ///< texture height
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] texTarget Texture target
+ *
+ * @return No return.
+ */
+ NVRenderTexture2D(
+ NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D);
+
+ virtual ~NVRenderTexture2D();
+
+ // Get the texture details for mipmap level 0 if it was set.
+ STextureDetails GetTextureDetails() const override;
+
+ /**
+ * @brief Create GL texture object and upload data
+ *
+ * @param[in] newBuffer Texture data for level 0
+ * @param[in] inMipLevel Texture level count
+ * @param[in] width Texture width
+ * @param[in] height Texture height
+ * @param[in] format Texture data format
+ * @param[in] formaInternal Texture internal format
+ *
+ * @return No return.
+ */
+ virtual void SetTextureData(
+ NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height,
+ NVRenderTextureFormats::Enum format,
+ NVRenderTextureFormats::Enum formaInternal = NVRenderTextureFormats::Unknown);
+
+ /**
+ * @brief Create memory storage for a texture object
+ * This create a texture storage which is immutable in size and format
+ * Use this for textures used within compute shaders
+ *
+ * @param[in] inLevels Texture level count
+ * @param[in] width Texture width
+ * @param[in] height Texture height
+ * @param[in] formaInternal Texture internal format
+ * @param[in] format Texture data format of dataBuffer
+ * @param[in] dataBuffer Texture data for level 0
+ *
+ * @return No return.
+ */
+ virtual void
+ SetTextureStorage(QT3DSU32 inLevels, QT3DSU32 width, QT3DSU32 height,
+ NVRenderTextureFormats::Enum formaInternal,
+ NVRenderTextureFormats::Enum format = NVRenderTextureFormats::Unknown,
+ NVDataRef<QT3DSU8> dataBuffer = NVDataRef<QT3DSU8>());
+
+ virtual void SetTextureDataMultisample(QT3DSU32 sampleCount, QT3DSU32 width, QT3DSU32 height,
+ NVRenderTextureFormats::Enum format);
+
+ bool IsMultisampleTexture() const override
+ {
+ return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS);
+ }
+ QT3DSU32 GetSampleCount() const override { return m_SampleCount; }
+ bool IsImmutableTexture() const override { return m_Immutable; }
+
+ // Update a sub-rect of the image. newBuffer is expected to be a continguous subrect of the
+ // image.
+ virtual void SetTextureSubData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 inXOffset,
+ QT3DSU32 inYOffset, QT3DSU32 inSubImageWidth,
+ QT3DSU32 inSubImageHeight, NVRenderTextureFormats::Enum format);
+ // Generate a set of mipmaps from mipLevel( 0 ). Uses the graphis layer to do this if
+ // possible
+ // glGenerateMipmap
+ virtual void GenerateMipmaps(NVRenderHint::Enum genType = NVRenderHint::Nicest);
+
+ /**
+ * @brief Bind a texture for shader access
+ *
+ *
+ * @return No return.
+ */
+ void Bind() override;
+
+ QT3DSU32 GetNumMipmaps() override { return m_MaxMipLevel; }
+
+ /**
+ * @brief Query if texture needs coordinate swizzle
+ *
+ * @return texture swizzle mode
+ */
+ NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode() override
+ {
+ // if our backend supports hardware texture swizzle then there is no need for a shader
+ // swizzle
+ return (m_Backend->GetRenderBackendCap(
+ NVRenderBackend::NVRenderBackendCaps::TexSwizzle))
+ ? NVRenderTextureSwizzleMode::NoSwizzle
+ : m_Backend->GetTextureSwizzleMode(m_Format);
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_TextureHandle);
+ }
+
+ static NVRenderTexture2D *Create(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp
new file mode 100644
index 00000000..fc0dfa45
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderSampler.h"
+#include "render/Qt3DSRenderTexture2DArray.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTexture2DArray::NVRenderTexture2DArray(NVRenderContextImpl &context,
+ NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget)
+ : NVRenderTextureBase(context, fnd, texTarget)
+ , m_Width(0)
+ , m_Height(0)
+ , m_Slices(0)
+ {
+ }
+
+ NVRenderTexture2DArray::~NVRenderTexture2DArray() { m_Context.TextureDestroyed(*this); }
+
+ void NVRenderTexture2DArray::SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel,
+ QT3DSU32 width, QT3DSU32 height, QT3DSU32 slices,
+ NVRenderTextureFormats::Enum format)
+ {
+ QT3DS_ASSERT(m_TextureHandle);
+
+ if (inMipLevel == 0) {
+ m_Width = width;
+ m_Height = height;
+ m_Slices = slices;
+ m_Format = format;
+ m_MaxMipLevel = inMipLevel;
+ }
+
+ if (m_MaxMipLevel < inMipLevel) {
+ m_MaxMipLevel = inMipLevel;
+ }
+
+ // get max size and check value
+ QT3DSI32 theMaxLayerSize, theMaxSize;
+ m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize,
+ &theMaxSize);
+ m_Backend->GetRenderBackendValue(
+ NVRenderBackend::NVRenderBackendQuery::MaxTextureArrayLayers, &theMaxLayerSize);
+ if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize
+ || slices > (QT3DSU32)theMaxLayerSize) {
+ qCCritical(INVALID_OPERATION,
+ "Width or height or Slices is greater than max texture size (%d, %d, %d)",
+ theMaxSize, theMaxSize, theMaxLayerSize);
+ }
+
+ // currently we do not support compressed texture arrays
+ QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(format)
+ || NVRenderTextureFormats::isDepthTextureFormat(format));
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(format)
+ || NVRenderTextureFormats::isDepthTextureFormat(format)) {
+ m_Backend->SetTextureData3D(m_TextureHandle, m_TexTarget, inMipLevel, m_Format, width,
+ height, slices, 0, format, newBuffer.begin());
+ }
+
+ // Set our texture parameters to a default that will look the best
+ if (inMipLevel > 0)
+ SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear);
+ }
+
+ STextureDetails NVRenderTexture2DArray::GetTextureDetails() const
+ {
+ return STextureDetails(m_Width, m_Height, m_Slices, m_SampleCount, m_Format);
+ }
+
+ void NVRenderTexture2DArray::Bind()
+ {
+ m_TextureUnit = m_Context.GetNextTextureUnit();
+
+ m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit);
+
+ applyTexParams();
+ applyTexSwizzle();
+ }
+
+ NVRenderTexture2DArray *NVRenderTexture2DArray::Create(NVRenderContextImpl &context)
+ {
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderTexture2DArray)(context, context.GetFoundation());
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h
new file mode 100644
index 00000000..30ed6dbb
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTexture2DArray.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H
+#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_2D_ARRAY_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include "render/Qt3DSRenderTextureBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+ class NVRenderTextureSampler;
+
+ class QT3DS_AUTOTEST_EXPORT NVRenderTexture2DArray : public NVRenderTextureBase
+ {
+ private:
+ QT3DSU32 m_Width; ///< texture width
+ QT3DSU32 m_Height; ///< texture height
+ QT3DSU32 m_Slices; ///< texture slices
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] texTarget Texture target
+ *
+ * @return No return.
+ */
+ NVRenderTexture2DArray(
+ NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::Texture2D_Array);
+
+ virtual ~NVRenderTexture2DArray();
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] newBuffer Pointer to pixel buffer
+ * @param[in] inMipLevel Pointer to foundation
+ * @param[in] width Texture target
+ * @param[in] height Texture target
+ * @param[in] slices Texture target
+ * @param[in] format Texture target
+ *
+ * @return No return.
+ */
+ void SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel, QT3DSU32 width, QT3DSU32 height,
+ QT3DSU32 slices, NVRenderTextureFormats::Enum format);
+
+ // Get the texture details for mipmap level 0 if it was set.
+ STextureDetails GetTextureDetails() const override;
+
+ /**
+ * @brief Bind a texture for shader access
+ *
+ *
+ * @return No return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief create a texture array object
+ *
+ *
+ * @ return a texture array object
+ */
+ static NVRenderTexture2DArray *Create(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp b/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp
new file mode 100644
index 00000000..d055d72c
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTextureBase.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderSampler.h"
+#include "render/Qt3DSRenderTextureBase.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTextureBase::NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget)
+ : m_Context(context)
+ , m_Foundation(fnd)
+ , mRefCount(0)
+ , m_Backend(context.GetBackend())
+ , m_TextureHandle(NULL)
+ , m_TextureUnit(QT3DS_MAX_U32)
+ , m_SamplerParamsDirty(true)
+ , m_TexStateDirty(false)
+ , m_SampleCount(1)
+ , m_Format(NVRenderTextureFormats::Unknown)
+ , m_TexTarget(texTarget)
+ , m_BaseLevel(0)
+ , m_MaxLevel(1000)
+ , m_MaxMipLevel(0)
+ , m_Immutable(false)
+ {
+ m_TextureHandle = m_Backend->CreateTexture();
+ m_Sampler = QT3DS_NEW(m_Context.GetFoundation().getAllocator(),
+ NVRenderTextureSampler)(context, context.GetFoundation());
+ }
+
+ NVRenderTextureBase::~NVRenderTextureBase()
+ {
+ if (m_Sampler)
+ QT3DS_FREE(m_Context.GetFoundation().getAllocator(), m_Sampler);
+ if (m_TextureHandle)
+ m_Backend->ReleaseTexture(m_TextureHandle);
+ }
+
+ void NVRenderTextureBase::SetBaseLevel(QT3DSI32 value)
+ {
+ if (m_BaseLevel != value) {
+ m_BaseLevel = value;
+ m_TexStateDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetMaxLevel(QT3DSI32 value)
+ {
+ if (m_MaxLevel != value) {
+ m_MaxLevel = value;
+ m_TexStateDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetMinFilter(NVRenderTextureMinifyingOp::Enum value)
+ {
+ if (m_Sampler->m_MinFilter != value) {
+ m_Sampler->m_MinFilter = value;
+ m_SamplerParamsDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetMagFilter(NVRenderTextureMagnifyingOp::Enum value)
+ {
+ if (m_Sampler->m_MagFilter != value) {
+ m_Sampler->m_MagFilter = value;
+ m_SamplerParamsDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetTextureWrapS(NVRenderTextureCoordOp::Enum value)
+ {
+ if (m_Sampler->m_WrapS != value) {
+ m_Sampler->m_WrapS = value;
+ m_SamplerParamsDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetTextureWrapT(NVRenderTextureCoordOp::Enum value)
+ {
+ if (m_Sampler->m_WrapT != value) {
+ m_Sampler->m_WrapT = value;
+ m_SamplerParamsDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetTextureCompareMode(NVRenderTextureCompareMode::Enum value)
+ {
+ if (m_Sampler->m_CompareMode != value) {
+ m_Sampler->m_CompareMode = value;
+ m_SamplerParamsDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value)
+ {
+ if (m_Sampler->m_CompareOp != value) {
+ m_Sampler->m_CompareOp = value;
+ m_SamplerParamsDirty = true;
+ }
+ }
+
+ void NVRenderTextureBase::applyTexParams()
+ {
+ if (m_SamplerParamsDirty) {
+ m_Backend->UpdateSampler(m_Sampler->GetSamplerHandle(), m_TexTarget,
+ m_Sampler->m_MinFilter, m_Sampler->m_MagFilter,
+ m_Sampler->m_WrapS, m_Sampler->m_WrapT, m_Sampler->m_WrapR,
+ m_Sampler->m_MinLod, m_Sampler->m_MaxLod, m_Sampler->m_LodBias,
+ m_Sampler->m_CompareMode, m_Sampler->m_CompareOp);
+
+ m_SamplerParamsDirty = false;
+ }
+
+ if (m_TexStateDirty) {
+ m_Backend->UpdateTextureObject(m_TextureHandle, m_TexTarget, m_BaseLevel, m_MaxLevel);
+ m_TexStateDirty = false;
+ }
+ }
+
+ void NVRenderTextureBase::applyTexSwizzle()
+ {
+ NVRenderTextureSwizzleMode::Enum theSwizzleMode =
+ m_Backend->GetTextureSwizzleMode(m_Format);
+ if (theSwizzleMode != m_Sampler->m_SwizzleMode) {
+ m_Sampler->m_SwizzleMode = theSwizzleMode;
+ m_Backend->UpdateTextureSwizzle(m_TextureHandle, m_TexTarget, theSwizzleMode);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureBase.h b/src/Runtime/Source/render/Qt3DSRenderTextureBase.h
new file mode 100644
index 00000000..872a634e
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTextureBase.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_BUFFER_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+ class NVRenderTextureSampler;
+
+ struct STextureDetails
+ {
+ QT3DSU32 m_Width;
+ QT3DSU32 m_Height;
+ QT3DSU32 m_Depth;
+ QT3DSU32 m_SampleCount;
+ NVRenderTextureFormats::Enum m_Format;
+
+ STextureDetails(QT3DSU32 w, QT3DSU32 h, QT3DSU32 d, QT3DSU32 samples, NVRenderTextureFormats::Enum f)
+ : m_Width(w)
+ , m_Height(h)
+ , m_Depth(d)
+ , m_SampleCount(samples)
+ , m_Format(f)
+ {
+ }
+ STextureDetails()
+ : m_Width(0)
+ , m_Height(0)
+ , m_Depth(0)
+ , m_SampleCount(1)
+ , m_Format(NVRenderTextureFormats::Unknown)
+ {
+ }
+ };
+
+ class NVRenderTextureBase : public NVRefCounted
+ {
+
+ protected:
+ NVRenderContextImpl &m_Context; ///< pointer to context
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ volatile QT3DSI32 mRefCount; ///< Using foundations' naming convention to ease implementation
+ NVRenderBackend *m_Backend; ///< pointer to backend
+ NVRenderBackend::NVRenderBackendTextureObject m_TextureHandle; ///< opaque backend handle
+ QT3DSU32 m_TextureUnit; ///< texture unit this texture should use
+ bool m_SamplerParamsDirty; ///< true if sampler state is dirty
+ bool m_TexStateDirty; ///< true if texture object state is dirty
+ QT3DSU32 m_SampleCount; ///< texture height
+ NVRenderTextureFormats::Enum m_Format; ///< texture format
+ NVRenderTextureTargetType::Enum m_TexTarget; ///< texture target
+ NVRenderTextureSampler *m_Sampler; ///< current texture sampler state
+ QT3DSI32 m_BaseLevel; ///< minimum lod specified
+ QT3DSI32 m_MaxLevel; ///< maximum lod specified
+ QT3DSU32 m_MaxMipLevel; ///< highest mip level
+ bool m_Immutable; ///< true if this is a immutable texture ( size and format )
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] texTarget Texture target
+ *
+ * @return No return.
+ */
+ NVRenderTextureBase(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget);
+
+ virtual ~NVRenderTextureBase();
+
+ // define refcount functions
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE(m_Foundation)
+
+ virtual void SetMinFilter(NVRenderTextureMinifyingOp::Enum value);
+ virtual void SetMagFilter(NVRenderTextureMagnifyingOp::Enum value);
+
+ virtual void SetBaseLevel(QT3DSI32 value);
+ virtual void SetMaxLevel(QT3DSI32 value);
+
+ virtual void SetTextureWrapS(NVRenderTextureCoordOp::Enum value);
+ virtual void SetTextureWrapT(NVRenderTextureCoordOp::Enum value);
+
+ virtual void SetTextureCompareMode(NVRenderTextureCompareMode::Enum value);
+ virtual void SetTextureCompareFunc(NVRenderTextureCompareOp::Enum value);
+
+ virtual void SetTextureUnit(QT3DSU32 unit) { m_TextureUnit = unit; }
+ virtual QT3DSU32 GetTextureUnit() const { return m_TextureUnit; }
+
+ // Get the texture details for mipmap level 0 if it was set.
+ virtual STextureDetails GetTextureDetails() const = 0;
+
+ virtual bool IsMultisampleTexture() const
+ {
+ return (m_TexTarget == NVRenderTextureTargetType::Texture2D_MS);
+ }
+ virtual QT3DSU32 GetSampleCount() const { return m_SampleCount; }
+ virtual bool IsImmutableTexture() const { return m_Immutable; }
+
+ /**
+ * @brief Bind a texture for shader access
+ *
+ *
+ * @return No return.
+ */
+ virtual void Bind() = 0;
+
+ virtual QT3DSU32 GetNumMipmaps() { return m_MaxMipLevel; }
+
+ /**
+ * @brief Query if texture needs coordinate swizzle
+ *
+ * @return texture swizzle mode
+ */
+ virtual NVRenderTextureSwizzleMode::Enum GetTextureSwizzleMode()
+ {
+ // if our backend supports hardware texture swizzle then there is no need for a shader
+ // swizzle
+ return (m_Backend->GetRenderBackendCap(
+ NVRenderBackend::NVRenderBackendCaps::TexSwizzle))
+ ? NVRenderTextureSwizzleMode::NoSwizzle
+ : m_Backend->GetTextureSwizzleMode(m_Format);
+ }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendTextureObject GetTextureObjectHandle()
+ {
+ return m_TextureHandle;
+ }
+
+ protected:
+ void applyTexParams();
+ void applyTexSwizzle();
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp b/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp
new file mode 100644
index 00000000..0919daf3
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTextureCube.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "EASTL/vector.h"
+#include "render/Qt3DSRenderContext.h"
+#include "render/Qt3DSRenderSampler.h"
+#include "render/Qt3DSRenderTextureCube.h"
+#include "foundation/Qt3DSDataRef.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTextureCube::NVRenderTextureCube(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget)
+ : NVRenderTextureBase(context, fnd, texTarget)
+ , m_Width(0)
+ , m_Height(0)
+ {
+ }
+
+ NVRenderTextureCube::~NVRenderTextureCube() { m_Context.TextureDestroyed(*this); }
+
+ void NVRenderTextureCube::SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel,
+ NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width,
+ QT3DSU32 height, NVRenderTextureFormats::Enum format)
+ {
+ QT3DS_ASSERT(m_TextureHandle);
+ QT3DS_ASSERT(inFace != NVRenderTextureCubeFaces::InvalidFace);
+
+ if (inMipLevel == 0) {
+ m_Width = width;
+ m_Height = height;
+ m_Format = format;
+ m_MaxMipLevel = inMipLevel;
+ }
+
+ if (m_MaxMipLevel < inMipLevel) {
+ m_MaxMipLevel = inMipLevel;
+ }
+
+ // get max size and check value
+ QT3DSI32 theMaxSize;
+ m_Backend->GetRenderBackendValue(NVRenderBackend::NVRenderBackendQuery::MaxTextureSize,
+ &theMaxSize);
+ if (width > (QT3DSU32)theMaxSize || height > (QT3DSU32)theMaxSize) {
+ qCCritical(INVALID_OPERATION, "Width or height is greater than max texture size (%d, %d)",
+ theMaxSize, theMaxSize);
+ }
+
+ NVRenderTextureTargetType::Enum outTarget =
+ static_cast<NVRenderTextureTargetType::Enum>((int)m_TexTarget + (int)inFace);
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(format)
+ || NVRenderTextureFormats::isDepthTextureFormat(format)) {
+ m_Backend->SetTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel, format, width,
+ height, 0, format, newBuffer.begin());
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(format)) {
+ m_Backend->SetCompressedTextureDataCubeFace(m_TextureHandle, outTarget, inMipLevel,
+ format, width, height, 0, newBuffer.size(),
+ newBuffer.begin());
+ }
+
+ // Set our texture parameters to a default that will look the best
+ if (inMipLevel > 0)
+ SetMinFilter(NVRenderTextureMinifyingOp::LinearMipmapLinear);
+ }
+
+ STextureDetails NVRenderTextureCube::GetTextureDetails() const
+ {
+ return STextureDetails(m_Width, m_Height, 6, m_SampleCount, m_Format);
+ }
+
+ void NVRenderTextureCube::Bind()
+ {
+ m_TextureUnit = m_Context.GetNextTextureUnit();
+
+ m_Backend->BindTexture(m_TextureHandle, m_TexTarget, m_TextureUnit);
+
+ applyTexParams();
+ applyTexSwizzle();
+ }
+
+ NVRenderTextureCube *NVRenderTextureCube::Create(NVRenderContextImpl &context)
+ {
+ return QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderTextureCube)(context, context.GetFoundation());
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderTextureCube.h b/src/Runtime/Source/render/Qt3DSRenderTextureCube.h
new file mode 100644
index 00000000..7310d44d
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTextureCube.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H
+#define QT3DS_RENDER_QT3DS_RENDER_TEXTURE_CUBE_H
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include "render/Qt3DSRenderTextureBase.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderContextImpl;
+ class NVRenderTextureSampler;
+
+ class NVRenderTextureCube : public NVRenderTextureBase
+ {
+ private:
+ QT3DSU32 m_Width; ///< texture width (per face)
+ QT3DSU32 m_Height; ///< texture height (per face)
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] texTarget Texture target
+ *
+ * @return No return.
+ */
+ NVRenderTextureCube(
+ NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVRenderTextureTargetType::Enum texTarget = NVRenderTextureTargetType::TextureCube);
+
+ virtual ~NVRenderTextureCube();
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] newBuffer Pointer to pixel buffer
+ * @param[in] inMipLevel Pointer to foundation
+ * @param[in] width Texture target
+ * @param[in] height Texture target
+ * @param[in] slices Texture target
+ * @param[in] format Texture target
+ *
+ * @return No return.
+ */
+ void SetTextureData(NVDataRef<QT3DSU8> newBuffer, QT3DSU8 inMipLevel,
+ NVRenderTextureCubeFaces::Enum inFace, QT3DSU32 width, QT3DSU32 height,
+ NVRenderTextureFormats::Enum format);
+
+ // Get the texture details for mipmap level 0 if it was set.
+ STextureDetails GetTextureDetails() const override;
+
+ /**
+ * @brief Bind a texture for shader access
+ *
+ *
+ * @return No return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief create a texture array object
+ *
+ *
+ * @ return a texture array object
+ */
+ static NVRenderTextureCube *Create(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp
new file mode 100644
index 00000000..4184436a
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderTimerQuery.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/StringTable.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderTimerQuery::NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd)
+ : NVRenderQueryBase(context, fnd)
+ {
+ }
+
+ NVRenderTimerQuery::~NVRenderTimerQuery() {}
+
+ void NVRenderTimerQuery::Begin()
+ {
+ m_Backend->BeginQuery(m_QueryHandle, NVRenderQueryType::Timer);
+ }
+
+ void NVRenderTimerQuery::End() { m_Backend->EndQuery(m_QueryHandle, NVRenderQueryType::Timer); }
+
+ void NVRenderTimerQuery::GetResult(QT3DSU32 *params)
+ {
+ m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params);
+ }
+
+ void NVRenderTimerQuery::GetResult(QT3DSU64 *params)
+ {
+ m_Backend->GetQueryResult(m_QueryHandle, NVRenderQueryResultType::Result, params);
+ }
+
+ void NVRenderTimerQuery::SetTimerQuery() { m_Backend->SetQueryTimer(m_QueryHandle); }
+
+ NVRenderTimerQuery *NVRenderTimerQuery::Create(NVRenderContextImpl &context)
+ {
+ if (!context.IsTimerQuerySupported())
+ return NULL;
+
+ NVRenderTimerQuery *retval = QT3DS_NEW(context.GetFoundation().getAllocator(),
+ NVRenderTimerQuery)(context, context.GetFoundation());
+
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h
new file mode 100644
index 00000000..f909f374
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderTimerQuery.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_TIMER_QUERY_H
+#define QT3DS_RENDER_TIMER_QUERY_H
+
+#include "render/Qt3DSRenderQueryBase.h"
+
+namespace qt3ds {
+class NVFoundationBase;
+}
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+
+ class NVRenderTimerQuery : public NVRenderQueryBase
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] fnd Pointer to foundation
+ *
+ * @return No return.
+ */
+ NVRenderTimerQuery(NVRenderContextImpl &context, NVFoundationBase &fnd);
+
+ ///< destructor
+ ~NVRenderTimerQuery();
+
+ /**
+ * @brief Get query type
+ *
+ * @return Return query type
+ */
+ NVRenderQueryType::Enum GetQueryType() const override
+ {
+ return NVRenderQueryType::Timer;
+ }
+
+ /**
+ * @brief Get a pointer to the foundation
+ *
+ * @return pointer to foundation
+ */
+ NVFoundationBase &GetFoundation() { return m_Foundation; }
+
+ /**
+ * @brief begin a query
+ *
+ * @return no return.
+ */
+ void Begin() override;
+
+ /**
+ * @brief end a query
+ *
+ * @return no return.
+ */
+ void End() override;
+
+ /**
+ * @brief Get the result of a query
+ *
+ * @param[out] params Contains result of query regarding query type
+ *
+ * @return no return.
+ */
+ void GetResult(QT3DSU32 *params) override;
+
+ /**
+ * @brief Get the result of a query
+ *
+ * @param[out] params Contains result of query regarding query type
+ *
+ * @return no return.
+ */
+ virtual void GetResult(QT3DSU64 *params);
+
+ /**
+ * @brief Places an absolute timer query into the render queue
+ * The result can be queried with GetResult
+ *
+ * @return no return.
+ */
+ virtual void SetTimerQuery();
+
+ /*
+ * @brief static creation function
+ *
+ * * @return a timer query object on success
+ */
+ static NVRenderTimerQuery *Create(NVRenderContextImpl &context);
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp
new file mode 100644
index 00000000..89d6204e
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/Qt3DSRenderVertexBuffer.h"
+#include "render/Qt3DSRenderContext.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderVertexBuffer::NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size,
+ QT3DSU32 stride, NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usageType,
+ NVDataRef<QT3DSU8> data)
+ : NVRenderDataBuffer(context, context.GetFoundation(), size, bindFlags, usageType, data)
+ , m_Stride(stride)
+ {
+ QT3DS_ASSERT(m_Stride);
+ }
+
+ NVRenderVertexBuffer::~NVRenderVertexBuffer() { m_Context.BufferDestroyed(*this); }
+
+ void NVRenderVertexBuffer::Bind()
+ {
+ if (m_Mapped) {
+ qCCritical(INVALID_OPERATION, "Attempting to Bind a locked buffer");
+ QT3DS_ASSERT(false);
+ }
+
+ m_Backend->BindBuffer(m_BufferHandle, m_BindFlags);
+ }
+
+ NVRenderVertexBuffer *NVRenderVertexBuffer::Create(NVRenderContextImpl &context,
+ NVRenderBufferUsageType::Enum usageType,
+ size_t size, QT3DSU32 stride,
+ NVConstDataRef<QT3DSU8> bufferData)
+ {
+ NVFoundationBase &fnd(context.GetFoundation());
+
+ QT3DSU32 vbufSize = sizeof(NVRenderVertexBuffer);
+ QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(fnd.getAllocator(), vbufSize, "VertexBuffer");
+ NVRenderVertexBuffer *retval = new (newMem) NVRenderVertexBuffer(
+ context, size, stride, NVRenderBufferBindValues::Vertex, usageType,
+ toDataRef(const_cast<QT3DSU8 *>(bufferData.begin()), bufferData.size()));
+ return retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h
new file mode 100644
index 00000000..914afe27
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderVertexBuffer.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H
+#define QT3DS_RENDER_QT3DS_RENDER_VERTEX_BUFFER_H
+#include "foundation/Qt3DSOption.h"
+#include "foundation/Utils.h"
+#include "render/Qt3DSRenderDrawable.h"
+#include "render/Qt3DSRenderDataBuffer.h"
+
+namespace qt3ds {
+namespace render {
+
+ // forward declaration
+ class NVRenderContextImpl;
+
+ ///< Vertex buffer representation
+ class NVRenderVertexBuffer : public NVRenderDataBuffer
+ {
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to context
+ * @param[in] entries Vertex buffer attribute layout entries
+ * @param[in] size Size of the buffer
+ * @param[in] bindFlags Where to binf this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ *application.
+ *
+ * @return No return.
+ */
+ NVRenderVertexBuffer(NVRenderContextImpl &context, size_t size, QT3DSU32 stride,
+ NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usageType, NVDataRef<QT3DSU8> data);
+
+ ///< destructor
+ virtual ~NVRenderVertexBuffer();
+
+ /**
+ * @brief return vertex data stride
+ *
+ * @return data stride.
+ */
+ virtual QT3DSU32 GetStride() const { return m_Stride; }
+
+ /**
+ * @brief get vertex count
+ *
+ * @return vertex count
+ */
+ virtual QT3DSU32 GetNumVertexes() const
+ {
+ QT3DS_ASSERT((m_BufferCapacity % m_Stride) == 0);
+ return m_BufferCapacity / m_Stride;
+ }
+
+ /**
+ * @brief bind the buffer bypasses the context state
+ *
+ * @return no return.
+ */
+ void Bind() override;
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ NVRenderBackend::NVRenderBackendBufferObject GetBuffertHandle() const override
+ {
+ return m_BufferHandle;
+ }
+
+ // this will be obsolete
+ const void *GetImplementationHandle() const override
+ {
+ return reinterpret_cast<void *>(m_BufferHandle);
+ }
+
+ // No stride means that stride is calculated from the size of last entry found via entry
+ // offset
+ // Leaves this buffer temporarily bound.
+ static NVRenderVertexBuffer *Create(NVRenderContextImpl &context,
+ NVRenderBufferUsageType::Enum usageType, size_t size,
+ QT3DSU32 stride, NVConstDataRef<QT3DSU8> bufferData);
+
+ private:
+ QT3DSU32 m_Stride; ///< veretex data stride
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp b/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp
new file mode 100644
index 00000000..3a53ad50
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderVertexShader.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "render/Qt3DSRenderVertexShader.h"
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderVertexShader::NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram)
+ : NVRenderShader(context, fnd, source, binaryProgram)
+ , m_ShaderHandle(NULL)
+ {
+ m_ShaderHandle = m_Backend->CreateVertexShader(source, m_ErrorMessage, binaryProgram);
+ }
+
+ NVRenderVertexShader::~NVRenderVertexShader()
+ {
+ if (m_ShaderHandle) {
+ m_Backend->ReleaseVertexShader(m_ShaderHandle);
+ }
+ }
+}
+}
diff --git a/src/Runtime/Source/render/Qt3DSRenderVertexShader.h b/src/Runtime/Source/render/Qt3DSRenderVertexShader.h
new file mode 100644
index 00000000..0a96045b
--- /dev/null
+++ b/src/Runtime/Source/render/Qt3DSRenderVertexShader.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_VERTEX_SHADER_H
+#define QT3DS_RENDER_VERTEX_SHADER_H
+
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "render/Qt3DSRenderShader.h"
+
+namespace qt3ds {
+namespace render {
+ using namespace foundation;
+
+ class NVRenderContextImpl;
+
+ ///< This class represents a vertex shader
+ class NVRenderVertexShader : public NVRenderShader
+ {
+
+ public:
+ /**
+ * @brief constructor
+ *
+ * @param[in] context Pointer to render context
+ * @param[in] fnd Pointer to foundation
+ * @param[in] source Pointer to shader source code
+ * @param[in] binaryProgram true if this is a binary program
+ *
+ * @return No return.
+ */
+ NVRenderVertexShader(NVRenderContextImpl &context, NVFoundationBase &fnd,
+ NVConstDataRef<QT3DSI8> source, bool binaryProgram);
+
+ /// @brief destructor
+ ~NVRenderVertexShader();
+
+ /**
+ * @brief Query if shader compiled succesfuly
+ *
+ * @return True if shader is valid.
+ */
+ bool IsValid() override { return (m_ShaderHandle != NULL); }
+
+ /**
+ * @brief get the backend object handle
+ *
+ * @return the backend object handle.
+ */
+ virtual NVRenderBackend::NVRenderBackendVertexShaderObject GetShaderHandle()
+ {
+ return m_ShaderHandle;
+ }
+
+ private:
+ NVRenderBackend::NVRenderBackendVertexShaderObject
+ m_ShaderHandle; ///< opaque backend handle
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h b/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h
new file mode 100644
index 00000000..12de5d88
--- /dev/null
+++ b/src/Runtime/Source/render/backends/Qt3DSRenderBackend.h
@@ -0,0 +1,2245 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_H
+#define QT3DS_RENDER_BACKEND_H
+
+/// @file Qt3DSRenderBackend.h
+/// NVRender backend definition.
+
+#include "foundation/Qt3DSAllocator.h"
+#include "foundation/Qt3DSNoCopy.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+#include "foundation/Qt3DSBounds3.h"
+#include <EASTL/string.h>
+
+#include <QtGui/qsurfaceformat.h>
+
+namespace qt3ds {
+namespace render {
+
+#define HandleToID_cast(staticType, dynamicType, handle) \
+ static_cast<staticType>(reinterpret_cast<dynamicType>(handle))
+
+ class NVRenderBackend : public NVRefCounted, public NoCopy
+ {
+
+ public:
+ /// opaque buffer object handle
+ typedef struct _NVRenderBackendBufferObject *NVRenderBackendBufferObject;
+ /// opaque attribute layout object handle
+ typedef struct _NVRenderBackendAttribLayoutObject *NVRenderBackendAttribLayoutObject;
+ /// opaque input assembler object handle
+ typedef struct _NVRenderBackendInputAssemblerObject *NVRenderBackendInputAssemblerObject;
+ /// opaque texture object handle
+ typedef struct _NVRenderBackendTextureObject *NVRenderBackendTextureObject;
+ /// opaque sampler object handle
+ typedef struct _NVRenderBackendSamplerObject *NVRenderBackendSamplerObject;
+ /// opaque renderbuffer object handle
+ typedef struct _NVRenderBackendRenderbufferObject *NVRenderBackendRenderbufferObject;
+ /// opaque framebuffer object handle
+ typedef struct _NVRenderBackendRenderTargetObject *NVRenderBackendRenderTargetObject;
+ /// opaque vertex shader object handle
+ typedef struct _NVRenderBackendVertexShaderObject *NVRenderBackendVertexShaderObject;
+ /// opaque fragment shader object handle
+ typedef struct _NVRenderBackendFragmentShaderObject *NVRenderBackendFragmentShaderObject;
+ /// opaque tesselation control shader object handle
+ typedef struct _NVRenderBackendTessControlShaderObject
+ *NVRenderBackendTessControlShaderObject;
+ /// opaque tesselation evaluation shader object handle
+ typedef struct _NVRenderBackendTessEvaluationShaderObject
+ *NVRenderBackendTessEvaluationShaderObject;
+ /// opaque geometry shader object handle
+ typedef struct _NVRenderBackendGeometryShaderObject *NVRenderBackendGeometryShaderObject;
+ /// opaque compute shader object handle
+ typedef struct _NVRenderBackendComputeShaderObject *NVRenderBackendComputeShaderObject;
+ /// opaque shader program object handle
+ typedef struct _NVRenderBackendShaderProgramObject *NVRenderBackendShaderProgramObject;
+ /// opaque depth stencil state object handle
+ typedef struct _NVRenderBackendDepthStencilStateObject
+ *NVRenderBackendDepthStencilStateObject;
+ /// opaque rasterizer state object handle
+ typedef struct _NVRenderBackendRasterizerStateObject *NVRenderBackendRasterizerStateObject;
+ /// opaque query object handle
+ typedef struct _NVRenderBackendQueryObject *NVRenderBackendQueryObject;
+ /// opaque sync object handle
+ typedef struct _NVRenderBackendSyncObject *NVRenderBackendSyncObject;
+ /// opaque sync object handle
+ typedef struct _NVRenderBackendProgramPipeline *NVRenderBackendProgramPipeline;
+ /// opaque sync object handle
+ typedef struct _NVRenderBackendPathObject *NVRenderBackendPathObject;
+
+ // backend capability caps
+ typedef struct
+ {
+ enum Enum {
+ ConstantBuffer, ///< Constant buffer support query
+ DepthStencilTexture, ///< depth stencil texture format suport query
+ DxtImages, ///< DXT image support query
+ FpRenderTarget, ///< render to floating point target support query
+ MsTexture, ///< Multisample texture support query
+ TexSwizzle, ///< Texture swizzle support query
+ FastBlits, ///< Hardware supports fast blits
+ Tessellation, ///< Hardware supports tessellation
+ Compute, ///< Hardware supports compute shader
+ Geometry, ///< Hardware supports geometry shader
+ SampleQuery, ///< Hardware supports query calls of type samples
+ TimerQuery, ///< Hardware supports query calls of type timer
+ CommandSync, ///< Hardware supports command sync object
+ TextureArray, ///< Hardware supports texture arrays
+ StorageBuffer, ///< Hardware supports shader storage buffers
+ AtomicCounterBuffer, ///< Hardware supports atomic counter buffers
+ ShaderImageLoadStore, ///< Hardware supports shader image load store operations
+ ProgramPipeline, ///< Driver supports separate programs
+ PathRendering, ///< Driver support path rendering
+ AdvancedBlend, ///< Driver supports advanced blend modes
+ BlendCoherency, ///< Hardware supports blend coherency
+ gpuShader5, // for high precision sampling
+ AdvancedBlendKHR, ///< Driver supports advanced blend modes
+ VertexArrayObject,
+ StandardDerivatives,
+ TextureLod
+ };
+ } NVRenderBackendCaps;
+
+ // backend queries
+ typedef struct
+ {
+ enum Enum {
+ MaxTextureSize, ///< Return max supported texture size
+ MaxTextureArrayLayers, ///< Return max supported layer count for texture arrays
+ MaxConstantBufferSlots, ///< Return max supported constant buffe slots for a single
+ ///shader stage
+ MaxConstantBufferBlockSize ///< Return max supported size for a single constant
+ ///buffer block
+ };
+ } NVRenderBackendQuery;
+
+ /// backend interface
+
+ /**
+ * @brief get the backend type
+ *
+ * @return true backend type
+ */
+ virtual NVRenderContextType GetRenderContextType() const = 0;
+
+ /**
+ * @brief get the version of the shading language
+ * @return version string, must be copied by clients to be retained.
+ */
+ virtual const char *GetShadingLanguageVersion() = 0;
+
+ /**
+ * @brief get maximum supported texture image units that
+ * can be used to access texture maps from the vertex shader and the fragment processor
+ *combined.
+ *
+ * @return max texture size
+ */
+ virtual QT3DSU32 GetMaxCombinedTextureUnits() = 0;
+
+ /**
+ * @brief query Backend capabilities
+ *
+ * @param[in] inCap CAPS flag to query
+ * @ConstantBuffer, @DepthStencilTexture, ...
+ *
+ * @return true if supported
+ */
+ virtual bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const = 0;
+
+ /**
+ * @brief query Backend values
+ *
+ * @param[in] inQuery Query flag to get value for
+ * @MaxTextureSize, @MaxTextureArrayLayers,
+ *...
+ * @param[in/out] params the query result is stored here
+ *
+ * @return no return
+ */
+ virtual void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery,
+ QT3DSI32 *params) const = 0;
+
+ /**
+ * @brief query for bit depth of the depth buffer
+ *
+ * @return depth buffer bitplanes
+ */
+ virtual QT3DSU32 GetDepthBits() const = 0;
+
+ /**
+ * @brief query for bit depth of the stencil buffer
+ *
+ * @return stencil buffer bitplanes
+ */
+ virtual QT3DSU32 GetStencilBits() const = 0;
+
+ /*
+ * @brief set a backend rende state
+ *
+ * @param[in] bEnable enable/disable state
+ * @param[in] value type of state
+ *
+ * @return no return
+ */
+ virtual void SetRenderState(bool bEnable, const NVRenderState::Enum value) = 0;
+
+ /**
+ * @brief get a backend rende state
+ *
+ * @param[in] value type of state
+ *
+ * @return true if state enabled otherwise false
+ */
+ virtual bool GetRenderState(const NVRenderState::Enum value) = 0;
+
+ /**
+ * @brief get current depth function
+ *
+ * @return active depth function
+ */
+ virtual NVRenderBoolOp::Enum GetDepthFunc() = 0;
+
+ /**
+ * @brief create a depth stencil state object
+ *
+ * @param[in] enableDepth enable depth test
+ * @param[in] depthMask enable depth writes
+ * @param[in] depthFunc depth compare function
+ * @param[in] enableStencil enable stencil test
+ * @param[in] stencilFuncFront stencil setup front faces
+ * @param[in] stencilFuncBack stencil setup back faces
+ * @param[in] depthStencilOpFront depth/stencil operations front faces
+ * @param[in] depthStencilOpBack depth/stencil operations back faces
+ *
+ * @return opaque handle to state object
+ */
+ virtual NVRenderBackendDepthStencilStateObject
+ CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc,
+ bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack) = 0;
+
+ /**
+ * @brief release a depth stencil state object
+ *
+ * @param[in] depthStencilState pointer to state object
+ *
+ * @return none
+ */
+ virtual void
+ ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0;
+
+ /**
+ * @brief create a rasterizer state object
+ *
+ * @param[in] depthBias any othe value than 0 enables depth bias
+ * @param[in] depthScale any othe value than 0 enables depth scale
+ * @param[in] cullFace select face to cull front or back
+ *
+ * @return opaque handle to state object
+ */
+ virtual NVRenderBackendRasterizerStateObject
+ CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) = 0;
+
+ /**
+ * @brief release a rasterizer state object
+ *
+ * @param[in] rasterizerState pointer to state object
+ *
+ * @return none
+ */
+ virtual void
+ ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0;
+
+ /**
+ * @brief set depth stencil state
+ *
+ * @param[in] depthStencilState pointer to state object
+ *
+ * @return none
+ */
+ virtual void
+ SetDepthStencilState(NVRenderBackendDepthStencilStateObject depthStencilState) = 0;
+
+ /**
+ * @brief set rasterizer state
+ *
+ * @param[in] rasterizerState pointer to state object
+ *
+ * @return none
+ */
+ virtual void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) = 0;
+
+ /**
+ * @brief set current depth function
+ *
+ * @param[in] func type of function
+ *
+ * @return no return
+ */
+ virtual void SetDepthFunc(const NVRenderBoolOp::Enum func) = 0;
+
+ /**
+ * @brief query if depth write is enabled
+ *
+ * @return true if enabled
+ */
+ virtual bool GetDepthWrite() = 0;
+
+ /**
+ * @brief enable / disable depth writes
+ *
+ * @param[in] bEnable true for enable
+ *
+ * @return no return
+ */
+ virtual void SetDepthWrite(bool bEnable) = 0;
+
+ /**
+ * @brief enable / disable color channel writes
+ *
+ * @param[in] bRed true for enable red channel
+ * @param[in] bGreen true for enable green channel
+ * @param[in] bBlue true for enable blue channel
+ * @param[in] bAlpha true for enable alpha channel
+ *
+ * @return no return
+ */
+ virtual void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0;
+
+ /**
+ * @brief enable / disable multisample rendering
+ *
+ * @param[in] bEnable true for enable
+ *
+ * @return no return
+ */
+ virtual void SetMultisample(bool bEnable) = 0;
+
+ /**
+ * @brief query blend functions
+ *
+ * @param[out] pBlendFuncArg blending functions
+ *
+ * @return no return
+ */
+ virtual void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) = 0;
+
+ /**
+ * @brief set blend functions
+ *
+ * @param[in] pBlendFuncArg blending functions
+ *
+ * @return no return
+ */
+ virtual void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) = 0;
+
+ /**
+ * @brief set blend equation
+ *
+ * @param[in] pBlendEquArg blending equation
+ *
+ * @return no return
+ */
+ virtual void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) = 0;
+
+ /**
+ * @brief guarantee blend coherency
+ *
+ *
+ * @return no return
+ */
+ virtual void SetBlendBarrier(void) = 0;
+
+ /**
+ * @brief query scissor rectangle
+ *
+ * @param[out] pRect contains scissor rect
+ *
+ * @return no return
+ */
+ virtual void GetScissorRect(NVRenderRect *pRect) = 0;
+
+ /**
+ * @brief set scissor rectangle
+ *
+ * @param[out] pRect contains scissor rect
+ *
+ * @return no return
+ */
+ virtual void SetScissorRect(const NVRenderRect &rect) = 0;
+
+ /**
+ * @brief query viewport rectangle
+ *
+ * @param[out] pRect contains viewport rect
+ *
+ * @return no return
+ */
+ virtual void GetViewportRect(NVRenderRect *pRect) = 0;
+
+ /**
+ * @brief set viewport rectangle
+ *
+ * @param[out] pRect contains viewport rect
+ *
+ * @return no return
+ */
+ virtual void SetViewportRect(const NVRenderRect &rect) = 0;
+
+ /**
+ * @brief query viewport rectangle
+ *
+ * @param[in] clearColor clear color
+ *
+ * @return no return
+ */
+ virtual void SetClearColor(const QT3DSVec4 *pClearColor) = 0;
+
+ /**
+ * @brief query viewport rectangle
+ *
+ * @param[in] flags clear flags
+ *
+ * @return no return
+ */
+ virtual void Clear(NVRenderClearFlags flags) = 0;
+
+ /**
+ * @brief create a buffer object
+ *
+ * @param[in] size Size of the buffer
+ * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ *application.
+ *
+ * @return The created buffer object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendBufferObject CreateBuffer(size_t size,
+ NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usage,
+ const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief bind a buffer object
+ *
+ * @param[in] bo Pointer to buffer object
+ * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ *
+ * @return no return.
+ */
+ virtual void BindBuffer(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags) = 0;
+
+ /**
+ * @brief Release a single buffer object
+ *
+ * @param[in] bo Pointer to buffer object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseBuffer(NVRenderBackendBufferObject bo) = 0;
+
+ /**
+ * @brief update a whole buffer object
+ *
+ * @param[in] bo Pointer to buffer object
+ * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ * @param[in] size Size of the data buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ *application.
+ *
+ * @return no return.
+ */
+ virtual void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t size, NVRenderBufferUsageType::Enum usage,
+ const void *data) = 0;
+
+ /**
+ * @brief update a range of a buffer object
+ *
+ * @param[in] bo Pointer to buffer object
+ * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ * @param[in] size Size of the data buffer
+ * @param[in] usage Usage of the buffer (e.g. static, dynamic...)
+ * @param[in] data A pointer to the buffer data that is allocated by the
+ *application.
+ *
+ * @return no return.
+ */
+ virtual void UpdateBufferRange(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags, size_t offset,
+ size_t size, const void *data) = 0;
+
+ /**
+ * @brief Get a pointer to the buffer data ( GL(ES) >= 3 only )
+ *
+ * @param[in] bo Pointer to buffer object
+ * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ * @param[in] offset Byte offset into the data buffer
+ * @param[in] length Byte length of mapping size
+ * @param[in] access Access of the buffer (e.g. read, write, ...)
+ *
+ * @return pointer to mapped data or null.
+ */
+ virtual void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t offset, size_t length,
+ NVRenderBufferAccessFlags accessFlags) = 0;
+
+ /**
+ * @brief Unmap a previously mapped buffer ( GL(ES) >= 3 only )
+ * This functions transfers the content to the hardware buffer
+ *
+ * @param[in] bo Pointer to buffer object
+ * @param[in] bindFlags Where to bind this buffer (e.g. vertex, index, ...)
+ * For OpenGL this should be a single
+ *value
+ *
+ * @return true if successful
+ */
+ virtual bool UnmapBuffer(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags) = 0;
+
+ /**
+ * @brief Set a memory barrier
+ *
+ * @param[in] barriers Flags for barriers
+ *
+ * @return no return.
+ */
+ virtual void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) = 0;
+
+ /**
+ * @brief create a query object
+ *
+ * @return The created query object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendQueryObject CreateQuery() = 0;
+
+ /**
+ * @brief delete query objects
+ *
+ * @param[in] qo Handle to query object
+ *
+ * @return no return
+ */
+ virtual void ReleaseQuery(NVRenderBackendQueryObject qo) = 0;
+
+ /**
+ * @brief Start query recording
+ *
+ * @param[in] qo Handle to query object
+ * @param[in] type Type of query
+ *
+ * @return no return
+ */
+ virtual void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0;
+
+ /**
+ * @brief End query recording
+ *
+ * @param[in] qo Handle to query object
+ * @param[in] type Type of query
+ *
+ * @return no return
+ */
+ virtual void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) = 0;
+
+ /**
+ * @brief Get a query result
+ *
+ * @param[in] qo Handle to query object
+ * @param[in] type Type of query
+ * @param[out] params Contains result of query regarding query type
+ *
+ * @return no return
+ */
+ virtual void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) = 0;
+
+ /**
+ * @brief Get a query result
+ *
+ * @param[in] qo Handle to query object
+ * @param[in] type Type of query
+ * @param[out] params Contains result of query regarding query type 64 bit returns
+ *
+ * @return no return
+ */
+ virtual void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) = 0;
+
+ /**
+ * @brief Record the GPU time using the query object
+ *
+ * @param[in] qo Handle to query object
+ *
+ * @return no return
+ */
+ virtual void SetQueryTimer(NVRenderBackendQueryObject qo) = 0;
+
+ /**
+ * @brief create a sync object and place it in the command queue
+ *
+ * @param[in] tpye Type to sync
+ * @param[in] syncFlags Currently unused
+ *
+ * @return The created sync object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye,
+ NVRenderSyncFlags syncFlags) = 0;
+
+ /**
+ * @brief delete sync object
+ *
+ * @param[in] so Handle to sync object
+ *
+ * @return no return
+ */
+ virtual void ReleaseSync(NVRenderBackendSyncObject so) = 0;
+
+ /**
+ * @brief wait for sync object to be signaled
+ *
+ * @param[in] so Handle to sync object
+ * @param[in] syncFlags Currently unused
+ * @param[in] timeout Currently ignored
+ *
+ * @return no return
+ */
+ virtual void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags,
+ QT3DSU64 timeout) = 0;
+
+ /**
+ * @brief create a render target object
+ *
+ *
+ * @return The created render target object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendRenderTargetObject CreateRenderTarget() = 0;
+
+ /**
+ * @brief Release a single render target object
+ *
+ * @param[in] rto Pointer to render target object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) = 0;
+
+ /**
+ * @brief Attach a renderbuffer object to the framebuffer
+ *
+ * @param[in] rto Pointer to render target object
+ * @param[in] attachment Attachment point (e.g COLOR0, DEPTH)
+ * @param[in] rbo Pointer to renderbuffer object
+ *
+ * @return no return.
+ */
+ virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo) = 0;
+
+ /**
+ * @brief Attach a texture object to the render target
+ *
+ * @param[in] rto Pointer to render target object
+ * @param[in] attachment Attachment point (e.g COLOR0, DEPTH)
+ * @param[in] to Pointer to texture object
+ * @param[in] target Attachment texture target
+ *
+ * @return no return.
+ */
+ virtual void RenderTargetAttach(
+ NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) = 0;
+
+ /**
+ * @brief Attach a texture object to the render target
+ *
+ * @param[in] rto Pointer to render target object
+ * @param[in] attachment Attachment point (e.g COLOR0, DEPTH)
+ * @param[in] to Pointer to texture object
+ * @param[in] level Texture mip level
+ * @param[in] layer Texture layer or slice
+ *
+ * @return no return.
+ */
+ virtual void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level,
+ QT3DSI32 layer) = 0;
+
+ /**
+ * @brief Make a render target active
+ *
+ * @param[in] rto Pointer to render target object
+ *
+ * @return no return.
+ */
+ virtual void SetRenderTarget(NVRenderBackendRenderTargetObject rto) = 0;
+
+ /**
+ * @brief Check if a render target is ready for render
+ *
+ * @param[in] rto Pointer to render target object
+ *
+ * @return true if usable.
+ */
+ virtual bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) = 0;
+
+ /**
+ * @brief Make a render target active for reading
+ *
+ * @param[in] rto Pointer to render target object
+ *
+ * @return no return.
+ */
+ virtual void SetReadTarget(NVRenderBackendRenderTargetObject rto) = 0;
+
+ /**
+ * @brief Set active buffers for drawing
+ *
+ * @param[in] rto Pointer to render target object
+ * @param[in] inDrawBufferSet Pointer to array of enabled render targets
+ *
+ * @return no return.
+ */
+ virtual void SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet) = 0;
+
+ /**
+ * @brief Set active buffer for reading
+ *
+ * @param[in] rto Pointer to render target object
+ * @param[in] inReadFace Buffer to read from
+ *
+ * @return no return.
+ */
+ virtual void SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace) = 0;
+
+ /**
+ * @brief Copy framebuffer attachments. Source is set with SetReadTarget dest with
+ * SetRenderTarget
+ *
+ * @param[in] srcX0 Lower left X coord of source rectangle
+ * @param[in] srcY0 Lower left Y coord of source rectangle
+ * @param[in] srcX1 Upper right X coord of source rectangle
+ * @param[in] srcY1 Upper right Y coord of source rectangle
+ * @param[in] dstX0 Lower left X coord of dest rectangle
+ * @param[in] dstY0 Lower left Y coord of dest rectangle
+ * @param[in] dstX1 Upper right X coord of dest rectangle
+ * @param[in] dstY1 Upper right Y coord of dest rectangle
+ * @param[in] inDrawBufferSet pointer to array of enabled render targets
+ * @param[in] filter Copy filter method (NEAREST or LINEAR)
+ *
+ * @return no return.
+ */
+ virtual void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter) = 0;
+
+ /**
+ * @brief create a render buffer object
+ *
+ * @param[in] storageFormat Format of the buffer
+ * @param[in] width Buffer with
+ * @param[in] height Buffer height
+ *
+ * @return The created render buffer object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendRenderbufferObject
+ CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width,
+ size_t height) = 0;
+
+ /**
+ * @brief Release a single renderbuffer object
+ *
+ * @param[in] bo Pointer to renderbuffer object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) = 0;
+
+ /**
+ * @brief resize a render buffer object
+ *
+ * @param[in] storageFormat Format of the buffer
+ * @param[in] width Buffer with
+ * @param[in] height Buffer height
+ *
+ * @return True on success
+ */
+ virtual bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height) = 0;
+
+ /**
+ * @brief create a texture object
+ *
+ * @return The created texture object or NULL if the creation failed..
+ */
+ virtual NVRenderBackendTextureObject CreateTexture() = 0;
+
+ /**
+ * @brief set texture data for a 2D texture
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] level Texture mip level
+ * @param[in] internalFormat format of the texture
+ * @param[in] width texture width
+ * @param[in] height texture height
+ * @param[in] border border
+ * @param[in] format format of provided pixel data
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief set texture data for the face of a Cube map
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target face
+ * @param[in] level Texture mip level
+ * @param[in] internalFormat format of the texture
+ * @param[in] width texture width
+ * @param[in] height texture height
+ * @param[in] border border
+ * @param[in] format format of provided pixel data
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetTextureDataCubeFace(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief create a storage for a 2D texture including mip levels
+ * Note that this makes texture immutable in size and format
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] levels Texture mip level count
+ * @param[in] internalFormat format of the texture
+ * @param[in] width texture width
+ * @param[in] height texture height
+ *
+ * @return No return
+ */
+ virtual void CreateTextureStorage2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 levels,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height) = 0;
+
+ /**
+ * @brief set texture sub data for a 2D texture
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] level Texture mip level
+ * @param[in] xOffset Texture x offset
+ * @param[in] yOffset Texture y offset
+ * @param[in] width Texture width
+ * @param[in] height Texture height
+ * @param[in] border border
+ * @param[in] format format of texture
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetTextureSubData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief set compressed texture data for a 2D texture
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] level Texture mip level
+ * @param[in] internalFormat format of the texture
+ * @param[in] width texture width
+ * @param[in] height texture height
+ * @param[in] border border
+ * @param[in] imageSize image size in bytes located at hostPtr
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetCompressedTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height, QT3DSI32 border,
+ size_t imageSize, const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief set compressed texture data for a Cubemap face
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] level Texture mip level
+ * @param[in] internalFormat format of the texture
+ * @param[in] width texture width
+ * @param[in] height texture height
+ * @param[in] border border
+ * @param[in] imageSize image size in bytes located at hostPtr
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetCompressedTextureDataCubeFace(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border,
+ size_t imageSize, const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief set compressed texture sub data for a 2D texture
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] level Texture mip level
+ * @param[in] xOffset Texture x offset
+ * @param[in] yOffset Texture y offset
+ * @param[in] width texture width
+ * @param[in] height texture height
+ * @param[in] format format of provided pixel data
+ * @param[in] imageSize image size in bytes located at hostPtr
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetCompressedTextureSubData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height,
+ NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief establish a multisampled 2D texture
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D MS
+ * @param[in] samples Textures sample count
+ * @param[in] internalFormat Format of the texture
+ * @param[in] width Texture width
+ * @param[in] height Texture height
+ * @param[in] bool Fixed sample locations
+ *
+ * @return No return
+ */
+ virtual void SetMultisampledTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ size_t samples,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height,
+ bool fixedsamplelocations) = 0;
+
+ /**
+ * @brief set texture data for a 3D texture or 2D texture array
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] level Texture mip level
+ * @param[in] internalFormat format of the texture
+ * @param[in] width texture width
+ * @param[in] height texture height
+ * @param[in] depth texture depth or slice count
+ * @param[in] border border
+ * @param[in] format format of provided pixel data
+ * @param[in] hostPtr A pointer to the buffer data that is allocated by the
+ * application.
+ *
+ * @return No return
+ */
+ virtual void SetTextureData3D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, size_t depth, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) = 0;
+
+ /**
+ * @brief generate mipmap levels
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Texture target 2D,...
+ * @param[in] hint How to generate mips (Nicest)
+ *
+ * @return No return
+ */
+ virtual void GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum genType) = 0;
+
+ /**
+ * @brief bind a texture object
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] target Where to bind this texture (e.g. 2D, 3D, ...)
+ * @param[in] unit Which unit to bind this texture
+ *
+ * @return no return.
+ */
+ virtual void BindTexture(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 unit) = 0;
+
+ /**
+ * @brief bind a image/texture object
+ *
+ * @param[in] to Pointer to texture object
+ * @param[in] unit Which unit to bind this texture
+ * @param[in] level Which level to bind
+ * @param[in] layered Bind layered texture (cube map, array,... )
+ * @param[in] level Specify layer. Only valid of layered=false.
+ * @param[in] access Access mode ( read, write, read-write )
+ * @param[in] format Texture format must be compatible with Image format
+ *
+ * @return no return.
+ */
+ virtual void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level,
+ bool layered, QT3DSI32 layer,
+ NVRenderImageAccessType::Enum accessFlags,
+ NVRenderTextureFormats::Enum format) = 0;
+
+ /**
+ * @brief Release a single texture object
+ *
+ * @param[in] to Pointer to buffer object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseTexture(NVRenderBackendTextureObject to) = 0;
+
+ /**
+ * @brief query texture swizzle mode
+ * This is mainly for luminance, alpha replacement with R8 formats
+ *
+ * @param[in] inFormat input texture format to check
+ *
+ * @return texture swizzle mode
+ */
+ virtual NVRenderTextureSwizzleMode::Enum
+ GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const = 0;
+
+ /**
+ * @ brief create a sampler
+ *
+ * @param[in] minFilter Texture min filter
+ * @param[in] magFilter Texture mag filter
+ * @param[in] wrapS Texture coord generation for S
+ * @param[in] wrapT Texture coord generation for T
+ * @param[in] wrapR Texture coord generation for R
+ * @param[in] minLod Texture min level of detail
+ * @param[in] maxLod Texture max level of detail
+ * @param[in] lodBias Texture level of detail example
+ * @param[in] compareMode Texture compare mode
+ * @param[in] compareFunc Texture compare function
+ * @param[in] anisoFilter Aniso filter value [1.0, 16.0]
+ * @param[in] borderColor Texture border color float[4]
+ *
+ * @return The created sampler object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendSamplerObject CreateSampler(
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0;
+
+ /**
+ * @ brief update a sampler
+ *
+ * @param[in] so Pointer to sampler object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] minFilter Texture min filter
+ * @param[in] magFilter Texture mag filter
+ * @param[in] wrapS Texture coord generation for S
+ * @param[in] wrapT Texture coord generation for T
+ * @param[in] wrapR Texture coord generation for R
+ * @param[in] minLod Texture min level of detail
+ * @param[in] maxLod Texture max level of detail
+ * @param[in] lodBias Texture level of detail bias (unused)
+ * @param[in] compareMode Texture compare mode
+ * @param[in] compareFunc Texture compare function
+ * @param[in] anisoFilter Aniso filter value [1.0, 16.0]
+ * @param[in] borderColor Texture border color float[4] (unused)
+ *
+ * @return No return
+ */
+ virtual void UpdateSampler(
+ NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) = 0;
+
+ /**
+ * @ brief Update a textures swizzle mode
+ *
+ * @param[in] so Pointer to texture object
+ * @param[in] target Texture target 2D, 3D
+ * @param[in] swizzleMode Texture swizzle mode
+ *
+ * @return No return
+ */
+ virtual void UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode) = 0;
+
+ /**
+ * @ brief Update state belonging to a texture object
+ *
+ * @param[in] so Pointer to texture object
+ * @param[in] target Texture target 2D, 3D, Cube
+ * @param[in] baseLevel Texture base level
+ * @param[in] maxLevel Texture max level
+ *
+ * @return No return
+ */
+ virtual void UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel,
+ QT3DSI32 maxLevel) = 0;
+
+ /**
+ * @brief Release a single sampler object
+ *
+ * @param[in] so Pointer to sampler object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseSampler(NVRenderBackendSamplerObject so) = 0;
+
+ /**
+ * @brief create a attribute layout object
+ *
+ * @param[in] attribs Array off vertex attributes.
+ *
+ * @return The created attribute layout object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendAttribLayoutObject
+ CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) = 0;
+
+ /**
+ * @brief Release a attribute layoutr object
+ *
+ * @param[in] ao Pointer to attribute layout object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) = 0;
+
+ /**
+ * @brief create a input assembler object
+ *
+ * @param[in] attribLayout Pointer to NVRenderBackendAttribLayoutObject object
+ * @param[in] buffers list of vertex buffers
+ * @param[in] indexBuffer index buffer object
+ * @param[in] strides list of strides of the buffer
+ * @param[in] offsets list of offsets into the buffer
+ * @param[in] patchVertexCount vertext count for a patch. Only valid for patch primitives
+ *
+ * @return The created input assembler object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendInputAssemblerObject
+ CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout,
+ NVConstDataRef<NVRenderBackendBufferObject> buffers,
+ const NVRenderBackendBufferObject indexBuffer,
+ NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets,
+ QT3DSU32 patchVertexCount) = 0;
+
+ /**
+ * @brief Release a input assembler object
+ *
+ * @param[in] iao Pointer to attribute layout object
+ *
+ * @return no return.
+ */
+ virtual void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) = 0;
+
+ /**
+ * @brief Set a input assembler object.
+ * This setup the render engine vertex assmebly
+ *
+ * @param[in] iao Pointer to attribute layout object
+ * @param[in] po Pointer program object
+ *
+ * @return false if it fails.
+ */
+ virtual bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief Set the per patch vertex count
+ *
+ * @param[in] iao Pointer to attribute layout object
+ * @param[in] count Count of vertices per patch
+ *
+ * @return false if it fails.
+ */
+ virtual void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) = 0;
+
+ /**
+ * @brief create a vertex shader object
+ *
+ * @param[in] source Pointer to shader source
+ * @param[in/out] errorMessage Pointer to copy the error message
+ * @param[in] binary True if the source is actually a binary program
+ *
+ * @return The created vertex shader object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage,
+ bool binary) = 0;
+
+ /**
+ * @brief release a vertex shader object
+ *
+ * @param[in] vso Pointer to vertex shader object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) = 0;
+
+ /**
+ * @brief create a fragment shader object
+ *
+ * @param[in] source Pointer to shader source
+ * @param[in/out] errorMessage Pointer to copy the error message
+ * @param[in] binary True if the source is actually a binary program
+ *
+ * @return The created vertex shader object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendFragmentShaderObject
+ CreateFragmentShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) = 0;
+
+ /**
+ * @brief release a fragment shader object
+ *
+ * @param[in] vso Pointer to fragment shader object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) = 0;
+
+ /**
+ * @brief create a tessellation control shader object
+ *
+ * @param[in] source Pointer to shader source
+ * @param[in/out] errorMessage Pointer to copy the error message
+ * @param[in] binary True if the source is actually a binary program
+ *
+ * @return The created tessellation control shader object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendTessControlShaderObject
+ CreateTessControlShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) = 0;
+
+ /**
+ * @brief release a tessellation control shader object
+ *
+ * @param[in] tcso Pointer to tessellation control shader object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) = 0;
+
+ /**
+ * @brief create a tessellation evaluation shader object
+ *
+ * @param[in] source Pointer to shader source
+ * @param[in/out] errorMessage Pointer to copy the error message
+ * @param[in] binary True if the source is actually a binary program
+ *
+ * @return The created tessellation evaluation shader object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendTessEvaluationShaderObject
+ CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) = 0;
+
+ /**
+ * @brief release a tessellation evaluation shader object
+ *
+ * @param[in] tcso Pointer to tessellation evaluation shader object
+ *
+ * @return No Return.
+ */
+ virtual void
+ ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) = 0;
+
+ /**
+ * @brief create a geometry shader object
+ *
+ * @param[in] source Pointer to shader source
+ * @param[in/out] errorMessage Pointer to copy the error message
+ * @param[in] binary True if the source is actually a binary program
+ *
+ * @return The created geometry shader object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendGeometryShaderObject
+ CreateGeometryShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) = 0;
+
+ /**
+ * @brief release a geometry shader object
+ *
+ * @param[in] tcso Pointer to geometry shader object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) = 0;
+
+ /**
+ * @brief create a compute shader object
+ *
+ * @param[in] source Pointer to shader source
+ * @param[in/out] errorMessage Pointer to copy the error message
+ * @param[in] binary True if the source is actually a binary program
+ *
+ * @return The created compute shader object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage,
+ bool binary) = 0;
+
+ /**
+ * @brief release a compute shader object
+ *
+ * @param[in] cso Pointer to compute shader object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) = 0;
+
+ /**
+ * @brief attach a vertex shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] vso Pointer to vertex shader object
+ *
+ * @return No Return.
+ */
+ virtual void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendVertexShaderObject vso) = 0;
+
+ /**
+ * @brief detach a vertex shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] vso Pointer to vertex shader object
+ *
+ * @return No Return.
+ */
+ virtual void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendVertexShaderObject vso) = 0;
+
+ /**
+ * @brief attach a fragment shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] fso Pointer to fragment shader object
+ *
+ * @return No Return.
+ */
+ virtual void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendFragmentShaderObject fso) = 0;
+
+ /**
+ * @brief detach a fragment shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] fso Pointer to fragment shader object
+ *
+ * @return No Return.
+ */
+ virtual void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendFragmentShaderObject fso) = 0;
+
+ /**
+ * @brief attach a tessellation control shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] tcso Pointer to tessellation control shader object
+ *
+ * @return No Return.
+ */
+ virtual void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessControlShaderObject tcso) = 0;
+
+ /**
+ * @brief detach a tessellation control shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] tcso Pointer to tessellation control shader object
+ *
+ * @return No Return.
+ */
+ virtual void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessControlShaderObject tcso) = 0;
+
+ /**
+ * @brief attach a tessellation evaluation shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] teso Pointer to tessellation evaluation shader object
+ *
+ * @return No Return.
+ */
+ virtual void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessEvaluationShaderObject teso) = 0;
+
+ /**
+ * @brief detach a tessellation evaluation shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] teso Pointer to tessellation evaluation shader object
+ *
+ * @return No Return.
+ */
+ virtual void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessEvaluationShaderObject teso) = 0;
+
+ /**
+ * @brief attach a geometry shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] teso Pointer to geometry shader object
+ *
+ * @return No Return.
+ */
+ virtual void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendGeometryShaderObject gso) = 0;
+
+ /**
+ * @brief detach a geometry shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] teso Pointer to geometry shader object
+ *
+ * @return No Return.
+ */
+ virtual void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendGeometryShaderObject gso) = 0;
+
+ /**
+ * @brief attach a compute shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] cso Pointer to compute shader object
+ *
+ * @return No Return.
+ */
+ virtual void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendComputeShaderObject cso) = 0;
+
+ /**
+ * @brief detach a compute shader object to a program object
+ *
+ * @param[in] po Pointer to program object
+ * @param[in] cso Pointer to compute shader object
+ *
+ * @return No Return.
+ */
+ virtual void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendComputeShaderObject cso) = 0;
+
+ /**
+ * @brief create a shader program object
+ *
+ * @param[in] isSeparable Tell the backend that this program is separable
+ *
+ * @return The created shader program object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) = 0;
+
+ /**
+ * @brief release a shader program object
+ *
+ * @param[in] po Pointer to shader program object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief link a shader program object
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in/out] errorMessage Pointer to copy the error message
+ *
+ * @return True if program is succesful linked.
+ */
+ virtual bool LinkProgram(NVRenderBackendShaderProgramObject po,
+ eastl::string &errorMessage) = 0;
+
+ /**
+ * @brief Make a program current
+ *
+ * @param[in] po Pointer to shader program object
+ *
+ * @return No return
+ */
+ virtual void SetActiveProgram(NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief create a program pipeline object
+ *
+ *
+ * @return The created program pipeline object or NULL if the creation failed.
+ */
+ virtual NVRenderBackendProgramPipeline CreateProgramPipeline() = 0;
+
+ /**
+ * @brief release a program pipeline object
+ *
+ * @param[in] ppo Pointer to program pipeline object
+ *
+ * @return No Return.
+ */
+ virtual void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0;
+
+ /**
+ * @brief Make a program pipeline current
+ *
+ * @param[in] ppo Pointer to program pipeline object
+ *
+ * @return No return
+ */
+ virtual void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) = 0;
+
+ /**
+ * @brief Make a program stage active for this pipeline
+ *
+ * @param[in] ppo Pointer to program pipeline object
+ * @param[in] flags Shader stage flags to which this po is bound to
+ * @param[in] po Pointer to shader program object
+ *
+ * @return No return
+ */
+ virtual void SetProgramStages(NVRenderBackendProgramPipeline ppo,
+ NVRenderShaderTypeFlags flags,
+ NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief Runs a compute program
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] numGroupsX The number of work groups to be launched in the X
+ * dimension
+ * @param[in] numGroupsY The number of work groups to be launched in the Y
+ * dimension
+ * @param[in] numGroupsZ The number of work groups to be launched in the Z
+ * dimension
+ *
+ * @return No return
+ */
+ virtual void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX,
+ QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) = 0;
+
+ /**
+ * @brief Query constant count for a program object
+ *
+ * @param[in] po Pointer to shader program object
+ *
+ * @return Return active constant count
+ */
+ virtual QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief Query constant buffer count for a program object
+ *
+ * @param[in] po Pointer to shader program object
+ *
+ * @return Return active constant buffer count
+ */
+ virtual QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief Query constant information by ID
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] id Constant ID
+ * @param[in] bufSize Max char for nameBuf
+ * @param[out] numElem Usually one unless for arrays
+ * @param[out] type Constant data type (QT3DSVec4, QT3DSVec3,...)
+ * @param[out] binding Unit binding point for samplers and images
+ * @param[out] nameBuf Name of the constant
+ *
+ * @return Return current constant location or -1 if not found
+ */
+ virtual QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 bufSize, QT3DSI32 *numElem,
+ NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding,
+ char *nameBuf) = 0;
+
+ /**
+ * @brief Query constant buffer information by ID
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] id Constant buffer ID
+ * @param[in] nameBufSize Size of nameBuf
+ * @param[out] paramCount Count ot parameter contained in the buffer
+ * @param[out] bufferSize Data size of the constant buffer
+ * @param[out] length Actual characters written
+ * @param[out] nameBuf Receives the name of the buffer
+ *
+ * @return Return current constant buffer location or -1 if not found
+ */
+ virtual QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf) = 0;
+
+ /**
+ * @brief Query constant buffer param indices
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] id Constant buffer ID
+ * @param[out] indices Receives the indices of the uniforms within the
+ * constant buffer
+ *
+ * @return no return value
+ */
+ virtual void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSI32 *indices) = 0;
+
+ /**
+ * @brief Query constant buffer param info by indices
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] count Number of indices
+ * @param[in] indices The indices of the uniforms within the constant
+ * buffer
+ * @param[out] type Array of param types ( float ,int, ...)
+ * @param[out] size Array of param size
+ * @param[out] offset Array of param offsets within the constant buffer
+ *
+ * @return no return value
+ */
+ virtual void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset) = 0;
+
+ /**
+ * @brief Bind program constant block
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] blockIndex Constant block index returned by
+ * GetConstantBufferInfoByID
+ * @param[in] binding Block binding location which should be the same as index
+ * in ProgramSetConstantBlock
+ *
+ * @return No return
+ */
+ virtual void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding) = 0;
+
+ /**
+ * @brief Bind constant buffer for usage in the current active shader program
+ *
+ * @param[in] index Constant ID
+ * @param[in] bo Pointer to constant buffer object
+ *
+ * @return No return
+ */
+ virtual void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0;
+
+ /**
+ * @brief Query storage buffer count for a program object
+ *
+ * @param[in] po Pointer to shader program object
+ *
+ * @return Return active storage buffer count
+ */
+ virtual QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief Query storage buffer information by ID
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] id Storage buffer ID
+ * @param[in] nameBufSize Size of nameBuf
+ * @param[out] paramCount Count of parameter contained in the buffer
+ * @param[out] bufferSize Data size of the constant buffer
+ * @param[out] length Actual characters written
+ * @param[out] nameBuf Receives the name of the buffer
+ *
+ * @return Return current storage buffer binding or -1 if not found
+ */
+ virtual QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) = 0;
+
+ /**
+ * @brief Bind a storage buffer for usage in the current active shader program
+ *
+ * @param[in] index Constant ID
+ * @param[in] bo Pointer to storage buffer object
+ *
+ * @return No return
+ */
+ virtual void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0;
+
+ /**
+ * @brief Query atomic counter buffer count for a program object
+ *
+ * @param[in] po Pointer to shader program object
+ *
+ * @return Return active atomic buffer count
+ */
+ virtual QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) = 0;
+
+ /**
+ * @brief Query atomic counter buffer information by ID
+ *
+ * @param[in] po Pointer to shader program object
+ * @param[in] id Storage buffer ID
+ * @param[in] nameBufSize Size of nameBuf
+ * @param[out] paramCount Count of parameter contained in the buffer
+ * @param[out] bufferSize Data size of the constant buffer
+ * @param[out] length Actual characters written
+ * @param[out] nameBuf Receives the name of the buffer
+ *
+ * @return Return current storage buffer binding or -1 if not found
+ */
+ virtual QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf) = 0;
+
+ /**
+ * @brief Bind a atomic counter buffer for usage in the current active shader program
+ *
+ * @param[in] index Constant ID
+ * @param[in] bo Pointer to atomic counter buffer object
+ *
+ * @return No return
+ */
+ virtual void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) = 0;
+
+ /**
+ * @brief Set constant value
+ *
+ * @param[in] po Pointer program object
+ * @param[in] id Constant ID
+ * @param[in] type Constant data type (QT3DSVec4, QT3DSVec3,...)
+ * @param[in] count Element count
+ * @param[in] value Pointer to constant value
+ * @param[in] transpose Transpose a matrix
+ *
+ * @return No return
+ */
+ virtual void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count,
+ const void *value, bool transpose = false) = 0;
+
+ /**
+ * @brief Draw the current active vertex buffer
+ *
+ * @param[in] drawMode Draw mode (Triangles, ....)
+ * @param[in] start Start vertex
+ * @param[in] count Vertex count
+ *
+ * @return no return.
+ */
+ virtual void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) = 0;
+
+ /**
+ * @brief Draw the current active vertex buffer using an indirect buffer
+ * This means the setup of the draw call is stored in a buffer bound to
+ * NVRenderBufferBindValues::Draw_Indirect
+ *
+ * @param[in] drawMode Draw mode (Triangles, ....)
+ * @param[in] indirect Offset into a indirect drawing setup buffer
+ *
+ * @return no return.
+ */
+ virtual void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) = 0;
+
+ /**
+ * @brief Draw the current active index buffer
+ *
+ * @param[in] drawMode Draw mode (Triangles, ....)
+ * @param[in] count Index count
+ * @param[in] type Index type (QT3DSU16, QT3DSU8)
+ * @param[in] indices Pointer to index buffer. In the case of buffer objects
+ * this is an offset into the active index buffer
+ *object.
+ *
+ * @return no return.
+ */
+ virtual void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count,
+ NVRenderComponentTypes::Enum type, const void *indices) = 0;
+
+ /**
+ * @brief Draw the current active index buffer using an indirect buffer
+ * This means the setup of the draw call is stored in a buffer bound to
+ * NVRenderBufferBindValues::Draw_Indirect
+ *
+ * @param[in] drawMode Draw mode (Triangles, ....)
+ * @param[in] type Index type (QT3DSU16, QT3DSU8)
+ * @param[in] indices Offset into a indirect drawing setup buffer
+ *
+ * @return no return.
+ */
+ virtual void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode,
+ NVRenderComponentTypes::Enum type,
+ const void *indirect) = 0;
+
+ /**
+ * @brief Read a pixel rectangle from render target (from bottom left)
+ *
+ * @param[in] rto Pointer to render target object
+ * @param[in] x Windows X start coord
+ * @param[in] y Windows Y start coord
+ * @param[in] width Read width dim
+ * @param[in] height Read height dim
+ * @param[out] pixels Returned pixel data
+ *
+ * @return No return
+ */
+ virtual void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width,
+ QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat,
+ void *pixels) = 0;
+
+ /**
+ * @brief Create a NV path render object
+ *
+ * @param[in] range Number of internal objects
+ *
+ * @return return path object on success or NULL
+ */
+ virtual NVRenderBackendPathObject CreatePathNVObject(size_t range) = 0;
+
+ /**
+ * @brief Relase a NV path render object
+ *
+ * @param[in] po Created path object
+ * @param[in] range Number of internal objects
+ *
+ * @return return path object on success or NULL
+ */
+ virtual void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) = 0;
+
+ /**
+ * @brief Set the path commands and data.
+ *
+ * @param[in] inPathObject Pointer to NV path object
+ * @param[in] inPathCommands vector of path commands ( moveTo,... )
+ * @param[in] inPathCoords vector of path coords
+ *
+ * @return No return
+ */
+ virtual void SetPathSpecification(NVRenderBackendPathObject inPathObject,
+ NVConstDataRef<QT3DSU8> inPathCommands,
+ NVConstDataRef<QT3DSF32> inPathCoords) = 0;
+
+ /**
+ * @brief Get Bounds of the path object
+ *
+ * @param[in] inPathObject Pointer to NV path object
+ *
+ * @return return bounds
+ */
+ virtual NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) = 0;
+ virtual NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) = 0;
+ virtual NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) = 0;
+
+ /**
+ * @brief Set stroke width. Defaults to 0 if unset.
+ *
+ * @param[in] inPathObject Pointer to NV path object
+ *
+ * @return No return
+ */
+ virtual void SetStrokeWidth(NVRenderBackendPathObject inPathObject,
+ QT3DSF32 inStrokeWidth) = 0;
+
+ /**
+ * @brief Path transform commands
+ *
+ * @param[in] inPathObject Pointer to NV path object
+ *
+ * @return No return
+ */
+ virtual void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) = 0;
+ virtual void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) = 0;
+
+ /**
+ * @brief Path stencil pass operations
+ *
+ * @param[in] inPathObject Pointer to NV path object
+ *
+ * @return No return
+ */
+ virtual void StencilStrokePath(NVRenderBackendPathObject inPathObject) = 0;
+ virtual void StencilFillPath(NVRenderBackendPathObject inPathObject) = 0;
+
+ /**
+ * @brief Does a instanced stencil fill pass
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] fillMode Fille mode
+ * @param[in] stencilMask Stencil mask
+ * @param[in] transformType Transforming glyphs
+ * @param[in] transformValues Pointer to array of transforms
+ *
+ * @return No return
+ */
+ virtual void StencilFillPathInstanced(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type,
+ const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask,
+ NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) = 0;
+
+ /**
+ * @brief Does a instanced stencil stroke pass
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] stencilRef Stencil reference
+ * @param[in] stencilMask Stencil mask
+ * @param[in] transformType Transforming glyphs
+ * @param[in] transformValues Pointer to array of transforms
+ *
+ * @return No return
+ */
+ virtual void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes, QT3DSI32 stencilRef,
+ QT3DSU32 stencilMask,
+ NVRenderPathTransformType::Enum transformType,
+ const QT3DSF32 *transformValues) = 0;
+
+ /**
+ * @brief Does a instanced cover fill pass
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] coverMode Cover mode
+ * @param[in] transformType Transforming glyphs
+ * @param[in] transformValues Pointer to array of transforms
+ *
+ * @return No return
+ */
+ virtual void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes,
+ NVRenderPathCoverMode::Enum coverMode,
+ NVRenderPathTransformType::Enum transformType,
+ const QT3DSF32 *transformValues) = 0;
+
+ /**
+ * @brief Does a instanced cover stroke pass
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] coverMode Cover mode
+ * @param[in] transformType Transforming glyphs
+ * @param[in] transformValues Pointer to array of transforms
+ *
+ * @return No return
+ */
+ virtual void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes,
+ NVRenderPathCoverMode::Enum coverMode,
+ NVRenderPathTransformType::Enum transformType,
+ const QT3DSF32 *transformValues) = 0;
+
+ /**
+ * @brief Path stencil and depth offset
+ *
+ * @param[in] inSlope slope
+ * @param[in] inBias bias
+ *
+ * @return No return
+ */
+ virtual void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) = 0;
+
+ /**
+ * @brief Path cover function
+ *
+ * @param[in] inDepthFunction depth function
+ *
+ * @return No return
+ */
+ virtual void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) = 0;
+
+ /**
+ * @brief Load glyphs
+ *
+ * @param[in] po Base of path objects
+ * @param[in] fontTarget System font, or application font,...
+ * @param[in] fontName Name of font ( may include path )
+ * @param[in] fontStyle Bold or italic
+ * @param[in] numGlyphs Glyph count
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] handleMissingGlyphs skip or use
+ * @param[in] pathParameterTemplate template
+ * @param[in] emScale scale ( true type scale e.g. 2048 )
+ *
+ * @return No return
+ */
+ virtual void LoadPathGlyphs(NVRenderBackendPathObject po,
+ NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs,
+ NVRenderPathFormatType::Enum type, const void *charCodes,
+ NVRenderPathMissingGlyphs::Enum handleMissingGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate,
+ QT3DSF32 emScale) = 0;
+
+ /**
+ * @brief Load indexed font set
+ *
+ * @param[in] po Base of path objects
+ * @param[in] fontTarget System font, or application font,...
+ * @param[in] fontName Name of font ( may include path )
+ * @param[in] fontStyle Bold or italic
+ * @param[in] firstGlyphIndex First glyph
+ * @param[in] numGlyphs Glyph count
+ * @param[in] pathParameterTemplate template
+ * @param[in] emScale scale ( true type scale e.g. 2048 )
+ *
+ * @return return load status
+ */
+ virtual NVRenderPathReturnValues::Enum
+ LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget,
+ const void *fontName, NVRenderPathFontStyleFlags fontStyle,
+ QT3DSU32 firstGlyphIndex, size_t numGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) = 0;
+
+ /**
+ * @brief Load indexed font set
+ *
+ * @param[in] fontTarget System font, or application font,...
+ * @param[in] fontName Name of font ( may include path )
+ * @param[in] fontStyle Bold or italic
+ * @param[in] pathParameterTemplate template
+ * @param[in] emScale scale ( true type scale e.g. 2048 )
+ * @param[out] po contains glyph count
+ *
+ * @return returnr base path object
+ */
+ virtual NVRenderBackendPathObject
+ LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale,
+ QT3DSU32 *count) = 0;
+
+ /**
+ * @brief Load font set
+ *
+ * @param[in] po Base of path objects
+ * @param[in] fontTarget System font, or application font,...
+ * @param[in] fontName Name of font ( may include path )
+ * @param[in] fontStyle Bold or italic
+ * @param[in] firstGlyph First glyph
+ * @param[in] numGlyphs Glyph count
+ * @param[in] handleMissingGlyphs skip or use
+ * @param[in] pathParameterTemplate template
+ * @param[in] emScale scale ( true type scale e.g. 2048 )
+ *
+ * @return No return
+ */
+ virtual void LoadPathGlyphRange(NVRenderBackendPathObject po,
+ NVRenderPathFontTarget::Enum fontTarget,
+ const void *fontName, NVRenderPathFontStyleFlags fontStyle,
+ QT3DSU32 firstGlyph, size_t numGlyphs,
+ NVRenderPathMissingGlyphs::Enum handleMissingGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate,
+ QT3DSF32 emScale) = 0;
+
+ /**
+ * @brief Query font metrics
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] metricQueryMask Qeury bit mask
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] stride scale ( true type scale e.g. 2048 )
+ * @param[out] metrics Filled with font metric values
+ *
+ * @return No return
+ */
+ virtual void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathGlyphFontMetricFlags metricQueryMask,
+ NVRenderPathFormatType::Enum type, const void *charCodes,
+ size_t stride, QT3DSF32 *metrics) = 0;
+
+ /**
+ * @brief Query font metrics
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] metricQueryMask Qeury bit mask
+ * @param[in] stride scale ( true type scale e.g. 2048 )
+ * @param[out] metrics Filled with font metric values
+ *
+ * @return No return
+ */
+ virtual void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathGlyphFontMetricFlags metricQueryMask,
+ size_t stride, QT3DSF32 *metrics) = 0;
+
+ /**
+ * @brief Query path spacing
+ *
+ * @param[in] po Base of path objects
+ * @param[in] numPaths Number path objects
+ * @param[in] pathListMode How to compute spacing
+ * @param[in] type type ( byte, int,... )
+ * @param[in] charCodes charachter string
+ * @param[in] advanceScale
+ * @param[in] kerningScale
+ * @param[in] transformType
+ * @param[out] metrics Filled with font metric values
+ *
+ * @return No return
+ */
+ virtual void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathListMode::Enum pathListMode,
+ NVRenderPathFormatType::Enum type, const void *charCodes,
+ QT3DSF32 advanceScale, QT3DSF32 kerningScale,
+ NVRenderPathTransformType::Enum transformType,
+ QT3DSF32 *spacing) = 0;
+
+ virtual QSurfaceFormat format() const = 0;
+
+ protected:
+ /// struct for what the backend supports
+ typedef struct NVRenderBackendSupport
+ {
+ union {
+ struct
+ {
+ bool bDXTImagesSupported : 1; ///< compressed images supported
+ bool bAnistropySupported : 1; ///< anistropic filtering supported
+ bool bTextureSwizzleSupported : 1; ///< texture swizzle supported
+ bool bDepthStencilSupported : 1; ///< depth stencil textures are supported
+ bool bFPRenderTargetsSupported : 1; ///< floating point render targets are
+ ///supported
+ bool bConstantBufferSupported : 1; ///< Constant (uniform) buffers are supported
+ bool bMsTextureSupported : 1; ///< Multisample textures are esupported
+ bool bFastBlitsSupported : 1; ///< The hardware supports fast memor blits
+ bool bTessellationSupported : 1; ///< Hardware supports tessellation
+ bool bComputeSupported : 1; ///< Hardware supports compute shader
+ bool bGeometrySupported : 1; ///< Hardware supports geometry shader
+ bool bTimerQuerySupported : 1; ///< Hardware supports timer queries
+ bool bProgramInterfaceSupported : 1; ///< API supports program interface queries
+ bool bStorageBufferSupported : 1; ///< Shader storage buffers are supported
+ bool bAtomicCounterBufferSupported : 1; ///< Atomic counter buffers are
+ /// supported
+ bool bShaderImageLoadStoreSupported : 1; ///< Shader image load / store
+ ///operations are supported
+ bool bProgramPipelineSupported : 1; ///< Driver supports separate programs
+ bool bNVPathRenderingSupported : 1; ///< Driver NV path rendering
+ bool bNVAdvancedBlendSupported : 1; ///< Advanced blend modes supported
+ bool bNVBlendCoherenceSupported : 1; ///< Advanced blend done coherently
+ ///supported
+ bool bGPUShader5ExtensionSupported : 1;
+ bool bKHRAdvancedBlendSupported : 1; ///< Advanced blend modes supported
+ bool bKHRBlendCoherenceSupported : 1; ///< Advanced blend done coherently
+ bool bVertexArrayObjectSupported : 1;
+ bool bStandardDerivativesSupported : 1;
+ bool bTextureLodSupported : 1;
+ } bits;
+
+ QT3DSU32 u32Values;
+ } caps;
+ } NVRenderBackendSupportBits;
+
+ NVRenderBackendSupportBits m_backendSupport; ///< holds the backend support bits
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp
new file mode 100644
index 00000000..d38c330c
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.cpp
@@ -0,0 +1,887 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/backends/gl/Q3DSRenderBackendGLES2.h"
+#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h"
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__)
+#else
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError()
+#endif
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_MULTISAMPLE_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_EXTENSION_FUNCTION(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#else
+#define GL_CALL_TIMER_EXT(x)
+#define GL_CALL_TESSELATION_EXT(x)
+#define GL_CALL_MULTISAMPLE_EXT(x)
+#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_EXTENSION_FUNCTION(x)
+#endif
+
+#ifndef GL_DEPTH_STENCIL_OES
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#endif
+
+namespace qt3ds {
+namespace render {
+
+/// constructor
+NVRenderBackendGLES2Impl::NVRenderBackendGLES2Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format)
+ : NVRenderBackendGLBase(fnd, stringTable, format)
+{
+ QString exts3tc = QStringLiteral("GL_EXT_texture_compression_s3tc");
+ QString extsdxt = QStringLiteral("GL_EXT_texture_compression_dxt1");
+ QString extsAniso = QStringLiteral("GL_EXT_texture_filter_anisotropic");
+ QString extsTexSwizzle = QStringLiteral("GL_ARB_texture_swizzle");
+ QString extsFPRenderTarget = QStringLiteral("GL_EXT_color_buffer_float");
+ QString extsTimerQuery = QStringLiteral("GL_EXT_timer_query");
+ QString extsGpuShader5 = QStringLiteral("EXT_gpu_shader5");
+ QString extDepthTexture = QStringLiteral("GL_OES_packed_depth_stencil");
+ QString extvao = QStringLiteral("GL_OES_vertex_array_object");
+ QString extStdDd = QStringLiteral("GL_OES_standard_derivatives");
+ QString extTexLod = QStringLiteral("GL_EXT_shader_texture_lod");
+
+ const char *languageVersion = GetShadingLanguageVersion();
+ qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion);
+
+ eastl::string apiVersion(getVersionString());
+ qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str());
+
+ eastl::string apiVendor(getVendorString());
+ qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str());
+
+ eastl::string apiRenderer(getRendererString());
+ qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str());
+
+ // clear support bits
+ m_backendSupport.caps.u32Values = 0;
+
+ const char *extensions = getExtensionString();
+ m_extensions = QString::fromLocal8Bit(extensions).split(" ");
+
+ // get extension count
+ GLint numExtensions = m_extensions.size();
+
+ for (QT3DSI32 i = 0; i < numExtensions; i++) {
+
+ const QString &extensionString = m_extensions.at(i);
+
+ // search for extension
+ if (!m_backendSupport.caps.bits.bDXTImagesSupported
+ && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) {
+ m_backendSupport.caps.bits.bDXTImagesSupported = true;
+ } else if (!m_backendSupport.caps.bits.bAnistropySupported
+ && extsAniso.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bAnistropySupported = true;
+ } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported
+ && extsFPRenderTarget.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bFPRenderTargetsSupported = true;
+ } else if (!m_backendSupport.caps.bits.bTimerQuerySupported
+ && extsTimerQuery.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bTimerQuerySupported = true;
+ } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported
+ && extsGpuShader5.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true;
+ } else if (!m_backendSupport.caps.bits.bTextureSwizzleSupported
+ && extsTexSwizzle.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bTextureSwizzleSupported = true;
+ } else if (!m_backendSupport.caps.bits.bDepthStencilSupported
+ && extDepthTexture.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bDepthStencilSupported = true;
+ } else if (!m_backendSupport.caps.bits.bVertexArrayObjectSupported
+ && extvao.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bVertexArrayObjectSupported = true;
+ } else if (!m_backendSupport.caps.bits.bStandardDerivativesSupported
+ && extStdDd.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bStandardDerivativesSupported = true;
+ } else if (!m_backendSupport.caps.bits.bTextureLodSupported
+ && extTexLod.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bTextureLodSupported = true;
+ }
+ }
+
+ qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensions);
+
+ // constant buffers support is always not true
+ m_backendSupport.caps.bits.bConstantBufferSupported = false;
+
+ // query hardware
+ GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount));
+
+ // internal state tracker
+ m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)();
+
+ // finally setup caps based on device
+ setAndInspectHardwareCaps();
+
+ // Initialize extensions
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+ m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions;
+ m_qt3dsExtensions->initializeOpenGLFunctions();
+#endif
+}
+/// destructor
+NVRenderBackendGLES2Impl::~NVRenderBackendGLES2Impl()
+{
+ if (m_pCurrentMiscState)
+ NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState);
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+ if (m_qt3dsExtensions)
+ delete m_qt3dsExtensions;
+#endif
+}
+
+void NVRenderBackendGLES2Impl::SetMultisampledTextureData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height,
+ bool fixedsamplelocations)
+{
+ NVRENDER_BACKEND_UNUSED(to);
+ NVRENDER_BACKEND_UNUSED(target);
+ NVRENDER_BACKEND_UNUSED(samples);
+ NVRENDER_BACKEND_UNUSED(internalFormat);
+ NVRENDER_BACKEND_UNUSED(width);
+ NVRENDER_BACKEND_UNUSED(height);
+ NVRENDER_BACKEND_UNUSED(fixedsamplelocations);
+}
+
+void NVRenderBackendGLES2Impl::SetTextureData3D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth,
+ QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr)
+{
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+ bool conversionRequired = format != internalFormat;
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+ }
+
+ if (conversionRequired) {
+ GLenum dummy;
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, dummy);
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) {
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ }
+
+ GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width,
+ (GLsizei)height, (GLsizei)depth, border, glformat,
+ gltype, hostPtr));
+
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+}
+
+void NVRenderBackendGLES2Impl::SetTextureData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format, const void *hostPtr)
+{
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+ bool conversionRequired = format != internalFormat;
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+ glInternalFormat = glformat;
+ }
+
+ if (conversionRequired) {
+ GLenum dummy;
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, dummy);
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ } else if (NVRenderTextureFormats::isDepthTextureFormat(format)) {
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ if (format == NVRenderTextureFormats::Depth24Stencil8) {
+ glformat = GL_DEPTH_STENCIL_OES;
+ gltype = GL_UNSIGNED_INT_24_8;
+ }
+ glInternalFormat = glformat;
+ }
+
+ Q_ASSERT(glformat == glInternalFormat);
+ GL_CALL_EXTRA_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width,
+ (GLsizei)height, border, glformat, gltype, hostPtr));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+}
+
+void NVRenderBackendGLES2Impl::UpdateSampler(
+ NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter,
+ NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT,
+ NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias,
+ NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc,
+ QT3DSF32 anisotropy, QT3DSF32 *borderColor)
+{
+
+ // Satisfy the compiler
+ // These are not available in GLES 3 and we don't use them right now
+ QT3DS_ASSERT(lodBias == 0.0);
+ QT3DS_ASSERT(!borderColor);
+ NVRENDER_BACKEND_UNUSED(lodBias);
+ NVRENDER_BACKEND_UNUSED(borderColor);
+ NVRENDER_BACKEND_UNUSED(wrapR);
+ NVRENDER_BACKEND_UNUSED(minLod);
+ NVRENDER_BACKEND_UNUSED(maxLod);
+ NVRENDER_BACKEND_UNUSED(compareMode);
+ NVRENDER_BACKEND_UNUSED(compareFunc);
+
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER,
+ m_Conversion.fromTextureMinifyingOpToGL(minFilter)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER,
+ m_Conversion.fromTextureMagnifyingOpToGL(magFilter)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S,
+ m_Conversion.fromTextureCoordOpToGL(wrapS)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T,
+ m_Conversion.fromTextureCoordOpToGL(wrapT)));
+
+ if (m_backendSupport.caps.bits.bAnistropySupported) {
+ GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ anisotropy));
+ }
+}
+
+void NVRenderBackendGLES2Impl::UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSI32 baseLevel, QT3DSI32 maxLevel)
+{
+ NVRENDER_BACKEND_UNUSED(to);
+
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel));
+}
+
+void NVRenderBackendGLES2Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode)
+{
+ NVRENDER_BACKEND_UNUSED(to);
+ NVRENDER_BACKEND_UNUSED(target);
+ NVRENDER_BACKEND_UNUSED(swizzleMode);
+#if defined(QT_OPENGL_ES)
+ if (m_backendSupport.caps.bits.bTextureSwizzleSupported) {
+ GLint glSwizzle[4];
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle);
+
+ // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0]));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1]));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2]));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3]));
+
+ }
+#endif
+}
+
+QT3DSU32
+NVRenderBackendGLES2Impl::GetDepthBits() const
+{
+ QT3DSI32 depthBits;
+ GL_CALL_EXTRA_FUNCTION(
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits));
+
+ return depthBits;
+}
+
+QT3DSU32
+NVRenderBackendGLES2Impl::GetStencilBits() const
+{
+ QT3DSI32 stencilBits;
+ GL_CALL_EXTRA_FUNCTION(
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
+ &stencilBits));
+
+ return stencilBits;
+}
+
+void NVRenderBackendGLES2Impl::GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum /*genType*/)
+{
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+ GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+}
+
+bool NVRenderBackendGLES2Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po)
+{
+ if (iao == nullptr) {
+ // unbind and return;
+ GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(0));
+ return true;
+ }
+
+ NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao;
+ NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout;
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ NVDataRef<NVRenderBackendShaderInputEntryGL> shaderAttribBuffer;
+ if (pProgram->m_shaderInput)
+ shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries;
+
+ if ((attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size())
+ || (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot)) {
+ return false;
+ }
+
+ if (inputAssembler->m_VaoID == 0) {
+ // generate vao
+ GL_CALL_EXTENSION_FUNCTION(glGenVertexArraysOES(1, &inputAssembler->m_VaoID));
+ QT3DS_ASSERT(inputAssembler->m_VaoID);
+ }
+
+ if (inputAssembler->m_cachedShaderHandle != programID) {
+ GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID));
+ inputAssembler->m_cachedShaderHandle = programID;
+
+ QT3DS_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]);
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(attrib.m_AttribName);
+
+ if (entry) {
+ NVRenderBackendLayoutEntryGL &entryData(*entry);
+ if (entryData.m_Type != attrib.m_Type
+ || entryData.m_NumComponents != attrib.m_NumComponents) {
+ qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout",
+ attrib.m_AttribName.c_str());
+ QT3DS_ASSERT(false);
+ return false;
+ } else {
+ entryData.m_AttribIndex = attrib.m_AttribLocation;
+ }
+ } else {
+ qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str());
+ }
+ }
+
+ // disable max possible used first
+ // this is currently sufficient since we always re-arrange input attributes from 0
+ for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++)
+ GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i));
+
+ // setup all attribs
+ QT3DS_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName);
+ if (entry) {
+ const NVRenderBackendLayoutEntryGL &entryData(*entry);
+ GLuint id = HandleToID_cast(
+ GLuint, size_t,
+ inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]);
+ GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id));
+ GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex));
+ GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot];
+ GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot];
+ GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer(
+ entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE,
+ stride, (const void *)(entryData.m_Offset + offset)));
+
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx));
+ }
+ }
+
+ // setup index buffer.
+ if (inputAssembler->m_IndexbufferHandle) {
+ GL_CALL_EXTRA_FUNCTION(glBindBuffer(
+ GL_ELEMENT_ARRAY_BUFFER,
+ HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle)));
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ }
+ } else {
+ GL_CALL_EXTENSION_FUNCTION(glBindVertexArrayOES(inputAssembler->m_VaoID));
+ }
+#ifdef _DEBUG
+ if (inputAssembler->m_VaoID) {
+ QT3DS_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]);
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(attrib.m_AttribName);
+
+ if (entry) {
+ NVRenderBackendLayoutEntryGL &entryData(*entry);
+ if (entryData.m_Type != attrib.m_Type
+ || entryData.m_NumComponents != attrib.m_NumComponents
+ || entryData.m_AttribIndex != attrib.m_AttribLocation) {
+ qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout",
+ attrib.m_AttribName.c_str());
+ QT3DS_ASSERT(false);
+ }
+ } else {
+ qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str());
+ }
+ }
+ }
+#endif // _DEBUG
+
+ return true;
+}
+
+void NVRenderBackendGLES2Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet)
+{
+ NVRENDER_BACKEND_UNUSED(rto);
+
+ m_DrawBuffersArray.clear();
+
+ for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) {
+ if (inDrawBufferSet[idx] < 0)
+ m_DrawBuffersArray.push_back(GL_NONE);
+ else
+ m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]);
+ }
+
+ GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(),
+ m_DrawBuffersArray.data()));
+}
+
+void NVRenderBackendGLES2Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace)
+{
+ NVRENDER_BACKEND_UNUSED(rto);
+ NVRENDER_BACKEND_UNUSED(inReadFace);
+}
+
+void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level,
+ QT3DSI32 layer)
+{
+ NVRENDER_BACKEND_UNUSED(attachment);
+ NVRENDER_BACKEND_UNUSED(to);
+ NVRENDER_BACKEND_UNUSED(level);
+ NVRENDER_BACKEND_UNUSED(layer);
+ Q_ASSERT(false);
+}
+
+void NVRenderBackendGLES2Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1,
+ QT3DSI32 srcY1, QT3DSI32 dstX0, QT3DSI32 dstY0,
+ QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter)
+{
+ GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
+ dstY1,
+ m_Conversion.fromClearFlagsToGL(flags),
+ m_Conversion.fromTextureMagnifyingOpToGL(filter)));
+}
+
+
+NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLES2Impl::CreateRenderTarget()
+{
+ GLuint fboID = 0;
+ GL_CALL_EXTRA_FUNCTION(glGenFramebuffers(1, &fboID));
+ return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID;
+}
+
+void NVRenderBackendGLES2Impl::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ if (fboID)
+ GL_CALL_EXTRA_FUNCTION(glDeleteFramebuffers(1, &fboID));
+}
+
+void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo)
+{
+ // rto must be the current render target
+ GLuint rbID = HandleToID_cast(GLuint, size_t, rbo);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+
+ GL_CALL_EXTRA_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER,
+ rbID));
+}
+
+void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target)
+{
+ // rto must be the current render target
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+
+ QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D
+ || m_backendSupport.caps.bits.bMsTextureSupported);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ if (attachment == NVRenderFrameBufferAttachments::DepthStencil) {
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ glTarget, texID, 0));
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ glTarget, texID, 0));
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID,
+ 0));
+ }
+}
+
+void NVRenderBackendGLES2Impl::SetRenderTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
+}
+
+void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID));
+}
+
+bool NVRenderBackendGLES2Impl::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */)
+{
+ GLenum completeStatus = GL_CALL_EXTRA_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ switch (completeStatus) {
+#define HANDLE_INCOMPLETE_STATUS(x) \
+ case x: \
+ qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \
+ return false;
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED)
+ #undef HANDLE_INCOMPLETE_STATUS
+ }
+ return true;
+}
+
+NVRenderBackend::NVRenderBackendRenderbufferObject
+NVRenderBackendGLES2Impl::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height)
+{
+ GLuint bufID = 0;
+
+ GL_CALL_EXTRA_FUNCTION(glGenRenderbuffers(1, &bufID));
+ GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID));
+ GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER,
+ GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat),
+ (GLsizei)width, (GLsizei)height));
+
+ // check for error
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR, GLConversion::processGLError(error));
+ QT3DS_ASSERT(false);
+ GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID));
+ bufID = 0;
+ }
+
+ GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0));
+
+ return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID;
+}
+
+void NVRenderBackendGLES2Impl::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo)
+{
+ GLuint bufID = HandleToID_cast(GLuint, size_t, rbo);
+
+ if (bufID)
+ GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID));
+}
+
+bool NVRenderBackendGLES2Impl::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height)
+{
+ bool success = true;
+ GLuint bufID = HandleToID_cast(GLuint, size_t, rbo);
+
+ QT3DS_ASSERT(bufID);
+
+ GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID));
+ GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER,
+ GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat),
+ (GLsizei)width, (GLsizei)height));
+
+ // check for error
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR, GLConversion::processGLError(error));
+ QT3DS_ASSERT(false);
+ success = false;
+ }
+
+ return success;
+}
+
+void *NVRenderBackendGLES2Impl::MapBuffer(NVRenderBackendBufferObject,
+ NVRenderBufferBindFlags bindFlags, size_t offset,
+ size_t length, NVRenderBufferAccessFlags accessFlags)
+{
+ void *ret = nullptr;
+ ret = GL_CALL_EXTRA_FUNCTION(
+ glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset,
+ length, m_Conversion.fromBufferAccessBitToGL(accessFlags)));
+
+ return ret;
+}
+
+bool NVRenderBackendGLES2Impl::UnmapBuffer(NVRenderBackendBufferObject,
+ NVRenderBufferBindFlags bindFlags)
+{
+ GLboolean ret;
+
+ ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags)));
+
+ return (ret) ? true : false;
+}
+
+QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po)
+{
+ QT3DS_ASSERT(po);
+ GLint numUniformBuffers = 0;
+ if (GetRenderBackendCap(NVRenderBackendCaps::ConstantBuffer)) {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS,
+ &numUniformBuffers));
+ }
+ return numUniformBuffers;
+}
+
+QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferInfoByID(
+ NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize,
+ QT3DSI32 *paramCount, QT3DSI32 *bufferSize,
+ QT3DSI32 *length, char *nameBuf)
+{
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(length);
+ QT3DS_ASSERT(nameBuf);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ GLuint blockIndex = GL_INVALID_INDEX;
+
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length,
+ nameBuf));
+
+ if (*length > 0) {
+ blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf));
+ if (blockIndex != GL_INVALID_INDEX) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex,
+ GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize));
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex,
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount));
+ }
+ }
+
+ return blockIndex;
+}
+
+void NVRenderBackendGLES2Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSI32 *indices)
+{
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(indices);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ if (indices) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id,
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
+ indices));
+ }
+}
+
+void NVRenderBackendGLES2Impl::GetConstantBufferParamInfoByIndices(
+ NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset)
+{
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(count);
+ QT3DS_ASSERT(indices);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ if (count && indices) {
+ if (type) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices,
+ GL_UNIFORM_TYPE, type));
+ // convert to UIC types
+ QT3DS_FOREACH(idx, count)
+ {
+ type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]);
+ }
+ }
+ if (size) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices,
+ GL_UNIFORM_SIZE, size));
+ }
+ if (offset) {
+ GL_CALL_EXTRA_FUNCTION(
+ glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset));
+ }
+ }
+}
+
+void NVRenderBackendGLES2Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding)
+{
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding));
+}
+
+void NVRenderBackendGLES2Impl::ProgramSetConstantBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+{
+ QT3DS_ASSERT(bo);
+
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID));
+}
+
+NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLES2Impl::CreateQuery()
+{
+ QT3DSU32 glQueryID = 0;
+
+ return (NVRenderBackendQueryObject)glQueryID;
+}
+
+void NVRenderBackendGLES2Impl::ReleaseQuery(NVRenderBackendQueryObject)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::BeginQuery(NVRenderBackendQueryObject,
+ NVRenderQueryType::Enum)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject,
+ NVRenderQueryResultType::Enum,
+ QT3DSU32 *)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject,
+ NVRenderQueryResultType::Enum,
+ QT3DSU64 *)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::SetQueryTimer(NVRenderBackendQueryObject)
+{
+
+}
+
+NVRenderBackend::NVRenderBackendSyncObject
+NVRenderBackendGLES2Impl::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags)
+{
+ GLsync syncID = 0;
+ return NVRenderBackendSyncObject(syncID);
+}
+
+void NVRenderBackendGLES2Impl::ReleaseSync(NVRenderBackendSyncObject)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags,
+ QT3DSU64)
+{
+
+}
+}
+}
diff --git a/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h
new file mode 100644
index 00000000..4890de0e
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Q3DSRenderBackendGLES2.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DS_RENDER_BACKEND_GLES2_H
+#define QT3DS_RENDER_BACKEND_GLES2_H
+
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/gl/Qt3DSRenderBackendGLBase.h"
+#include "render/backends/gl/Qt3DSOpenGLExtensions.h"
+
+#include <QtGui/qopenglextrafunctions.h>
+#include <QtOpenGLExtensions/QtOpenGLExtensions>
+
+namespace qt3ds {
+namespace render {
+
+ ///< forward declaration
+ class NVRenderBackendMiscStateGL;
+
+ using namespace foundation;
+
+ class NVRenderBackendGLES2Impl : public NVRenderBackendGLBase
+ {
+ public:
+ /// constructor
+ NVRenderBackendGLES2Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format);
+ /// destructor
+ virtual ~NVRenderBackendGLES2Impl();
+
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ public:
+ QT3DSU32 GetDepthBits() const override;
+ QT3DSU32 GetStencilBits() const override;
+ void GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum genType) override;
+
+ void SetMultisampledTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ size_t samples,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height,
+ bool fixedsamplelocations) override;
+
+ void SetTextureData3D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, size_t depth, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = nullptr) override;
+
+ void SetTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = nullptr) override;
+
+ void UpdateSampler(
+ NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSF32 minLod = -1000.0f, QT3DSF32 maxLod = 1000.0f, QT3DSF32 lodBias = 0.0f,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0f, QT3DSF32 *borderColor = nullptr) override;
+
+ void UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel,
+ QT3DSI32 maxLevel) override;
+
+ void UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode) override;
+
+ bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po) override;
+
+ void SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet) override;
+ void SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace) override;
+
+ void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter) override;
+
+
+ NVRenderBackendRenderTargetObject CreateRenderTarget() override;
+ void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target
+ = NVRenderTextureTargetType::Texture2D) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level,
+ QT3DSI32 layer) override;
+ void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override;
+ bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override;
+
+ virtual NVRenderBackendRenderbufferObject
+ CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width,
+ size_t height) override;
+ void SetReadTarget(NVRenderBackendRenderTargetObject rto) override;
+ void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override;
+ bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height) override;
+
+ void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t offset, size_t length,
+ NVRenderBufferAccessFlags accessFlags) override;
+ bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override;
+
+ QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf) override;
+ void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSI32 *indices) override;
+ void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 count, QT3DSU32 *indices,
+ QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset) override;
+ void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding) override;
+ void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ NVRenderBackendQueryObject CreateQuery() override;
+ void ReleaseQuery(NVRenderBackendQueryObject qo) override;
+ void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override;
+ void SetQueryTimer(NVRenderBackendQueryObject qo) override;
+
+ NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye,
+ NVRenderSyncFlags syncFlags) override;
+ void ReleaseSync(NVRenderBackendSyncObject so) override;
+ void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags,
+ QT3DSU64 timeout) override;
+
+ protected:
+ NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+ Qt3DSOpenGLES2Extensions *m_qt3dsExtensions;
+#endif
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp
new file mode 100644
index 00000000..564ecd5a
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/backends/gl/Qt3DSOpenGLExtensions.h"
+
+Qt3DSOpenGLExtensions::Qt3DSOpenGLExtensions()
+ : QAbstractOpenGLExtension(*(new Qt3DSOpenGLExtensionsPrivate))
+{
+}
+
+bool Qt3DSOpenGLExtensions::initializeOpenGLFunctions()
+{
+ if (isInitialized())
+ return true;
+
+ QT_PREPEND_NAMESPACE(QOpenGLContext) *context =
+ QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext();
+ if (!context) {
+ qWarning("A current OpenGL context is required to resolve functions");
+ return false;
+ }
+
+ Q_D(Qt3DSOpenGLExtensions);
+
+ d->BlendBarrierNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)()>(
+ context->getProcAddress("glBlendBarrierNV"));
+ d->PathGlyphIndexArrayNV = reinterpret_cast<GLenum (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint,
+ GLfloat)>(
+ context->getProcAddress("glPathGlyphIndexArrayNV"));
+ d->PathGlyphIndexRangeNV = reinterpret_cast<GLenum (QOPENGLF_APIENTRYP)(
+ GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2])>(
+ context->getProcAddress("glPathGlyphIndexRangeNV"));
+ QAbstractOpenGLExtension::initializeOpenGLFunctions();
+ return true;
+}
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+Qt3DSOpenGLES2Extensions::Qt3DSOpenGLES2Extensions()
+{
+}
+
+bool Qt3DSOpenGLES2Extensions::initializeOpenGLFunctions()
+{
+ if (isInitialized())
+ return true;
+
+ QT_PREPEND_NAMESPACE(QOpenGLContext) *context =
+ QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext();
+ if (!context) {
+ qWarning("A current OpenGL context is required to resolve functions");
+ return false;
+ }
+
+ Q_D(Qt3DSOpenGLExtensions);
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+ d->PatchParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLenum, GLint)>(
+ context->getProcAddress("glPatchParameteriEXT"));
+ d->QueryCounterEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum)>(
+ context->getProcAddress("glQueryCounterEXT"));
+ d->GetQueryObjectui64vEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, GLuint64 *)>(
+ context->getProcAddress("glGetQueryObjectui64vEXT"));
+ d->GenPathsNV = reinterpret_cast<GLuint (QOPENGLF_APIENTRYP)(
+ GLsizei)>(
+ context->getProcAddress("glGenPathsNV"));
+ d->DeletePathsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLsizei)>(
+ context->getProcAddress("glDeletePathsNV"));
+ d->PathCommandsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLsizei, const GLubyte *, GLsizei, GLenum, const void *)>(
+ context->getProcAddress("glPathCommandsNV"));
+ d->PathGlyphsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, const void *, GLbitfield, GLsizei, GLenum, const void *,
+ GLenum, GLuint, GLfloat)>(
+ context->getProcAddress("glPathGlyphsNV"));
+ d->PathGlyphRangeNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, const void *, GLbitfield, GLuint, GLsizei, GLenum,
+ GLuint, GLfloat)>(
+ context->getProcAddress("glPathGlyphRangeNV"));
+ d->PathParameterfNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, GLfloat)>(
+ context->getProcAddress("glPathParameterfNV"));
+ d->PathStencilDepthOffsetNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLfloat, GLfloat)>(
+ context->getProcAddress("glPathStencilDepthOffsetNV"));
+ d->StencilFillPathNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, GLuint)>(
+ context->getProcAddress("glStencilFillPathNV"));
+ d->StencilStrokePathNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLint, GLuint)>(
+ context->getProcAddress("glStencilStrokePathNV"));
+ d->StencilFillPathInstancedNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLsizei, GLenum, const void *, GLuint, GLenum, GLuint, GLenum,
+ const GLfloat *)>(
+ context->getProcAddress("glStencilFillPathInstancedNV"));
+ d->StencilStrokePathInstancedNV
+ = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei, GLenum,
+ const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *)>(
+ context->getProcAddress("glStencilStrokePathInstancedNV"));
+ d->PathCoverDepthFuncNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLenum func)>(
+ context->getProcAddress("glPathCoverDepthFuncNV"));
+ d->CoverFillPathInstancedNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLsizei, GLenum, const void *, GLuint, GLenum, GLenum,
+ const GLfloat *)>(
+ context->getProcAddress("glCoverFillPathInstancedNV"));
+ d->CoverStrokePathInstancedNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLsizei, GLenum, const void *, GLuint, GLenum, GLenum,
+ const GLfloat *)>(
+ context->getProcAddress("glCoverStrokePathInstancedNV"));
+ d->GetPathParameterfvNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLuint, GLenum, GLfloat *)>(
+ context->getProcAddress("glGetPathParameterfvNV"));
+ d->GetPathMetricsNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLbitfield, GLsizei, GLenum, const void *, GLuint, GLsizei, GLfloat *)>(
+ context->getProcAddress("glGetPathMetricsNV"));
+ d->GetPathMetricRangeNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLbitfield, GLuint, GLsizei, GLsizei, GLfloat *)>(
+ context->getProcAddress("glGetPathMetricRangeNV"));
+ d->GetPathSpacingNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
+ GLenum, GLsizei, GLenum, const void *, GLuint, GLfloat, GLfloat, GLenum,
+ GLfloat *)>(
+ context->getProcAddress("glGetPathSpacingNV"));
+ d->BindVertexArrayOES = reinterpret_cast<void (QOPENGLF_APIENTRYP)
+ (GLuint)>(
+ context->getProcAddress("glBindVertexArrayOES"));
+ d->DeleteVertexArraysOES = reinterpret_cast<void (QOPENGLF_APIENTRYP)
+ (GLsizei, const GLuint *)>(
+ context->getProcAddress("glDeleteVertexArraysOES"));
+ d->GenVertexArraysOES = reinterpret_cast<void (QOPENGLF_APIENTRYP)
+ (GLsizei, GLuint *)>(
+ context->getProcAddress("glGenVertexArraysOES"));
+ d->IsVertexArrayOES = reinterpret_cast<GLboolean (QOPENGLF_APIENTRYP)
+ (GLuint)>(
+ context->getProcAddress("glIsVertexArrayOES"));
+#endif
+ Qt3DSOpenGLExtensions::initializeOpenGLFunctions();
+ return true;
+}
+#endif // QT_OPENGL_ES
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h
new file mode 100644
index 00000000..c9ba76a6
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLExtensions.h
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DSOPENGLEXTENSIONS_H
+#define QT3DSOPENGLEXTENSIONS_H
+
+#include <QtOpenGLExtensions/QtOpenGLExtensions>
+
+/* Some OpenGL extensions that are not (yet) found in Qt's OpenGL extensions.
+ * These should be auto-generated and added to QtOpenGLExtensions module */
+class Qt3DSOpenGLExtensionsPrivate : public QAbstractOpenGLExtensionPrivate
+{
+public:
+ void (QOPENGLF_APIENTRYP BlendBarrierNV)();
+ GLenum (QOPENGLF_APIENTRYP PathGlyphIndexArrayNV)(
+ GLuint, GLenum, const void*, GLbitfield, GLuint, GLsizei, GLuint,
+ GLfloat);
+ GLenum (QOPENGLF_APIENTRYP PathGlyphIndexRangeNV)(
+ GLenum, const void*, GLbitfield, GLuint, GLfloat, GLuint[2]);
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+ void (QOPENGLF_APIENTRYP PatchParameteriEXT)(GLenum, GLint);
+ void (QOPENGLF_APIENTRYP QueryCounterEXT)(GLuint, GLenum);
+ void (QOPENGLF_APIENTRYP GetQueryObjectui64vEXT)(GLuint, GLenum,
+ GLuint64 *);
+ GLuint (QOPENGLF_APIENTRYP GenPathsNV)(GLsizei);
+ void (QOPENGLF_APIENTRYP DeletePathsNV)(GLuint, GLsizei);
+ void (QOPENGLF_APIENTRYP PathCommandsNV)(GLuint, GLsizei, const GLubyte *,
+ GLsizei, GLenum, const void *);
+ void (QOPENGLF_APIENTRYP PathGlyphsNV)(GLuint, GLenum, const void *,
+ GLbitfield, GLsizei, GLenum, const void *, GLenum, GLuint, GLfloat);
+ void (QOPENGLF_APIENTRYP PathGlyphRangeNV)(GLuint, GLenum, const void *,
+ GLbitfield, GLuint, GLsizei, GLenum, GLuint, GLfloat);
+ void (QOPENGLF_APIENTRYP PathParameterfNV)(GLuint, GLenum, GLfloat);
+ void (QOPENGLF_APIENTRYP PathStencilDepthOffsetNV)(GLfloat, GLfloat);
+ void (QOPENGLF_APIENTRYP StencilFillPathNV)(GLuint, GLenum, GLuint);
+ void (QOPENGLF_APIENTRYP StencilStrokePathNV)(GLuint, GLint, GLuint);
+ void (QOPENGLF_APIENTRYP StencilFillPathInstancedNV)(GLsizei, GLenum,
+ const void *, GLuint, GLenum, GLuint, GLenum, const GLfloat *);
+ void (QOPENGLF_APIENTRYP StencilStrokePathInstancedNV)(GLsizei, GLenum,
+ const void *, GLuint, GLint, GLuint, GLenum, const GLfloat *);
+ void (QOPENGLF_APIENTRYP PathCoverDepthFuncNV)(GLenum);
+ void (QOPENGLF_APIENTRYP CoverFillPathInstancedNV)(GLsizei, GLenum,
+ const void *, GLuint, GLenum, GLenum, const GLfloat *);
+ void (QOPENGLF_APIENTRYP CoverStrokePathInstancedNV)(GLsizei, GLenum,
+ const void *, GLuint, GLenum, GLenum, const GLfloat *);
+ void (QOPENGLF_APIENTRYP GetPathParameterfvNV)(GLuint, GLenum, GLfloat *);
+ void (QOPENGLF_APIENTRYP GetPathMetricsNV)(GLbitfield, GLsizei, GLenum,
+ const void *, GLuint, GLsizei, GLfloat *);
+ void (QOPENGLF_APIENTRYP GetPathMetricRangeNV)(GLbitfield, GLuint, GLsizei,
+ GLsizei, GLfloat *);
+ void (QOPENGLF_APIENTRYP GetPathSpacingNV)(GLenum, GLsizei, GLenum,
+ const void *, GLuint, GLfloat, GLfloat, GLenum, GLfloat *);
+ void (QOPENGLF_APIENTRYP BindVertexArrayOES) (GLuint array);
+ void (QOPENGLF_APIENTRYP DeleteVertexArraysOES) (GLsizei n, const GLuint *arrays);
+ void (QOPENGLF_APIENTRYP GenVertexArraysOES) (GLsizei n, GLuint *arrays);
+ GLboolean (QOPENGLF_APIENTRYP IsVertexArrayOES) (GLuint array);
+#endif
+};
+
+class Qt3DSOpenGLExtensions : public QAbstractOpenGLExtension
+{
+public:
+ Qt3DSOpenGLExtensions();
+
+ bool initializeOpenGLFunctions() override;
+
+ void glBlendBarrierNV();
+ GLenum glPathGlyphIndexArrayNV(GLuint firstPathName, GLenum fontTarget,
+ const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex,
+ GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+ GLenum glPathGlyphIndexRangeNV(GLenum fontTarget, const void *fontName,
+ GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale,
+ GLuint baseAndCount[2]);
+
+protected:
+ Q_DECLARE_PRIVATE(Qt3DSOpenGLExtensions)
+};
+
+inline void Qt3DSOpenGLExtensions::glBlendBarrierNV()
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->BlendBarrierNV();
+}
+
+inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexArrayNV(
+ GLuint firstPathName, GLenum fontTarget, const void *fontName,
+ GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs,
+ GLuint pathParameterTemplate, GLfloat emScale)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ return d->PathGlyphIndexArrayNV(firstPathName, fontTarget, fontName,
+ fontStyle, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale);
+}
+
+inline GLenum Qt3DSOpenGLExtensions::glPathGlyphIndexRangeNV(GLenum fontTarget,
+ const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate,
+ GLfloat emScale, GLuint baseAndCount[2])
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ return d->PathGlyphIndexRangeNV(fontTarget, fontName, fontStyle,
+ pathParameterTemplate, emScale, baseAndCount);
+}
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2_ANGLE)
+class Qt3DSOpenGLES2Extensions : public Qt3DSOpenGLExtensions
+{
+public:
+ Qt3DSOpenGLES2Extensions();
+
+ // tesselation shader
+ void glPatchParameteriEXT(GLenum pname, GLint value);
+
+ // timer
+ void glQueryCounterEXT(GLuint id, GLenum target);
+ void glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params);
+
+ // nv paths
+
+ GLuint glGenPathsNV(GLsizei range);
+ void glDeletePathsNV(GLuint path, GLsizei range);
+ void glPathCommandsNV(GLuint path, GLsizei numCommands,
+ const GLubyte *commands, GLsizei numCoords, GLenum coordType,
+ const void *coords);
+ void glPathGlyphsNV(GLuint firstPathName, GLenum fontTarget,
+ const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs,
+ GLenum type, const void *charcodes, GLenum handleMissingGlyphs,
+ GLuint pathParameterTemplate, GLfloat emScale);
+ void glPathGlyphRangeNV(GLuint firstPathName, GLenum fontTarget,
+ const void *fontName, GLbitfield fontStyle, GLuint firstGlyph,
+ GLsizei numGlyphs, GLenum handleMissingGlyphs,
+ GLuint pathParameterTemplate, GLfloat emScale);
+ void glPathParameterfNV(GLuint path, GLenum pname, GLfloat value);
+ void glPathStencilDepthOffsetNV(GLfloat factor, GLfloat units);
+ void glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask);
+ void glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask);
+ void glStencilFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType,
+ const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask,
+ GLenum transformType, const GLfloat *transformValues);
+ void glStencilStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType,
+ const void *paths, GLuint pathBase, GLint reference, GLuint mask,
+ GLenum transformType, const GLfloat *transformValues);
+ void glPathCoverDepthFuncNV(GLenum func);
+ void glCoverFillPathInstancedNV(GLsizei numPaths, GLenum pathNameType,
+ const void *paths, GLuint pathBase, GLenum coverMode,
+ GLenum transformType, const GLfloat *transformValues);
+ void glCoverStrokePathInstancedNV(GLsizei numPaths, GLenum pathNameType,
+ const void *paths, GLuint pathBase, GLenum coverMode,
+ GLenum transformType, const GLfloat *transformValues);
+ void glGetPathParameterfvNV(GLuint path, GLenum pname, GLfloat *value);
+ void glGetPathMetricsNV(GLbitfield metricQueryMask, GLsizei numPaths,
+ GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride,
+ GLfloat *metrics);
+ void glGetPathMetricRangeNV(GLbitfield metricQueryMask,
+ GLuint firstPathName, GLsizei numPaths, GLsizei stride,
+ GLfloat *metrics);
+ void glGetPathSpacingNV(GLenum pathListMode, GLsizei numPaths,
+ GLenum pathNameType, const void *paths, GLuint pathBase,
+ GLfloat advanceScale, GLfloat kerningScale, GLenum transformType,
+ GLfloat *returnedSpacing);
+ void glBindVertexArrayOES(GLuint array);
+ void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays);
+ void glGenVertexArraysOES(GLsizei n, GLuint *arrays);
+ GLboolean glIsVertexArrayOES(GLuint array);
+
+ bool initializeOpenGLFunctions() Q_DECL_FINAL;
+};
+
+inline void Qt3DSOpenGLES2Extensions::glPatchParameteriEXT(GLenum pname,
+ GLint value)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PatchParameteriEXT(pname, value);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glQueryCounterEXT(GLuint id,
+ GLenum target)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->QueryCounterEXT(id, target);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGetQueryObjectui64vEXT(GLuint id,
+ GLenum pname, GLuint64 *params)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GetQueryObjectui64vEXT(id, pname, params);
+}
+
+inline GLuint Qt3DSOpenGLES2Extensions::glGenPathsNV(GLsizei range)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ return d->GenPathsNV(range);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glDeletePathsNV(GLuint path,
+ GLsizei range)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->DeletePathsNV(path, range);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glPathCommandsNV(GLuint path,
+ GLsizei numCommands, const GLubyte *commands, GLsizei numCoords,
+ GLenum coordType, const void *coords)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PathCommandsNV(path, numCommands, commands, numCoords, coordType,
+ coords);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glPathGlyphsNV(GLuint firstPathName,
+ GLenum fontTarget, const void *fontName, GLbitfield fontStyle,
+ GLsizei numGlyphs, GLenum type, const void *charcodes,
+ GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PathGlyphsNV(firstPathName, fontTarget, fontName, fontStyle, numGlyphs,
+ type, charcodes, handleMissingGlyphs, pathParameterTemplate, emScale);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glPathGlyphRangeNV(GLuint firstPathName,
+ GLenum fontTarget, const void *fontName, GLbitfield fontStyle,
+ GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs,
+ GLuint pathParameterTemplate, GLfloat emScale)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PathGlyphRangeNV(firstPathName, fontTarget, fontName, fontStyle,
+ firstGlyph, numGlyphs, handleMissingGlyphs, pathParameterTemplate,
+ emScale);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glPathParameterfNV(GLuint path,
+ GLenum pname, GLfloat value)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PathParameterfNV(path, pname, value);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glPathStencilDepthOffsetNV(GLfloat factor,
+ GLfloat units)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PathStencilDepthOffsetNV(factor, units);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glStencilFillPathNV(GLuint path,
+ GLenum fillMode, GLuint mask)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->StencilFillPathNV(path, fillMode, mask);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathNV(GLuint path,
+ GLint reference, GLuint mask)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->StencilStrokePathNV(path, reference, mask);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glStencilFillPathInstancedNV(
+ GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase,
+ GLenum fillMode, GLuint mask, GLenum transformType,
+ const GLfloat *transformValues)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->StencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase,
+ fillMode, mask, transformType, transformValues);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glStencilStrokePathInstancedNV(
+ GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase,
+ GLint reference, GLuint mask, GLenum transformType,
+ const GLfloat *transformValues)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->StencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase,
+ reference, mask, transformType, transformValues);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glPathCoverDepthFuncNV(GLenum func)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->PathCoverDepthFuncNV(func);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glCoverFillPathInstancedNV(
+ GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase,
+ GLenum coverMode, GLenum transformType, const GLfloat *transformValues)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->CoverFillPathInstancedNV(numPaths, pathNameType, paths, pathBase,
+ coverMode, transformType, transformValues);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glCoverStrokePathInstancedNV(
+ GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase,
+ GLenum coverMode, GLenum transformType, const GLfloat *transformValues)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->CoverStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase,
+ coverMode, transformType, transformValues);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGetPathParameterfvNV(GLuint path,
+ GLenum pname, GLfloat *value)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GetPathParameterfvNV(path, pname, value);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGetPathMetricsNV(
+ GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType,
+ const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GetPathMetricsNV(metricQueryMask, numPaths, pathNameType, paths,
+ pathBase, stride, metrics);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGetPathMetricRangeNV(
+ GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths,
+ GLsizei stride, GLfloat *metrics)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GetPathMetricRangeNV(metricQueryMask, firstPathName, numPaths, stride,
+ metrics);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGetPathSpacingNV(GLenum pathListMode,
+ GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase,
+ GLfloat advanceScale, GLfloat kerningScale, GLenum transformType,
+ GLfloat *returnedSpacing)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase,
+ advanceScale, kerningScale, transformType, returnedSpacing);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glBindVertexArrayOES(GLuint array)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->BindVertexArrayOES(array);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->DeleteVertexArraysOES(n, arrays);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GenVertexArraysOES(n, arrays);
+}
+
+inline GLboolean Qt3DSOpenGLES2Extensions::glIsVertexArrayOES(GLuint array)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ return d->IsVertexArrayOES(array);
+}
+
+#endif // QT_OPENGL_ES
+
+#endif // QT3DSOPENGLEXTENSIONS_H
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h
new file mode 100644
index 00000000..0e6dc6d4
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLPrefix.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DSOPENGLPREFIX_H
+#define QT3DSOPENGLPREFIX_H
+
+#include <QtGui/qtguiglobal.h>
+#if defined(QT_OPENGL_ES)
+#define GL_GLEXT_PROTOTYPES
+#if defined(QT_OPENGL_ES_3_2)
+#include <GLES3/gl32.h>
+#else
+#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
+#endif
+
+// Adding this to ensure that platform version of gl2ext.h is included
+// before Qt's qopengles2ext.h which is missing symbols we need
+#include <GLES2/gl2ext.h>
+#endif
+
+#endif // QT3DSOPENGLPREFIX_H
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h
new file mode 100644
index 00000000..882e2761
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLTokens.h
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DSOPENGLTOKENS_H
+#define QT3DSOPENGLTOKENS_H
+
+/**
+ * This is our general internal to GL type conversion routines
+ * Add defines which are not in standard GL(ext) header but in GL2(ext)
+ * The define are the same with different names
+ * Expectation is the NVIDIA defines (need for compile)
+ */
+#ifndef GL_NVIDIA_PLATFORM_BINARY_NV
+#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
+#endif
+
+#if defined(__APPLE__) || defined(ANDROID) || defined(__INTEGRITY)
+#ifndef GL_DEPTH_COMPONENT24
+#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES
+#endif
+#ifndef GL_DEPTH_COMPONENT32
+#define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES
+#endif
+
+/**
+_* tessellation_shader defines
+ */
+#ifndef GL_TESS_EVALUATION_SHADER
+#define GL_TESS_EVALUATION_SHADER GL_TESS_EVALUATION_SHADER_EXT
+#endif
+#ifndef GL_TESS_CONTROL_SHADER
+#define GL_TESS_CONTROL_SHADER GL_TESS_CONTROL_SHADER_EXT
+#endif
+#ifndef GL_PATCHES
+#define GL_PATCHES GL_PATCHES_EXT
+#endif
+#ifndef GL_PATCH_VERTICES
+#define GL_PATCH_VERTICES GL_PATCH_VERTICES_EXT
+#endif
+#ifndef GL_TESS_CONTROL_SHADER_BIT
+#define GL_TESS_CONTROL_SHADER_BIT GL_TESS_CONTROL_SHADER_BIT_EXT
+#endif
+#ifndef GL_TESS_EVALUATION_SHADER_BIT
+#define GL_TESS_EVALUATION_SHADER_BIT GL_TESS_EVALUATION_SHADER_BIT_EXT
+#endif
+#ifndef GL_VERTEX_SHADER_BIT
+#define GL_VERTEX_SHADER_BIT GL_VERTEX_SHADER_BIT_EXT
+#endif
+#ifndef GL_FRAGMENT_SHADER_BIT
+#define GL_FRAGMENT_SHADER_BIT GL_FRAGMENT_SHADER_BIT_EXT
+#endif
+#ifndef GL_GEOMETRY_SHADER_BIT
+#define GL_GEOMETRY_SHADER_BIT GL_GEOMETRY_SHADER_BIT_EXT
+#endif
+
+
+/**
+ * sample shading extension
+ */
+#ifndef GL_SAMPLE_SHADING
+#define GL_SAMPLE_SHADING GL_SAMPLE_SHADING_OES
+#endif
+#ifndef GL_MIN_SAMPLE_SHADING_VALUE
+#define GL_MIN_SAMPLE_SHADING_VALUE GL_MIN_SAMPLE_SHADING_VALUE_OES
+#endif
+
+/**
+ * Timer query extension
+ */
+#ifndef GL_TIME_ELAPSED
+#define GL_TIME_ELAPSED GL_TIME_ELAPSED_EXT
+#endif
+#ifndef GL_TIMESTAMP
+#define GL_TIMESTAMP GL_TIMESTAMP_EXT
+#endif
+
+/**
+ * compute shader
+ */
+#ifndef GL_IMAGE_2D
+#define GL_IMAGE_2D 0x904D
+#endif
+
+/**
+ * texture formats ( make build happy )
+ */
+#ifndef GL_R16
+#define GL_R16 0x822A
+#endif
+
+#endif // __APPLE__ || ANDROID || __INTEGRITY
+
+#if defined(__APPLE__) || defined(ANDROID)
+
+#ifndef GL_NV_blend_equation_advanced
+#define GL_NV_blend_equation_advanced 1
+#define GL_BLEND_OVERLAP_NV 0x9281
+#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280
+#define GL_BLUE_NV 0x1905
+#define GL_COLORBURN_NV 0x929A
+#define GL_COLORDODGE_NV 0x9299
+#define GL_CONJOINT_NV 0x9284
+#define GL_CONTRAST_NV 0x92A1
+#define GL_DARKEN_NV 0x9297
+#define GL_DIFFERENCE_NV 0x929E
+#define GL_DISJOINT_NV 0x9283
+#define GL_DST_ATOP_NV 0x928F
+#define GL_DST_IN_NV 0x928B
+#define GL_DST_NV 0x9287
+#define GL_DST_OUT_NV 0x928D
+#define GL_DST_OVER_NV 0x9289
+#define GL_EXCLUSION_NV 0x92A0
+#define GL_GREEN_NV 0x1904
+#define GL_HARDLIGHT_NV 0x929B
+#define GL_HARDMIX_NV 0x92A9
+#define GL_HSL_COLOR_NV 0x92AF
+#define GL_HSL_HUE_NV 0x92AD
+#define GL_HSL_LUMINOSITY_NV 0x92B0
+#define GL_HSL_SATURATION_NV 0x92AE
+#define GL_INVERT_OVG_NV 0x92B4
+#define GL_INVERT_RGB_NV 0x92A3
+#define GL_LIGHTEN_NV 0x9298
+#define GL_LINEARBURN_NV 0x92A5
+#define GL_LINEARDODGE_NV 0x92A4
+#define GL_LINEARLIGHT_NV 0x92A7
+#define GL_MINUS_CLAMPED_NV 0x92B3
+#define GL_MINUS_NV 0x929F
+#define GL_MULTIPLY_NV 0x9294
+#define GL_OVERLAY_NV 0x9296
+#define GL_PINLIGHT_NV 0x92A8
+#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2
+#define GL_PLUS_CLAMPED_NV 0x92B1
+#define GL_PLUS_DARKER_NV 0x9292
+#define GL_PLUS_NV 0x9291
+#define GL_RED_NV 0x1903
+#define GL_SCREEN_NV 0x9295
+#define GL_SOFTLIGHT_NV 0x929C
+#define GL_SRC_ATOP_NV 0x928E
+#define GL_SRC_IN_NV 0x928A
+#define GL_SRC_NV 0x9286
+#define GL_SRC_OUT_NV 0x928C
+#define GL_SRC_OVER_NV 0x9288
+#define GL_UNCORRELATED_NV 0x9282
+#define GL_VIVIDLIGHT_NV 0x92A6
+#define GL_XOR_NV 0x1506
+#endif /* GL_NV_blend_equation_advanced */
+
+#ifndef GL_SHADER_STORAGE_BUFFER
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#endif
+
+#ifndef GL_ATOMIC_COUNTER_BUFFER
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#endif
+
+#ifndef GL_ALL_BARRIER_BITS
+#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_ALL_BARRIER_BITS 0xFFFFFFFF
+#endif
+
+#ifndef GL_SHADER_STORAGE_BARRIER_BIT
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#endif
+
+#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#endif
+
+#ifndef GL_UNSIGNED_INT_IMAGE_2D
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#endif
+
+
+
+#ifndef GL_NV_path_rendering
+#define GL_NV_path_rendering 1
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_PATH_FOG_GEN_MODE_NV 0x90AC
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_LINE_TO_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_BOLD_BIT_NV 0x01
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_ROUNDED_RECT_NV 0xE8
+#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9
+#define GL_ROUNDED_RECT2_NV 0xEA
+#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB
+#define GL_ROUNDED_RECT4_NV 0xEC
+#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED
+#define GL_ROUNDED_RECT8_NV 0xEE
+#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF
+#define GL_RELATIVE_RECT_NV 0xF7
+#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368
+#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369
+#define GL_FONT_UNAVAILABLE_NV 0x936A
+#define GL_FONT_UNINTELLIGIBLE_NV 0x936B
+#define GL_CONIC_CURVE_TO_NV 0x1A
+#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B
+#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000
+#define GL_STANDARD_FONT_FORMAT_NV 0x936C
+#define GL_2_BYTES_NV 0x1407
+#define GL_3_BYTES_NV 0x1408
+#define GL_4_BYTES_NV 0x1409
+#define GL_EYE_LINEAR_NV 0x2400
+#define GL_OBJECT_LINEAR_NV 0x2401
+#define GL_CONSTANT_NV 0x8576
+#define GL_PATH_PROJECTION_NV 0x1701
+#define GL_PATH_MODELVIEW_NV 0x1700
+#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3
+#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6
+#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36
+#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3
+#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4
+#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7
+#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38
+#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4
+#define GL_FRAGMENT_INPUT_NV 0x936D
+#endif /* GL_NV_path_rendering */
+
+#ifndef GL_SHADER_STORAGE_BLOCK
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#endif
+
+#ifndef GL_ACTIVE_RESOURCES
+#define GL_ACTIVE_RESOURCES 0x92F5
+#endif
+
+#ifndef GL_BUFFER_BINDING
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_ACTIVE_VARIABLES 0x9305
+#endif
+
+#ifndef GL_UNIFORM
+#define GL_UNIFORM 0x92E1
+#endif
+
+#ifndef GL_COMPUTE_SHADER
+#define GL_COMPUTE_SHADER 0x91B9
+#endif
+
+#endif // __APPLE__ || ANDROID
+
+#endif // QT3DSOPENGLTOKENS_H
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h
new file mode 100644
index 00000000..32f7dad7
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSOpenGLUtil.h
@@ -0,0 +1,2201 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DSOPENGLUTIL_H
+#define QT3DSOPENGLUTIL_H
+
+#include "render/backends/gl/Qt3DSOpenGLPrefix.h"
+#include "render/backends/gl/Qt3DSOpenGLTokens.h"
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLExtraFunctions>
+
+#include "foundation/Qt3DSVec2.h"
+#include "foundation/Qt3DSVec3.h"
+#include "foundation/Qt3DSVec4.h"
+#include "foundation/Qt3DSFoundation.h"
+
+// The actual binding to the hardware the does some minor conversions between gles and
+// the nv render enumeration types
+namespace qt3ds {
+namespace render {
+
+#ifndef GL_TEXTURE_2D_MULTISAMPLE
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#endif
+
+#ifndef GL_IMAGE_2D
+#define GL_IMAGE_2D 0x904D
+#endif
+
+#ifndef GL_MULTISAMPLE_EXT
+#define GL_MULTISAMPLE_EXT 0x809D
+#endif
+
+#ifndef GL_COLOR_ATTACHMENT1
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#endif
+
+#ifndef GL_RED
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#endif
+
+#ifndef GL_PATCHES
+#define GL_PATCHES 0x000E
+#endif
+
+#ifndef GL_READ_ONLY
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#endif
+
+#ifndef GL_SHADER_STORAGE_BUFFER
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#endif
+
+#ifndef GL_ATOMIC_COUNTER_BUFFER
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#endif
+
+#ifndef GL_DRAW_INDIRECT_BUFFER
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#endif
+
+#ifndef GL_VERTEX_SHADER_BIT
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#endif
+
+#ifndef GL_FRAGMENT_SHADER_BIT
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#endif
+
+#ifndef GL_GEOMETRY_SHADER_BIT
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#endif
+
+#ifndef GL_TESS_CONTROL_SHADER_BIT
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#endif
+
+#ifndef GL_TESS_EVALUATION_SHADER_BIT
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#endif
+
+#ifndef GL_ETC1_RGB8_OES
+#define GL_ETC1_RGB8_OES 0x8D64
+#endif
+
+#ifndef GL_COMPRESSED_RED_RGTC1
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#endif
+
+#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#endif
+
+#ifndef GL_COMPRESSED_RG_RGTC2
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#endif
+
+#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#endif
+
+#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#endif
+
+#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#endif
+
+#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM_ARB
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#endif
+
+#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#endif
+
+#ifndef GL_COMPRESSED_RGB8_ETC2
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#endif
+
+#ifndef GL_COMPRESSED_SRGB8_ETC2
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#endif
+
+#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#endif
+
+#ifndef GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#endif
+
+#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#endif
+
+#ifndef GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#endif
+
+#ifndef GL_COMPRESSED_R11_EAC
+#define GL_COMPRESSED_R11_EAC 0x9270
+#endif
+
+#ifndef GL_COMPRESSED_SIGNED_R11_EAC
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#endif
+
+#ifndef GL_COMPRESSED_RG11_EAC
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#endif
+
+#ifndef GL_COMPRESSED_SIGNED_RG11_EAC
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#endif
+
+#define QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ZERO, Zero) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE, One) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_COLOR, SrcColor) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_COLOR, OneMinusSrcColor) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_COLOR, DstColor) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_COLOR, OneMinusDstColor) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_SRC_ALPHA, SrcAlpha) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_SRC_ALPHA, OneMinusSrcAlpha) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_DST_ALPHA, DstAlpha) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_DST_ALPHA, OneMinusDstAlpha) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_COLOR, ConstantColor) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_COLOR, OneMinusConstantColor) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_CONSTANT_ALPHA, ConstantAlpha) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(GL_ONE_MINUS_CONSTANT_ALPHA, OneMinusConstantAlpha) \
+ QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(GL_SRC_ALPHA_SATURATE, SrcAlphaSaturate)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT, Front) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_BACK, Back) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(GL_FRONT_AND_BACK, FrontAndBack)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CW, Clockwise) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(GL_CCW, CounterClockwise)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NEVER, Never) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LESS, Less) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_EQUAL, Equal) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_LEQUAL, LessThanOrEqual) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GREATER, Greater) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_NOTEQUAL, NotEqual) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_GEQUAL, GreaterThanOrEqual) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(GL_ALWAYS, AlwaysTrue)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_HINT \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_FASTEST, Fastest) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_NICEST, Nicest) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(GL_DONT_CARE, Unspecified)
+
+#define QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_KEEP, Keep) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_ZERO, Zero) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_REPLACE, Replace) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR, Increment) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INCR_WRAP, IncrementWrap) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR, Decrement) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_DECR_WRAP, DecrementWrap) \
+ QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(GL_INVERT, Invert)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_BYTE, QT3DSU8) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_BYTE, QT3DSI8) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_SHORT, QT3DSU16) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_SHORT, QT3DSI16) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_UNSIGNED_INT, QT3DSU32) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(GL_INT, QT3DSI32) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(GL_FLOAT, QT3DSF32)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_STATIC_DRAW, Static) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(GL_DYNAMIC_DRAW, Dynamic)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_NEAREST, Nearest) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(GL_LINEAR, Linear) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_NEAREST, NearestMipmapNearest) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_NEAREST, LinearMipmapNearest) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_NEAREST_MIPMAP_LINEAR, NearestMipmapLinear) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(GL_LINEAR_MIPMAP_LINEAR, LinearMipmapLinear)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_CLAMP_TO_EDGE, ClampToEdge) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_MIRRORED_REPEAT, MirroredRepeat) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(GL_REPEAT, Repeat)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT, QT3DSF32) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC2, QT3DSVec2) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC3, QT3DSVec3) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_VEC4, QT3DSVec4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT, QT3DSI32) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC2, QT3DSI32_2) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC3, QT3DSI32_3) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_INT_VEC4, QT3DSI32_4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL, QT3DSRenderBool) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC2, bool_2) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC3, bool_3) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_BOOL_VEC4, bool_4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT, QT3DSU32) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC2, QT3DSU32_2) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC3, QT3DSU32_3) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_UNSIGNED_INT_VEC4, QT3DSU32_4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT3, QT3DSMat33) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_FLOAT_MAT4, QT3DSMat44) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D, NVRenderTexture2DPtr) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_2D_ARRAY, NVRenderTexture2DArrayPtr) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_SAMPLER_CUBE, NVRenderTextureCubePtr) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(GL_IMAGE_2D, NVRenderImage2DPtr)
+// cube Sampler and mat22 unsupported
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT, QT3DSF32, 1) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC2, QT3DSF32, 2) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC3, QT3DSF32, 3) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_VEC4, QT3DSF32, 4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT2, QT3DSF32, 4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT3, QT3DSF32, 9) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(GL_FLOAT_MAT4, QT3DSF32, 16)
+#if defined(GL_DEPTH_COMPONENT32)
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT32, Depth32) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8)
+#else
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGBA4, RGBA4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB565, RGB565) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_RGB5_A1, RGBA5551) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT16, Depth16) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_DEPTH_COMPONENT24, Depth24) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(GL_STENCIL_INDEX8, StencilIndex8)
+#endif
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color0, 0) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color1, 1) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color2, 2) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color3, 3) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color4, 4) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color5, 5) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color6, 6) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(Color7, 7) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_ATTACHMENT, Depth) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_STENCIL_ATTACHMENT, Stencil) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(GL_DEPTH_STENCIL_ATTACHMENT, DepthStencil)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_COLOR_BUFFER_BIT, Color) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_DEPTH_BUFFER_BIT, Depth) \
+ QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(GL_STENCIL_BUFFER_BIT, Stencil)
+
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS
+#define QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS
+
+ static bool IsGlEsContext(NVRenderContextType inContextType)
+ {
+ NVRenderContextType esContextTypes(NVRenderContextValues::GLES2
+ | NVRenderContextValues::GLES3
+ | NVRenderContextValues::GLES3PLUS);
+
+ if ((inContextType & esContextTypes))
+ return true;
+
+ return false;
+ }
+
+ struct GLConversion
+ {
+ GLConversion()
+ { }
+
+ static const char *processGLError(GLenum error)
+ {
+ const char *errorString = "";
+ switch (error) {
+#define stringiseError(error) \
+ case error: \
+ errorString = #error; \
+ break
+ stringiseError(GL_NO_ERROR);
+ stringiseError(GL_INVALID_ENUM);
+ stringiseError(GL_INVALID_VALUE);
+ stringiseError(GL_INVALID_OPERATION);
+ stringiseError(GL_INVALID_FRAMEBUFFER_OPERATION);
+ stringiseError(GL_OUT_OF_MEMORY);
+#undef stringiseError
+ default:
+ errorString = "Unknown GL error";
+ break;
+ }
+ return errorString;
+ }
+
+ static NVRenderSrcBlendFunc::Enum fromGLToSrcBlendFunc(QT3DSI32 value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \
+ case srcVal: \
+ return NVRenderSrcBlendFunc::enumVal;
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \
+ case srcVal: \
+ return NVRenderSrcBlendFunc::enumVal;
+ QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY
+ default:
+ QT3DS_ASSERT(false);
+ return NVRenderSrcBlendFunc::Unknown;
+ }
+ }
+
+ static GLenum fromSrcBlendFuncToGL(NVRenderSrcBlendFunc::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \
+ case NVRenderSrcBlendFunc::enumVal: \
+ return srcVal;
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal) \
+ case NVRenderSrcBlendFunc::enumVal: \
+ return srcVal;
+ QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY
+ default:
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+ }
+
+ static NVRenderDstBlendFunc::Enum fromGLToDstBlendFunc(QT3DSI32 value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \
+ case srcVal: \
+ return NVRenderDstBlendFunc::enumVal;
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal)
+ QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY
+ default:
+ QT3DS_ASSERT(false);
+ return NVRenderDstBlendFunc::Unknown;
+ }
+ }
+
+ static GLenum fromDstBlendFuncToGL(NVRenderDstBlendFunc::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC(srcVal, enumVal) \
+ case NVRenderDstBlendFunc::enumVal: \
+ return srcVal;
+#define QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY(srcVal, enumVal)
+ QT3DS_RENDER_ITERATE_QT3DS_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC
+#undef QT3DS_RENDER_HANDLE_GL_COLOR_FUNC_SRC_ONLY
+ default:
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+ }
+
+ static GLenum fromBlendEquationToGL(NVRenderBlendEquation::Enum value,
+ bool nvAdvancedBlendSupported,
+ bool khrAdvancedBlendSupported)
+ {
+ switch (value) {
+ case NVRenderBlendEquation::Add:
+ return GL_FUNC_ADD;
+ case NVRenderBlendEquation::Subtract:
+ return GL_FUNC_SUBTRACT;
+ case NVRenderBlendEquation::ReverseSubtract:
+ return GL_FUNC_REVERSE_SUBTRACT;
+ default:
+ QT3DS_ASSERT(nvAdvancedBlendSupported || khrAdvancedBlendSupported);
+ break;
+ }
+
+ if (nvAdvancedBlendSupported) {
+ switch (value) {
+ case NVRenderBlendEquation::Overlay:
+ return GL_OVERLAY_NV;
+ case NVRenderBlendEquation::ColorBurn:
+ return GL_COLORBURN_NV;
+ case NVRenderBlendEquation::ColorDodge:
+ return GL_COLORDODGE_NV;
+ default:
+ break;
+ }
+ }
+
+#if defined(GL_KHR_blend_equation_advanced)
+ if (khrAdvancedBlendSupported) {
+ switch (value) {
+ case NVRenderBlendEquation::Overlay:
+ return GL_OVERLAY_KHR;
+ case NVRenderBlendEquation::ColorBurn:
+ return GL_COLORBURN_KHR;
+ case NVRenderBlendEquation::ColorDodge:
+ return GL_COLORDODGE_KHR;
+ default:
+ break;
+ }
+ }
+#endif
+
+ QT3DS_ASSERT(false);
+ return GL_FUNC_ADD;
+ }
+
+ static NVRenderFaces::Enum fromGLToFaces(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \
+ case x: \
+ return NVRenderFaces::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderFaces::Unknown;
+ }
+
+ static GLenum fromFacesToGL(NVRenderFaces::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE(x, y) \
+ case NVRenderFaces::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_FACE
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_FACE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVReadFaces::Enum fromGLToReadFaces(GLenum value)
+ {
+ switch (value) {
+ case GL_FRONT:
+ return NVReadFaces::Front;
+ case GL_BACK:
+ return NVReadFaces::Back;
+ case GL_COLOR_ATTACHMENT0:
+ return NVReadFaces::Color0;
+ case GL_COLOR_ATTACHMENT1:
+ return NVReadFaces::Color1;
+ case GL_COLOR_ATTACHMENT2:
+ return NVReadFaces::Color2;
+ case GL_COLOR_ATTACHMENT3:
+ return NVReadFaces::Color3;
+ case GL_COLOR_ATTACHMENT4:
+ return NVReadFaces::Color4;
+ case GL_COLOR_ATTACHMENT5:
+ return NVReadFaces::Color5;
+ case GL_COLOR_ATTACHMENT6:
+ return NVReadFaces::Color6;
+ case GL_COLOR_ATTACHMENT7:
+ return NVReadFaces::Color7;
+
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVReadFaces::Unknown;
+ }
+
+ static GLenum fromReadFacesToGL(NVReadFaces::Enum value)
+ {
+ switch (value) {
+ case NVReadFaces::Front:
+ return GL_FRONT;
+ case NVReadFaces::Back:
+ return GL_BACK;
+ case NVReadFaces::Color0:
+ return GL_COLOR_ATTACHMENT0;
+ case NVReadFaces::Color1:
+ return GL_COLOR_ATTACHMENT1;
+ case NVReadFaces::Color2:
+ return GL_COLOR_ATTACHMENT2;
+ case NVReadFaces::Color3:
+ return GL_COLOR_ATTACHMENT3;
+ case NVReadFaces::Color4:
+ return GL_COLOR_ATTACHMENT4;
+ case NVReadFaces::Color5:
+ return GL_COLOR_ATTACHMENT5;
+ case NVReadFaces::Color6:
+ return GL_COLOR_ATTACHMENT6;
+ case NVReadFaces::Color7:
+ return GL_COLOR_ATTACHMENT7;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderWinding::Enum fromGLToWinding(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \
+ case x: \
+ return NVRenderWinding::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderWinding::Unknown;
+ }
+
+ static GLenum fromWindingToGL(NVRenderWinding::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING(x, y) \
+ case NVRenderWinding::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDER_WINDING
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDER_WINDING
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderBoolOp::Enum fromGLToBoolOp(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \
+ case x: \
+ return NVRenderBoolOp::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderBoolOp::Unknown;
+ }
+
+ static GLenum fromBoolOpToGL(NVRenderBoolOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \
+ case NVRenderBoolOp::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderHint::Enum fromGLToHint(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \
+ case x: \
+ return NVRenderHint::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_HINT
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderHint::Unknown;
+ }
+
+ static GLenum fromHintToGL(NVRenderHint::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_HINT(x, y) \
+ case NVRenderHint::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_HINT
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_HINT
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderStencilOp::Enum fromGLToStencilOp(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \
+ case x: \
+ return NVRenderStencilOp::y;
+ QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP
+#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return NVRenderStencilOp::Unknown;
+ }
+
+ static GLenum fromStencilOpToGL(NVRenderStencilOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP(x, y) \
+ case NVRenderStencilOp::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_QT3DS_GL_STENCIL_OP
+#undef QT3DS_RENDER_HANDLE_QT3DS_GL_STENCIL_OP
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderComponentTypes::Enum fromGLToBufferComponentTypes(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \
+ case x: \
+ return NVRenderComponentTypes::y;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y)
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderComponentTypes::Unknown;
+ }
+
+ static GLenum fromBufferComponentTypesToGL(NVRenderComponentTypes::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE(x, y) \
+ case NVRenderComponentTypes::y: \
+ return x;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE_ALIAS(x, y) \
+ case NVRenderComponentTypes::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_COMPONENT_TYPES
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_COMPONENT_TYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static GLenum fromIndexBufferComponentsTypesToGL(NVRenderComponentTypes::Enum value)
+ {
+ switch (value) {
+ case NVRenderComponentTypes::QT3DSU8:
+ return GL_UNSIGNED_BYTE;
+ case NVRenderComponentTypes::QT3DSU16:
+ return GL_UNSIGNED_SHORT;
+ case NVRenderComponentTypes::QT3DSU32:
+ return GL_UNSIGNED_INT;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static GLenum fromBindBufferFlagsToGL(NVRenderBufferBindFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLenum retval = GL_INVALID_ENUM;
+ if (value & NVRenderBufferBindValues::Vertex)
+ retval = GL_ARRAY_BUFFER;
+ else if (value & NVRenderBufferBindValues::Index)
+ retval = GL_ELEMENT_ARRAY_BUFFER;
+ else if (value & NVRenderBufferBindValues::Constant)
+ retval = GL_UNIFORM_BUFFER;
+ else if (value & NVRenderBufferBindValues::Storage)
+ retval = GL_SHADER_STORAGE_BUFFER;
+ else if (value & NVRenderBufferBindValues::Atomic_Counter)
+ retval = GL_ATOMIC_COUNTER_BUFFER;
+ else if (value & NVRenderBufferBindValues::Draw_Indirect)
+ retval = GL_DRAW_INDIRECT_BUFFER;
+ else
+ QT3DS_ASSERT(false);
+
+ return retval;
+ }
+
+ static NVRenderBufferBindFlags fromGLToBindBufferFlags(GLenum value)
+ {
+ QT3DSU32 retval = 0;
+
+ if (value == GL_ARRAY_BUFFER)
+ retval |= NVRenderBufferBindValues::Vertex;
+ else if (value == GL_ELEMENT_ARRAY_BUFFER)
+ retval |= NVRenderBufferBindValues::Index;
+ else if (value == GL_UNIFORM_BUFFER)
+ retval |= NVRenderBufferBindValues::Constant;
+ else if (value == GL_SHADER_STORAGE_BUFFER)
+ retval |= NVRenderBufferBindValues::Storage;
+ else if (value == GL_ATOMIC_COUNTER_BUFFER)
+ retval |= NVRenderBufferBindValues::Atomic_Counter;
+ else if (value == GL_DRAW_INDIRECT_BUFFER)
+ retval |= NVRenderBufferBindValues::Draw_Indirect;
+ else
+ QT3DS_ASSERT(false);
+
+ return NVRenderBufferBindFlags(retval);
+ }
+
+ static NVRenderBufferUsageType::Enum fromGLToBufferUsageType(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \
+ case x: \
+ return NVRenderBufferUsageType::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderBufferUsageType::Unknown;
+ }
+
+ static GLenum fromBufferUsageTypeToGL(NVRenderBufferUsageType::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE(x, y) \
+ case NVRenderBufferUsageType::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BUFFER_USAGE_TYPE
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BUFFER_USAGE_TYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static GLenum fromQueryTypeToGL(NVRenderQueryType::Enum type)
+ {
+ GLenum retval = GL_INVALID_ENUM;
+ if (type == NVRenderQueryType::Samples)
+ retval = GL_ANY_SAMPLES_PASSED;
+#if defined(GL_TIME_ELAPSED)
+ else if (type == NVRenderQueryType::Timer)
+ retval = GL_TIME_ELAPSED;
+#elif defined(GL_TIME_ELAPSED_EXT)
+ else if (type == NVRenderQueryType::Timer)
+ retval = GL_TIME_ELAPSED_EXT;
+#endif
+ else
+ QT3DS_ASSERT(false);
+
+ return retval;
+ }
+
+ static GLenum fromQueryResultTypeToGL(NVRenderQueryResultType::Enum type)
+ {
+ GLenum retval = GL_INVALID_ENUM;
+ if (type == NVRenderQueryResultType::ResultAvailable)
+ retval = GL_QUERY_RESULT_AVAILABLE;
+ else if (type == NVRenderQueryResultType::Result)
+ retval = GL_QUERY_RESULT;
+ else
+ QT3DS_ASSERT(false);
+
+ return retval;
+ }
+
+ static GLenum fromSyncTypeToGL(NVRenderSyncType::Enum type)
+ {
+ GLenum retval = GL_INVALID_ENUM;
+ if (type == NVRenderSyncType::GpuCommandsComplete)
+ retval = GL_SYNC_GPU_COMMANDS_COMPLETE;
+ else
+ QT3DS_ASSERT(false);
+
+ return retval;
+ }
+
+ static NVRenderTextureFormats::Enum
+ replaceDeprecatedTextureFormat(NVRenderContextType type, NVRenderTextureFormats::Enum value,
+ NVRenderTextureSwizzleMode::Enum &swizzleMode)
+ {
+ NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2
+ | NVRenderContextValues::GLES2);
+ NVRenderTextureFormats::Enum newValue = value;
+ swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+
+ if (!(type & deprecatedContextFlags)) {
+ switch (value) {
+ case NVRenderTextureFormats::Luminance8:
+ newValue = NVRenderTextureFormats::R8;
+ swizzleMode = NVRenderTextureSwizzleMode::L8toR8;
+ break;
+ case NVRenderTextureFormats::LuminanceAlpha8:
+ newValue = NVRenderTextureFormats::RG8;
+ swizzleMode = NVRenderTextureSwizzleMode::L8A8toRG8;
+ break;
+ case NVRenderTextureFormats::Alpha8:
+ newValue = NVRenderTextureFormats::R8;
+ swizzleMode = NVRenderTextureSwizzleMode::A8toR8;
+ break;
+ case NVRenderTextureFormats::Luminance16:
+ newValue = NVRenderTextureFormats::R16;
+ swizzleMode = NVRenderTextureSwizzleMode::L16toR16;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return newValue;
+ }
+
+ static void
+ NVRenderConvertSwizzleModeToGL(const NVRenderTextureSwizzleMode::Enum swizzleMode,
+ GLint glSwizzle[4])
+ {
+ switch (swizzleMode) {
+ case NVRenderTextureSwizzleMode::L16toR16:
+ case NVRenderTextureSwizzleMode::L8toR8:
+ glSwizzle[0] = GL_RED;
+ glSwizzle[1] = GL_RED;
+ glSwizzle[2] = GL_RED;
+ glSwizzle[3] = GL_ONE;
+ break;
+ case NVRenderTextureSwizzleMode::L8A8toRG8:
+ glSwizzle[0] = GL_RED;
+ glSwizzle[1] = GL_RED;
+ glSwizzle[2] = GL_RED;
+ glSwizzle[3] = GL_GREEN;
+ break;
+ case NVRenderTextureSwizzleMode::A8toR8:
+ glSwizzle[0] = GL_ZERO;
+ glSwizzle[1] = GL_ZERO;
+ glSwizzle[2] = GL_ZERO;
+ glSwizzle[3] = GL_RED;
+ break;
+ case NVRenderTextureSwizzleMode::NoSwizzle:
+ default:
+ glSwizzle[0] = GL_RED;
+ glSwizzle[1] = GL_GREEN;
+ glSwizzle[2] = GL_BLUE;
+ glSwizzle[3] = GL_ALPHA;
+ break;
+ }
+ }
+
+ static bool fromUncompressedTextureFormatToGL(NVRenderContextType type,
+ NVRenderTextureFormats::Enum value,
+ GLenum &outFormat, GLenum &outDataType,
+ GLenum &outInternalFormat)
+ {
+ switch (value) {
+ case NVRenderTextureFormats::R8:
+ if (type == NVRenderContextValues::GLES2) {
+ outFormat = GL_ALPHA;
+ outInternalFormat = GL_ALPHA;
+ } else {
+ outFormat = GL_RED;
+ outInternalFormat = GL_R8;
+ }
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::RG8:
+ outFormat = GL_RG;
+ outInternalFormat = GL_RG8;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::RGBA8:
+ outFormat = GL_RGBA;
+ outInternalFormat = GL_RGBA8;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::RGB8:
+ outFormat = GL_RGB;
+ outInternalFormat = GL_RGB8;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::RGB565:
+ outFormat = GL_RGB;
+ outInternalFormat = GL_RGB8;
+ outDataType = GL_UNSIGNED_SHORT_5_6_5;
+ return true;
+ case NVRenderTextureFormats::RGBA5551:
+ outFormat = GL_RGBA;
+ outInternalFormat = GL_RGBA8;
+ outDataType = GL_UNSIGNED_SHORT_5_5_5_1;
+ return true;
+ case NVRenderTextureFormats::Alpha8:
+ outFormat = GL_ALPHA;
+ outInternalFormat = GL_ALPHA;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::Luminance8:
+ outFormat = GL_LUMINANCE;
+ outInternalFormat = GL_LUMINANCE;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::LuminanceAlpha8:
+ outFormat = GL_LUMINANCE_ALPHA;
+ outInternalFormat = GL_LUMINANCE_ALPHA;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::Luminance16:
+#if defined(QT_OPENGL_ES)
+ outFormat = GL_LUMINANCE16F_EXT;
+ outInternalFormat = GL_LUMINANCE16F_EXT;
+#else
+ outFormat = GL_LUMINANCE;
+ outInternalFormat = GL_LUMINANCE;
+#endif
+ outDataType = GL_UNSIGNED_INT;
+ return true;
+ default:
+ break;
+ }
+
+ NVRenderContextType contextFlags(NVRenderContextValues::GL2
+ | NVRenderContextValues::GLES2);
+ // check extented texture formats
+ if (!(type & contextFlags)) {
+ switch (value) {
+#if !defined(QT_OPENGL_ES)
+ case NVRenderTextureFormats::R16: {
+ if (IsGlEsContext(type)) {
+ outFormat = GL_RED_INTEGER;
+ outInternalFormat = GL_R16UI;
+ } else {
+ outFormat = GL_RED;
+ outInternalFormat = GL_R16;
+ }
+ outDataType = GL_UNSIGNED_SHORT;
+ return true;
+ }
+#endif
+ case NVRenderTextureFormats::R16F:
+ outFormat = GL_RED;
+ outInternalFormat = GL_R16F;
+ outDataType = GL_HALF_FLOAT;
+ return true;
+ case NVRenderTextureFormats::R32UI:
+ outFormat = GL_RED_INTEGER;
+ outInternalFormat = GL_R32UI;
+ outDataType = GL_UNSIGNED_INT;
+ return true;
+ case NVRenderTextureFormats::R32F:
+ outFormat = GL_RED;
+ outInternalFormat = GL_R32F;
+ outDataType = GL_FLOAT;
+ return true;
+ case NVRenderTextureFormats::RGBA16F:
+ outFormat = GL_RGBA;
+ outInternalFormat = GL_RGBA16F;
+ outDataType = GL_HALF_FLOAT;
+ return true;
+ case NVRenderTextureFormats::RG16F:
+ outFormat = GL_RG;
+ outInternalFormat = GL_RG16F;
+ outDataType = GL_HALF_FLOAT;
+ return true;
+ case NVRenderTextureFormats::RG32F:
+ outFormat = GL_RG;
+ outInternalFormat = GL_RG32F;
+ outDataType = GL_FLOAT;
+ return true;
+ case NVRenderTextureFormats::RGBA32F:
+ outFormat = GL_RGBA;
+ outInternalFormat = GL_RGBA32F;
+ outDataType = GL_FLOAT;
+ return true;
+ case NVRenderTextureFormats::RGB32F:
+ outFormat = GL_RGB;
+ outInternalFormat = GL_RGB32F;
+ outDataType = GL_FLOAT;
+ return true;
+ case NVRenderTextureFormats::R11G11B10:
+ outFormat = GL_RGB;
+ outInternalFormat = GL_R11F_G11F_B10F;
+ outDataType = GL_UNSIGNED_INT_10F_11F_11F_REV;
+ return true;
+ case NVRenderTextureFormats::RGB9E5:
+ outFormat = GL_RGB;
+ outInternalFormat = GL_RGB9_E5;
+ outDataType = GL_UNSIGNED_INT_5_9_9_9_REV;
+ return true;
+ case NVRenderTextureFormats::SRGB8:
+ outFormat = GL_RGB;
+ outInternalFormat = GL_SRGB8;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ case NVRenderTextureFormats::SRGB8A8:
+ outFormat = GL_RGBA;
+ outInternalFormat = GL_SRGB8_ALPHA8;
+ outDataType = GL_UNSIGNED_BYTE;
+ return true;
+ default:
+ break;
+ }
+ }
+
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ static GLenum fromCompressedTextureFormatToGL(NVRenderTextureFormats::Enum value)
+ {
+ switch (value) {
+ case NVRenderTextureFormats::RGBA_DXT1:
+ return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case NVRenderTextureFormats::RGB_DXT1:
+ return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ case NVRenderTextureFormats::RGBA_DXT3:
+ return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ case NVRenderTextureFormats::RGBA_DXT5:
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ case NVRenderTextureFormats::R_ATI1N_UNorm:
+ return GL_COMPRESSED_RED_RGTC1;
+ case NVRenderTextureFormats::R_ATI1N_SNorm:
+ return GL_COMPRESSED_SIGNED_RED_RGTC1;
+ case NVRenderTextureFormats::RG_ATI2N_UNorm:
+ return GL_COMPRESSED_RG_RGTC2;
+ case NVRenderTextureFormats::RG_ATI2N_SNorm:
+ return GL_COMPRESSED_SIGNED_RG_RGTC2;
+ case NVRenderTextureFormats::RGB_BP_UNSIGNED_FLOAT:
+ return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB;
+ case NVRenderTextureFormats::RGB_BP_SIGNED_FLOAT:
+ return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB;
+ case NVRenderTextureFormats::RGB_BP_UNorm:
+ return GL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
+ case NVRenderTextureFormats::R11_EAC_UNorm:
+ return GL_COMPRESSED_R11_EAC;
+ case NVRenderTextureFormats::R11_EAC_SNorm:
+ return GL_COMPRESSED_SIGNED_R11_EAC;
+ case NVRenderTextureFormats::RG11_EAC_UNorm:
+ return GL_COMPRESSED_RG11_EAC;
+ case NVRenderTextureFormats::RG11_EAC_SNorm:
+ return GL_COMPRESSED_SIGNED_RG11_EAC;
+ case NVRenderTextureFormats::RGB8_ETC2:
+ return GL_COMPRESSED_RGB8_ETC2;
+ case NVRenderTextureFormats::SRGB8_ETC2:
+ return GL_COMPRESSED_SRGB8_ETC2;
+ case NVRenderTextureFormats::RGB8_PunchThrough_Alpha1_ETC2:
+ return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case NVRenderTextureFormats::SRGB8_PunchThrough_Alpha1_ETC2:
+ return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ case NVRenderTextureFormats::RGBA8_ETC2_EAC:
+ return GL_COMPRESSED_RGBA8_ETC2_EAC;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ETC2_EAC:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
+ case NVRenderTextureFormats::RGB8_ETC1:
+ return GL_ETC1_RGB8_OES;
+#ifdef GL_KHR_texture_compression_astc_hdr
+ case NVRenderTextureFormats::RGBA_ASTC_4x4:
+ return GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_5x4:
+ return GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_5x5:
+ return GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_6x5:
+ return GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_6x6:
+ return GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_8x5:
+ return GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_8x6:
+ return GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_8x8:
+ return GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_10x5:
+ return GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_10x6:
+ return GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_10x8:
+ return GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_10x10:
+ return GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_12x10:
+ return GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
+ case NVRenderTextureFormats::RGBA_ASTC_12x12:
+ return GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_4x4:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x4:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_5x5:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x5:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_6x6:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x5:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x6:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_8x8:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x5:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x6:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x8:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_10x10:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x10:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
+ case NVRenderTextureFormats::SRGB8_Alpha8_ASTC_12x12:
+ return GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
+#endif // GL_KHR_texture_compression_astc_hdr
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static bool fromDepthTextureFormatToGL(NVRenderContextType type,
+ NVRenderTextureFormats::Enum value,
+ GLenum &outFormat, GLenum &outDataType,
+ GLenum &outInternalFormat)
+ {
+ NVRenderContextType theContextFlags(NVRenderContextValues::GLES2
+ | NVRenderContextValues::GL2);
+
+ bool supportDepth24 = !(type & theContextFlags);
+ bool supportDepth32f = !(type & theContextFlags);
+ bool supportDepth24Stencil8 = !(type & theContextFlags);
+
+ switch (value) {
+ case NVRenderTextureFormats::Depth16:
+ outFormat = GL_DEPTH_COMPONENT;
+ outInternalFormat = GL_DEPTH_COMPONENT16;
+ outDataType = GL_UNSIGNED_SHORT;
+ return true;
+ case NVRenderTextureFormats::Depth24:
+ outFormat = GL_DEPTH_COMPONENT;
+ outInternalFormat = (supportDepth24) ? GL_DEPTH_COMPONENT24 : GL_DEPTH_COMPONENT16;
+ outDataType = (supportDepth24) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+ return true;
+ case NVRenderTextureFormats::Depth32:
+ outFormat = GL_DEPTH_COMPONENT;
+ outInternalFormat =
+ (supportDepth32f) ? GL_DEPTH_COMPONENT32F : GL_DEPTH_COMPONENT16;
+ outDataType = (supportDepth32f) ? GL_FLOAT : GL_UNSIGNED_SHORT;
+ return true;
+ case NVRenderTextureFormats::Depth24Stencil8:
+ outFormat = (supportDepth24Stencil8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT;
+ outInternalFormat =
+ (supportDepth24Stencil8) ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16;
+ outDataType = (supportDepth24Stencil8) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_SHORT;
+ return true;
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ static GLenum fromTextureTargetToGL(NVRenderTextureTargetType::Enum value)
+ {
+ GLenum retval = 0;
+ if (value == NVRenderTextureTargetType::Texture2D)
+ retval = GL_TEXTURE_2D;
+ else if (value == NVRenderTextureTargetType::Texture2D_MS)
+ retval = GL_TEXTURE_2D_MULTISAMPLE;
+ else if (value == NVRenderTextureTargetType::Texture2D_Array)
+ retval = GL_TEXTURE_2D_ARRAY;
+ else if (value == NVRenderTextureTargetType::TextureCube)
+ retval = GL_TEXTURE_CUBE_MAP;
+ else if (value == NVRenderTextureTargetType::TextureCubeNegX)
+ retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+ else if (value == NVRenderTextureTargetType::TextureCubePosX)
+ retval = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ else if (value == NVRenderTextureTargetType::TextureCubeNegY)
+ retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ else if (value == NVRenderTextureTargetType::TextureCubePosY)
+ retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+ else if (value == NVRenderTextureTargetType::TextureCubeNegZ)
+ retval = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+ else if (value == NVRenderTextureTargetType::TextureCubePosZ)
+ retval = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+ else
+ QT3DS_ASSERT(false);
+
+ return retval;
+ }
+
+ static NVRenderTextureTargetType::Enum fromGLToTextureTarget(GLenum value)
+ {
+ NVRenderTextureTargetType::Enum retval = NVRenderTextureTargetType::Unknown;
+
+ if (value == GL_TEXTURE_2D)
+ retval = NVRenderTextureTargetType::Texture2D;
+ else if (value == GL_TEXTURE_2D_MULTISAMPLE)
+ retval = NVRenderTextureTargetType::Texture2D_MS;
+ else
+ QT3DS_ASSERT(false);
+
+ return retval;
+ }
+
+ static GLenum fromTextureUnitToGL(NVRenderTextureUnit::Enum value)
+ {
+ QT3DSU32 v = value;
+ GLenum retval = GL_TEXTURE0;
+ retval = GL_TEXTURE0 + v;
+
+ return retval;
+ }
+
+ static GLenum fromGLToTextureUnit(GLenum value)
+ {
+ QT3DS_ASSERT(value > GL_TEXTURE0);
+
+ QT3DSU32 v = value - GL_TEXTURE0;
+ NVRenderTextureUnit::Enum retval =
+ NVRenderTextureUnit::Enum(NVRenderTextureUnit::TextureUnit_0 + v);
+
+ return retval;
+ }
+
+ static GLenum fromTextureMinifyingOpToGL(NVRenderTextureMinifyingOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \
+ case NVRenderTextureMinifyingOp::y: \
+ return x;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \
+ case NVRenderTextureMinifyingOp::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderTextureMinifyingOp::Enum fromGLToTextureMinifyingOp(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \
+ case x: \
+ return NVRenderTextureMinifyingOp::y;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y) \
+ case x: \
+ return NVRenderTextureMinifyingOp::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderTextureMinifyingOp::Unknown;
+ }
+
+ static GLenum fromTextureMagnifyingOpToGL(NVRenderTextureMagnifyingOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \
+ case NVRenderTextureMagnifyingOp::y: \
+ return x;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y)
+ QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderTextureMagnifyingOp::Enum fromGLToTextureMagnifyingOp(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP(x, y) \
+ case x: \
+ return NVRenderTextureMagnifyingOp::y;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP(x, y)
+ QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_SCALE_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_MINIFYING_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderTextureMagnifyingOp::Unknown;
+ }
+
+ static GLenum fromTextureCoordOpToGL(NVRenderTextureCoordOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \
+ case NVRenderTextureCoordOp::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderTextureCoordOp::Enum fromGLToTextureCoordOp(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP(x, y) \
+ case x: \
+ return NVRenderTextureCoordOp::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_TEXTURE_WRAP_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_TEXTURE_WRAP_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderTextureCoordOp::Unknown;
+ }
+
+ static GLenum fromTextureCompareModeToGL(NVRenderTextureCompareMode::Enum value)
+ {
+ switch (value) {
+ case NVRenderTextureCompareMode::NoCompare:
+ return GL_NONE;
+ case NVRenderTextureCompareMode::CompareToRef:
+ return GL_COMPARE_REF_TO_TEXTURE;
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return NVRenderTextureCompareMode::Unknown;
+ }
+
+ static GLenum fromGLToTextureCompareMode(GLenum value)
+ {
+ switch (value) {
+ case GL_NONE:
+ return NVRenderTextureCompareMode::NoCompare;
+ case GL_COMPARE_REF_TO_TEXTURE:
+ return NVRenderTextureCompareMode::CompareToRef;
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return GL_INVALID_ENUM;
+ }
+
+ static GLenum fromTextureCompareFuncToGL(NVRenderTextureCompareOp::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP(x, y) \
+ case NVRenderTextureCompareOp::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_BOOL_OP
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_BOOL_OP
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static GLenum fromImageFormatToGL(NVRenderTextureFormats::Enum value)
+ {
+ switch (value) {
+ case NVRenderTextureFormats::R8:
+ return GL_R8;
+ case NVRenderTextureFormats::R32I:
+ return GL_R32I;
+ case NVRenderTextureFormats::R32UI:
+ return GL_R32UI;
+ case NVRenderTextureFormats::R32F:
+ return GL_R32F;
+ case NVRenderTextureFormats::RGBA8:
+ return GL_RGBA8;
+ case NVRenderTextureFormats::SRGB8A8:
+ return GL_RGBA8_SNORM;
+ case NVRenderTextureFormats::RG16F:
+ return GL_RG16F;
+ case NVRenderTextureFormats::RGBA16F:
+ return GL_RGBA16F;
+ case NVRenderTextureFormats::RGBA32F:
+ return GL_RGBA32F;
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return GL_INVALID_ENUM;
+ }
+
+
+ static GLenum fromImageAccessToGL(NVRenderImageAccessType::Enum value)
+ {
+ switch (value) {
+ case NVRenderImageAccessType::Read:
+ return GL_READ_ONLY;
+ case NVRenderImageAccessType::Write:
+ return GL_WRITE_ONLY;
+ case NVRenderImageAccessType::ReadWrite:
+ return GL_READ_WRITE;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return GL_INVALID_ENUM;
+ }
+
+ static GLbitfield fromBufferAccessBitToGL(NVRenderBufferAccessFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLbitfield retval = 0;
+
+ if (value & NVRenderBufferAccessTypeValues::Read)
+ retval |= GL_MAP_READ_BIT;
+ if (value & NVRenderBufferAccessTypeValues::Write)
+ retval |= GL_MAP_WRITE_BIT;
+ if (value & NVRenderBufferAccessTypeValues::Invalid)
+ retval |= GL_MAP_INVALIDATE_BUFFER_BIT;
+ if (value & NVRenderBufferAccessTypeValues::InvalidRange)
+ retval |= GL_MAP_INVALIDATE_RANGE_BIT;
+
+ QT3DS_ASSERT(retval);
+ return retval;
+ }
+
+ static GLbitfield fromMemoryBarrierFlagsToGL(NVRenderBufferBarrierFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLbitfield retval = 0;
+#if !defined(QT_OPENGL_ES)
+ if (value & NVRenderBufferBarrierValues::AtomicCounter)
+ retval |= GL_ATOMIC_COUNTER_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::BufferUpdate)
+ retval |= GL_BUFFER_UPDATE_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::CommandBuffer)
+ retval |= GL_COMMAND_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::ElementArray)
+ retval |= GL_ELEMENT_ARRAY_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::Framebuffer)
+ retval |= GL_FRAMEBUFFER_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::PixelBuffer)
+ retval |= GL_PIXEL_BUFFER_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::ShaderImageAccess)
+ retval |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::ShaderStorage)
+ retval |= GL_SHADER_STORAGE_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::TextureFetch)
+ retval |= GL_TEXTURE_FETCH_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::TextureUpdate)
+ retval |= GL_TEXTURE_UPDATE_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::TransformFeedback)
+ retval |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::UniformBuffer)
+ retval |= GL_UNIFORM_BARRIER_BIT;
+ if (value & NVRenderBufferBarrierValues::VertexAttribArray)
+ retval |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
+#endif
+ QT3DS_ASSERT(retval);
+ return retval;
+ }
+
+ static GLbitfield fromShaderTypeFlagsToGL(NVRenderShaderTypeFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLbitfield retval = 0;
+ if (value & NVRenderShaderTypeValue::Vertex)
+ retval |= GL_VERTEX_SHADER_BIT;
+ if (value & NVRenderShaderTypeValue::Fragment)
+ retval |= GL_FRAGMENT_SHADER_BIT;
+ if (value & NVRenderShaderTypeValue::TessControl)
+ retval |= GL_TESS_CONTROL_SHADER_BIT;
+ if (value & NVRenderShaderTypeValue::TessEvaluation)
+ retval |= GL_TESS_EVALUATION_SHADER_BIT;
+ if (value & NVRenderShaderTypeValue::Geometry)
+#if defined(QT_OPENGL_ES_3_1)
+ retval |= GL_GEOMETRY_SHADER_BIT_EXT;
+#else
+ retval |= GL_GEOMETRY_SHADER_BIT;
+#endif
+ QT3DS_ASSERT(retval || !value);
+ return retval;
+ }
+
+ static GLenum fromPropertyDataTypesToShaderGL(NVRenderShaderDataTypes::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \
+ case NVRenderShaderDataTypes::nv: \
+ return gl;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderShaderDataTypes::Enum fromShaderGLToPropertyDataTypes(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES(gl, nv) \
+ case gl: \
+ return NVRenderShaderDataTypes::nv;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_UNIFORM_TYPES
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_UNIFORM_TYPES
+ case GL_SAMPLER_2D_SHADOW:
+ return NVRenderShaderDataTypes::NVRenderTexture2DPtr;
+#if !defined(QT_OPENGL_ES)
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ return NVRenderShaderDataTypes::QT3DSU32;
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ return NVRenderShaderDataTypes::NVRenderImage2DPtr;
+#endif
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderShaderDataTypes::Unknown;
+ }
+
+ static GLenum fromComponentTypeAndNumCompsToAttribGL(NVRenderComponentTypes::Enum compType,
+ QT3DSU32 numComps)
+ {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \
+ if (compType == NVRenderComponentTypes::ct && numComps == nc) \
+ return gl;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static void fromAttribGLToComponentTypeAndNumComps(
+ GLenum enumVal, NVRenderComponentTypes::Enum &outCompType, QT3DSU32 &outNumComps)
+ {
+ switch (enumVal) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES(gl, ct, nc) \
+ case gl: \
+ outCompType = NVRenderComponentTypes::ct; \
+ outNumComps = nc; \
+ return;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_SHADER_ATTRIB_TYPES
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_SHADER_ATTRIB_TYPES
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ outCompType = NVRenderComponentTypes::Unknown;
+ outNumComps = 0;
+ }
+
+ static GLenum
+ fromRenderBufferFormatsToRenderBufferGL(NVRenderRenderBufferFormats::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \
+ case NVRenderRenderBufferFormats::nv: \
+ return gl;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderRenderBufferFormats::Enum
+ fromRenderBufferGLToRenderBufferFormats(GLenum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT(gl, nv) \
+ case gl: \
+ return NVRenderRenderBufferFormats::nv;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_FORMATS
+ QT3DS_RENDER_ITERATE_GL_QT3DS_RENDERBUFFER_COVERAGE_FORMATS
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_RENDERBUFFER_FORMAT
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderRenderBufferFormats::Unknown;
+ }
+
+ static GLenum fromFramebufferAttachmentsToGL(NVRenderFrameBufferAttachments::Enum value)
+ {
+ switch (value) {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \
+ case NVRenderFrameBufferAttachments::x: \
+ return GL_COLOR_ATTACHMENT0 + idx;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \
+ case NVRenderFrameBufferAttachments::y: \
+ return x;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS
+ QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderFrameBufferAttachments::Unknown;
+ }
+
+ static NVRenderFrameBufferAttachments::Enum fromGLToFramebufferAttachments(GLenum value)
+ {
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT(x, idx) \
+ if (value == GL_COLOR_ATTACHMENT0 + idx) \
+ return NVRenderFrameBufferAttachments::x;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT(x, y) \
+ if (value == x) \
+ return NVRenderFrameBufferAttachments::y;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_ATTACHMENTS
+ QT3DS_RENDER_ITERATE_GL_QT3DS_FRAMEBUFFER_COVERAGE_ATTACHMENTS
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_COLOR_ATTACHMENT
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_FRAMEBUFFER_ATTACHMENT
+ QT3DS_ASSERT(false);
+ return NVRenderFrameBufferAttachments::Unknown;
+ }
+
+ static GLbitfield fromClearFlagsToGL(NVRenderClearFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLbitfield retval = 0;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \
+ if ((value & NVRenderClearValues::nv)) \
+ retval |= gl;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS
+ QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS
+ return retval;
+ }
+
+ static NVRenderClearFlags fromGLToClearFlags(GLbitfield value)
+ {
+ QT3DSU32 retval = 0;
+#define QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS(gl, nv) \
+ if ((value & gl)) \
+ retval |= NVRenderClearValues::nv;
+ QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_FLAGS
+ QT3DS_RENDER_ITERATE_GL_QT3DS_CLEAR_COVERAGE_FLAGS
+#undef QT3DS_RENDER_HANDLE_GL_QT3DS_CLEAR_FLAGS
+ return NVRenderClearFlags(retval);
+ }
+
+ static GLenum fromDrawModeToGL(NVRenderDrawMode::Enum value, bool inTesselationSupported)
+ {
+ switch (value) {
+ case NVRenderDrawMode::Points:
+ return GL_POINTS;
+ case NVRenderDrawMode::Lines:
+ return GL_LINES;
+ case NVRenderDrawMode::LineStrip:
+ return GL_LINE_STRIP;
+ case NVRenderDrawMode::LineLoop:
+ return GL_LINE_LOOP;
+ case NVRenderDrawMode::TriangleStrip:
+ return GL_TRIANGLE_STRIP;
+ case NVRenderDrawMode::TriangleFan:
+ return GL_TRIANGLE_FAN;
+ case NVRenderDrawMode::Triangles:
+ return GL_TRIANGLES;
+ case NVRenderDrawMode::Patches:
+ return (inTesselationSupported) ? GL_PATCHES : GL_TRIANGLES;
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return GL_INVALID_ENUM;
+ }
+
+ static NVRenderDrawMode::Enum fromGLToDrawMode(GLenum value)
+ {
+ switch (value) {
+ case GL_POINTS:
+ return NVRenderDrawMode::Points;
+ case GL_LINES:
+ return NVRenderDrawMode::Lines;
+ case GL_LINE_STRIP:
+ return NVRenderDrawMode::LineStrip;
+ case GL_LINE_LOOP:
+ return NVRenderDrawMode::LineLoop;
+ case GL_TRIANGLE_STRIP:
+ return NVRenderDrawMode::TriangleStrip;
+ case GL_TRIANGLE_FAN:
+ return NVRenderDrawMode::TriangleFan;
+ case GL_TRIANGLES:
+ return NVRenderDrawMode::Triangles;
+ case GL_PATCHES:
+ return NVRenderDrawMode::Patches;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderDrawMode::Unknown;
+ }
+
+ static GLenum fromRenderStateToGL(NVRenderState::Enum value)
+ {
+ switch (value) {
+ case NVRenderState::Blend:
+ return GL_BLEND;
+ case NVRenderState::CullFace:
+ return GL_CULL_FACE;
+ case NVRenderState::DepthTest:
+ return GL_DEPTH_TEST;
+ case NVRenderState::Multisample:
+#if defined(QT_OPENGL_ES)
+ return GL_MULTISAMPLE_EXT;
+#else
+ return GL_MULTISAMPLE;
+#endif
+ case NVRenderState::StencilTest:
+ return GL_STENCIL_TEST;
+ case NVRenderState::ScissorTest:
+ return GL_SCISSOR_TEST;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ static NVRenderState::Enum fromGLToRenderState(GLenum value)
+ {
+ switch (value) {
+ case GL_BLEND:
+ return NVRenderState::Blend;
+ case GL_CULL_FACE:
+ return NVRenderState::CullFace;
+ case GL_DEPTH_TEST:
+ return NVRenderState::DepthTest;
+#if defined(QT_OPENGL_ES)
+ case GL_MULTISAMPLE_EXT:
+#else
+ case GL_MULTISAMPLE:
+#endif
+ return NVRenderState::Multisample;
+ case GL_STENCIL_TEST:
+ return NVRenderState::StencilTest;
+ case GL_SCISSOR_TEST:
+ return NVRenderState::ScissorTest;
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return NVRenderState::Unknown;
+ }
+
+ static bool fromReadPixelsToGlFormatAndType(NVRenderReadPixelFormats::Enum inReadPixels,
+ GLuint *outFormat, GLuint *outType)
+ {
+ switch (inReadPixels) {
+ case NVRenderReadPixelFormats::Alpha8:
+ *outFormat = GL_ALPHA;
+ *outType = GL_UNSIGNED_BYTE;
+ break;
+ case NVRenderReadPixelFormats::RGB565:
+ *outFormat = GL_RGB;
+ *outType = GL_UNSIGNED_SHORT_5_6_5;
+ case NVRenderReadPixelFormats::RGB8:
+ *outFormat = GL_RGB;
+ *outType = GL_UNSIGNED_BYTE;
+ break;
+ case NVRenderReadPixelFormats::RGBA4444:
+ *outFormat = GL_RGBA;
+ *outType = GL_UNSIGNED_SHORT_4_4_4_4;
+ break;
+ case NVRenderReadPixelFormats::RGBA5551:
+ *outFormat = GL_RGBA;
+ *outType = GL_UNSIGNED_SHORT_5_5_5_1;
+ break;
+ case NVRenderReadPixelFormats::RGBA8:
+ *outFormat = GL_RGBA;
+ *outType = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ *outFormat = 0;
+ *outType = 0;
+ QT3DS_ASSERT(false);
+ return false;
+ };
+
+ return true;
+ }
+
+ static GLenum fromPathFillModeToGL(NVRenderPathFillMode::Enum inMode)
+ {
+ GLenum glFillMode;
+
+ switch (inMode) {
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathFillMode::Fill:
+ glFillMode = GL_PATH_FILL_MODE_NV;
+ break;
+ case NVRenderPathFillMode::CountUp:
+ glFillMode = GL_COUNT_UP_NV;
+ break;
+ case NVRenderPathFillMode::CountDown:
+ glFillMode = GL_COUNT_DOWN_NV;
+ break;
+ case NVRenderPathFillMode::Invert:
+ glFillMode = GL_INVERT;
+ break;
+#endif
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+
+ return glFillMode;
+ }
+
+ static GLenum fromPathFontTargetToGL(NVRenderPathFontTarget::Enum inFontTarget)
+ {
+ GLenum glFontTarget;
+
+ switch (inFontTarget) {
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathFontTarget::StandardFont:
+ glFontTarget = GL_STANDARD_FONT_NAME_NV;
+ break;
+ case NVRenderPathFontTarget::SystemFont:
+ glFontTarget = GL_SYSTEM_FONT_NAME_NV;
+ break;
+ case NVRenderPathFontTarget::FileFont:
+ glFontTarget = GL_FILE_NAME_NV;
+ break;
+#endif
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+
+ return glFontTarget;
+ }
+
+ static NVRenderPathReturnValues::Enum fromGLToPathFontReturn(GLenum inReturnValue)
+ {
+ NVRenderPathReturnValues::Enum returnValue;
+
+ switch (inReturnValue) {
+#if !defined(QT_OPENGL_ES)
+ case GL_FONT_GLYPHS_AVAILABLE_NV:
+ returnValue = NVRenderPathReturnValues::FontGlypsAvailable;
+ break;
+ case GL_FONT_TARGET_UNAVAILABLE_NV:
+ returnValue = NVRenderPathReturnValues::FontTargetUnavailable;
+ break;
+ case GL_FONT_UNAVAILABLE_NV:
+ returnValue = NVRenderPathReturnValues::FontUnavailable;
+ break;
+ case GL_FONT_UNINTELLIGIBLE_NV:
+ returnValue = NVRenderPathReturnValues::FontUnintelligible;
+ break;
+#endif
+ case GL_INVALID_ENUM:
+ case GL_INVALID_VALUE:
+ returnValue = NVRenderPathReturnValues::InvalidEnum;
+ break;
+ case GL_OUT_OF_MEMORY:
+ returnValue = NVRenderPathReturnValues::OutOfMemory;
+ break;
+ default:
+ QT3DS_ASSERT(false);
+ returnValue = NVRenderPathReturnValues::FontTargetUnavailable;
+ break;
+ }
+
+ return returnValue;
+ }
+
+ static GLenum fromPathMissingGlyphsToGL(NVRenderPathMissingGlyphs::Enum inHandleGlyphs)
+ {
+ GLenum glMissingGlyphs;
+
+ switch (inHandleGlyphs) {
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathMissingGlyphs::SkipMissing:
+ glMissingGlyphs = GL_SKIP_MISSING_GLYPH_NV;
+ break;
+ case NVRenderPathMissingGlyphs::UseMissing:
+ glMissingGlyphs = GL_USE_MISSING_GLYPH_NV;
+ break;
+#endif
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+
+ return glMissingGlyphs;
+ }
+
+ static GLenum fromPathListModeToGL(NVRenderPathListMode::Enum inListMode)
+ {
+ GLenum glListMode;
+
+ switch (inListMode) {
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathListMode::AccumAdjacentPairs:
+ glListMode = GL_ACCUM_ADJACENT_PAIRS_NV;
+ break;
+ case NVRenderPathListMode::AdjacentPairs:
+ glListMode = GL_ADJACENT_PAIRS_NV;
+ break;
+ case NVRenderPathListMode::FirstToRest:
+ glListMode = GL_FIRST_TO_REST_NV;
+ break;
+#endif
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+
+ return glListMode;
+ }
+
+ static GLenum fromPathCoverModeToGL(NVRenderPathCoverMode::Enum inMode)
+ {
+ GLenum glCoverMode;
+
+ switch (inMode) {
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathCoverMode::ConvexHull:
+ glCoverMode = GL_CONVEX_HULL_NV;
+ break;
+ case NVRenderPathCoverMode::BoundingBox:
+ glCoverMode = GL_BOUNDING_BOX_NV;
+ break;
+ case NVRenderPathCoverMode::BoundingBoxOfBoundingBox:
+ glCoverMode = GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV;
+ break;
+ case NVRenderPathCoverMode::PathFillCover:
+ glCoverMode = GL_PATH_FILL_COVER_MODE_NV;
+ break;
+ case NVRenderPathCoverMode::PathStrokeCover:
+ glCoverMode = GL_PATH_STROKE_COVER_MODE_NV;
+ break;
+#endif
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+
+ return glCoverMode;
+ }
+
+ static GLenum fromPathTypeToGL(NVRenderPathFormatType::Enum value)
+ {
+ switch (value) {
+ case NVRenderPathFormatType::Byte:
+ return GL_BYTE;
+ case NVRenderPathFormatType::UByte:
+ return GL_UNSIGNED_BYTE;
+ case NVRenderPathFormatType::Short:
+ return GL_SHORT;
+ case NVRenderPathFormatType::UShort:
+ return GL_UNSIGNED_SHORT;
+ case NVRenderPathFormatType::Int:
+ return GL_INT;
+ case NVRenderPathFormatType::Uint:
+ return GL_UNSIGNED_INT;
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathFormatType::Bytes2:
+ return GL_2_BYTES_NV;
+ case NVRenderPathFormatType::Bytes3:
+ return GL_3_BYTES_NV;
+ case NVRenderPathFormatType::Bytes4:
+ return GL_4_BYTES_NV;
+ case NVRenderPathFormatType::Utf8:
+ return GL_UTF8_NV;
+ case NVRenderPathFormatType::Utf16:
+ return GL_UTF16_NV;
+#endif
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return GL_UNSIGNED_BYTE;
+ }
+
+ static GLbitfield fromPathFontStyleToGL(NVRenderPathFontStyleFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLbitfield retval = 0;
+#if !defined(QT_OPENGL_ES)
+ if (value & NVRenderPathFontStyleValues::Bold)
+ retval |= GL_BOLD_BIT_NV;
+ if (value & NVRenderPathFontStyleValues::Italic)
+ retval |= GL_ITALIC_BIT_NV;
+#endif
+ QT3DS_ASSERT(retval || !value);
+ return retval;
+ }
+
+ static GLenum fromPathTransformToGL(NVRenderPathTransformType::Enum value)
+ {
+ switch (value) {
+ case NVRenderPathTransformType::NoTransform:
+ return GL_NONE;
+#if !defined(QT_OPENGL_ES)
+ case NVRenderPathTransformType::TranslateX:
+ return GL_TRANSLATE_X_NV;
+ case NVRenderPathTransformType::TranslateY:
+ return GL_TRANSLATE_Y_NV;
+ case NVRenderPathTransformType::Translate2D:
+ return GL_TRANSLATE_2D_NV;
+ case NVRenderPathTransformType::Translate3D:
+ return GL_TRANSLATE_3D_NV;
+ case NVRenderPathTransformType::Affine2D:
+ return GL_AFFINE_2D_NV;
+ case NVRenderPathTransformType::Affine3D:
+ return GL_AFFINE_3D_NV;
+ case NVRenderPathTransformType::TransposeAffine2D:
+ return GL_TRANSPOSE_AFFINE_2D_NV;
+ case NVRenderPathTransformType::TransposeAffine3D:
+ return GL_TRANSPOSE_AFFINE_3D_NV;
+#endif
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return GL_UNSIGNED_BYTE;
+ }
+
+ static GLbitfield fromPathMetricQueryFlagsToGL(NVRenderPathGlyphFontMetricFlags flags)
+ {
+ QT3DSU32 value = flags;
+ GLbitfield retval = 0;
+#if !defined(QT_OPENGL_ES)
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphWidth)
+ retval |= GL_GLYPH_WIDTH_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphHeight)
+ retval |= GL_GLYPH_HEIGHT_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingX)
+ retval |= GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingY)
+ retval |= GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphHorizontalBearingAdvance)
+ retval |= GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingX)
+ retval |= GL_GLYPH_VERTICAL_BEARING_X_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingY)
+ retval |= GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphVerticalBearingAdvance)
+ retval |= GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::GlyphHasKerning)
+ retval |= GL_GLYPH_HAS_KERNING_BIT_NV;
+
+ if (value & NVRenderPathGlyphFontMetricValues::FontXMinBounds)
+ retval |= GL_FONT_X_MIN_BOUNDS_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontYMinBounds)
+ retval |= GL_FONT_Y_MIN_BOUNDS_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontXMaxBounds)
+ retval |= GL_FONT_X_MAX_BOUNDS_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontYMaxBounds)
+ retval |= GL_FONT_Y_MAX_BOUNDS_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontUnitsPerEm)
+ retval |= GL_FONT_UNITS_PER_EM_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontAscender)
+ retval |= GL_FONT_ASCENDER_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontDescender)
+ retval |= GL_FONT_DESCENDER_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontHeight)
+ retval |= GL_FONT_HEIGHT_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth)
+ retval |= GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceHeight)
+ retval |= GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontUnderlinePosition)
+ retval |= GL_FONT_UNDERLINE_POSITION_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontMaxAdvanceWidth)
+ retval |= GL_FONT_UNDERLINE_THICKNESS_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontHasKerning)
+ retval |= GL_FONT_HAS_KERNING_BIT_NV;
+ if (value & NVRenderPathGlyphFontMetricValues::FontNumGlyphIndices)
+ retval |= GL_FONT_NUM_GLYPH_INDICES_BIT_NV;
+#endif
+ QT3DS_ASSERT(retval || !value);
+ return retval;
+ }
+ };
+}
+}
+
+#endif // QT3DSOPENGLUTIL_H
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp
new file mode 100644
index 00000000..d78c51d9
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.cpp
@@ -0,0 +1,784 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/backends/gl/Qt3DSRenderBackendGL3.h"
+#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h"
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__)
+#else
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError()
+#endif
+
+#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x);
+
+#if defined(QT_OPENGL_ES)
+#define GL_CALL_TIMER_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#else
+#define GL_CALL_TIMER_EXT(x) m_timerExtension->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_TESSELATION_EXT(x) m_tessellationShader->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_MULTISAMPLE_EXT(x) m_multiSample->x; RENDER_LOG_ERROR_PARAMS(x);
+#endif
+
+namespace qt3ds {
+namespace render {
+
+#ifndef GL_PATCH_VERTICES
+#define GL_PATCH_VERTICES 0x8E72
+#endif
+
+ /// constructor
+ NVRenderBackendGL3Impl::NVRenderBackendGL3Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format)
+ : NVRenderBackendGLBase(fnd, stringTable, format)
+ {
+ eastl::string exts3tc("GL_EXT_texture_compression_s3tc");
+ eastl::string extsdxt("GL_EXT_texture_compression_dxt1");
+ eastl::string extsAniso("GL_EXT_texture_filter_anisotropic");
+ eastl::string extsTexSwizzle("GL_ARB_texture_swizzle");
+ eastl::string extsAstcHDR("GL_KHR_texture_compression_astc_hdr");
+ eastl::string extsAstcLDR("GL_KHR_texture_compression_astc_ldr");
+ eastl::string extsFPRenderTarget("GL_EXT_color_buffer_float");
+ eastl::string extsTimerQuery("GL_EXT_timer_query");
+ eastl::string extsGpuShader5("EXT_gpu_shader5");
+
+ const char *languageVersion = GetShadingLanguageVersion();
+ qCInfo(TRACE_INFO, "GLSL version: %s", languageVersion);
+
+ eastl::string apiVersion(getVersionString());
+ qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str());
+
+ eastl::string apiVendor(getVendorString());
+ qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str());
+
+ eastl::string apiRenderer(getRendererString());
+ qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str());
+
+ // clear support bits
+ m_backendSupport.caps.u32Values = 0;
+
+ // get extension count
+ GLint numExtensions = 0;
+ GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions));
+
+ eastl::string extensionBuffer;
+
+ for (QT3DSI32 i = 0; i < numExtensions; i++) {
+ char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i));
+
+ m_extensions.push_back(QString::fromLocal8Bit(extensionString));
+
+ if (extensionBuffer.size())
+ extensionBuffer.append(" ");
+ extensionBuffer.append(extensionString);
+
+ // search for extension
+ if (!m_backendSupport.caps.bits.bDXTImagesSupported
+ && (exts3tc.compare(extensionString) == 0 || extsdxt.compare(extensionString) == 0)) {
+ m_backendSupport.caps.bits.bDXTImagesSupported = true;
+ } else if (!m_backendSupport.caps.bits.bAnistropySupported
+ && extsAniso.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bAnistropySupported = true;
+ } else if (!m_backendSupport.caps.bits.bFPRenderTargetsSupported
+ && extsFPRenderTarget.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bFPRenderTargetsSupported = true;
+ } else if (!m_backendSupport.caps.bits.bTimerQuerySupported
+ && extsTimerQuery.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bTimerQuerySupported = true;
+ } else if (!m_backendSupport.caps.bits.bGPUShader5ExtensionSupported
+ && extsGpuShader5.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bGPUShader5ExtensionSupported = true;
+ }
+
+ }
+
+ qCInfo(TRACE_INFO, "OpenGL extensions: %s", extensionBuffer.c_str());
+
+ // texture swizzle is always true
+ m_backendSupport.caps.bits.bTextureSwizzleSupported = true;
+ // depthstencil renderbuffer support is always true
+ m_backendSupport.caps.bits.bDepthStencilSupported = true;
+ // constant buffers support is always true
+ m_backendSupport.caps.bits.bConstantBufferSupported = true;
+ m_backendSupport.caps.bits.bStandardDerivativesSupported = true;
+ m_backendSupport.caps.bits.bVertexArrayObjectSupported = true;
+ m_backendSupport.caps.bits.bTextureLodSupported = true;
+
+ if (!isESCompatible()) {
+ // render to float textures is always supported on none ES systems which support >=GL3
+ m_backendSupport.caps.bits.bFPRenderTargetsSupported = true;
+ // multisampled texture is always supported on none ES systems which support >=GL3
+ m_backendSupport.caps.bits.bMsTextureSupported = true;
+ // timer queries are always supported on none ES systems which support >=GL3
+ m_backendSupport.caps.bits.bTimerQuerySupported = true;
+ }
+
+ // query hardware
+ GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_MaxAttribCount));
+
+ // internal state tracker
+ m_pCurrentMiscState = QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendMiscStateGL)();
+
+ // finally setup caps based on device
+ setAndInspectHardwareCaps();
+
+ // Initialize extensions
+#if defined(QT_OPENGL_ES_2)
+ m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions;
+ m_qt3dsExtensions->initializeOpenGLFunctions();
+#else
+ m_timerExtension = new QOpenGLExtension_ARB_timer_query;
+ m_timerExtension->initializeOpenGLFunctions();
+ m_tessellationShader = new QOpenGLExtension_ARB_tessellation_shader;
+ m_tessellationShader->initializeOpenGLFunctions();
+ m_multiSample = new QOpenGLExtension_ARB_texture_multisample;
+ m_multiSample->initializeOpenGLFunctions();
+ m_qt3dsExtensions = new Qt3DSOpenGLExtensions;
+ m_qt3dsExtensions->initializeOpenGLFunctions();
+#endif
+ }
+ /// destructor
+ NVRenderBackendGL3Impl::~NVRenderBackendGL3Impl()
+ {
+ if (m_pCurrentMiscState)
+ NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState);
+#if !defined(QT_OPENGL_ES_2)
+ if (m_timerExtension)
+ delete m_timerExtension;
+ if (m_tessellationShader)
+ delete m_tessellationShader;
+ if (m_multiSample)
+ delete m_multiSample;
+#endif
+ if (m_qt3dsExtensions)
+ delete m_qt3dsExtensions;
+ }
+
+ void NVRenderBackendGL3Impl::SetMultisampledTextureData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height,
+ bool fixedsamplelocations)
+ {
+// Not supported by ES 3 yet
+#if defined(QT_OPENGL_ES)
+ NVRENDER_BACKEND_UNUSED(to);
+ NVRENDER_BACKEND_UNUSED(target);
+ NVRENDER_BACKEND_UNUSED(samples);
+ NVRENDER_BACKEND_UNUSED(internalFormat);
+ NVRENDER_BACKEND_UNUSED(width);
+ NVRENDER_BACKEND_UNUSED(height);
+ NVRENDER_BACKEND_UNUSED(fixedsamplelocations);
+#else
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat))
+ GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+ else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat))
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+
+ GL_CALL_MULTISAMPLE_EXT(glTexImage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat,
+ (GLsizei)width, (GLsizei)height, fixedsamplelocations));
+
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+#endif
+ }
+
+ void NVRenderBackendGL3Impl::SetTextureData3D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, size_t depth,
+ QT3DSI32 border, NVRenderTextureFormats::Enum format, const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+ bool conversionRequired = format != internalFormat;
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat))
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+
+ if (conversionRequired) {
+ GLenum dummy;
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, dummy);
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ } else if (NVRenderTextureFormats::isDepthTextureFormat(format))
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+
+ GL_CALL_EXTRA_FUNCTION(glTexImage3D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height,
+ (GLsizei)depth, border, glformat, gltype, hostPtr));
+
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ void NVRenderBackendGL3Impl::UpdateSampler(
+ NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter,
+ NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT,
+ NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias,
+ NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc,
+ QT3DSF32 anisotropy, QT3DSF32 *borderColor)
+ {
+
+ // Satisfy the compiler
+ // These are not available in GLES 3 and we don't use them right now
+ QT3DS_ASSERT(lodBias == 0.0);
+ QT3DS_ASSERT(!borderColor);
+ NVRENDER_BACKEND_UNUSED(lodBias);
+ NVRENDER_BACKEND_UNUSED(borderColor);
+
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER,
+ m_Conversion.fromTextureMinifyingOpToGL(minFilter)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER,
+ m_Conversion.fromTextureMagnifyingOpToGL(magFilter)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S,
+ m_Conversion.fromTextureCoordOpToGL(wrapS)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T,
+ m_Conversion.fromTextureCoordOpToGL(wrapT)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_R,
+ m_Conversion.fromTextureCoordOpToGL(wrapR)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MIN_LOD, minLod));
+ GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_LOD, maxLod));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE,
+ m_Conversion.fromTextureCompareModeToGL(compareMode)));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC,
+ m_Conversion.fromTextureCompareFuncToGL(compareFunc)));
+
+ if (m_backendSupport.caps.bits.bAnistropySupported) {
+ GL_CALL_EXTRA_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy));
+ }
+ }
+
+ void NVRenderBackendGL3Impl::UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSI32 baseLevel, QT3DSI32 maxLevel)
+ {
+ NVRENDER_BACKEND_UNUSED(to);
+
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_BASE_LEVEL, baseLevel));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAX_LEVEL, maxLevel));
+ }
+
+ void NVRenderBackendGL3Impl::UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode)
+ {
+ NVRENDER_BACKEND_UNUSED(to);
+ if (m_backendSupport.caps.bits.bTextureSwizzleSupported) {
+ GLint glSwizzle[4];
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ m_Conversion.NVRenderConvertSwizzleModeToGL(swizzleMode, glSwizzle);
+#if defined(QT_OPENGL_ES)
+ // since ES3 spec has no GL_TEXTURE_SWIZZLE_RGBA set it separately
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R, glSwizzle[0]));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G, glSwizzle[1]));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B, glSwizzle[2]));
+ GL_CALL_EXTRA_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A, glSwizzle[3]));
+#else
+ GL_CALL_EXTRA_FUNCTION(glTexParameteriv(glTarget, GL_TEXTURE_SWIZZLE_RGBA, glSwizzle));
+#endif
+ }
+ }
+
+ QT3DSU32
+ NVRenderBackendGL3Impl::GetDepthBits() const
+ {
+ QT3DSI32 depthBits;
+ GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv(
+ GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depthBits));
+
+ return depthBits;
+ }
+
+ QT3DSU32
+ NVRenderBackendGL3Impl::GetStencilBits() const
+ {
+ QT3DSI32 stencilBits;
+ GL_CALL_EXTRA_FUNCTION(glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
+ &stencilBits));
+
+ return stencilBits;
+ }
+
+ void NVRenderBackendGL3Impl::GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum /*genType*/)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+ GL_CALL_EXTRA_FUNCTION(glGenerateMipmap(glTarget));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ bool NVRenderBackendGL3Impl::SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po)
+ {
+ if (iao == NULL) {
+ // unbind and return;
+ GL_CALL_EXTRA_FUNCTION(glBindVertexArray(0));
+ return true;
+ }
+
+ NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao;
+ NVRenderBackendAttributeLayoutGL *attribLayout = inputAssembler->m_attribLayout;
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ NVDataRef<NVRenderBackendShaderInputEntryGL> shaderAttribBuffer;
+ if (pProgram->m_shaderInput)
+ shaderAttribBuffer = pProgram->m_shaderInput->m_ShaderInputEntries;
+
+ if (attribLayout->m_LayoutAttribEntries.size() < shaderAttribBuffer.size())
+ return false;
+
+ if (inputAssembler->m_VertexbufferHandles.size() <= attribLayout->m_MaxInputSlot) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ if (inputAssembler->m_VaoID == 0) {
+ // generate vao
+ GL_CALL_EXTRA_FUNCTION(glGenVertexArrays(1, &inputAssembler->m_VaoID));
+ QT3DS_ASSERT(inputAssembler->m_VaoID);
+ }
+
+ // set patch parameter count if changed
+ if (m_backendSupport.caps.bits.bTessellationSupported
+ && m_pCurrentMiscState->m_PatchVertexCount != inputAssembler->m_PatchVertexCount) {
+ m_pCurrentMiscState->m_PatchVertexCount = inputAssembler->m_PatchVertexCount;
+#if defined(QT_OPENGL_ES)
+ GL_CALL_TESSELATION_EXT(glPatchParameteriEXT(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount));
+#else
+ GL_CALL_TESSELATION_EXT(glPatchParameteri(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount));
+#endif
+ }
+
+ if (inputAssembler->m_cachedShaderHandle != programID) {
+ GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID));
+ inputAssembler->m_cachedShaderHandle = programID;
+
+ QT3DS_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]);
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(attrib.m_AttribName);
+
+ if (entry) {
+ NVRenderBackendLayoutEntryGL &entryData(*entry);
+ if (entryData.m_Type != attrib.m_Type
+ || entryData.m_NumComponents != attrib.m_NumComponents) {
+ qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout",
+ attrib.m_AttribName.c_str());
+ QT3DS_ASSERT(false);
+ return false;
+ } else {
+ entryData.m_AttribIndex = attrib.m_AttribLocation;
+ }
+ } else {
+ qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str());
+ }
+ }
+
+ // disable max possible used first
+ // this is currently sufficient since we always re-arrange input attributes from 0
+ for (QT3DSU32 i = 0; i < attribLayout->m_LayoutAttribEntries.size(); i++) {
+ GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(i));
+ }
+
+ // setup all attribs
+ QT3DS_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(shaderAttribBuffer[idx].m_AttribName);
+ if (entry) {
+ const NVRenderBackendLayoutEntryGL &entryData(*entry);
+ GLuint id = HandleToID_cast(
+ GLuint, size_t,
+ inputAssembler->m_VertexbufferHandles.mData[entryData.m_InputSlot]);
+ GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ARRAY_BUFFER, id));
+ GL_CALL_EXTRA_FUNCTION(glEnableVertexAttribArray(entryData.m_AttribIndex));
+ GLuint offset = inputAssembler->m_offsets[entryData.m_InputSlot];
+ GLuint stride = inputAssembler->m_strides[entryData.m_InputSlot];
+ GL_CALL_EXTRA_FUNCTION(glVertexAttribPointer(
+ entryData.m_AttribIndex, entryData.m_NumComponents, GL_FLOAT, GL_FALSE,
+ stride, (const void *)(entryData.m_Offset + offset)));
+
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glDisableVertexAttribArray(idx));
+ }
+ }
+
+ // setup index buffer.
+ if (inputAssembler->m_IndexbufferHandle) {
+ GL_CALL_EXTRA_FUNCTION(glBindBuffer(
+ GL_ELEMENT_ARRAY_BUFFER,
+ HandleToID_cast(GLuint, size_t, inputAssembler->m_IndexbufferHandle)));
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ }
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glBindVertexArray(inputAssembler->m_VaoID));
+ }
+#ifdef _DEBUG
+ if (inputAssembler->m_VaoID) {
+ QT3DS_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]);
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(attrib.m_AttribName);
+
+ if (entry) {
+ NVRenderBackendLayoutEntryGL &entryData(*entry);
+ if (entryData.m_Type != attrib.m_Type
+ || entryData.m_NumComponents != attrib.m_NumComponents
+ || entryData.m_AttribIndex != attrib.m_AttribLocation) {
+ qCCritical(INVALID_OPERATION, "Attrib %s doesn't match vertex layout",
+ attrib.m_AttribName.c_str());
+ QT3DS_ASSERT(false);
+ }
+ } else {
+ qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str());
+ }
+ }
+ }
+#endif // _DEBUG
+
+ return true;
+ }
+
+ void NVRenderBackendGL3Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet)
+ {
+ NVRENDER_BACKEND_UNUSED(rto);
+
+ m_DrawBuffersArray.clear();
+
+ for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) {
+ if (inDrawBufferSet[idx] < 0)
+ m_DrawBuffersArray.push_back(GL_NONE);
+ else
+ m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]);
+ }
+
+ GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(), m_DrawBuffersArray.data()));
+ }
+
+ void NVRenderBackendGL3Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace)
+ {
+ NVRENDER_BACKEND_UNUSED(rto);
+
+ GL_CALL_EXTRA_FUNCTION(glReadBuffer(m_Conversion.fromReadFacesToGL(inReadFace)));
+ }
+
+ void NVRenderBackendGL3Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level,
+ QT3DSI32 layer)
+ {
+ // rto must be the current render target
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttach, texID, level, layer))
+ }
+
+ void NVRenderBackendGL3Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto)
+ {
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID));
+ }
+
+ void NVRenderBackendGL3Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter)
+ {
+ GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ m_Conversion.fromClearFlagsToGL(flags),
+ m_Conversion.fromTextureMagnifyingOpToGL(filter)));
+ }
+
+ void *NVRenderBackendGL3Impl::MapBuffer(NVRenderBackendBufferObject,
+ NVRenderBufferBindFlags bindFlags, size_t offset,
+ size_t length, NVRenderBufferAccessFlags accessFlags)
+ {
+ void *ret = NULL;
+ ret = GL_CALL_EXTRA_FUNCTION(glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset,
+ length, m_Conversion.fromBufferAccessBitToGL(accessFlags)));
+
+ return ret;
+ }
+
+ bool NVRenderBackendGL3Impl::UnmapBuffer(NVRenderBackendBufferObject,
+ NVRenderBufferBindFlags bindFlags)
+ {
+ GLboolean ret;
+
+ ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags)));
+
+ return (ret) ? true : false;
+ }
+
+ QT3DSI32 NVRenderBackendGL3Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po)
+ {
+ QT3DS_ASSERT(po);
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GLint numUniformBuffers;
+ GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBuffers));
+
+ return numUniformBuffers;
+ }
+
+ QT3DSI32
+ NVRenderBackendGL3Impl::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize,
+ QT3DSI32 *paramCount, QT3DSI32 *bufferSize,
+ QT3DSI32 *length, char *nameBuf)
+ {
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(length);
+ QT3DS_ASSERT(nameBuf);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ GLuint blockIndex = GL_INVALID_INDEX;
+
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length, nameBuf));
+
+ if (*length > 0) {
+ blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf));
+ if (blockIndex != GL_INVALID_INDEX) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex,
+ GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize));
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex,
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount));
+ }
+ }
+
+ return blockIndex;
+ }
+
+ void
+ NVRenderBackendGL3Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSI32 *indices)
+ {
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(indices);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ if (indices) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id,
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices));
+ }
+ }
+
+ void NVRenderBackendGL3Impl::GetConstantBufferParamInfoByIndices(
+ NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset)
+ {
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(count);
+ QT3DS_ASSERT(indices);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ if (count && indices) {
+ if (type) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_TYPE, type));
+ // convert to UIC types
+ QT3DS_FOREACH(idx, count)
+ {
+ type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]);
+ }
+ }
+ if (size) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_SIZE, size));
+ }
+ if (offset) {
+ GL_CALL_EXTRA_FUNCTION(
+ glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset));
+ }
+ }
+ }
+
+ void NVRenderBackendGL3Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding));
+ }
+
+ void NVRenderBackendGL3Impl::ProgramSetConstantBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+ {
+ QT3DS_ASSERT(bo);
+
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID));
+ }
+
+ NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGL3Impl::CreateQuery()
+ {
+ QT3DSU32 glQueryID = 0;
+
+ GL_CALL_EXTRA_FUNCTION(glGenQueries(1, &glQueryID));
+
+ return (NVRenderBackendQueryObject)glQueryID;
+ }
+
+ void NVRenderBackendGL3Impl::ReleaseQuery(NVRenderBackendQueryObject qo)
+ {
+ GLuint queryID = HandleToID_cast(GLuint, size_t, qo);
+
+ GL_CALL_EXTRA_FUNCTION(glDeleteQueries(1, &queryID));
+ }
+
+ void NVRenderBackendGL3Impl::BeginQuery(NVRenderBackendQueryObject qo,
+ NVRenderQueryType::Enum type)
+ {
+ GLuint queryID = HandleToID_cast(GLuint, size_t, qo);
+
+ GL_CALL_EXTRA_FUNCTION(glBeginQuery(m_Conversion.fromQueryTypeToGL(type), queryID));
+ }
+
+ void NVRenderBackendGL3Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum type)
+ {
+ GL_CALL_EXTRA_FUNCTION(glEndQuery(m_Conversion.fromQueryTypeToGL(type)));
+ }
+
+ void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType,
+ QT3DSU32 *params)
+ {
+ GLuint queryID = HandleToID_cast(GLuint, size_t, qo);
+
+ if (params)
+ GL_CALL_EXTRA_FUNCTION(glGetQueryObjectuiv(
+ queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params));
+ }
+
+ void NVRenderBackendGL3Impl::GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType,
+ QT3DSU64 *params)
+ {
+ if (m_backendSupport.caps.bits.bTimerQuerySupported) {
+ GLuint queryID = HandleToID_cast(GLuint, size_t, qo);
+
+ if (params)
+#if defined(QT_OPENGL_ES)
+ GL_CALL_TIMER_EXT(glGetQueryObjectui64vEXT(
+ queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params));
+#else
+ GL_CALL_TIMER_EXT(glGetQueryObjectui64v(
+ queryID, m_Conversion.fromQueryResultTypeToGL(resultType), params));
+#endif
+ }
+ }
+
+ void NVRenderBackendGL3Impl::SetQueryTimer(NVRenderBackendQueryObject qo)
+ {
+ if (m_backendSupport.caps.bits.bTimerQuerySupported) {
+ GLuint queryID = HandleToID_cast(GLuint, size_t, qo);
+#if defined(QT_OPENGL_ES)
+ GL_CALL_TIMER_EXT(glQueryCounterEXT(queryID, GL_TIMESTAMP_EXT));
+#else
+ GL_CALL_TIMER_EXT(glQueryCounter(queryID, GL_TIMESTAMP));
+#endif
+ }
+ }
+
+ NVRenderBackend::NVRenderBackendSyncObject
+ NVRenderBackendGL3Impl::CreateSync(NVRenderSyncType::Enum syncType, NVRenderSyncFlags)
+ {
+ GLsync syncID = 0;
+
+ syncID = GL_CALL_EXTRA_FUNCTION(glFenceSync(m_Conversion.fromSyncTypeToGL(syncType), 0));
+
+ return NVRenderBackendSyncObject(syncID);
+ }
+
+ void NVRenderBackendGL3Impl::ReleaseSync(NVRenderBackendSyncObject so)
+ {
+ GLsync syncID = (GLsync)so;
+
+ GL_CALL_EXTRA_FUNCTION(glDeleteSync(syncID));
+ }
+
+ void NVRenderBackendGL3Impl::WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags,
+ QT3DSU64)
+ {
+ GLsync syncID = (GLsync)so;
+
+ GL_CALL_EXTRA_FUNCTION(glWaitSync(syncID, 0, GL_TIMEOUT_IGNORED));
+ }
+}
+}
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h
new file mode 100644
index 00000000..7147b341
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL3.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_GL3_H
+#define QT3DS_RENDER_BACKEND_GL3_H
+
+/// @file Qt3DSRenderBackendGL3.h
+/// NVRender OpenGL 3 backend definition.
+
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/gl/Qt3DSRenderBackendGLBase.h"
+#include "render/backends/gl/Qt3DSOpenGLExtensions.h"
+
+#include <QtGui/QOpenGLExtraFunctions>
+#include <QtOpenGLExtensions/QtOpenGLExtensions>
+
+namespace qt3ds {
+namespace render {
+
+ ///< forward declaration
+ class NVRenderBackendMiscStateGL;
+
+ using namespace foundation;
+
+ class NVRenderBackendGL3Impl : public NVRenderBackendGLBase
+ {
+ public:
+ /// constructor
+ NVRenderBackendGL3Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format);
+ /// destructor
+ virtual ~NVRenderBackendGL3Impl();
+
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ public:
+ QT3DSU32 GetDepthBits() const override;
+ QT3DSU32 GetStencilBits() const override;
+ void GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum genType) override;
+
+ void SetMultisampledTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ size_t samples,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height,
+ bool fixedsamplelocations) override;
+
+ void SetTextureData3D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, size_t depth, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) override;
+
+ void UpdateSampler(
+ NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override;
+
+ void UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel,
+ QT3DSI32 maxLevel) override;
+
+ void UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode) override;
+
+ bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po) override;
+
+ void SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet) override;
+ void SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace) override;
+
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override;
+ void SetReadTarget(NVRenderBackendRenderTargetObject rto) override;
+
+ void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter) override;
+
+ void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t offset, size_t length,
+ NVRenderBufferAccessFlags accessFlags) override;
+ bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override;
+
+ QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override;
+ void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSI32 *indices) override;
+ void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset) override;
+ void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding) override;
+ void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ NVRenderBackendQueryObject CreateQuery() override;
+ void ReleaseQuery(NVRenderBackendQueryObject qo) override;
+ void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override;
+ void SetQueryTimer(NVRenderBackendQueryObject qo) override;
+
+ NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye,
+ NVRenderSyncFlags syncFlags) override;
+ void ReleaseSync(NVRenderBackendSyncObject so) override;
+ void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags,
+ QT3DSU64 timeout) override;
+
+ protected:
+ NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state
+#if defined(QT_OPENGL_ES_2)
+ Qt3DSOpenGLES2Extensions *m_qt3dsExtensions;
+#else
+ QOpenGLExtension_ARB_timer_query *m_timerExtension;
+ QOpenGLExtension_ARB_tessellation_shader *m_tessellationShader;
+ QOpenGLExtension_ARB_texture_multisample *m_multiSample;
+ Qt3DSOpenGLExtensions *m_qt3dsExtensions;
+#endif
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp
new file mode 100644
index 00000000..083fc35e
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.cpp
@@ -0,0 +1,875 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/backends/gl/Qt3DSRenderBackendGL4.h"
+#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h"
+
+#define NVRENDER_BACKEND_UNUSED(arg) (void)arg;
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__)
+#else
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError()
+#endif
+
+#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x);
+
+#if defined(QT_OPENGL_ES)
+#define GL_CALL_NVPATH_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#else
+#define GL_CALL_NVPATH_EXT(x) m_nvPathRendering->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_DIRECTSTATE_EXT(x) m_directStateAccess->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; RENDER_LOG_ERROR_PARAMS(x);
+#endif
+
+#ifndef GL_GEOMETRY_SHADER_EXT
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#endif
+
+namespace qt3ds {
+namespace render {
+
+ /// constructor
+ NVRenderBackendGL4Impl::NVRenderBackendGL4Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format)
+ : NVRenderBackendGL3Impl(fnd, stringTable, format)
+ {
+ eastl::string extTess("GL_ARB_tessellation_shader");
+ eastl::string extGeometry("GL_EXT_geometry_shader4");
+ eastl::string arbCompute("GL_ARB_compute_shader");
+ eastl::string arbStorageBuffer("GL_ARB_shader_storage_buffer_object");
+ eastl::string arbAtomicCounterBuffer("GL_ARB_shader_atomic_counters");
+ eastl::string arbProgInterface("GL_ARB_program_interface_query");
+ eastl::string arbShaderImageLoadStore("GL_ARB_shader_image_load_store");
+ eastl::string nvPathRendering("GL_NV_path_rendering");
+ eastl::string nvBlendAdvanced("GL_NV_blend_equation_advanced");
+ eastl::string khrBlendAdvanced("GL_KHR_blend_equation_advanced");
+ eastl::string nvBlendAdvancedCoherent("GL_NV_blend_equation_advanced_coherent");
+ eastl::string khrBlendAdvancedCoherent("GL_KHR_blend_equation_advanced_coherent");
+
+ eastl::string apiVersion(getVersionString());
+ qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str());
+
+ // get extension count
+ GLint numExtensions = 0;
+ GL_CALL_EXTRA_FUNCTION(glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions));
+
+ for (QT3DSI32 i = 0; i < numExtensions; i++) {
+ char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i));
+
+ // search for extension
+ if (!m_backendSupport.caps.bits.bTessellationSupported
+ && extTess.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bTessellationSupported = true;
+ } else if (!m_backendSupport.caps.bits.bComputeSupported
+ && arbCompute.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bComputeSupported = true;
+ } else if (!m_backendSupport.caps.bits.bGeometrySupported
+ && extGeometry.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bGeometrySupported = true;
+ } else if (!m_backendSupport.caps.bits.bStorageBufferSupported
+ && arbStorageBuffer.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bStorageBufferSupported = true;
+ } else if (!m_backendSupport.caps.bits.bAtomicCounterBufferSupported
+ && arbAtomicCounterBuffer.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true;
+ } else if (!m_backendSupport.caps.bits.bProgramInterfaceSupported
+ && arbProgInterface.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bProgramInterfaceSupported = true;
+ } else if (!m_backendSupport.caps.bits.bShaderImageLoadStoreSupported
+ && arbShaderImageLoadStore.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true;
+ } else if (!m_backendSupport.caps.bits.bNVPathRenderingSupported
+ && nvPathRendering.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bNVPathRenderingSupported = true;
+ } else if (!m_backendSupport.caps.bits.bNVAdvancedBlendSupported
+ && nvBlendAdvanced.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bNVAdvancedBlendSupported = true;
+ } else if (!m_backendSupport.caps.bits.bNVBlendCoherenceSupported
+ && nvBlendAdvancedCoherent.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bNVBlendCoherenceSupported = true;
+ } else if (!m_backendSupport.caps.bits.bKHRAdvancedBlendSupported
+ && khrBlendAdvanced.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bKHRAdvancedBlendSupported = true;
+ } else if (!m_backendSupport.caps.bits.bKHRBlendCoherenceSupported
+ && khrBlendAdvancedCoherent.compare(extensionString) == 0) {
+ m_backendSupport.caps.bits.bKHRBlendCoherenceSupported = true;
+ }
+ }
+
+ // always true for GL4.1 and GLES 3.1 devices
+ m_backendSupport.caps.bits.bMsTextureSupported = true;
+ m_backendSupport.caps.bits.bProgramPipelineSupported = true;
+
+ if (!isESCompatible()) {
+ // TODO: investigate GL 4.0 support
+ // we expect minimum GL 4.1 context anything beyond is handeled via extensions
+ // Tessellation is always supported on none ES systems which support >=GL4
+ m_backendSupport.caps.bits.bTessellationSupported = true;
+ // geometry shader is always supported on none ES systems which support >=GL4 ( actually
+ // 3.2 already )
+ m_backendSupport.caps.bits.bGeometrySupported = true;
+ } else {
+ // always true for GLES 3.1 devices
+ m_backendSupport.caps.bits.bComputeSupported = true;
+ m_backendSupport.caps.bits.bProgramInterfaceSupported = true;
+ m_backendSupport.caps.bits.bStorageBufferSupported = true;
+ m_backendSupport.caps.bits.bAtomicCounterBufferSupported = true;
+ m_backendSupport.caps.bits.bShaderImageLoadStoreSupported = true;
+ }
+
+#if !defined(QT_OPENGL_ES)
+ // Initialize extensions
+ m_nvPathRendering = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_NV_path_rendering)();
+ m_nvPathRendering->initializeOpenGLFunctions();
+ m_directStateAccess = QT3DS_NEW(m_Foundation.getAllocator(), QOpenGLExtension_EXT_direct_state_access)();
+ m_directStateAccess->initializeOpenGLFunctions();
+#endif
+ }
+
+ /// destructor
+ NVRenderBackendGL4Impl::~NVRenderBackendGL4Impl()
+ {
+#if !defined(QT_OPENGL_ES)
+ if (m_nvPathRendering)
+ NVDelete(m_Foundation.getAllocator(), m_nvPathRendering);
+ if (m_directStateAccess)
+ NVDelete(m_Foundation.getAllocator(), m_directStateAccess);
+#endif
+ }
+
+ void NVRenderBackendGL4Impl::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect)
+ {
+ GL_CALL_EXTRA_FUNCTION(
+ glDrawArraysIndirect(m_Conversion.fromDrawModeToGL(
+ drawMode, m_backendSupport.caps.bits.bTessellationSupported),
+ indirect));
+ }
+
+ void NVRenderBackendGL4Impl::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode,
+ NVRenderComponentTypes::Enum type,
+ const void *indirect)
+ {
+ GL_CALL_EXTRA_FUNCTION(glDrawElementsIndirect(
+ m_Conversion.fromDrawModeToGL(drawMode,
+ m_backendSupport.caps.bits.bTessellationSupported),
+ m_Conversion.fromIndexBufferComponentsTypesToGL(type), indirect));
+ }
+
+ void NVRenderBackendGL4Impl::CreateTextureStorage2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSU32 levels,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+
+ // up to now compressed is not supported
+ QT3DS_ASSERT(NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat));
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+ GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+
+ GL_CALL_EXTRA_FUNCTION(
+ glTexStorage2D(glTarget, levels, glInternalFormat, (GLsizei)width, (GLsizei)height));
+
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ void NVRenderBackendGL4Impl::SetMultisampledTextureData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, size_t samples,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height,
+ bool fixedsamplelocations)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_EXTRA_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, texID));
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat))
+ GLConversion::fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+ else if (NVRenderTextureFormats::isDepthTextureFormat(internalFormat))
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+ GL_CALL_EXTRA_FUNCTION(glTexStorage2DMultisample(glTarget, (GLsizei)samples, glInternalFormat,
+ (GLsizei)width, (GLsizei)height,
+ fixedsamplelocations));
+
+ GL_CALL_EXTRA_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ NVRenderBackend::NVRenderBackendTessControlShaderObject
+ NVRenderBackendGL4Impl::CreateTessControlShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+#if !defined(QT_OPENGL_ES)
+ GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_CONTROL_SHADER));
+#else
+ GLuint shaderID = 0;
+#endif
+ if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) {
+ GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID));
+ shaderID = 0;
+ }
+
+ return (NVRenderBackend::NVRenderBackendTessControlShaderObject)shaderID;
+ }
+
+ NVRenderBackend::NVRenderBackendTessEvaluationShaderObject
+ NVRenderBackendGL4Impl::CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+#if !defined(QT_OPENGL_ES)
+ GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_TESS_EVALUATION_SHADER));
+#else
+ GLuint shaderID = 0;
+#endif
+
+ if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) {
+ GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID));
+ shaderID = 0;
+ }
+
+ return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)shaderID;
+ }
+
+ NVRenderBackend::NVRenderBackendGeometryShaderObject
+ NVRenderBackendGL4Impl::CreateGeometryShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+#if defined(QT_OPENGL_ES)
+ GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER_EXT));
+#else
+ GLuint shaderID = GL_CALL_EXTRA_FUNCTION(glCreateShader(GL_GEOMETRY_SHADER));
+#endif
+ if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) {
+ GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID));
+ shaderID = 0;
+ }
+
+ return (NVRenderBackend::NVRenderBackendGeometryShaderObject)shaderID;
+ }
+
+ void NVRenderBackendGL4Impl::SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao,
+ QT3DSU32 count)
+ {
+ QT3DS_ASSERT(iao);
+ QT3DS_ASSERT(count);
+ NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao;
+ inputAssembler->m_PatchVertexCount = count;
+ }
+
+ void NVRenderBackendGL4Impl::SetMemoryBarrier(NVRenderBufferBarrierFlags barriers)
+ {
+ GL_CALL_EXTRA_FUNCTION(glMemoryBarrier(m_Conversion.fromMemoryBarrierFlagsToGL(barriers)));
+ }
+
+ void NVRenderBackendGL4Impl::BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit,
+ QT3DSI32 level, bool layered, QT3DSI32 layer,
+ NVRenderImageAccessType::Enum access,
+ NVRenderTextureFormats::Enum format)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+
+ GL_CALL_EXTRA_FUNCTION(glBindImageTexture(unit, texID, level, layered, layer,
+ m_Conversion.fromImageAccessToGL(access),
+ m_Conversion.fromImageFormatToGL(format)));
+ }
+
+ QT3DSI32 NVRenderBackendGL4Impl::GetStorageBufferCount(NVRenderBackendShaderProgramObject po)
+ {
+ GLint numStorageBuffers = 0;
+ QT3DS_ASSERT(po);
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ if (m_backendSupport.caps.bits.bProgramInterfaceSupported)
+ GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_SHADER_STORAGE_BLOCK,
+ GL_ACTIVE_RESOURCES, &numStorageBuffers));
+#endif
+ return numStorageBuffers;
+ }
+
+ QT3DSI32
+ NVRenderBackendGL4Impl::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf)
+ {
+ GLint bufferIndex = GL_INVALID_INDEX;
+
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(length);
+ QT3DS_ASSERT(nameBuf);
+ QT3DS_ASSERT(bufferSize);
+ QT3DS_ASSERT(paramCount);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ if (m_backendSupport.caps.bits.bProgramInterfaceSupported) {
+ GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_SHADER_STORAGE_BLOCK, id, nameBufSize,
+ length, nameBuf));
+
+ if (*length > 0) {
+#define QUERY_COUNT 3
+ GLsizei actualCount;
+ GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE,
+ GL_NUM_ACTIVE_VARIABLES };
+ GLint params[QUERY_COUNT];
+ GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_SHADER_STORAGE_BLOCK, id,
+ QUERY_COUNT, props, QUERY_COUNT, &actualCount,
+ params));
+
+ QT3DS_ASSERT(actualCount == QUERY_COUNT);
+
+ bufferIndex = params[0];
+ *bufferSize = params[1];
+ *paramCount = params[2];
+ }
+ }
+#endif
+ return bufferIndex;
+ }
+
+ void NVRenderBackendGL4Impl::ProgramSetStorageBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+ {
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ GL_CALL_EXTRA_FUNCTION(
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, HandleToID_cast(GLuint, size_t, bo)));
+#endif
+ }
+
+ QT3DSI32 NVRenderBackendGL4Impl::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po)
+ {
+ GLint numAtomicCounterBuffers = 0;
+ QT3DS_ASSERT(po);
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ if (m_backendSupport.caps.bits.bProgramInterfaceSupported)
+ GL_CALL_EXTRA_FUNCTION(glGetProgramInterfaceiv(programID, GL_ATOMIC_COUNTER_BUFFER,
+ GL_ACTIVE_RESOURCES, &numAtomicCounterBuffers));
+#endif
+ return numAtomicCounterBuffers;
+ }
+
+ QT3DSI32
+ NVRenderBackendGL4Impl::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize,
+ QT3DSI32 *paramCount, QT3DSI32 *bufferSize,
+ QT3DSI32 *length, char *nameBuf)
+ {
+ GLint bufferIndex = GL_INVALID_INDEX;
+
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(length);
+ QT3DS_ASSERT(nameBuf);
+ QT3DS_ASSERT(bufferSize);
+ QT3DS_ASSERT(paramCount);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ if (m_backendSupport.caps.bits.bProgramInterfaceSupported) {
+ {
+#define QUERY_COUNT 3
+ GLsizei actualCount;
+ GLenum props[QUERY_COUNT] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE,
+ GL_NUM_ACTIVE_VARIABLES };
+ GLint params[QUERY_COUNT];
+ GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_ATOMIC_COUNTER_BUFFER, id,
+ QUERY_COUNT, props, QUERY_COUNT, &actualCount,
+ params));
+
+ QT3DS_ASSERT(actualCount == QUERY_COUNT);
+
+ bufferIndex = params[0];
+ *bufferSize = params[1];
+ *paramCount = params[2];
+
+ GLenum props1[1] = { GL_ATOMIC_COUNTER_BUFFER_INDEX };
+ GL_CALL_EXTRA_FUNCTION(glGetProgramResourceiv(programID, GL_UNIFORM, id, 1, props1, 1,
+ &actualCount, params));
+
+ QT3DS_ASSERT(actualCount == 1);
+
+ *nameBuf = '\0';
+ GL_CALL_EXTRA_FUNCTION(glGetProgramResourceName(programID, GL_UNIFORM, params[0], nameBufSize,
+ length, nameBuf));
+ }
+ }
+#endif
+ return bufferIndex;
+ }
+
+ void NVRenderBackendGL4Impl::ProgramSetAtomicCounterBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+ {
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ GL_CALL_EXTRA_FUNCTION(
+ glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, index, HandleToID_cast(GLuint, size_t, bo)));
+#endif
+ }
+
+ void NVRenderBackendGL4Impl::SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count,
+ const void *value, bool transpose)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type);
+
+ switch (glType) {
+ case GL_FLOAT:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform1fv(programID, id, count, (GLfloat *)value));
+ break;
+ case GL_FLOAT_VEC2:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform2fv(programID, id, count, (GLfloat *)value));
+ break;
+ case GL_FLOAT_VEC3:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform3fv(programID, id, count, (GLfloat *)value));
+ break;
+ case GL_FLOAT_VEC4:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform4fv(programID, id, count, (GLfloat *)value));
+ break;
+ case GL_INT:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, (GLint *)value));
+ break;
+ case GL_BOOL:
+ {
+ GLint boolValue = *(GLboolean *)value;
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, &boolValue));
+ }
+ break;
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform2iv(programID, id, count, (GLint *)value));
+ break;
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform3iv(programID, id, count, (GLint *)value));
+ break;
+ case GL_INT_VEC4:
+ case GL_BOOL_VEC4:
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform4iv(programID, id, count, (GLint *)value));
+ break;
+ case GL_FLOAT_MAT3:
+ GL_CALL_EXTRA_FUNCTION(
+ glProgramUniformMatrix3fv(programID, id, count, transpose, (GLfloat *)value));
+ break;
+ case GL_FLOAT_MAT4:
+ GL_CALL_EXTRA_FUNCTION(
+ glProgramUniformMatrix4fv(programID, id, count, transpose, (GLfloat *)value));
+ break;
+ case GL_IMAGE_2D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE: {
+ if (count <= 1) {
+ GLint sampler = *(GLint *)value;
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler));
+ } else {
+ GLint *sampler = (GLint *)value;
+ GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, sampler));
+ }
+ } break;
+ default:
+ qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type);
+ QT3DS_ASSERT(false);
+ break;
+ }
+ }
+
+ NVRenderBackend::NVRenderBackendComputeShaderObject
+ NVRenderBackendGL4Impl::CreateComputeShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ GLuint shaderID = 0;
+#if defined(GL_COMPUTE_SHADER)
+ shaderID = m_glExtraFunctions->glCreateShader(GL_COMPUTE_SHADER);
+
+ if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) {
+ GL_CALL_EXTRA_FUNCTION(glDeleteShader(shaderID));
+ shaderID = 0;
+ }
+#endif
+ return (NVRenderBackend::NVRenderBackendComputeShaderObject)shaderID;
+ }
+
+ void NVRenderBackendGL4Impl::DispatchCompute(NVRenderBackendShaderProgramObject,
+ QT3DSU32 numGroupsX, QT3DSU32 numGroupsY,
+ QT3DSU32 numGroupsZ)
+ {
+ GL_CALL_EXTRA_FUNCTION(glDispatchCompute(numGroupsX, numGroupsY, numGroupsZ));
+ }
+
+ NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGL4Impl::CreateProgramPipeline()
+ {
+ GLuint pipeline;
+ GL_CALL_EXTRA_FUNCTION(glGenProgramPipelines(1, &pipeline));
+
+ return NVRenderBackend::NVRenderBackendProgramPipeline(pipeline);
+ }
+
+ void NVRenderBackendGL4Impl::ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo)
+ {
+ GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo);
+ GL_CALL_EXTRA_FUNCTION(glDeleteProgramPipelines(1, &pipeline));
+ }
+
+ void NVRenderBackendGL4Impl::SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo)
+ {
+ GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo);
+
+ GL_CALL_EXTRA_FUNCTION(glBindProgramPipeline(pipeline));
+ }
+
+ void NVRenderBackendGL4Impl::SetProgramStages(NVRenderBackendProgramPipeline ppo,
+ NVRenderShaderTypeFlags flags,
+ NVRenderBackendShaderProgramObject po)
+ {
+ GLuint pipeline = HandleToID_cast(GLuint, size_t, ppo);
+ GLuint programID = 0;
+
+ if (po) {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ }
+
+ GL_CALL_EXTRA_FUNCTION(
+ glUseProgramStages(pipeline, m_Conversion.fromShaderTypeFlagsToGL(flags), programID));
+ }
+
+ void NVRenderBackendGL4Impl::SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg)
+ {
+ if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported ||
+ m_backendSupport.caps.bits.bKHRAdvancedBlendSupported)
+ GL_CALL_EXTRA_FUNCTION(glBlendEquation(m_Conversion.fromBlendEquationToGL(
+ pBlendEquArg.m_RGBEquation, m_backendSupport.caps.bits.bNVAdvancedBlendSupported,
+ m_backendSupport.caps.bits.bKHRAdvancedBlendSupported)));
+ }
+
+ void NVRenderBackendGL4Impl::SetBlendBarrier(void)
+ {
+ if (m_backendSupport.caps.bits.bNVAdvancedBlendSupported)
+ GL_CALL_QT3DS_EXT(glBlendBarrierNV());
+ }
+
+ NVRenderBackend::NVRenderBackendPathObject
+ NVRenderBackendGL4Impl::CreatePathNVObject(size_t range)
+ {
+ GLuint pathID = GL_CALL_NVPATH_EXT(glGenPathsNV((GLsizei)range));
+
+ return NVRenderBackend::NVRenderBackendPathObject(pathID);
+ }
+ void NVRenderBackendGL4Impl::SetPathSpecification(NVRenderBackendPathObject inPathObject,
+ NVConstDataRef<QT3DSU8> inPathCommands,
+ NVConstDataRef<QT3DSF32> inPathCoords)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, inPathObject);
+ GL_CALL_NVPATH_EXT(glPathCommandsNV(pathID, inPathCommands.size(), inPathCommands.begin(),
+ inPathCoords.size(), GL_FLOAT, inPathCoords.begin()));
+ }
+
+ NVBounds3
+ NVRenderBackendGL4Impl::GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject)
+ {
+ float data[4];
+#if defined(GL_NV_path_rendering)
+ GL_CALL_NVPATH_EXT(glGetPathParameterfvNV(
+ HandleToID_cast(GLuint, size_t, inPathObject),
+ GL_PATH_OBJECT_BOUNDING_BOX_NV, data));
+#endif
+ return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f));
+ }
+
+ NVBounds3 NVRenderBackendGL4Impl::GetPathObjectFillBox(NVRenderBackendPathObject inPathObject)
+ {
+ float data[4];
+#if defined(GL_NV_path_rendering)
+ GL_CALL_NVPATH_EXT(glGetPathParameterfvNV(
+ HandleToID_cast(GLuint, size_t, inPathObject),
+ GL_PATH_FILL_BOUNDING_BOX_NV, data));
+#endif
+ return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f));
+ }
+
+ NVBounds3 NVRenderBackendGL4Impl::GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject)
+ {
+ float data[4];
+#if defined(GL_NV_path_rendering)
+ GL_CALL_NVPATH_EXT(glGetPathParameterfvNV(
+ HandleToID_cast(GLuint, size_t, inPathObject),
+ GL_PATH_STROKE_BOUNDING_BOX_NV, data));
+#endif
+ return NVBounds3(QT3DSVec3(data[0], data[1], 0.0f), QT3DSVec3(data[2], data[3], 0.0f));
+ }
+
+ void NVRenderBackendGL4Impl::SetStrokeWidth(NVRenderBackendPathObject inPathObject,
+ QT3DSF32 inStrokeWidth)
+ {
+#if defined(GL_NV_path_rendering)
+ GL_CALL_NVPATH_EXT(glPathParameterfNV(HandleToID_cast(GLuint, size_t, inPathObject),
+ GL_PATH_STROKE_WIDTH_NV, inStrokeWidth));
+#endif
+ }
+
+ void NVRenderBackendGL4Impl::SetPathProjectionMatrix(const QT3DSMat44 inPathProjection)
+ {
+#if defined(QT_OPENGL_ES)
+ NVRENDER_BACKEND_UNUSED(inPathProjection);
+#else
+ GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_PROJECTION, inPathProjection.front()));
+#endif
+ }
+
+ void NVRenderBackendGL4Impl::SetPathModelViewMatrix(const QT3DSMat44 inPathModelview)
+ {
+#if defined(QT_OPENGL_ES)
+ NVRENDER_BACKEND_UNUSED(inPathModelview);
+#else
+ GL_CALL_DIRECTSTATE_EXT(glMatrixLoadfEXT(GL_MODELVIEW, inPathModelview.front()));
+#endif
+ }
+
+ void NVRenderBackendGL4Impl::SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias)
+ {
+ GL_CALL_NVPATH_EXT(glPathStencilDepthOffsetNV(inSlope, inBias));
+ }
+
+ void NVRenderBackendGL4Impl::SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction)
+ {
+ GL_CALL_NVPATH_EXT(glPathCoverDepthFuncNV(m_Conversion.fromBoolOpToGL(inDepthFunction)));
+ }
+
+ void NVRenderBackendGL4Impl::StencilStrokePath(NVRenderBackendPathObject inPathObject)
+ {
+ GL_CALL_NVPATH_EXT(glStencilStrokePathNV(HandleToID_cast(GLuint, size_t, inPathObject), 0x1, (GLuint)~0));
+ }
+
+ void NVRenderBackendGL4Impl::StencilFillPath(NVRenderBackendPathObject inPathObject)
+ {
+#if defined(GL_NV_path_rendering)
+ GL_CALL_NVPATH_EXT(glStencilFillPathNV(HandleToID_cast(GLuint, size_t, inPathObject),
+ GL_COUNT_UP_NV, (GLuint)~0));
+#endif
+ }
+
+ void NVRenderBackendGL4Impl::ReleasePathNVObject(NVRenderBackendPathObject po, size_t range)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glDeletePathsNV(pathID, (GLsizei)range));
+ }
+
+ void NVRenderBackendGL4Impl::StencilFillPathInstanced(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type,
+ const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask,
+ NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glStencilFillPathInstancedNV(
+ (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID,
+ m_Conversion.fromPathFillModeToGL(fillMode), stencilMask,
+ m_Conversion.fromPathTransformToGL(transformType), transformValues));
+ }
+
+ void NVRenderBackendGL4Impl::StencilStrokePathInstancedN(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type,
+ const void *charCodes, QT3DSI32 stencilRef, QT3DSU32 stencilMask,
+ NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glStencilStrokePathInstancedNV(
+ (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID, stencilRef,
+ stencilMask, m_Conversion.fromPathTransformToGL(transformType), transformValues));
+ }
+
+ void NVRenderBackendGL4Impl::CoverFillPathInstanced(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type,
+ const void *charCodes, NVRenderPathCoverMode::Enum coverMode,
+ NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glCoverFillPathInstancedNV(
+ (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID,
+ m_Conversion.fromPathCoverModeToGL(coverMode),
+ m_Conversion.fromPathTransformToGL(transformType), transformValues));
+ }
+
+ void NVRenderBackendGL4Impl::CoverStrokePathInstanced(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type,
+ const void *charCodes, NVRenderPathCoverMode::Enum coverMode,
+ NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glCoverStrokePathInstancedNV(
+ (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type), charCodes, pathID,
+ m_Conversion.fromPathCoverModeToGL(coverMode),
+ m_Conversion.fromPathTransformToGL(transformType), transformValues));
+ }
+
+ void NVRenderBackendGL4Impl::LoadPathGlyphs(
+ NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs, NVRenderPathFormatType::Enum type,
+ const void *charCodes, NVRenderPathMissingGlyphs::Enum handleMissingGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+ GLuint pathTemplateID = (pathParameterTemplate == NULL)
+ ? ~0
+ : HandleToID_cast(GLuint, size_t, pathParameterTemplate);
+
+ GL_CALL_NVPATH_EXT(glPathGlyphsNV(pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName,
+ m_Conversion.fromPathFontStyleToGL(fontStyle), (GLsizei)numGlyphs,
+ m_Conversion.fromPathTypeToGL(type), charCodes,
+ m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs),
+ pathTemplateID, emScale));
+ }
+
+ NVRenderPathReturnValues::Enum NVRenderBackendGL4Impl::LoadPathGlyphsIndexed(
+ NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyphIndex, size_t numGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+ GLuint pathTemplateID = (pathParameterTemplate == NULL)
+ ? ~0
+ : HandleToID_cast(GLuint, size_t, pathParameterTemplate);
+ GLenum glRet = 0;
+
+ glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexArrayNV(
+ pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName,
+ m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyphIndex,
+ (GLsizei)numGlyphs, pathTemplateID, emScale));
+
+ return m_Conversion.fromGLToPathFontReturn(glRet);
+ }
+
+ NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGL4Impl::LoadPathGlyphsIndexedRange(
+ NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle, NVRenderBackendPathObject pathParameterTemplate,
+ QT3DSF32 emScale, QT3DSU32 *count)
+ {
+ GLuint pathTemplateID = (pathParameterTemplate == NULL)
+ ? ~0
+ : HandleToID_cast(GLuint, size_t, pathParameterTemplate);
+ GLenum glRet = 0;
+ GLuint baseAndCount[2] = { 0, 0 };
+
+ glRet = GL_CALL_QT3DS_EXT(glPathGlyphIndexRangeNV(m_Conversion.fromPathFontTargetToGL(fontTarget),
+ fontName,
+ m_Conversion.fromPathFontStyleToGL(fontStyle),
+ pathTemplateID, emScale, baseAndCount));
+
+ if (count)
+ *count = baseAndCount[1];
+
+ return NVRenderBackend::NVRenderBackendPathObject(baseAndCount[0]);
+ }
+
+ void NVRenderBackendGL4Impl::LoadPathGlyphRange(
+ NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle, QT3DSU32 firstGlyph, size_t numGlyphs,
+ NVRenderPathMissingGlyphs::Enum handleMissingGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+ GLuint pathTemplateID = (pathParameterTemplate == NULL)
+ ? ~0
+ : HandleToID_cast(GLuint, size_t, pathParameterTemplate);
+
+ GL_CALL_NVPATH_EXT(glPathGlyphRangeNV(
+ pathID, m_Conversion.fromPathFontTargetToGL(fontTarget), fontName,
+ m_Conversion.fromPathFontStyleToGL(fontStyle), firstGlyph, (GLsizei)numGlyphs,
+ m_Conversion.fromPathMissingGlyphsToGL(handleMissingGlyphs), pathTemplateID, emScale));
+ }
+
+ void NVRenderBackendGL4Impl::GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathGlyphFontMetricFlags metricQueryMask,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes, size_t stride,
+ QT3DSF32 *metrics)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glGetPathMetricsNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask),
+ (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type),
+ charCodes, pathID, (GLsizei)stride, metrics));
+ }
+
+ void
+ NVRenderBackendGL4Impl::GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathGlyphFontMetricFlags metricQueryMask,
+ size_t stride, QT3DSF32 *metrics)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glGetPathMetricRangeNV(m_Conversion.fromPathMetricQueryFlagsToGL(metricQueryMask),
+ pathID, (GLsizei)numPaths, (GLsizei)stride, metrics));
+ }
+
+ void NVRenderBackendGL4Impl::GetPathSpacing(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathListMode::Enum pathListMode,
+ NVRenderPathFormatType::Enum type, const void *charCodes, QT3DSF32 advanceScale,
+ QT3DSF32 kerningScale, NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing)
+ {
+ GLuint pathID = HandleToID_cast(GLuint, size_t, po);
+
+ GL_CALL_NVPATH_EXT(glGetPathSpacingNV(m_Conversion.fromPathListModeToGL(pathListMode),
+ (GLsizei)numPaths, m_Conversion.fromPathTypeToGL(type),
+ charCodes, pathID, advanceScale, kerningScale,
+ m_Conversion.fromPathTransformToGL(transformType), spacing));
+ }
+}
+}
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h
new file mode 100644
index 00000000..bfdc03b7
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGL4.h
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_GL4_H
+#define QT3DS_RENDER_BACKEND_GL4_H
+
+/// @file Qt3DSRenderBackendGL4.h
+/// NVRender OpenGL 4 backend definition.
+
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/gl/Qt3DSRenderBackendGL3.h"
+
+namespace qt3ds {
+namespace render {
+
+ using namespace foundation;
+
+ class NVRenderBackendGL4Impl : public NVRenderBackendGL3Impl
+ {
+ public:
+ /// constructor
+ NVRenderBackendGL4Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format);
+ /// destructor
+ virtual ~NVRenderBackendGL4Impl();
+
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ public:
+ void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override;
+ void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode,
+ NVRenderComponentTypes::Enum type, const void *indirect) override;
+
+ void CreateTextureStorage2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 levels,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height) override;
+
+ void SetMultisampledTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ size_t samples,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height,
+ bool fixedsamplelocations) override;
+
+ void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count, const void *value,
+ bool transpose) override;
+
+ void SetPatchVertexCount(NVRenderBackendInputAssemblerObject iao, QT3DSU32 count) override;
+ virtual NVRenderBackendTessControlShaderObject
+ CreateTessControlShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) override;
+ virtual NVRenderBackendTessEvaluationShaderObject
+ CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) override;
+ virtual NVRenderBackendGeometryShaderObject
+ CreateGeometryShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override;
+
+ QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override;
+ void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf) override;
+ void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override;
+ void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level,
+ bool layered, QT3DSI32 layer,
+ NVRenderImageAccessType::Enum access,
+ NVRenderTextureFormats::Enum format) override;
+
+ virtual NVRenderBackendComputeShaderObject
+ CreateComputeShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override;
+ void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX,
+ QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override;
+
+ NVRenderBackendProgramPipeline CreateProgramPipeline() override;
+ void ReleaseProgramPipeline(NVRenderBackendProgramPipeline ppo) override;
+ void SetActiveProgramPipeline(NVRenderBackendProgramPipeline ppo) override;
+ void SetProgramStages(NVRenderBackendProgramPipeline ppo,
+ NVRenderShaderTypeFlags flags,
+ NVRenderBackendShaderProgramObject po) override;
+
+ void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override;
+ void SetBlendBarrier(void) override;
+
+ NVRenderBackendPathObject CreatePathNVObject(size_t range) override;
+ void SetPathSpecification(NVRenderBackendPathObject inPathObject,
+ NVConstDataRef<QT3DSU8> inPathCommands,
+ NVConstDataRef<QT3DSF32> inPathCoords) override;
+ NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject inPathObject) override;
+ NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject inPathObject) override;
+ NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject inPathObject) override;
+ void SetStrokeWidth(NVRenderBackendPathObject inPathObject, QT3DSF32 inStrokeWidth) override;
+
+ void SetPathProjectionMatrix(const QT3DSMat44 inPathProjection) override;
+ void SetPathModelViewMatrix(const QT3DSMat44 inPathModelview) override;
+ void SetPathStencilDepthOffset(QT3DSF32 inSlope, QT3DSF32 inBias) override;
+ void SetPathCoverDepthFunc(NVRenderBoolOp::Enum inDepthFunction) override;
+ void StencilStrokePath(NVRenderBackendPathObject inPathObject) override;
+ void StencilFillPath(NVRenderBackendPathObject inPathObject) override;
+ void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override;
+
+ void StencilFillPathInstanced(
+ NVRenderBackendPathObject po, size_t numPaths, NVRenderPathFormatType::Enum type,
+ const void *charCodes, NVRenderPathFillMode::Enum fillMode, QT3DSU32 stencilMask,
+ NVRenderPathTransformType::Enum transformType, const QT3DSF32 *transformValues) override;
+ void StencilStrokePathInstancedN(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes, QT3DSI32 stencilRef,
+ QT3DSU32 stencilMask,
+ NVRenderPathTransformType::Enum transformType,
+ const QT3DSF32 *transformValues) override;
+ void CoverFillPathInstanced(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes,
+ NVRenderPathCoverMode::Enum coverMode,
+ NVRenderPathTransformType::Enum transformType,
+ const QT3DSF32 *transformValues) override;
+ void CoverStrokePathInstanced(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathFormatType::Enum type,
+ const void *charCodes,
+ NVRenderPathCoverMode::Enum coverMode,
+ NVRenderPathTransformType::Enum transformType,
+ const QT3DSF32 *transformValues) override;
+ void LoadPathGlyphs(NVRenderBackendPathObject po,
+ NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle, size_t numGlyphs,
+ NVRenderPathFormatType::Enum type, const void *charCodes,
+ NVRenderPathMissingGlyphs::Enum handleMissingGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override;
+ virtual NVRenderPathReturnValues::Enum
+ LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget,
+ const void *fontName, NVRenderPathFontStyleFlags fontStyle,
+ QT3DSU32 firstGlyphIndex, size_t numGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override;
+ virtual NVRenderBackendPathObject
+ LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum fontTarget, const void *fontName,
+ NVRenderPathFontStyleFlags fontStyle,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale,
+ QT3DSU32 *count) override;
+ void LoadPathGlyphRange(NVRenderBackendPathObject po,
+ NVRenderPathFontTarget::Enum fontTarget,
+ const void *fontName, NVRenderPathFontStyleFlags fontStyle,
+ QT3DSU32 firstGlyph, size_t numGlyphs,
+ NVRenderPathMissingGlyphs::Enum handleMissingGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate,
+ QT3DSF32 emScale) override;
+ void GetPathMetrics(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathGlyphFontMetricFlags metricQueryMask,
+ NVRenderPathFormatType::Enum type, const void *charCodes,
+ size_t stride, QT3DSF32 *metrics) override;
+ void GetPathMetricsRange(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathGlyphFontMetricFlags metricQueryMask,
+ size_t stride, QT3DSF32 *metrics) override;
+ void GetPathSpacing(NVRenderBackendPathObject po, size_t numPaths,
+ NVRenderPathListMode::Enum pathListMode,
+ NVRenderPathFormatType::Enum type, const void *charCodes,
+ QT3DSF32 advanceScale, QT3DSF32 kerningScale,
+ NVRenderPathTransformType::Enum transformType, QT3DSF32 *spacing) override;
+ private:
+#if !defined(QT_OPENGL_ES)
+ QOpenGLExtension_NV_path_rendering *m_nvPathRendering;
+ QOpenGLExtension_EXT_direct_state_access *m_directStateAccess;
+#endif
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp
new file mode 100644
index 00000000..940ab094
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.cpp
@@ -0,0 +1,2220 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/backends/gl/Qt3DSRenderBackendGLBase.h"
+#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h"
+#include "foundation/StringTable.h"
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__)
+#else
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError()
+#endif
+
+#define GL_CALL_FUNCTION(x) m_glFunctions->x; RENDER_LOG_ERROR_PARAMS(x);
+#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; RENDER_LOG_ERROR_PARAMS(x);
+
+namespace qt3ds {
+namespace render {
+
+#ifndef GL_PROGRAM_SEPARABLE
+#define GL_PROGRAM_SEPARABLE 0x8258
+#endif
+
+#ifndef GL_UNSIGNED_INT_IMAGE_2D
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#endif
+
+#ifndef GL_UNSIGNED_INT_ATOMIC_COUNTER
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#endif
+
+ /// constructor
+ NVRenderBackendGLBase::NVRenderBackendGLBase(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format)
+ : mRefCount(0)
+ , m_Foundation(fnd)
+ , m_StringTable(stringTable)
+ , m_Conversion()
+ , m_MaxAttribCount(0)
+ , m_DrawBuffersArray(m_Foundation.getAllocator(),
+ "NVRenderBackendGLBase::m_DrawBuffersArray")
+ , m_format(format)
+ {
+ m_glFunctions = new QOpenGLFunctions;
+ m_glFunctions->initializeOpenGLFunctions();
+ m_glExtraFunctions = new QOpenGLExtraFunctions;
+ m_glExtraFunctions->initializeOpenGLFunctions();
+
+ // internal state tracker
+ m_pCurrentRasterizerState =
+ QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendRasterizerStateGL)();
+ m_pCurrentDepthStencilState =
+ QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)();
+ }
+ /// destructor
+ NVRenderBackendGLBase::~NVRenderBackendGLBase()
+ {
+ if (m_pCurrentRasterizerState)
+ NVDelete(m_Foundation.getAllocator(), m_pCurrentRasterizerState);
+ if (m_pCurrentDepthStencilState)
+ NVDelete(m_Foundation.getAllocator(), m_pCurrentDepthStencilState);
+ if (m_glFunctions)
+ delete m_glFunctions;
+ if (m_glExtraFunctions)
+ delete m_glExtraFunctions;
+ }
+
+ NVRenderContextType NVRenderBackendGLBase::GetRenderContextType() const
+ {
+ if (m_format.renderableType() == QSurfaceFormat::OpenGLES) {
+ if (m_format.majorVersion() == 2)
+ return NVRenderContextValues::GLES2;
+
+ if (m_format.majorVersion() == 3) {
+ if (m_format.minorVersion() >= 1)
+ return NVRenderContextValues::GLES3PLUS;
+ else
+ return NVRenderContextValues::GLES3;
+ }
+ } else if (m_format.majorVersion() == 2) {
+ return NVRenderContextValues::GL2;
+ } else if (m_format.majorVersion() == 3) {
+ return NVRenderContextValues::GL3;
+ } else if (m_format.majorVersion() == 4) {
+ return NVRenderContextValues::GL4;
+ }
+
+ return NVRenderContextValues::NullContext;
+ }
+
+ bool NVRenderBackendGLBase::isESCompatible() const
+ {
+ return m_format.renderableType() == QSurfaceFormat::OpenGLES;
+ }
+
+ const char *NVRenderBackendGLBase::GetShadingLanguageVersion()
+ {
+ const char *retval = (const char *)GL_CALL_FUNCTION(
+ glGetString(GL_SHADING_LANGUAGE_VERSION));
+ if (retval == NULL)
+ return "";
+
+ return retval;
+ }
+
+ QT3DSU32
+ NVRenderBackendGLBase::GetMaxCombinedTextureUnits()
+ {
+ QT3DSI32 maxUnits;
+ GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxUnits));
+ return maxUnits;
+ }
+
+ bool NVRenderBackendGLBase::GetRenderBackendCap(
+ NVRenderBackend::NVRenderBackendCaps::Enum inCap) const
+ {
+ bool bSupported = false;
+
+ switch (inCap) {
+ case NVRenderBackendCaps::FpRenderTarget:
+ bSupported = m_backendSupport.caps.bits.bFPRenderTargetsSupported;
+ break;
+ case NVRenderBackendCaps::DepthStencilTexture:
+ bSupported = m_backendSupport.caps.bits.bDepthStencilSupported;
+ break;
+ case NVRenderBackendCaps::ConstantBuffer:
+ bSupported = m_backendSupport.caps.bits.bConstantBufferSupported;
+ break;
+ case NVRenderBackendCaps::DxtImages:
+ bSupported = m_backendSupport.caps.bits.bDXTImagesSupported;
+ break;
+ case NVRenderBackendCaps::MsTexture:
+ bSupported = m_backendSupport.caps.bits.bMsTextureSupported;
+ break;
+ case NVRenderBackendCaps::TexSwizzle:
+ bSupported = m_backendSupport.caps.bits.bTextureSwizzleSupported;
+ break;
+ case NVRenderBackendCaps::FastBlits:
+ bSupported = m_backendSupport.caps.bits.bFastBlitsSupported;
+ break;
+ case NVRenderBackendCaps::Tessellation:
+ bSupported = m_backendSupport.caps.bits.bTessellationSupported;
+ break;
+ case NVRenderBackendCaps::Compute:
+ bSupported = m_backendSupport.caps.bits.bComputeSupported;
+ break;
+ case NVRenderBackendCaps::Geometry:
+ bSupported = m_backendSupport.caps.bits.bGeometrySupported;
+ break;
+ case NVRenderBackendCaps::SampleQuery: {
+ // On the following context sample query is not supported
+ NVRenderContextType noSamplesQuerySupportedContextFlags(NVRenderContextValues::GL2
+ | NVRenderContextValues::GLES2);
+ NVRenderContextType ctxType = GetRenderContextType();
+ bSupported = !(ctxType & noSamplesQuerySupportedContextFlags);
+ } break;
+ case NVRenderBackendCaps::TimerQuery:
+ bSupported = m_backendSupport.caps.bits.bTimerQuerySupported;
+ break;
+ case NVRenderBackendCaps::CommandSync: {
+ // On the following context sync objects are not supported
+ NVRenderContextType noSyncObjectSupportedContextFlags(NVRenderContextValues::GL2
+ | NVRenderContextValues::GLES2);
+ NVRenderContextType ctxType = GetRenderContextType();
+ bSupported = !(ctxType & noSyncObjectSupportedContextFlags);
+ } break;
+ case NVRenderBackendCaps::TextureArray: {
+ // On the following context texture arrays are not supported
+ NVRenderContextType noTextureArraySupportedContextFlags(NVRenderContextValues::GL2
+ | NVRenderContextValues::GLES2);
+ NVRenderContextType ctxType = GetRenderContextType();
+ bSupported = !(ctxType & noTextureArraySupportedContextFlags);
+ } break;
+ case NVRenderBackendCaps::StorageBuffer:
+ bSupported = m_backendSupport.caps.bits.bStorageBufferSupported;
+ break;
+ case NVRenderBackendCaps::AtomicCounterBuffer:
+ bSupported = m_backendSupport.caps.bits.bAtomicCounterBufferSupported;
+ break;
+ case NVRenderBackendCaps::ShaderImageLoadStore:
+ bSupported = m_backendSupport.caps.bits.bShaderImageLoadStoreSupported;
+ break;
+ case NVRenderBackendCaps::ProgramPipeline:
+ bSupported = m_backendSupport.caps.bits.bProgramPipelineSupported;
+ break;
+ case NVRenderBackendCaps::PathRendering:
+ bSupported = m_backendSupport.caps.bits.bNVPathRenderingSupported;
+ break;
+ case NVRenderBackendCaps::AdvancedBlend:
+ bSupported = m_backendSupport.caps.bits.bNVAdvancedBlendSupported |
+ m_backendSupport.caps.bits.bKHRAdvancedBlendSupported;
+ break;
+ case NVRenderBackendCaps::AdvancedBlendKHR:
+ bSupported = m_backendSupport.caps.bits.bKHRAdvancedBlendSupported;
+ break;
+ case NVRenderBackendCaps::BlendCoherency:
+ bSupported = m_backendSupport.caps.bits.bNVBlendCoherenceSupported |
+ m_backendSupport.caps.bits.bKHRBlendCoherenceSupported;
+ break;
+ case NVRenderBackendCaps::gpuShader5:
+ bSupported = m_backendSupport.caps.bits.bGPUShader5ExtensionSupported;
+ break;
+ case NVRenderBackendCaps::VertexArrayObject:
+ bSupported = m_backendSupport.caps.bits.bVertexArrayObjectSupported;
+ break;
+ case NVRenderBackendCaps::StandardDerivatives:
+ bSupported = m_backendSupport.caps.bits.bStandardDerivativesSupported;
+ break;
+ case NVRenderBackendCaps::TextureLod:
+ bSupported = m_backendSupport.caps.bits.bTextureLodSupported;
+ break;
+ default:
+ QT3DS_ASSERT(false);
+ bSupported = false;
+ break;
+ }
+
+ return bSupported;
+ }
+
+ void NVRenderBackendGLBase::GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery,
+ QT3DSI32 *params) const
+ {
+ if (params) {
+ switch (inQuery) {
+ case NVRenderBackendQuery::MaxTextureSize:
+ GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_TEXTURE_SIZE, params));
+ break;
+ case NVRenderBackendQuery::MaxTextureArrayLayers: {
+ NVRenderContextType noTextureArraySupportedContextFlags(
+ NVRenderContextValues::GL2 | NVRenderContextValues::GLES2);
+ NVRenderContextType ctxType = GetRenderContextType();
+ if (!(ctxType & noTextureArraySupportedContextFlags)) {
+ GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, params));
+ } else {
+ *params = 0;
+ }
+ } break;
+ case NVRenderBackendQuery::MaxConstantBufferSlots: {
+ NVRenderContextType noConstantBufferSupportedContextFlags(
+ NVRenderContextValues::GL2 | NVRenderContextValues::GLES2);
+ NVRenderContextType ctxType = GetRenderContextType();
+ if (!(ctxType & noConstantBufferSupportedContextFlags)) {
+ GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, params));
+ } else {
+ *params = 0;
+ }
+ } break;
+ case NVRenderBackendQuery::MaxConstantBufferBlockSize: {
+ NVRenderContextType noConstantBufferSupportedContextFlags(
+ NVRenderContextValues::GL2 | NVRenderContextValues::GLES2);
+ NVRenderContextType ctxType = GetRenderContextType();
+ if (!(ctxType & noConstantBufferSupportedContextFlags)) {
+ GL_CALL_FUNCTION(glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, params));
+ } else {
+ *params = 0;
+ }
+ } break;
+ default:
+ QT3DS_ASSERT(false);
+ *params = 0;
+ break;
+ }
+ }
+ }
+
+ QT3DSU32
+ NVRenderBackendGLBase::GetDepthBits() const
+ {
+ QT3DSI32 depthBits;
+ GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_BITS, &depthBits));
+ return depthBits;
+ }
+
+ QT3DSU32
+ NVRenderBackendGLBase::GetStencilBits() const
+ {
+ QT3DSI32 stencilBits;
+ GL_CALL_FUNCTION(glGetIntegerv(GL_STENCIL_BITS, &stencilBits));
+ return stencilBits;
+ }
+
+ void NVRenderBackendGLBase::SetMultisample(bool bEnable)
+ {
+ QT3DS_ASSERT(m_backendSupport.caps.bits.bMsTextureSupported || !bEnable);
+ // For GL ES explicit multisample enabling is not needed
+ // and does not exist
+ NVRenderContextType noMsaaEnableContextFlags(NVRenderContextValues::GLES2
+ | NVRenderContextValues::GLES3
+ | NVRenderContextValues::GLES3PLUS);
+ NVRenderContextType ctxType = GetRenderContextType();
+ if (!(ctxType & noMsaaEnableContextFlags)) {
+ SetRenderState(bEnable, NVRenderState::Multisample);
+ }
+ }
+
+ void NVRenderBackendGLBase::SetRenderState(bool bEnable, const NVRenderState::Enum value)
+ {
+ if (value == NVRenderState::DepthWrite) {
+ GL_CALL_FUNCTION(glDepthMask(bEnable));
+ } else {
+ if (bEnable) {
+ GL_CALL_FUNCTION(glEnable(m_Conversion.fromRenderStateToGL(value)));
+ } else {
+ GL_CALL_FUNCTION(glDisable(m_Conversion.fromRenderStateToGL(value)));
+ }
+ }
+ }
+
+ NVRenderBackend::NVRenderBackendDepthStencilStateObject
+ NVRenderBackendGLBase::CreateDepthStencilState(
+ bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc, bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack)
+ {
+ NVRenderBackendDepthStencilStateGL *retval =
+ QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendDepthStencilStateGL)(
+ enableDepth, depthMask, depthFunc, enableStencil, stencilFuncFront, stencilFuncBack,
+ depthStencilOpFront, depthStencilOpBack);
+
+ return (NVRenderBackend::NVRenderBackendDepthStencilStateObject)retval;
+ }
+
+ void NVRenderBackendGLBase::ReleaseDepthStencilState(
+ NVRenderBackendDepthStencilStateObject inDepthStencilState)
+ {
+ NVRenderBackendDepthStencilStateGL *inputState =
+ (NVRenderBackendDepthStencilStateGL *)inDepthStencilState;
+ if (inputState)
+ NVDelete(m_Foundation.getAllocator(), inputState);
+ }
+
+ NVRenderBackend::NVRenderBackendRasterizerStateObject
+ NVRenderBackendGLBase::CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale,
+ NVRenderFaces::Enum cullFace)
+ {
+ NVRenderBackendRasterizerStateGL *retval =
+ QT3DS_NEW(m_Foundation.getAllocator(),
+ NVRenderBackendRasterizerStateGL)(depthBias, depthScale, cullFace);
+
+ return (NVRenderBackend::NVRenderBackendRasterizerStateObject)retval;
+ }
+
+ void NVRenderBackendGLBase::ReleaseRasterizerState(
+ NVRenderBackendRasterizerStateObject rasterizerState)
+ {
+ NVRenderBackendRasterizerStateGL *inputState =
+ (NVRenderBackendRasterizerStateGL *)rasterizerState;
+ if (inputState)
+ NVDelete(m_Foundation.getAllocator(), inputState);
+ }
+
+ void NVRenderBackendGLBase::SetDepthStencilState(
+ NVRenderBackendDepthStencilStateObject inDepthStencilState)
+ {
+ NVRenderBackendDepthStencilStateGL *inputState =
+ (NVRenderBackendDepthStencilStateGL *)inDepthStencilState;
+ if (inputState && !(*m_pCurrentDepthStencilState == *inputState)) {
+ // we check on a per single state base
+ if (inputState->m_DepthEnable != m_pCurrentDepthStencilState->m_DepthEnable) {
+ SetRenderState(inputState->m_DepthEnable, NVRenderState::DepthTest);
+ m_pCurrentDepthStencilState->m_DepthEnable = inputState->m_DepthEnable;
+ }
+ if (inputState->m_StencilEnable != m_pCurrentDepthStencilState->m_StencilEnable) {
+ SetRenderState(inputState->m_StencilEnable, NVRenderState::StencilTest);
+ m_pCurrentDepthStencilState->m_StencilEnable = inputState->m_StencilEnable;
+ }
+
+ if (inputState->m_DepthMask != m_pCurrentDepthStencilState->m_DepthMask) {
+ GL_CALL_FUNCTION(glDepthMask(inputState->m_DepthMask));
+ m_pCurrentDepthStencilState->m_DepthMask = inputState->m_DepthMask;
+ }
+
+ if (inputState->m_DepthFunc != m_pCurrentDepthStencilState->m_DepthFunc) {
+ GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(inputState->m_DepthFunc)));
+ m_pCurrentDepthStencilState->m_DepthFunc = inputState->m_DepthFunc;
+ }
+
+ if (!(inputState->m_DepthStencilOpFront
+ == m_pCurrentDepthStencilState->m_DepthStencilOpFront)) {
+ GL_CALL_FUNCTION(glStencilOpSeparate(
+ GL_FRONT,
+ m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_StencilFail),
+ m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthFail),
+ m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpFront.m_DepthPass)));
+ m_pCurrentDepthStencilState->m_DepthStencilOpFront =
+ inputState->m_DepthStencilOpFront;
+ }
+
+ if (!(inputState->m_DepthStencilOpBack
+ == m_pCurrentDepthStencilState->m_DepthStencilOpBack)) {
+ GL_CALL_FUNCTION(glStencilOpSeparate(
+ GL_BACK,
+ m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_StencilFail),
+ m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthFail),
+ m_Conversion.fromStencilOpToGL(inputState->m_DepthStencilOpBack.m_DepthPass)));
+ m_pCurrentDepthStencilState->m_DepthStencilOpBack =
+ inputState->m_DepthStencilOpBack;
+ }
+
+ if (!(inputState->m_StencilFuncFront
+ == m_pCurrentDepthStencilState->m_StencilFuncFront)) {
+ GL_CALL_FUNCTION(glStencilFuncSeparate(
+ GL_FRONT,
+ m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncFront.m_Function),
+ inputState->m_StencilFuncFront.m_ReferenceValue,
+ inputState->m_StencilFuncFront.m_Mask));
+ m_pCurrentDepthStencilState->m_StencilFuncFront = inputState->m_StencilFuncFront;
+ }
+
+ if (!(inputState->m_StencilFuncBack
+ == m_pCurrentDepthStencilState->m_StencilFuncBack)) {
+ GL_CALL_FUNCTION(glStencilFuncSeparate(
+ GL_BACK, m_Conversion.fromBoolOpToGL(inputState->m_StencilFuncBack.m_Function),
+ inputState->m_StencilFuncBack.m_ReferenceValue,
+ inputState->m_StencilFuncBack.m_Mask));
+ m_pCurrentDepthStencilState->m_StencilFuncBack = inputState->m_StencilFuncBack;
+ }
+ }
+ }
+
+ void
+ NVRenderBackendGLBase::SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState)
+ {
+ NVRenderBackendRasterizerStateGL *inputState =
+ (NVRenderBackendRasterizerStateGL *)rasterizerState;
+ if (inputState && !(*m_pCurrentRasterizerState == *inputState)) {
+ // store current state
+ *m_pCurrentRasterizerState = *inputState;
+
+ if (m_pCurrentRasterizerState->m_DepthBias != 0.0
+ || m_pCurrentRasterizerState->m_DepthScale != 0.0) {
+ GL_CALL_FUNCTION(glEnable(GL_POLYGON_OFFSET_FILL));
+ } else {
+ GL_CALL_FUNCTION(glDisable(GL_POLYGON_OFFSET_FILL));
+ }
+
+ GL_CALL_FUNCTION(glPolygonOffset(m_pCurrentRasterizerState->m_DepthBias,
+ m_pCurrentRasterizerState->m_DepthScale));
+
+ GL_CALL_FUNCTION(
+ glCullFace(m_Conversion.fromFacesToGL(m_pCurrentRasterizerState->m_CullFace)));
+ }
+ }
+
+ bool NVRenderBackendGLBase::GetRenderState(const NVRenderState::Enum value)
+ {
+ bool enabled = GL_CALL_FUNCTION(glIsEnabled(m_Conversion.fromRenderStateToGL(value)));
+ return enabled;
+ }
+
+ NVRenderBoolOp::Enum NVRenderBackendGLBase::GetDepthFunc()
+ {
+ QT3DSI32 value;
+ GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_FUNC, &value));
+ return m_Conversion.fromGLToBoolOp(value);
+ }
+
+ void NVRenderBackendGLBase::SetDepthFunc(const NVRenderBoolOp::Enum func)
+ {
+ GL_CALL_FUNCTION(glDepthFunc(m_Conversion.fromBoolOpToGL(func)));
+ }
+
+ bool NVRenderBackendGLBase::GetDepthWrite()
+ {
+ QT3DSI32 value;
+ GL_CALL_FUNCTION(glGetIntegerv(GL_DEPTH_WRITEMASK, (GLint *)&value));
+ return value ? true : false;
+ }
+
+ void NVRenderBackendGLBase::SetDepthWrite(bool bEnable) { GL_CALL_FUNCTION(glDepthMask(bEnable)); }
+
+ void NVRenderBackendGLBase::SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha)
+ {
+ GL_CALL_FUNCTION(glColorMask(bRed, bGreen, bBlue, bAlpha));
+ }
+
+ void NVRenderBackendGLBase::GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg)
+ {
+ QT3DS_ASSERT(pBlendFuncArg);
+ QT3DSI32_4 values;
+
+ GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_RGB, (GLint *)&values.x));
+ GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint *)&values.y));
+ GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_RGB, (GLint *)&values.z));
+ GL_CALL_FUNCTION(glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint *)&values.w));
+
+ pBlendFuncArg->m_SrcRGB = m_Conversion.fromGLToSrcBlendFunc(values.x);
+ pBlendFuncArg->m_SrcAlpha = m_Conversion.fromGLToSrcBlendFunc(values.y);
+ pBlendFuncArg->m_DstRGB = m_Conversion.fromGLToDstBlendFunc(values.z);
+ pBlendFuncArg->m_DstAlpha = m_Conversion.fromGLToDstBlendFunc(values.w);
+ }
+
+ void NVRenderBackendGLBase::SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg)
+ {
+ QT3DSI32_4 values;
+
+ values.x = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcRGB);
+ values.y = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstRGB);
+ values.z = m_Conversion.fromSrcBlendFuncToGL(blendFuncArg.m_SrcAlpha);
+ values.w = m_Conversion.fromDstBlendFuncToGL(blendFuncArg.m_DstAlpha);
+
+ GL_CALL_FUNCTION(glBlendFuncSeparate(values.x, values.y, values.z, values.w));
+ }
+
+ void NVRenderBackendGLBase::SetBlendEquation(const NVRenderBlendEquationArgument &)
+ {
+ // needs GL4 / GLES 3.1
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::SetBlendBarrier()
+ {
+ // needs GL4 / GLES 3.1
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GetScissorRect(NVRenderRect *pRect)
+ {
+ QT3DS_ASSERT(pRect);
+ GL_CALL_FUNCTION(glGetIntegerv(GL_SCISSOR_BOX, (GLint *)pRect));
+ }
+
+ void NVRenderBackendGLBase::SetScissorRect(const NVRenderRect &rect)
+ {
+ GL_CALL_FUNCTION(glScissor(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height));
+ }
+
+ void NVRenderBackendGLBase::GetViewportRect(NVRenderRect *pRect)
+ {
+ QT3DS_ASSERT(pRect);
+ GL_CALL_FUNCTION(glGetIntegerv(GL_VIEWPORT, (GLint *)pRect));
+ }
+
+ void NVRenderBackendGLBase::SetViewportRect(const NVRenderRect &rect)
+ {
+ GL_CALL_FUNCTION(glViewport(rect.m_X, rect.m_Y, rect.m_Width, rect.m_Height););
+ }
+
+ void NVRenderBackendGLBase::SetClearColor(const QT3DSVec4 *pClearColor)
+ {
+ QT3DS_ASSERT(pClearColor);
+
+ GL_CALL_FUNCTION(glClearColor(pClearColor->x, pClearColor->y,
+ pClearColor->z, pClearColor->w));
+ }
+
+ void NVRenderBackendGLBase::Clear(NVRenderClearFlags flags)
+ {
+ GL_CALL_FUNCTION(glClear(m_Conversion.fromClearFlagsToGL(flags)));
+ }
+
+ NVRenderBackend::NVRenderBackendBufferObject
+ NVRenderBackendGLBase::CreateBuffer(size_t size, NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usage, const void *hostPtr)
+ {
+ GLuint bufID = 0;
+
+ GL_CALL_FUNCTION(glGenBuffers(1, &bufID));
+
+ if (bufID && size) {
+ GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags);
+ if (target != GL_INVALID_ENUM) {
+ GL_CALL_FUNCTION(glBindBuffer(target, bufID));
+ GL_CALL_FUNCTION(glBufferData(target, size, hostPtr,
+ m_Conversion.fromBufferUsageTypeToGL(usage)));
+ } else {
+ GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID));
+ bufID = 0;
+ qCCritical(GL_ERROR, GLConversion::processGLError(target));
+ }
+ }
+
+ return (NVRenderBackend::NVRenderBackendBufferObject)bufID;
+ }
+
+ void NVRenderBackendGLBase::BindBuffer(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags)
+ {
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GL_CALL_FUNCTION(glBindBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags), bufID));
+ }
+
+ void NVRenderBackendGLBase::ReleaseBuffer(NVRenderBackendBufferObject bo)
+ {
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GL_CALL_FUNCTION(glDeleteBuffers(1, &bufID));
+ }
+
+ void NVRenderBackendGLBase::UpdateBuffer(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags, size_t size,
+ NVRenderBufferUsageType::Enum usage, const void *data)
+ {
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags);
+ GL_CALL_FUNCTION(glBindBuffer(target, bufID));
+ GL_CALL_FUNCTION(glBufferData(target, size, data, m_Conversion.fromBufferUsageTypeToGL(usage)));
+ }
+
+ void NVRenderBackendGLBase::UpdateBufferRange(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags, size_t offset,
+ size_t size, const void *data)
+ {
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GLenum target = m_Conversion.fromBindBufferFlagsToGL(bindFlags);
+ GL_CALL_FUNCTION(glBindBuffer(target, bufID));
+ GL_CALL_FUNCTION(glBufferSubData(target, offset, size, data));
+ }
+
+ void *NVRenderBackendGLBase::MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags,
+ size_t, size_t, NVRenderBufferAccessFlags)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return NULL;
+ }
+
+ bool NVRenderBackendGLBase::UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return true;
+ }
+
+ void NVRenderBackendGLBase::SetMemoryBarrier(NVRenderBufferBarrierFlags)
+ {
+ // needs GL 4 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLBase::CreateQuery()
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return NVRenderBackendQueryObject(0);
+ }
+
+ void NVRenderBackendGLBase::ReleaseQuery(NVRenderBackendQueryObject)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject,
+ NVRenderQueryResultType::Enum, QT3DSU32 *)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GetQueryResult(NVRenderBackendQueryObject,
+ NVRenderQueryResultType::Enum, QT3DSU64 *)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::SetQueryTimer(NVRenderBackendQueryObject)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ NVRenderBackend::NVRenderBackendSyncObject
+ NVRenderBackendGLBase::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return NVRenderBackendSyncObject(0);
+ }
+
+ void NVRenderBackendGLBase::ReleaseSync(NVRenderBackendSyncObject)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags,
+ QT3DSU64)
+ {
+ // needs GL 3 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLBase::CreateRenderTarget()
+ {
+ GLuint fboID = 0;
+
+ GL_CALL_FUNCTION(glGenFramebuffers(1, &fboID));
+
+ return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID;
+ }
+
+ void NVRenderBackendGLBase::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto)
+ {
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ if (fboID) {
+ GL_CALL_FUNCTION(glDeleteFramebuffers(1, &fboID));
+ }
+ }
+
+ void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo)
+ {
+ // rto must be the current render target
+ GLuint rbID = HandleToID_cast(GLuint, size_t, rbo);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+
+ GL_CALL_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER, rbID));
+ }
+
+ void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target)
+ {
+ // rto must be the current render target
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+
+ QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D
+ || m_backendSupport.caps.bits.bMsTextureSupported);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ GL_CALL_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID, 0))
+ }
+
+ void NVRenderBackendGLBase::RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum,
+ NVRenderBackendTextureObject, QT3DSI32, QT3DSI32)
+ {
+ // Needs GL3 or GLES 3
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::SetRenderTarget(NVRenderBackendRenderTargetObject rto)
+ {
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ GL_CALL_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
+ }
+
+ bool NVRenderBackendGLBase::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */)
+ {
+ // rto must be the current render target
+ GLenum completeStatus = GL_CALL_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ switch (completeStatus) {
+#define HANDLE_INCOMPLETE_STATUS(x) \
+ case x: \
+ qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \
+ return false;
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED)
+#undef HANDLE_INCOMPLETE_STATUS
+ }
+ return true;
+ }
+
+ NVRenderBackend::NVRenderBackendRenderbufferObject
+ NVRenderBackendGLBase::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height)
+ {
+ GLuint bufID = 0;
+
+ GL_CALL_FUNCTION(glGenRenderbuffers(1, &bufID));
+ GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID));
+ GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER,
+ GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat),
+ (GLsizei)width, (GLsizei)height));
+
+ // check for error
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR, GLConversion::processGLError(error));
+ QT3DS_ASSERT(false);
+ GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID));
+ bufID = 0;
+ }
+
+ GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0));
+
+ return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID;
+ }
+
+ void NVRenderBackendGLBase::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo)
+ {
+ GLuint bufID = HandleToID_cast(GLuint, size_t, rbo);
+
+ if (bufID) {
+ GL_CALL_FUNCTION(glDeleteRenderbuffers(1, &bufID));
+ }
+ }
+
+ bool NVRenderBackendGLBase::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height)
+ {
+ bool success = true;
+ GLuint bufID = HandleToID_cast(GLuint, size_t, rbo);
+
+ QT3DS_ASSERT(bufID);
+
+ GL_CALL_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID));
+ GL_CALL_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER,
+ GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat),
+ (GLsizei)width, (GLsizei)height));
+
+ // check for error
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR, GLConversion::processGLError(error));
+ QT3DS_ASSERT(false);
+ success = false;
+ }
+
+ return success;
+ }
+
+ NVRenderBackend::NVRenderBackendTextureObject NVRenderBackendGLBase::CreateTexture()
+ {
+ GLuint texID = 0;
+
+ GL_CALL_FUNCTION(glGenTextures(1, &texID));
+ return (NVRenderBackend::NVRenderBackendTextureObject)texID;
+ }
+
+ void NVRenderBackendGLBase::BindTexture(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 unit)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0 + unit));
+ GL_CALL_FUNCTION(glBindTexture(m_Conversion.fromTextureTargetToGL(target), texID));
+ }
+
+ void NVRenderBackendGLBase::BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool,
+ QT3DSI32, NVRenderImageAccessType::Enum,
+ NVRenderTextureFormats::Enum)
+ {
+ // needs GL 4 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::ReleaseTexture(NVRenderBackendTextureObject to)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GL_CALL_FUNCTION(glDeleteTextures(1, &texID));
+ }
+
+ void NVRenderBackendGLBase::SetTextureData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format, const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTarget, texID));
+ bool conversionRequired = format != internalFormat;
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat))
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+
+ if (conversionRequired) {
+ GLenum dummy;
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, dummy);
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ } else if (NVRenderTextureFormats::isDepthTextureFormat(format))
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+
+ GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height,
+ border, glformat, gltype, hostPtr));
+
+ GL_CALL_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ // This will look very SetTextureData2D, but the target for glBindTexture will be different from
+ // the target for
+ // glTexImage2D.
+ void NVRenderBackendGLBase::SetTextureDataCubeFace(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format, const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GLenum glTexTarget =
+ m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID));
+ bool conversionRequired = format != internalFormat;
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ internalFormat = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(),
+ internalFormat, swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = GL_UNSIGNED_BYTE;
+
+ if (NVRenderTextureFormats::isUncompressedTextureFormat(internalFormat))
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
+ glformat, gltype, glInternalFormat);
+
+
+ if (conversionRequired) {
+ GLenum dummy;
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, dummy);
+ } else if (NVRenderTextureFormats::isCompressedTextureFormat(internalFormat)) {
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ glInternalFormat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ } else if (NVRenderTextureFormats::isDepthTextureFormat(format))
+ m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+
+ // for es2 internal format must be same as format
+ if (GetRenderContextType() == NVRenderContextValues::GLES2)
+ glInternalFormat = glformat;
+
+ GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height,
+ border, glformat, gltype, hostPtr));
+
+ GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0));
+ }
+
+ void NVRenderBackendGLBase::CreateTextureStorage2D(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32,
+ NVRenderTextureFormats::Enum, size_t, size_t)
+ {
+ // you need GL 4.2 or GLES 3.1
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::SetTextureSubData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset,
+ size_t width, size_t height,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTarget, texID));
+
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ format = m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), format,
+ swizzleMode);
+
+ GLenum glformat = 0, glInternalFormat = 0, gltype = 0;
+ m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
+ gltype, glInternalFormat);
+ GL_CALL_FUNCTION(glTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width,
+ (GLsizei)height, glformat, gltype, hostPtr));
+
+ GL_CALL_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ void NVRenderBackendGLBase::SetCompressedTextureData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border,
+ size_t imageSize, const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTarget, texID));
+
+ GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width,
+ (GLsizei)height, border, (GLsizei)imageSize, hostPtr));
+
+ GL_CALL_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ void NVRenderBackendGLBase::SetCompressedTextureDataCubeFace(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width, size_t height, QT3DSI32 border,
+ size_t imageSize, const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GLenum glTexTarget =
+ m_Conversion.fromTextureTargetToGL(NVRenderTextureTargetType::TextureCube);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTexTarget, texID));
+
+ GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(internalFormat);
+ GL_CALL_FUNCTION(glCompressedTexImage2D(glTarget, level, glformat, (GLsizei)width,
+ (GLsizei)height, border, (GLsizei)imageSize, hostPtr));
+
+ GL_CALL_FUNCTION(glBindTexture(glTexTarget, 0));
+ }
+
+ void NVRenderBackendGLBase::SetCompressedTextureSubData2D(
+ NVRenderBackendTextureObject to, NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height,
+ NVRenderTextureFormats::Enum format, size_t imageSize, const void *hostPtr)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTarget, texID));
+
+ GLenum glformat = m_Conversion.fromCompressedTextureFormatToGL(format);
+ GL_CALL_FUNCTION(glCompressedTexSubImage2D(glTarget, level, xOffset, yOffset, (GLsizei)width,
+ (GLsizei)height, glformat, (GLsizei)imageSize,
+ hostPtr));
+
+ GL_CALL_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ void NVRenderBackendGLBase::SetTextureData3D(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32,
+ NVRenderTextureFormats::Enum, size_t, size_t,
+ size_t, QT3DSI32, NVRenderTextureFormats::Enum,
+ const void *)
+ {
+ // needs GL3 or GLES3
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum genType)
+ {
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+ GL_CALL_FUNCTION(glActiveTexture(GL_TEXTURE0));
+ GL_CALL_FUNCTION(glBindTexture(glTarget, texID));
+
+ GLenum glValue = GLConversion::fromHintToGL(genType);
+ GL_CALL_FUNCTION(glHint(GL_GENERATE_MIPMAP_HINT, glValue));
+ GL_CALL_FUNCTION(glGenerateMipmap(glTarget));
+
+ GL_CALL_FUNCTION(glBindTexture(glTarget, 0));
+ }
+
+ NVRenderTextureSwizzleMode::Enum
+ NVRenderBackendGLBase::GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const
+ {
+ NVRenderTextureSwizzleMode::Enum swizzleMode = NVRenderTextureSwizzleMode::NoSwizzle;
+ m_Conversion.replaceDeprecatedTextureFormat(GetRenderContextType(), inFormat, swizzleMode);
+
+ return swizzleMode;
+ }
+
+ NVRenderBackend::NVRenderBackendSamplerObject NVRenderBackendGLBase::CreateSampler(
+ NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter,
+ NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT,
+ NVRenderTextureCoordOp::Enum wrapR, QT3DSI32 minLod, QT3DSI32 maxLod, QT3DSF32 lodBias,
+ NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc,
+ QT3DSF32 anisotropy, QT3DSF32 *borderColor)
+ {
+ // Satisfy the compiler
+ // We don"t setup the state here for GL
+ // but we need to pass on the variables here
+ // to satisfy the interface
+ NVRENDER_BACKEND_UNUSED(minFilter);
+ NVRENDER_BACKEND_UNUSED(magFilter);
+ NVRENDER_BACKEND_UNUSED(wrapS);
+ NVRENDER_BACKEND_UNUSED(wrapT);
+ NVRENDER_BACKEND_UNUSED(wrapR);
+ NVRENDER_BACKEND_UNUSED(minLod);
+ NVRENDER_BACKEND_UNUSED(maxLod);
+ NVRENDER_BACKEND_UNUSED(lodBias);
+ NVRENDER_BACKEND_UNUSED(compareMode);
+ NVRENDER_BACKEND_UNUSED(compareFunc);
+ NVRENDER_BACKEND_UNUSED(anisotropy);
+ NVRENDER_BACKEND_UNUSED(borderColor);
+
+ // return a dummy handle
+ return (NVRenderBackend::NVRenderBackendSamplerObject)0x0001;
+ }
+
+ void NVRenderBackendGLBase::UpdateSampler(
+ NVRenderBackendSamplerObject /* so */, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter, NVRenderTextureMagnifyingOp::Enum magFilter,
+ NVRenderTextureCoordOp::Enum wrapS, NVRenderTextureCoordOp::Enum wrapT,
+ NVRenderTextureCoordOp::Enum wrapR, QT3DSF32 minLod, QT3DSF32 maxLod, QT3DSF32 lodBias,
+ NVRenderTextureCompareMode::Enum compareMode, NVRenderTextureCompareOp::Enum compareFunc,
+ QT3DSF32 anisotropy, QT3DSF32 *borderColor)
+ {
+ // Satisfy the compiler
+ // These are not available in GLES 2 and we don't use them right now
+ NVRENDER_BACKEND_UNUSED(wrapR);
+ NVRENDER_BACKEND_UNUSED(lodBias);
+ NVRENDER_BACKEND_UNUSED(minLod);
+ NVRENDER_BACKEND_UNUSED(maxLod);
+ NVRENDER_BACKEND_UNUSED(compareMode);
+ NVRENDER_BACKEND_UNUSED(compareFunc);
+ NVRENDER_BACKEND_UNUSED(borderColor);
+
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER,
+ m_Conversion.fromTextureMinifyingOpToGL(minFilter)));
+ GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER,
+ m_Conversion.fromTextureMagnifyingOpToGL(magFilter)));
+ GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_S,
+ m_Conversion.fromTextureCoordOpToGL(wrapS)));
+ GL_CALL_FUNCTION(glTexParameteri(glTarget, GL_TEXTURE_WRAP_T,
+ m_Conversion.fromTextureCoordOpToGL(wrapT)));
+ if (m_backendSupport.caps.bits.bAnistropySupported) {
+ GL_CALL_FUNCTION(glTexParameterf(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy));
+ }
+ }
+
+ void NVRenderBackendGLBase::UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSI32 baseLevel, QT3DSI32 maxLevel)
+ {
+ NVRENDER_BACKEND_UNUSED(to);
+ NVRENDER_BACKEND_UNUSED(target);
+ NVRENDER_BACKEND_UNUSED(baseLevel);
+ NVRENDER_BACKEND_UNUSED(maxLevel);
+ }
+
+ void NVRenderBackendGLBase::UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode)
+ {
+ NVRENDER_BACKEND_UNUSED(to);
+ NVRENDER_BACKEND_UNUSED(target);
+
+ // Nothing to do here still might be called
+ QT3DS_ASSERT(swizzleMode == NVRenderTextureSwizzleMode::NoSwizzle);
+
+ NVRENDER_BACKEND_UNUSED(swizzleMode);
+ }
+
+ void NVRenderBackendGLBase::ReleaseSampler(NVRenderBackendSamplerObject so)
+ {
+ GLuint samplerID = HandleToID_cast(GLuint, size_t, so);
+ if (!samplerID)
+ return;
+ // otherwise nothing to do
+ }
+
+ NVRenderBackend::NVRenderBackendAttribLayoutObject
+ NVRenderBackendGLBase::CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs)
+ {
+ QT3DSU32 attribLayoutSize = sizeof(NVRenderBackendAttributeLayoutGL);
+ QT3DSU32 entrySize = sizeof(NVRenderBackendLayoutEntryGL) * attribs.size();
+ QT3DSU8 *newMem = (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), attribLayoutSize + entrySize,
+ "BackendAttributeLayoutGL");
+ NVDataRef<NVRenderBackendLayoutEntryGL> entryRef =
+ PtrAtOffset<NVRenderBackendLayoutEntryGL>(newMem, attribLayoutSize, entrySize);
+ QT3DSU32 maxInputSlot = 0;
+
+ // copy data
+ QT3DS_FOREACH(idx, attribs.size())
+ {
+ entryRef[idx].m_AttribName = m_StringTable->RegisterStr(attribs.mData[idx].m_Name);
+ entryRef[idx].m_Normalize = 0;
+ entryRef[idx].m_AttribIndex = 0; // will be set later
+ entryRef[idx].m_Type = m_Conversion.fromComponentTypeAndNumCompsToAttribGL(
+ attribs.mData[idx].m_ComponentType, attribs.mData[idx].m_NumComponents);
+ entryRef[idx].m_NumComponents = attribs.mData[idx].m_NumComponents;
+ entryRef[idx].m_InputSlot = attribs.mData[idx].m_InputSlot;
+ entryRef[idx].m_Offset = attribs.mData[idx].m_FirstItemOffset;
+
+ if (maxInputSlot < entryRef[idx].m_InputSlot)
+ maxInputSlot = entryRef[idx].m_InputSlot;
+ }
+
+ NVRenderBackendAttributeLayoutGL *retval =
+ new (newMem) NVRenderBackendAttributeLayoutGL(entryRef, maxInputSlot);
+
+ return (NVRenderBackend::NVRenderBackendAttribLayoutObject)retval;
+ }
+
+ void NVRenderBackendGLBase::ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao)
+ {
+ NVRenderBackendAttributeLayoutGL *attribLayout = (NVRenderBackendAttributeLayoutGL *)ao;
+
+ NVDelete(m_Foundation.getAllocator(), attribLayout);
+ };
+
+ NVRenderBackend::NVRenderBackendInputAssemblerObject
+ NVRenderBackendGLBase::CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout,
+ NVConstDataRef<NVRenderBackendBufferObject> buffers,
+ const NVRenderBackendBufferObject indexBuffer,
+ NVConstDataRef<QT3DSU32> strides,
+ NVConstDataRef<QT3DSU32> offsets,
+ QT3DSU32 patchVertexCount)
+ {
+ NVRenderBackendAttributeLayoutGL *attribLayoutGL =
+ (NVRenderBackendAttributeLayoutGL *)attribLayout;
+
+ NVRenderBackendInputAssemblerGL *retval = QT3DS_NEW(m_Foundation.getAllocator(),
+ NVRenderBackendInputAssemblerGL)(
+ m_Foundation, attribLayoutGL, buffers, indexBuffer, strides, offsets, patchVertexCount);
+
+ return (NVRenderBackend::NVRenderBackendInputAssemblerObject)retval;
+ }
+
+ void NVRenderBackendGLBase::ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao)
+ {
+ NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao;
+ NVDelete(m_Foundation.getAllocator(), inputAssembler);
+ }
+
+ bool NVRenderBackendGLBase::compileSource(GLuint shaderID, NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ GLint shaderSourceSize = static_cast<GLint>(source.size());
+ const char *shaderSourceData = (const char *)source.begin();
+ GLint shaderStatus = GL_TRUE;
+
+ if (!binary) {
+
+ GL_CALL_FUNCTION(glShaderSource(shaderID, 1, &shaderSourceData, &shaderSourceSize));
+ GL_CALL_FUNCTION(glCompileShader(shaderID));
+
+ GLint logLen;
+ GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_COMPILE_STATUS, &shaderStatus));
+ GL_CALL_FUNCTION(glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLen));
+
+ // Check if some log exists. We also write warnings here
+ // Should at least contain more than the null termination
+ if (logLen > 2) {
+ errorMessage.resize(logLen + 1);
+
+ GLint lenWithoutNull;
+ GL_CALL_FUNCTION(glGetShaderInfoLog(shaderID, logLen, &lenWithoutNull,
+ (char *)errorMessage.c_str()));
+ }
+ } else {
+ GL_CALL_FUNCTION(glShaderBinary(1, &shaderID, GL_NVIDIA_PLATFORM_BINARY_NV, shaderSourceData,
+ shaderSourceSize));
+ GLenum binaryError = m_glFunctions->glGetError();
+ if (binaryError != GL_NO_ERROR) {
+ shaderStatus = GL_FALSE;
+ qCCritical(GL_ERROR, GLConversion::processGLError(binaryError));
+ }
+ }
+
+ return (shaderStatus == GL_TRUE);
+ }
+
+ NVRenderBackend::NVRenderBackendVertexShaderObject
+ NVRenderBackendGLBase::CreateVertexShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_VERTEX_SHADER));
+
+ if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) {
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ shaderID = 0;
+ }
+
+ return (NVRenderBackend::NVRenderBackendVertexShaderObject)shaderID;
+ }
+
+ NVRenderBackend::NVRenderBackendFragmentShaderObject
+ NVRenderBackendGLBase::CreateFragmentShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ GLuint shaderID = GL_CALL_FUNCTION(glCreateShader(GL_FRAGMENT_SHADER));
+
+ if (shaderID && !compileSource(shaderID, source, errorMessage, binary)) {
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ shaderID = 0;
+ }
+
+ return (NVRenderBackend::NVRenderBackendFragmentShaderObject)shaderID;
+ }
+
+ NVRenderBackend::NVRenderBackendTessControlShaderObject
+ NVRenderBackendGLBase::CreateTessControlShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ // needs GL 4 or GLES EXT_tessellation_shader support
+ NVRENDER_BACKEND_UNUSED(source);
+ NVRENDER_BACKEND_UNUSED(errorMessage);
+ NVRENDER_BACKEND_UNUSED(binary);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return (NVRenderBackend::NVRenderBackendTessControlShaderObject)0;
+ }
+
+ NVRenderBackend::NVRenderBackendTessEvaluationShaderObject
+ NVRenderBackendGLBase::CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ // needs GL 4 or GLES EXT_tessellation_shader support
+ NVRENDER_BACKEND_UNUSED(source);
+ NVRENDER_BACKEND_UNUSED(errorMessage);
+ NVRENDER_BACKEND_UNUSED(binary);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return (NVRenderBackend::NVRenderBackendTessEvaluationShaderObject)0;
+ }
+
+ NVRenderBackend::NVRenderBackendGeometryShaderObject
+ NVRenderBackendGLBase::CreateGeometryShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ // needs GL 4 or GLES EXT_geometry_shader support
+ NVRENDER_BACKEND_UNUSED(source);
+ NVRENDER_BACKEND_UNUSED(errorMessage);
+ NVRENDER_BACKEND_UNUSED(binary);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return (NVRenderBackend::NVRenderBackendGeometryShaderObject)0;
+ }
+
+ NVRenderBackend::NVRenderBackendComputeShaderObject
+ NVRenderBackendGLBase::CreateComputeShader(NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary)
+ {
+ // needs GL 4.3 or GLES3.1 support
+ NVRENDER_BACKEND_UNUSED(source);
+ NVRENDER_BACKEND_UNUSED(errorMessage);
+ NVRENDER_BACKEND_UNUSED(binary);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return (NVRenderBackend::NVRenderBackendComputeShaderObject)0;
+ }
+
+ void NVRenderBackendGLBase::ReleaseVertexShader(NVRenderBackendVertexShaderObject vso)
+ {
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, vso);
+
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ }
+
+ void NVRenderBackendGLBase::ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso)
+ {
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, fso);
+
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ }
+
+ void
+ NVRenderBackendGLBase::ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso)
+ {
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso);
+
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ }
+
+ void NVRenderBackendGLBase::ReleaseTessEvaluationShader(
+ NVRenderBackendTessEvaluationShaderObject teso)
+ {
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, teso);
+
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ }
+
+ void NVRenderBackendGLBase::ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso)
+ {
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, gso);
+
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ }
+
+ void NVRenderBackendGLBase::ReleaseComputeShader(NVRenderBackendComputeShaderObject cso)
+ {
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, cso);
+
+ GL_CALL_FUNCTION(glDeleteShader(shaderID));
+ }
+
+ void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendVertexShaderObject vso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, vso);
+
+ GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendFragmentShaderObject fso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, fso);
+
+ GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessControlShaderObject tcso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso);
+
+ GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessEvaluationShaderObject teso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, teso);
+
+ GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendGeometryShaderObject gso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, gso);
+
+ GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendComputeShaderObject cso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, cso);
+
+ GL_CALL_FUNCTION(glAttachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendVertexShaderObject vso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, vso);
+
+ GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendFragmentShaderObject fso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, fso);
+
+ GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessControlShaderObject tcso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, tcso);
+
+ GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessEvaluationShaderObject teso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, teso);
+
+ GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendGeometryShaderObject gso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, gso);
+
+ GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ void NVRenderBackendGLBase::DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendComputeShaderObject cso)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint shaderID = HandleToID_cast(GLuint, size_t, cso);
+
+ GL_CALL_FUNCTION(glDetachShader(static_cast<GLuint>(pProgram->m_ProgramID), shaderID));
+ }
+
+ NVRenderBackend::NVRenderBackendShaderProgramObject
+ NVRenderBackendGLBase::CreateShaderProgram(bool isSeparable)
+ {
+ NVRenderBackendShaderProgramGL *theProgram = NULL;
+ GLuint programID = GL_CALL_FUNCTION(glCreateProgram());
+
+ if (programID) {
+ theProgram =
+ QT3DS_NEW(m_Foundation.getAllocator(), NVRenderBackendShaderProgramGL)(programID);
+
+ if (!theProgram) {
+ GL_CALL_FUNCTION(glDeleteProgram(programID));
+ } else if (isSeparable && m_backendSupport.caps.bits.bProgramPipelineSupported) {
+ GL_CALL_EXTRA_FUNCTION(glProgramParameteri(programID, GL_PROGRAM_SEPARABLE, GL_TRUE));
+ }
+ }
+
+ return (NVRenderBackend::NVRenderBackendShaderProgramObject)theProgram;
+ }
+
+ void NVRenderBackendGLBase::ReleaseShaderProgram(NVRenderBackendShaderProgramObject po)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_FUNCTION(glDeleteProgram(programID));
+
+ if (pProgram->m_shaderInput) {
+ NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput);
+ pProgram->m_shaderInput = NULL;
+ }
+
+ NVDelete(m_Foundation.getAllocator(), pProgram);
+ }
+
+ bool NVRenderBackendGLBase::LinkProgram(NVRenderBackendShaderProgramObject po,
+ eastl::string &errorMessage)
+ {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_FUNCTION(glLinkProgram(programID));
+
+ GLint linkStatus, logLen;
+ GL_CALL_FUNCTION(glGetProgramiv(programID, GL_LINK_STATUS, &linkStatus));
+ GL_CALL_FUNCTION(glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLen));
+
+ // if succesfuly linked get the attribute information
+ if (linkStatus) {
+ // release old stuff
+ if (pProgram->m_shaderInput) {
+ NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput);
+ pProgram->m_shaderInput = NULL;
+ }
+
+ GLint numAttribs;
+ GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTES, &numAttribs));
+
+ if (numAttribs) {
+ NVRenderBackendShaderInputEntryGL *tempShaderInputEntry =
+ (NVRenderBackendShaderInputEntryGL *)QT3DS_ALLOC(
+ m_Foundation.getAllocator(),
+ sizeof(NVRenderBackendShaderInputEntryGL) * m_MaxAttribCount,
+ "BackendShaderInputEntryGL");
+
+ GLint maxLength;
+ GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength));
+ QT3DSI8 *nameBuf =
+ (QT3DSI8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), maxLength, "LinkProgram");
+
+ // fill in data
+ QT3DSU32 count = 0;
+ QT3DS_FOREACH(idx, numAttribs)
+ {
+ GLint size = 0;
+ GLenum glType;
+ NVRenderComponentTypes::Enum compType = NVRenderComponentTypes::Unknown;
+ QT3DSU32 numComps = 0;
+
+ GL_CALL_FUNCTION(glGetActiveAttrib(programID, idx, maxLength, NULL, &size, &glType,
+ (char *)nameBuf));
+ // Skip anything named with gl_
+ if (memcmp(nameBuf, "gl_", 3) == 0)
+ continue;
+
+ m_Conversion.fromAttribGLToComponentTypeAndNumComps(glType, compType, numComps);
+
+ tempShaderInputEntry[count].m_AttribName =
+ m_StringTable->RegisterStr((char *)nameBuf);
+ tempShaderInputEntry[count].m_AttribLocation =
+ GL_CALL_FUNCTION(glGetAttribLocation(programID, (char *)nameBuf));
+ tempShaderInputEntry[count].m_Type = glType;
+ tempShaderInputEntry[count].m_NumComponents = numComps;
+
+ ++count;
+ }
+
+ // Now allocate space for the actuall entries
+ QT3DSU32 shaderInputSize = sizeof(NVRenderBackendShaderInputGL);
+ QT3DSU32 entrySize = sizeof(NVRenderBackendShaderInputEntryGL) * count;
+ QT3DSU8 *newMem =
+ (QT3DSU8 *)QT3DS_ALLOC(m_Foundation.getAllocator(), shaderInputSize + entrySize,
+ "BackendShaderInputEntryGL");
+ NVDataRef<NVRenderBackendShaderInputEntryGL> entryRef =
+ PtrAtOffset<NVRenderBackendShaderInputEntryGL>(newMem, shaderInputSize,
+ entrySize);
+ // fill data
+ QT3DS_FOREACH(idx, count)
+ {
+ entryRef[idx].m_AttribName = tempShaderInputEntry[idx].m_AttribName;
+ entryRef[idx].m_AttribLocation = tempShaderInputEntry[idx].m_AttribLocation;
+ entryRef[idx].m_Type = tempShaderInputEntry[idx].m_Type;
+ entryRef[idx].m_NumComponents = tempShaderInputEntry[idx].m_NumComponents;
+ }
+
+ // placement new
+ NVRenderBackendShaderInputGL *shaderInput =
+ new (newMem) NVRenderBackendShaderInputGL(entryRef);
+ // set the pointer
+ pProgram->m_shaderInput = shaderInput;
+
+ QT3DS_FREE(m_Foundation.getAllocator(), nameBuf);
+ QT3DS_FREE(m_Foundation.getAllocator(), tempShaderInputEntry);
+ }
+ }
+
+ // Check if some log exists. We also write warnings here
+ // Should at least contain more than the null termination
+ if (logLen > 2) {
+ errorMessage.resize(logLen + 1);
+
+ GLint lenWithoutNull;
+ GL_CALL_FUNCTION(glGetProgramInfoLog(programID, logLen, &lenWithoutNull,
+ (char *)errorMessage.c_str()));
+ }
+
+ return (linkStatus == GL_TRUE);
+ }
+
+ void NVRenderBackendGLBase::SetActiveProgram(NVRenderBackendShaderProgramObject po)
+ {
+ GLuint programID = 0;
+
+ if (po) {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ }
+
+ GL_CALL_FUNCTION(glUseProgram(programID));
+ }
+
+ NVRenderBackend::NVRenderBackendProgramPipeline NVRenderBackendGLBase::CreateProgramPipeline()
+ {
+ // needs GL 4 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ return NVRenderBackend::NVRenderBackendProgramPipeline(0);
+ }
+
+ void NVRenderBackendGLBase::ReleaseProgramPipeline(NVRenderBackendProgramPipeline)
+ {
+ // needs GL 4 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::SetActiveProgramPipeline(NVRenderBackendProgramPipeline)
+ {
+ // needs GL 4 context
+ //TODO: should be fixed?
+ // QT3DS_ASSERT(false);
+ }
+
+ void NVRenderBackendGLBase::SetProgramStages(NVRenderBackendProgramPipeline,
+ NVRenderShaderTypeFlags,
+ NVRenderBackendShaderProgramObject)
+ {
+ // needs GL 4 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32,
+ QT3DSU32)
+ {
+ // needs GL 4 context
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ QT3DSI32 NVRenderBackendGLBase::GetConstantCount(NVRenderBackendShaderProgramObject po)
+ {
+ QT3DS_ASSERT(po);
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GLint numUniforms;
+ GL_CALL_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORMS, &numUniforms));
+
+ return numUniforms;
+ }
+
+ QT3DSI32 NVRenderBackendGLBase::GetConstantBufferCount(NVRenderBackendShaderProgramObject po)
+ {
+ // needs GL3 and above
+ NVRENDER_BACKEND_UNUSED(po);
+
+ return 0;
+ }
+
+ QT3DSI32
+ NVRenderBackendGLBase::GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 bufSize, QT3DSI32 *numElem,
+ NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding,
+ char *nameBuf)
+ {
+ QT3DS_ASSERT(po);
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GLenum glType;
+ GL_CALL_FUNCTION(glGetActiveUniform(programID, id, bufSize, NULL, numElem, &glType, nameBuf));
+ *type = m_Conversion.fromShaderGLToPropertyDataTypes(glType);
+
+ QT3DSI32 uniformLoc = GL_CALL_FUNCTION(glGetUniformLocation(programID, nameBuf));
+
+ // get unit binding point
+ *binding = -1;
+ if (uniformLoc != -1 && (glType == GL_IMAGE_2D || glType == GL_UNSIGNED_INT_IMAGE_2D
+ || glType == GL_UNSIGNED_INT_ATOMIC_COUNTER)) {
+ GL_CALL_FUNCTION(glGetUniformiv(programID, uniformLoc, binding));
+ }
+
+ return uniformLoc;
+ }
+
+ QT3DSI32
+ NVRenderBackendGLBase::GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf)
+ {
+ // needs GL3 and above
+ NVRENDER_BACKEND_UNUSED(po);
+ NVRENDER_BACKEND_UNUSED(id);
+ NVRENDER_BACKEND_UNUSED(nameBufSize);
+ NVRENDER_BACKEND_UNUSED(paramCount);
+ NVRENDER_BACKEND_UNUSED(bufferSize);
+ NVRENDER_BACKEND_UNUSED(length);
+ NVRENDER_BACKEND_UNUSED(nameBuf);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return -1;
+ }
+
+ void NVRenderBackendGLBase::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSI32 *indices)
+ {
+ // needs GL3 and above
+ NVRENDER_BACKEND_UNUSED(po);
+ NVRENDER_BACKEND_UNUSED(id);
+ NVRENDER_BACKEND_UNUSED(indices);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GetConstantBufferParamInfoByIndices(
+ NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset)
+ {
+ // needs GL3 and above
+ NVRENDER_BACKEND_UNUSED(po);
+ NVRENDER_BACKEND_UNUSED(count);
+ NVRENDER_BACKEND_UNUSED(indices);
+ NVRENDER_BACKEND_UNUSED(type);
+ NVRENDER_BACKEND_UNUSED(size);
+ NVRENDER_BACKEND_UNUSED(offset);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding)
+ {
+ // needs GL3 and above
+ NVRENDER_BACKEND_UNUSED(po);
+ NVRENDER_BACKEND_UNUSED(blockIndex);
+ NVRENDER_BACKEND_UNUSED(binding);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::ProgramSetConstantBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+ {
+ // needs GL3 and above
+ NVRENDER_BACKEND_UNUSED(index);
+ NVRENDER_BACKEND_UNUSED(bo);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ QT3DSI32 NVRenderBackendGLBase::GetStorageBufferCount(NVRenderBackendShaderProgramObject po)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(po);
+
+ return 0;
+ }
+
+ QT3DSI32
+ NVRenderBackendGLBase::GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(po);
+ NVRENDER_BACKEND_UNUSED(id);
+ NVRENDER_BACKEND_UNUSED(nameBufSize);
+ NVRENDER_BACKEND_UNUSED(paramCount);
+ NVRENDER_BACKEND_UNUSED(bufferSize);
+ NVRENDER_BACKEND_UNUSED(length);
+ NVRENDER_BACKEND_UNUSED(nameBuf);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return -1;
+ }
+
+ void NVRenderBackendGLBase::ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(index);
+ NVRENDER_BACKEND_UNUSED(bo);
+ }
+
+ QT3DSI32 NVRenderBackendGLBase::GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(po);
+
+ return 0;
+ }
+
+ QT3DSI32
+ NVRenderBackendGLBase::GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize,
+ QT3DSI32 *paramCount, QT3DSI32 *bufferSize,
+ QT3DSI32 *length, char *nameBuf)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(po);
+ NVRENDER_BACKEND_UNUSED(id);
+ NVRENDER_BACKEND_UNUSED(nameBufSize);
+ NVRENDER_BACKEND_UNUSED(paramCount);
+ NVRENDER_BACKEND_UNUSED(bufferSize);
+ NVRENDER_BACKEND_UNUSED(length);
+ NVRENDER_BACKEND_UNUSED(nameBuf);
+
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return -1;
+ }
+
+ void NVRenderBackendGLBase::ProgramSetAtomicCounterBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(index);
+ NVRENDER_BACKEND_UNUSED(bo);
+ }
+
+ void NVRenderBackendGLBase::SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32 id,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count,
+ const void *value, bool transpose)
+ {
+ GLenum glType = m_Conversion.fromPropertyDataTypesToShaderGL(type);
+
+ switch (glType) {
+ case GL_FLOAT:
+ GL_CALL_FUNCTION(glUniform1fv(id, count, (GLfloat *)value));
+ break;
+ case GL_FLOAT_VEC2:
+ GL_CALL_FUNCTION(glUniform2fv(id, count, (GLfloat *)value));
+ break;
+ case GL_FLOAT_VEC3:
+ GL_CALL_FUNCTION(glUniform3fv(id, count, (GLfloat *)value));
+ break;
+ case GL_FLOAT_VEC4:
+ GL_CALL_FUNCTION(glUniform4fv(id, count, (GLfloat *)value));
+ break;
+ case GL_INT:
+ GL_CALL_FUNCTION(glUniform1iv(id, count, (GLint *)value));
+ break;
+ case GL_BOOL:
+ {
+ GLint boolValue = *(GLboolean *)value;
+ GL_CALL_FUNCTION(glUniform1iv(id, count, &boolValue));
+ }
+ break;
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ GL_CALL_FUNCTION(glUniform2iv(id, count, (GLint *)value));
+ break;
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ GL_CALL_FUNCTION(glUniform3iv(id, count, (GLint *)value));
+ break;
+ case GL_INT_VEC4:
+ case GL_BOOL_VEC4:
+ GL_CALL_FUNCTION(glUniform4iv(id, count, (GLint *)value));
+ break;
+ case GL_FLOAT_MAT3:
+ GL_CALL_FUNCTION(glUniformMatrix3fv(id, count, transpose, (GLfloat *)value));
+ break;
+ case GL_FLOAT_MAT4:
+ GL_CALL_FUNCTION(glUniformMatrix4fv(id, count, transpose, (GLfloat *)value));
+ break;
+ case GL_IMAGE_2D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE: {
+ if (count > 1) {
+ GLint *sampler = (GLint *)value;
+ GL_CALL_FUNCTION(glUniform1iv(id, count, sampler));
+ } else {
+ GLint sampler = *(GLint *)value;
+ GL_CALL_FUNCTION(glUniform1i(id, sampler));
+ }
+ } break;
+ default:
+ qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type);
+ QT3DS_ASSERT(false);
+ break;
+ }
+ }
+
+ void NVRenderBackendGLBase::Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count)
+ {
+ GL_CALL_FUNCTION(glDrawArrays(m_Conversion.fromDrawModeToGL(
+ drawMode, m_backendSupport.caps.bits.bTessellationSupported),
+ start, count));
+ }
+
+ void NVRenderBackendGLBase::DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(drawMode);
+ NVRENDER_BACKEND_UNUSED(indirect);
+ }
+
+ void NVRenderBackendGLBase::DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count,
+ NVRenderComponentTypes::Enum type, const void *indices)
+ {
+ GL_CALL_FUNCTION(glDrawElements(m_Conversion.fromDrawModeToGL(
+ drawMode, m_backendSupport.caps.bits.bTessellationSupported),
+ count, m_Conversion.fromIndexBufferComponentsTypesToGL(type),
+ indices));
+ }
+
+ void NVRenderBackendGLBase::DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode,
+ NVRenderComponentTypes::Enum type,
+ const void *indirect)
+ {
+ // needs GL4 and above
+ NVRENDER_BACKEND_UNUSED(drawMode);
+ NVRENDER_BACKEND_UNUSED(type);
+ NVRENDER_BACKEND_UNUSED(indirect);
+ }
+
+ void NVRenderBackendGLBase::ReadPixel(NVRenderBackendRenderTargetObject /* rto */, QT3DSI32 x,
+ QT3DSI32 y, QT3DSI32 width, QT3DSI32 height,
+ NVRenderReadPixelFormats::Enum inFormat, void *pixels)
+ {
+ GLuint glFormat;
+ GLuint glType;
+ if (m_Conversion.fromReadPixelsToGlFormatAndType(inFormat, &glFormat, &glType)) {
+ GL_CALL_FUNCTION(glReadPixels(x, y, width, height, glFormat, glType, pixels));
+ }
+ }
+
+ NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::CreatePathNVObject(size_t)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return NVRenderBackend::NVRenderBackendPathObject(0);
+ }
+
+ void NVRenderBackendGLBase::ReleasePathNVObject(NVRenderBackendPathObject, size_t)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::LoadPathGlyphs(NVRenderBackendPathObject,
+ NVRenderPathFontTarget::Enum, const void *,
+ NVRenderPathFontStyleFlags, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathMissingGlyphs::Enum,
+ NVRenderBackendPathObject, QT3DSF32)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::LoadPathGlyphRange(NVRenderBackendPathObject,
+ NVRenderPathFontTarget::Enum, const void *,
+ NVRenderPathFontStyleFlags, QT3DSU32, size_t,
+ NVRenderPathMissingGlyphs::Enum,
+ NVRenderBackendPathObject, QT3DSF32)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ NVRenderPathReturnValues::Enum NVRenderBackendGLBase::LoadPathGlyphsIndexed(
+ NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *,
+ NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject, QT3DSF32)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+
+ return NVRenderPathReturnValues::FontUnavailable;
+ }
+
+ NVRenderBackend::NVRenderBackendPathObject NVRenderBackendGLBase::LoadPathGlyphsIndexedRange(
+ NVRenderPathFontTarget::Enum, const void *, NVRenderPathFontStyleFlags,
+ NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *)
+ {
+ return NVRenderBackendPathObject(0);
+ }
+
+ void NVRenderBackendGLBase::GetPathMetrics(NVRenderBackendPathObject, size_t,
+ NVRenderPathGlyphFontMetricFlags,
+ NVRenderPathFormatType::Enum, const void *, size_t,
+ QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GetPathMetricsRange(NVRenderBackendPathObject, size_t,
+ NVRenderPathGlyphFontMetricFlags, size_t,
+ QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::GetPathSpacing(NVRenderBackendPathObject, size_t,
+ NVRenderPathListMode::Enum,
+ NVRenderPathFormatType::Enum, const void *, QT3DSF32,
+ QT3DSF32, NVRenderPathTransformType::Enum, QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::StencilFillPathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathFillMode::Enum, QT3DSU32,
+ NVRenderPathTransformType::Enum,
+ const QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum,
+ const void *, QT3DSI32, QT3DSU32,
+ NVRenderPathTransformType::Enum,
+ const QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::CoverFillPathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathCoverMode::Enum,
+ NVRenderPathTransformType::Enum,
+ const QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ void NVRenderBackendGLBase::CoverStrokePathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathCoverMode::Enum,
+ NVRenderPathTransformType::Enum,
+ const QT3DSF32 *)
+ {
+ // Needs GL 4 backend
+ qCCritical(INVALID_OPERATION) << QObject::tr("Unsupported method: ") << __FUNCTION__;
+ }
+
+ ///< private calls
+ const char *NVRenderBackendGLBase::getVersionString()
+ {
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VERSION));
+ if (retval == NULL)
+ return "";
+
+ return retval;
+ }
+
+ const char *NVRenderBackendGLBase::getVendorString()
+ {
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VENDOR));
+ if (retval == NULL)
+ return "";
+
+ return retval;
+ }
+
+ const char *NVRenderBackendGLBase::getRendererString()
+ {
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER));
+ if (retval == NULL)
+ return "";
+
+ return retval;
+ }
+
+ const char *NVRenderBackendGLBase::getExtensionString()
+ {
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS));
+ if (retval == NULL)
+ return "";
+
+ return retval;
+ }
+
+ /**
+ * @brief This function inspects the various strings to setup
+ * HW capabilities of the device.
+ * We can do a lot of smart things here based on GL version
+ * renderer string and vendor.
+ *
+ * @return No return
+ */
+ void NVRenderBackendGLBase::setAndInspectHardwareCaps()
+ {
+ eastl::string apiVersion(getVersionString());
+ qCInfo(TRACE_INFO, "GL version: %s", apiVersion.c_str());
+
+ // we assume all GLES versions running on mobile with shared memory
+ // this means framebuffer blits are slow and should be optimized or avoided
+ if (apiVersion.find("OpenGL ES") == eastl::string::npos) {
+ // no ES device
+ m_backendSupport.caps.bits.bFastBlitsSupported = true;
+ }
+ }
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+ void NVRenderBackendGLBase::checkGLError(const char *function, const char *file,
+ const unsigned int line) const
+ {
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR) << GLConversion::processGLError(error) << " "
+ << function << " " << file << " " << line;
+ }
+ }
+#else
+ void NVRenderBackendGLBase::checkGLError() const
+ {
+#if !defined(NDEBUG) || defined(_DEBUG)
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR)
+ qCCritical(GL_ERROR) << GLConversion::processGLError(error);
+#endif
+ }
+#endif
+
+}
+}
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h
new file mode 100644
index 00000000..9048a9c4
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendGLBase.h
@@ -0,0 +1,530 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_GL_BASE_H
+#define QT3DS_RENDER_BACKEND_GL_BASE_H
+
+/// @file Qt3DSRenderBackendGLBase.h
+/// NVRender OpenGL Core backend definition.
+
+#include "foundation/Qt3DSContainers.h"
+#include "foundation/StringTable.h"
+#include "render/backends/Qt3DSRenderBackend.h"
+#include "render/backends/gl/Qt3DSOpenGLUtil.h"
+#include <EASTL/string.h>
+
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QOpenGLFunctions>
+#include <QtOpenGLExtensions/QtOpenGLExtensions>
+
+#define NVRENDER_BACKEND_UNUSED(arg) (void)arg;
+
+// Enable this to log opengl errors instead of an assert
+//#define RENDER_BACKEND_LOG_GL_ERRORS
+
+namespace qt3ds {
+namespace render {
+
+ ///< forward declaration
+ class NVRenderBackendRasterizerStateGL;
+ class NVRenderBackendDepthStencilStateGL;
+
+ using namespace foundation;
+
+ typedef eastl::basic_string<char8_t, ForwardingAllocator> TContextStr;
+
+ class NVRenderBackendGLBase : public NVRenderBackend
+ {
+ public:
+ /// constructor
+ NVRenderBackendGLBase(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format);
+ /// destructor
+ virtual ~NVRenderBackendGLBase();
+
+ public:
+ /// API Interface
+ NVRenderContextType GetRenderContextType() const override;
+ bool isESCompatible() const;
+
+ const char *GetShadingLanguageVersion() override;
+ /// get implementation depended values
+ QT3DSU32 GetMaxCombinedTextureUnits() override;
+ bool GetRenderBackendCap(NVRenderBackendCaps::Enum inCap) const override;
+ QT3DSU32 GetDepthBits() const override;
+ QT3DSU32 GetStencilBits() const override;
+ void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override;
+
+ /// state get/set functions
+ void SetRenderState(bool bEnable, const NVRenderState::Enum value) override;
+ bool GetRenderState(const NVRenderState::Enum value) override;
+ virtual NVRenderBackendDepthStencilStateObject
+ CreateDepthStencilState(bool enableDepth, bool depthMask, NVRenderBoolOp::Enum depthFunc,
+ bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack) override;
+ virtual void
+ ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override;
+ virtual NVRenderBackendRasterizerStateObject
+ CreateRasterizerState(QT3DSF32 depthBias, QT3DSF32 depthScale, NVRenderFaces::Enum cullFace) override;
+ void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override;
+ virtual void
+ SetDepthStencilState(NVRenderBackendDepthStencilStateObject inDepthStencilState) override;
+ void SetRasterizerState(NVRenderBackendRasterizerStateObject rasterizerState) override;
+ NVRenderBoolOp::Enum GetDepthFunc() override;
+ void SetDepthFunc(const NVRenderBoolOp::Enum func) override;
+ bool GetDepthWrite() override;
+ void SetDepthWrite(bool bEnable) override;
+ void SetColorWrites(bool bRed, bool bGreen, bool bBlue, bool bAlpha) override;
+ void SetMultisample(bool bEnable) override;
+ void GetBlendFunc(NVRenderBlendFunctionArgument *pBlendFuncArg) override;
+ void SetBlendFunc(const NVRenderBlendFunctionArgument &blendFuncArg) override;
+ void SetBlendEquation(const NVRenderBlendEquationArgument &pBlendEquArg) override;
+ void SetBlendBarrier(void) override;
+ void GetScissorRect(NVRenderRect *pRect) override;
+ void SetScissorRect(const NVRenderRect &rect) override;
+ void GetViewportRect(NVRenderRect *pRect) override;
+ void SetViewportRect(const NVRenderRect &rect) override;
+
+ void SetClearColor(const QT3DSVec4 *pClearColor) override;
+ void Clear(NVRenderClearFlags flags) override;
+
+ /// resource handling
+ NVRenderBackendBufferObject CreateBuffer(size_t size,
+ NVRenderBufferBindFlags bindFlags,
+ NVRenderBufferUsageType::Enum usage,
+ const void *hostPtr = NULL) override;
+ void BindBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override;
+ void ReleaseBuffer(NVRenderBackendBufferObject bo) override;
+ void UpdateBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t size, NVRenderBufferUsageType::Enum usage,
+ const void *data) override;
+ void UpdateBufferRange(NVRenderBackendBufferObject bo,
+ NVRenderBufferBindFlags bindFlags, size_t offset,
+ size_t size, const void *data) override;
+ void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t offset, size_t length,
+ NVRenderBufferAccessFlags accessFlags) override;
+ bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override;
+ void SetMemoryBarrier(NVRenderBufferBarrierFlags barriers) override;
+
+ NVRenderBackendQueryObject CreateQuery() override;
+ void ReleaseQuery(NVRenderBackendQueryObject qo) override;
+ void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override;
+ void SetQueryTimer(NVRenderBackendQueryObject qo) override;
+
+ NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye,
+ NVRenderSyncFlags syncFlags) override;
+ void ReleaseSync(NVRenderBackendSyncObject so) override;
+ void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags,
+ QT3DSU64 timeout) override;
+
+ NVRenderBackendRenderTargetObject CreateRenderTarget() override;
+ void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo) override;
+ void RenderTargetAttach(
+ NVRenderBackendRenderTargetObject rto, NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target = NVRenderTextureTargetType::Texture2D) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level, QT3DSI32 layer) override;
+ void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override;
+ bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override;
+
+ virtual NVRenderBackendRenderbufferObject
+ CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width,
+ size_t height) override;
+ void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override;
+ bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height) override;
+
+ NVRenderBackendTextureObject CreateTexture() override;
+ void BindTexture(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 unit) override;
+ void BindImageTexture(NVRenderBackendTextureObject to, QT3DSU32 unit, QT3DSI32 level,
+ bool layered, QT3DSI32 layer,
+ NVRenderImageAccessType::Enum access,
+ NVRenderTextureFormats::Enum format) override;
+ void ReleaseTexture(NVRenderBackendTextureObject to) override;
+ void SetTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) override;
+ void SetTextureDataCubeFace(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) override;
+ void CreateTextureStorage2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 levels,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height) override;
+ void SetTextureSubData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ QT3DSI32 xOffset, QT3DSI32 yOffset, size_t width, size_t height,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) override;
+ void SetCompressedTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height, QT3DSI32 border,
+ size_t imageSize, const void *hostPtr = NULL) override;
+ void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height, QT3DSI32 border,
+ size_t imageSize, const void *hostPtr = NULL) override;
+ void SetCompressedTextureSubData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ QT3DSU32 level, QT3DSI32 xOffset, QT3DSI32 yOffset,
+ size_t width, size_t height,
+ NVRenderTextureFormats::Enum format,
+ size_t imageSize, const void *hostPtr = NULL) override;
+ void SetMultisampledTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ size_t samples,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height,
+ bool fixedsamplelocations) override = 0;
+
+ void SetTextureData3D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, size_t depth, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = NULL) override;
+
+ void GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum genType) override;
+
+ virtual NVRenderTextureSwizzleMode::Enum
+ GetTextureSwizzleMode(const NVRenderTextureFormats::Enum inFormat) const override;
+
+ NVRenderBackendSamplerObject CreateSampler(
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSI32 minLod = -1000, QT3DSI32 maxLod = 1000, QT3DSF32 lodBias = 0.0,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override;
+
+ void UpdateSampler(
+ NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSF32 minLod = -1000.0, QT3DSF32 maxLod = 1000.0, QT3DSF32 lodBias = 0.0,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0, QT3DSF32 *borderColor = NULL) override;
+
+ void UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel,
+ QT3DSI32 maxLevel) override;
+
+ void UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode) override;
+
+ void ReleaseSampler(NVRenderBackendSamplerObject so) override;
+
+ virtual NVRenderBackendAttribLayoutObject
+ CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry> attribs) override;
+ void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject ao) override;
+
+ virtual NVRenderBackendInputAssemblerObject
+ CreateInputAssembler(NVRenderBackendAttribLayoutObject attribLayout,
+ NVConstDataRef<NVRenderBackendBufferObject> buffers,
+ const NVRenderBackendBufferObject indexBuffer,
+ NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets,
+ QT3DSU32 patchVertexCount) override;
+ void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) override;
+
+ bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po) override = 0;
+ void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override
+ {
+ QT3DS_ASSERT(false);
+ }
+
+ // shader
+ virtual NVRenderBackendVertexShaderObject
+ CreateVertexShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override;
+ virtual NVRenderBackendFragmentShaderObject
+ CreateFragmentShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override;
+ virtual NVRenderBackendTessControlShaderObject
+ CreateTessControlShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) override;
+ virtual NVRenderBackendTessEvaluationShaderObject
+ CreateTessEvaluationShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage,
+ bool binary) override;
+ virtual NVRenderBackendGeometryShaderObject
+ CreateGeometryShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override;
+ virtual NVRenderBackendComputeShaderObject
+ CreateComputeShader(NVConstDataRef<QT3DSI8> source, eastl::string &errorMessage, bool binary) override;
+ void ReleaseVertexShader(NVRenderBackendVertexShaderObject vso) override;
+ void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject fso) override;
+ void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject tcso) override;
+ void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject teso) override;
+ void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject gso) override;
+ void ReleaseComputeShader(NVRenderBackendComputeShaderObject cso) override;
+ void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendVertexShaderObject vso) override;
+ void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendFragmentShaderObject fso) override;
+ void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessControlShaderObject tcso) override;
+ void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessEvaluationShaderObject teso) override;
+ void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendGeometryShaderObject gso) override;
+ void AttachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendComputeShaderObject cso) override;
+ void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendVertexShaderObject vso) override;
+ void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendFragmentShaderObject fso) override;
+ void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessControlShaderObject tcso) override;
+ void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendTessEvaluationShaderObject teso) override;
+ void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendGeometryShaderObject gso) override;
+ void DetachShader(NVRenderBackendShaderProgramObject po,
+ NVRenderBackendComputeShaderObject cso) override;
+ NVRenderBackendShaderProgramObject CreateShaderProgram(bool isSeparable) override;
+ void ReleaseShaderProgram(NVRenderBackendShaderProgramObject po) override;
+ bool LinkProgram(NVRenderBackendShaderProgramObject po,
+ eastl::string &errorMessage) override;
+ void SetActiveProgram(NVRenderBackendShaderProgramObject po) override;
+ void DispatchCompute(NVRenderBackendShaderProgramObject po, QT3DSU32 numGroupsX,
+ QT3DSU32 numGroupsY, QT3DSU32 numGroupsZ) override;
+ NVRenderBackendProgramPipeline CreateProgramPipeline() override;
+ void ReleaseProgramPipeline(NVRenderBackendProgramPipeline po) override;
+ void SetActiveProgramPipeline(NVRenderBackendProgramPipeline po) override;
+ void SetProgramStages(NVRenderBackendProgramPipeline ppo,
+ NVRenderShaderTypeFlags flags,
+ NVRenderBackendShaderProgramObject po) override;
+
+ // uniforms
+ QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 bufSize, QT3DSI32 *numElem,
+ NVRenderShaderDataTypes::Enum *type, QT3DSI32 *binding,
+ char *nameBuf) override;
+ void SetConstantValue(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ NVRenderShaderDataTypes::Enum type, QT3DSI32 count,
+ const void *value, bool transpose) override;
+
+ // uniform buffers
+ QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override;
+ void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSI32 *indices) override;
+ void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset) override;
+ void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding) override;
+ void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ // storage buffers
+ QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length, char *nameBuf) override;
+ void ProgramSetStorageBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ // atomic counter buffers
+ QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf) override;
+ void ProgramSetAtomicCounterBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ /// draw calls
+ void Draw(NVRenderDrawMode::Enum drawMode, QT3DSU32 start, QT3DSU32 count) override;
+ void DrawIndirect(NVRenderDrawMode::Enum drawMode, const void *indirect) override;
+ void DrawIndexed(NVRenderDrawMode::Enum drawMode, QT3DSU32 count,
+ NVRenderComponentTypes::Enum type, const void *indices) override;
+ void DrawIndexedIndirect(NVRenderDrawMode::Enum drawMode,
+ NVRenderComponentTypes::Enum type, const void *indirect) override;
+
+ // read calls
+ void ReadPixel(NVRenderBackendRenderTargetObject rto, QT3DSI32 x, QT3DSI32 y, QT3DSI32 width,
+ QT3DSI32 height, NVRenderReadPixelFormats::Enum inFormat, void *pixels) override;
+
+ // NV path rendering
+ NVRenderBackendPathObject CreatePathNVObject(size_t range) override;
+ // Pathing requires gl4 backend.
+ void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef<QT3DSU8>,
+ NVConstDataRef<QT3DSF32>) override
+ {
+ }
+
+ ///< Bounds of the fill and stroke
+ NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override
+ {
+ return NVBounds3();
+ }
+ NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override
+ {
+ return NVBounds3();
+ }
+ NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override
+ {
+ return NVBounds3();
+ }
+
+ /**
+ * Defaults to 0 if unset.
+ */
+ void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {}
+ void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {}
+ void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {}
+ void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {}
+ void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {}
+ void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {}
+ void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {}
+ void ReleasePathNVObject(NVRenderBackendPathObject po, size_t range) override;
+
+ void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum,
+ const void *, NVRenderPathFontStyleFlags, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject,
+ QT3DSF32) override;
+ virtual NVRenderPathReturnValues::Enum
+ LoadPathGlyphsIndexed(NVRenderBackendPathObject po, NVRenderPathFontTarget::Enum fontTarget,
+ const void *fontName, NVRenderPathFontStyleFlags fontStyle,
+ QT3DSU32 firstGlyphIndex, size_t numGlyphs,
+ NVRenderBackendPathObject pathParameterTemplate, QT3DSF32 emScale) override;
+ virtual NVRenderBackendPathObject
+ LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum, const void *,
+ NVRenderPathFontStyleFlags,
+ NVRenderBackend::NVRenderBackendPathObject, QT3DSF32, QT3DSU32 *) override;
+ void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum,
+ const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t,
+ NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject,
+ QT3DSF32) override;
+ void GetPathMetrics(NVRenderBackendPathObject, size_t,
+ NVRenderPathGlyphFontMetricFlags, NVRenderPathFormatType::Enum,
+ const void *, size_t, QT3DSF32 *) override;
+ void GetPathMetricsRange(NVRenderBackendPathObject, size_t,
+ NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override;
+ void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum,
+ NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32,
+ NVRenderPathTransformType::Enum, QT3DSF32 *) override;
+
+ void StencilFillPathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathFillMode::Enum, QT3DSU32,
+ NVRenderPathTransformType::Enum, const QT3DSF32 *) override;
+ void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *, QT3DSI32,
+ QT3DSU32, NVRenderPathTransformType::Enum,
+ const QT3DSF32 *) override;
+ void CoverFillPathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathCoverMode::Enum,
+ NVRenderPathTransformType::Enum, const QT3DSF32 *) override;
+ void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathCoverMode::Enum,
+ NVRenderPathTransformType::Enum, const QT3DSF32 *) override;
+
+ QSurfaceFormat format() const override
+ {
+ return m_format;
+ }
+
+ protected:
+ virtual NVFoundationBase &GetFoundation() { return m_Foundation; }
+ virtual bool compileSource(GLuint shaderID, NVConstDataRef<QT3DSI8> source,
+ eastl::string &errorMessage, bool binary);
+ virtual const char *getVersionString();
+ virtual const char *getVendorString();
+ virtual const char *getRendererString();
+ virtual const char *getExtensionString();
+
+ virtual void setAndInspectHardwareCaps();
+
+ protected:
+ volatile QT3DSI32 mRefCount; ///< reference count
+ NVFoundationBase &m_Foundation; ///< Foundation class for allocations and other base things
+ NVScopedRefCounted<qt3ds::foundation::IStringTable>
+ m_StringTable; ///< pointer to a string table
+ GLConversion m_Conversion; ///< Class for conversion from base type to GL types
+ QStringList m_extensions; ///< contains the OpenGL extension string
+ QT3DSI32 m_MaxAttribCount; ///< Maximum attributes which can be used
+ nvvector<GLenum> m_DrawBuffersArray; ///< Contains the drawbuffer enums
+ QSurfaceFormat m_format;
+
+ NVRenderBackendRasterizerStateGL
+ *m_pCurrentRasterizerState; ///< this holds the current rasterizer state
+ NVRenderBackendDepthStencilStateGL
+ *m_pCurrentDepthStencilState; ///< this holds the current depth stencil state
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+ void checkGLError(const char *function, const char *file, const unsigned int line) const;
+#else
+ void checkGLError() const;
+#endif
+ QOpenGLFunctions *m_glFunctions;
+ QOpenGLExtraFunctions *m_glExtraFunctions;
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h
new file mode 100644
index 00000000..e14111af
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H
+#define QT3DS_RENDER_BACKEND_INPUT_ASSEMBLER_GL_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/StringTable.h"
+#include "foundation/Utils.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+
+namespace qt3ds {
+namespace render {
+
+ struct NVRenderBackendLayoutEntryGL
+ {
+ CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader
+ QT3DSU8 m_Normalize; ///< normalize parameter
+ QT3DSU32 m_AttribIndex; ///< attribute index
+ QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT
+ QT3DSU32 m_NumComponents; ///< component count. max 4
+ QT3DSU32 m_InputSlot; ///< Input slot where to fetch the data from
+ QT3DSU32 m_Offset; ///< offset in byte
+ };
+
+ ///< this class handles the vertex attribute layout setup
+ class NVRenderBackendAttributeLayoutGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendAttributeLayoutGL(NVDataRef<NVRenderBackendLayoutEntryGL> entries,
+ QT3DSU32 maxInputSlot)
+ : m_LayoutAttribEntries(entries)
+ , m_MaxInputSlot(maxInputSlot)
+ {
+ }
+ ///< destructor
+ ~NVRenderBackendAttributeLayoutGL(){}
+
+ NVRenderBackendLayoutEntryGL *getEntryByName(CRegisteredString entryName) const
+ {
+ QT3DS_FOREACH(idx, m_LayoutAttribEntries.size())
+ {
+ if (m_LayoutAttribEntries[idx].m_AttribName == entryName)
+ return &m_LayoutAttribEntries.mData[idx];
+ }
+ return NULL;
+ }
+
+ Option<NVRenderBackendLayoutEntryGL> getEntryByAttribIndex(QT3DSU32 attribIndex) const
+ {
+ QT3DS_FOREACH(idx, m_LayoutAttribEntries.size())
+ {
+ if (m_LayoutAttribEntries[idx].m_AttribIndex == attribIndex)
+ return m_LayoutAttribEntries[idx];
+ }
+ return Empty();
+ }
+
+ NVDataRef<NVRenderBackendLayoutEntryGL>
+ m_LayoutAttribEntries; ///< vertex attribute layout entries
+ QT3DSU32 m_MaxInputSlot; ///< max used input slot
+ };
+
+ ///< this class handles the input assembler setup
+ class NVRenderBackendInputAssemblerGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendInputAssemblerGL(
+ NVFoundationBase &fnd, NVRenderBackendAttributeLayoutGL *attribLayout,
+ NVConstDataRef<NVRenderBackend::NVRenderBackendBufferObject> buffers,
+ const NVRenderBackend::NVRenderBackendBufferObject indexBuffer,
+ NVConstDataRef<QT3DSU32> strides, NVConstDataRef<QT3DSU32> offsets, QT3DSU32 patchVertexCount)
+ : m_Foundation(fnd)
+ , m_attribLayout(attribLayout)
+ , m_VertexbufferHandles(buffers)
+ , m_IndexbufferHandle(indexBuffer)
+ , m_VaoID(0)
+ , m_cachedShaderHandle(0)
+ , m_PatchVertexCount(patchVertexCount)
+ {
+ QT3DSU32 *strideMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32),
+ "BackendAttributeLayoutGL:m_strides");
+ QT3DSU32 *offsetMem = (QT3DSU32 *)QT3DS_ALLOC(fnd.getAllocator(), strides.mSize * sizeof(QT3DSU32),
+ "BackendAttributeLayoutGL:m_strides");
+ // copy offsets and strides
+ QT3DS_FOREACH(idx, strides.size())
+ {
+ strideMem[idx] = strides.mData[idx];
+ offsetMem[idx] = offsets.mData[idx];
+ }
+
+ m_strides = toDataRef(strideMem, strides.size());
+ m_offsets = toDataRef(offsetMem, offsets.size());
+ }
+ ///< destructor
+ ~NVRenderBackendInputAssemblerGL()
+ {
+ QT3DS_FREE(m_Foundation.getAllocator(), m_strides.mData);
+ QT3DS_FREE(m_Foundation.getAllocator(), m_offsets.mData);
+ };
+
+ NVFoundationBase &m_Foundation; ///< pointer to foundation
+ NVRenderBackendAttributeLayoutGL *m_attribLayout; ///< pointer to attribute layout
+ NVConstDataRef<NVRenderBackend::NVRenderBackendBufferObject>
+ m_VertexbufferHandles; ///< opaque vertex buffer backend handles
+ NVRenderBackend::NVRenderBackendBufferObject
+ m_IndexbufferHandle; ///< opaque index buffer backend handles
+ QT3DSU32 m_VaoID; ///< this is only used if GL version is greater or equal 3
+ QT3DSU32 m_cachedShaderHandle; ///< this is the shader id which was last used with this object
+ QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive
+ NVDataRef<QT3DSU32> m_strides; ///< buffer strides
+ NVDataRef<QT3DSU32> m_offsets; ///< buffer offsets
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h
new file mode 100644
index 00000000..3a74a8e3
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H
+#define QT3DS_RENDER_BACKEND_RENDER_STATE_OBJECTS_GL_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Utils.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+
+namespace qt3ds {
+namespace render {
+
+ ///< this class handles the shader input variables
+ class NVRenderBackendDepthStencilStateGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendDepthStencilStateGL(bool enableDepth, bool depthMask,
+ NVRenderBoolOp::Enum depthFunc, bool enableStencil,
+ NVRenderStencilFunctionArgument &stencilFuncFront,
+ NVRenderStencilFunctionArgument &stencilFuncBack,
+ NVRenderStencilOperationArgument &depthStencilOpFront,
+ NVRenderStencilOperationArgument &depthStencilOpBack)
+ : m_DepthEnable(enableDepth)
+ , m_DepthMask(depthMask)
+ , m_DepthFunc(depthFunc)
+ , m_StencilEnable(enableStencil)
+ , m_StencilFuncFront(stencilFuncFront)
+ , m_StencilFuncBack(stencilFuncBack)
+ , m_DepthStencilOpFront(depthStencilOpFront)
+ , m_DepthStencilOpBack(depthStencilOpBack)
+ {
+ }
+
+ ///< constructor
+ NVRenderBackendDepthStencilStateGL()
+ : m_DepthEnable(true)
+ , m_DepthMask(true)
+ , m_DepthFunc(NVRenderBoolOp::LessThanOrEqual)
+ , m_StencilEnable(false)
+ {
+ }
+
+ ///< destructor
+ ~NVRenderBackendDepthStencilStateGL(){}
+
+ ///< assignement
+ NVRenderBackendDepthStencilStateGL &operator=(const NVRenderBackendDepthStencilStateGL &rhs)
+ {
+ // Check for self-assignment!
+ if (this == &rhs)
+ return *this;
+
+ m_DepthEnable = rhs.m_DepthEnable;
+ m_DepthMask = rhs.m_DepthMask;
+ m_DepthFunc = rhs.m_DepthFunc;
+ m_StencilEnable = rhs.m_StencilEnable;
+ m_StencilFuncFront = rhs.m_StencilFuncFront;
+ m_StencilFuncBack = rhs.m_StencilFuncBack;
+ m_DepthStencilOpFront = rhs.m_DepthStencilOpFront;
+ m_DepthStencilOpBack = rhs.m_DepthStencilOpBack;
+
+ return *this;
+ }
+
+ bool operator==(const NVRenderBackendDepthStencilStateGL &other) const
+ {
+ return (m_DepthEnable == other.m_DepthEnable && m_DepthMask == other.m_DepthMask
+ && m_DepthFunc == other.m_DepthFunc && m_StencilEnable == other.m_StencilEnable
+ && m_StencilFuncFront == other.m_StencilFuncFront
+ && m_StencilFuncBack == other.m_StencilFuncBack
+ && m_DepthStencilOpFront == other.m_DepthStencilOpFront
+ && m_DepthStencilOpBack == other.m_DepthStencilOpBack);
+ }
+
+ bool m_DepthEnable; ///< depth test enabled
+ bool m_DepthMask; ///< enable / disable depth writes
+ NVRenderBoolOp::Enum m_DepthFunc; ///< depth comparison func
+ bool m_StencilEnable; ///< enable disable stencil test
+ NVRenderStencilFunctionArgument m_StencilFuncFront; ///< stencil setup for front faces
+ NVRenderStencilFunctionArgument m_StencilFuncBack; ///< stencil setup for back faces
+ NVRenderStencilOperationArgument
+ m_DepthStencilOpFront; ///< depth stencil operation for front faces
+ NVRenderStencilOperationArgument
+ m_DepthStencilOpBack; ///< depth stencil operation for back faces
+ };
+
+ class NVRenderBackendMiscStateGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendMiscStateGL()
+ : m_PatchVertexCount(1)
+ {
+ }
+
+ QT3DSU32 m_PatchVertexCount; ///< vertex count for a single patch primitive
+ };
+
+ class NVRenderBackendRasterizerStateGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendRasterizerStateGL(QT3DSF32 depthBias, QT3DSF32 depthScale,
+ NVRenderFaces::Enum cullFace)
+ : m_DepthBias(depthBias)
+ , m_DepthScale(depthScale)
+ , m_CullFace(cullFace)
+ {
+ }
+ ///< constructor
+ NVRenderBackendRasterizerStateGL()
+ : m_DepthBias(0.0)
+ , m_DepthScale(0.0)
+ , m_CullFace(NVRenderFaces::Back)
+ {
+ }
+
+ NVRenderBackendRasterizerStateGL &operator=(const NVRenderBackendRasterizerStateGL &rhs)
+ {
+ // Check for self-assignment!
+ if (this == &rhs)
+ return *this;
+
+ m_DepthBias = rhs.m_DepthBias;
+ m_DepthScale = rhs.m_DepthScale;
+ m_CullFace = rhs.m_CullFace;
+
+ return *this;
+ }
+
+ bool operator==(const NVRenderBackendRasterizerStateGL &other) const
+ {
+ return (m_DepthBias == other.m_DepthBias && m_DepthScale == other.m_DepthScale
+ && m_CullFace == other.m_CullFace);
+ }
+
+ QT3DSF32 m_DepthBias; ///< depth bias
+ QT3DSF32 m_DepthScale; ///< mulitply constant
+ NVRenderFaces::Enum m_CullFace; ///< cull face front or back
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h
new file mode 100644
index 00000000..f7caffd8
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H
+#define QT3DS_RENDER_BACKEND_SHADER_PROGRAM_GL_H
+
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Utils.h"
+#include "render/Qt3DSRenderBaseTypes.h"
+
+namespace qt3ds {
+namespace render {
+
+ struct NVRenderBackendShaderInputEntryGL
+ {
+ CRegisteredString m_AttribName; ///< must be the same name as used in the vertex shader
+ QT3DSU32 m_AttribLocation; ///< attribute index
+ QT3DSU32 m_Type; ///< GL vertex format type @sa GL_FLOAT, GL_INT
+ QT3DSU32 m_NumComponents; ///< component count. max 4
+ };
+
+ ///< this class handles the shader input variables
+ class NVRenderBackendShaderInputGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendShaderInputGL(NVDataRef<NVRenderBackendShaderInputEntryGL> entries)
+ : m_ShaderInputEntries(entries)
+ {
+ }
+ ///< destructor
+ ~NVRenderBackendShaderInputGL(){}
+
+ NVRenderBackendShaderInputEntryGL *getEntryByName(CRegisteredString entryName) const
+ {
+ QT3DS_FOREACH(idx, m_ShaderInputEntries.size())
+ {
+ if (m_ShaderInputEntries[idx].m_AttribName == entryName)
+ return &m_ShaderInputEntries.mData[idx];
+ }
+ return NULL;
+ }
+
+ Option<NVRenderBackendShaderInputEntryGL>
+ getEntryByAttribLocation(QT3DSU32 attribLocation) const
+ {
+ QT3DS_FOREACH(idx, m_ShaderInputEntries.size())
+ {
+ if (m_ShaderInputEntries[idx].m_AttribLocation == attribLocation)
+ return m_ShaderInputEntries[idx];
+ }
+ return Empty();
+ }
+
+ NVDataRef<NVRenderBackendShaderInputEntryGL> m_ShaderInputEntries; ///< shader input entries
+ };
+
+ ///< this class represents the internals of a GL program
+ class NVRenderBackendShaderProgramGL
+ {
+ public:
+ ///< constructor
+ NVRenderBackendShaderProgramGL(QT3DSU32 programID)
+ : m_ProgramID(programID)
+ , m_shaderInput(NULL)
+ {
+ }
+
+ ///< destructor
+ ~NVRenderBackendShaderProgramGL(){}
+
+ QT3DSU32 m_ProgramID; ///< this is the OpenGL object ID
+ NVRenderBackendShaderInputGL *m_shaderInput; ///< pointer to shader input object
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp b/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp
new file mode 100644
index 00000000..88670ef7
--- /dev/null
+++ b/src/Runtime/Source/render/backends/gl/Qt3DSRenderContextGL.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "foundation/Qt3DSMat44.h"
+#include "render/Qt3DSRenderContext.h"
+#include "foundation/Utils.h"
+#include "EASTL/set.h"
+#include "EASTL/utility.h"
+#include "render/Qt3DSRenderShaderProgram.h"
+
+using namespace qt3ds;
+using namespace qt3ds::render;
+using namespace eastl;
+
+namespace qt3ds {
+namespace render {
+
+ NVRenderContext &NVRenderContext::CreateGL(NVFoundationBase &foundation,
+ IStringTable &inStringTable,
+ const QSurfaceFormat &format)
+ {
+ NVRenderContext *retval = NULL;
+
+ QT3DS_ASSERT(format.majorVersion() >= 2);
+
+ // create backend
+ NVScopedRefCounted<IStringTable> theStringTable(inStringTable);
+ NVScopedRefCounted<NVRenderBackend> theBackend;
+ bool isES = format.renderableType() == QSurfaceFormat::OpenGLES;
+ if (isES && (format.majorVersion() == 2
+ || (format.majorVersion() == 3 && format.minorVersion() == 0))) {
+ theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGLES2Impl)(foundation,
+ *theStringTable,
+ format);
+ } else if (format.majorVersion() == 3 && format.minorVersion() >= 1 && !isES) {
+ theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation,
+ *theStringTable,
+ format);
+ } else if (format.majorVersion() == 4
+ || (isES && format.majorVersion() == 3 && format.minorVersion() >= 1)) {
+#ifdef Q_OS_MACOS
+ // TODO: macOS crashes with glTextStorage2DMultisample, so fall back to OpenGL3
+ // for now (QT3DS-590)
+ theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL3Impl)(foundation,
+ *theStringTable,
+ format);
+#else
+ theBackend = QT3DS_NEW(foundation.getAllocator(), NVRenderBackendGL4Impl)(foundation,
+ *theStringTable,
+ format);
+#endif
+ } else {
+ QT3DS_ASSERT(false);
+ qCCritical(INTERNAL_ERROR) << "Can't find a suitable OpenGL version for" << format;
+ }
+
+
+ retval = QT3DS_NEW(foundation.getAllocator(), NVRenderContextImpl)(foundation, *theBackend,
+ *theStringTable);
+
+ return *retval;
+ }
+}
+}
diff --git a/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp
new file mode 100644
index 00000000..af93e928
--- /dev/null
+++ b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.cpp
@@ -0,0 +1,588 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "render/backends/software/Qt3DSRenderBackendNULL.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/Qt3DSBroadcastingAllocator.h"
+#include "foundation/Qt3DSAtomic.h"
+
+#include <QSurfaceFormat>
+
+using namespace qt3ds::render;
+using namespace qt3ds::foundation;
+using namespace qt3ds;
+
+namespace {
+struct SNullBackend : public NVRenderBackend
+{
+ NVFoundationBase &m_Foundation;
+ QT3DSI32 mRefCount;
+
+ SNullBackend(NVFoundationBase &fnd)
+ : m_Foundation(fnd)
+ , mRefCount(0)
+ {
+ }
+
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation.getAllocator())
+
+ /// backend interface
+
+ NVRenderContextType GetRenderContextType() const override
+ {
+ return NVRenderContextValues::NullContext;
+ }
+ const char *GetShadingLanguageVersion() override { return ""; }
+ QT3DSU32 GetMaxCombinedTextureUnits() override { return 32; }
+ bool GetRenderBackendCap(NVRenderBackendCaps::Enum) const override { return false; }
+ void GetRenderBackendValue(NVRenderBackendQuery::Enum inQuery, QT3DSI32 *params) const override
+ {
+ if (params) {
+ switch (inQuery) {
+ case NVRenderBackendQuery::MaxTextureSize:
+ *params = 4096;
+ break;
+ case NVRenderBackendQuery::MaxTextureArrayLayers:
+ *params = 0;
+ break;
+ default:
+ QT3DS_ASSERT(false);
+ *params = 0;
+ break;
+ }
+ }
+ }
+ QT3DSU32 GetDepthBits() const override { return 16; }
+ QT3DSU32 GetStencilBits() const override { return 0; }
+ void SetRenderState(bool, const NVRenderState::Enum) override {}
+ bool GetRenderState(const NVRenderState::Enum) override { return false; }
+ virtual NVRenderBackendDepthStencilStateObject
+ CreateDepthStencilState(bool, bool, NVRenderBoolOp::Enum, bool,
+ NVRenderStencilFunctionArgument &, NVRenderStencilFunctionArgument &,
+ NVRenderStencilOperationArgument &, NVRenderStencilOperationArgument &) override
+ {
+ return NVRenderBackendDepthStencilStateObject(1);
+ }
+ void ReleaseDepthStencilState(NVRenderBackendDepthStencilStateObject) override {}
+ NVRenderBackendRasterizerStateObject CreateRasterizerState(QT3DSF32, QT3DSF32,
+ NVRenderFaces::Enum) override
+ {
+ return NVRenderBackendRasterizerStateObject(1);
+ }
+ void ReleaseRasterizerState(NVRenderBackendRasterizerStateObject) override {}
+ void SetDepthStencilState(NVRenderBackendDepthStencilStateObject) override {}
+ void SetRasterizerState(NVRenderBackendRasterizerStateObject) override {}
+ NVRenderBoolOp::Enum GetDepthFunc() override { return NVRenderBoolOp::Equal; }
+ void SetDepthFunc(const NVRenderBoolOp::Enum) override {}
+ bool GetDepthWrite() override { return false; }
+
+ void SetDepthWrite(bool) override {}
+ void SetColorWrites(bool, bool, bool, bool) override {}
+ void SetMultisample(bool) override {}
+ void GetBlendFunc(NVRenderBlendFunctionArgument *) override {}
+ void SetBlendFunc(const NVRenderBlendFunctionArgument &) override {}
+ void SetBlendEquation(const NVRenderBlendEquationArgument &) override {}
+ void SetBlendBarrier(void) override {}
+ void GetScissorRect(NVRenderRect *) override {}
+ void SetScissorRect(const NVRenderRect &) override {}
+ void GetViewportRect(NVRenderRect *) override {}
+ void SetViewportRect(const NVRenderRect &) override {}
+ void SetClearColor(const QT3DSVec4 *) override {}
+ void Clear(NVRenderClearFlags) override {}
+ NVRenderBackendBufferObject CreateBuffer(size_t, NVRenderBufferBindFlags,
+ NVRenderBufferUsageType::Enum, const void *) override
+ {
+ return NVRenderBackendBufferObject(1);
+ }
+ void BindBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override {}
+ void ReleaseBuffer(NVRenderBackendBufferObject) override {}
+
+ void UpdateBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t,
+ NVRenderBufferUsageType::Enum, const void *) override
+ {
+ }
+ void UpdateBufferRange(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t,
+ const void *) override
+ {
+ }
+ void *MapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags, size_t, size_t,
+ NVRenderBufferAccessFlags) override
+ {
+ return NULL;
+ }
+ bool UnmapBuffer(NVRenderBackendBufferObject, NVRenderBufferBindFlags) override { return true; }
+ void SetMemoryBarrier(NVRenderBufferBarrierFlags) override {}
+ NVRenderBackendQueryObject CreateQuery() override { return NVRenderBackendQueryObject(1); }
+ void ReleaseQuery(NVRenderBackendQueryObject) override {}
+ void BeginQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {}
+ void EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum) override {}
+ void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum,
+ QT3DSU32 *) override {}
+ void GetQueryResult(NVRenderBackendQueryObject, NVRenderQueryResultType::Enum,
+ QT3DSU64 *) override {}
+ void SetQueryTimer(NVRenderBackendQueryObject) override {}
+ NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags) override
+ {
+ return NVRenderBackendSyncObject(1);
+ };
+ void ReleaseSync(NVRenderBackendSyncObject) override {}
+ void WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags, QT3DSU64) override {}
+ NVRenderBackendRenderTargetObject CreateRenderTarget() override
+ {
+ return NVRenderBackendRenderTargetObject(1);
+ }
+ void ReleaseRenderTarget(NVRenderBackendRenderTargetObject) override {}
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum,
+ NVRenderBackendRenderbufferObject) override
+ {
+ }
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum,
+ NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum) override
+ {
+ }
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum,
+ NVRenderBackendTextureObject, QT3DSI32, QT3DSI32) override
+ {
+ }
+ void SetRenderTarget(NVRenderBackendRenderTargetObject) override {}
+ bool RenderTargetIsValid(NVRenderBackendRenderTargetObject) override { return false; }
+ void SetReadTarget(NVRenderBackendRenderTargetObject) override {}
+ void SetDrawBuffers(NVRenderBackendRenderTargetObject, NVConstDataRef<QT3DSI32>) override {}
+ void SetReadBuffer(NVRenderBackendRenderTargetObject, NVReadFaces::Enum) override {}
+
+ void BlitFramebuffer(QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32,
+ NVRenderClearFlags, NVRenderTextureMagnifyingOp::Enum) override
+ {
+ }
+ NVRenderBackendRenderbufferObject CreateRenderbuffer(NVRenderRenderBufferFormats::Enum,
+ size_t, size_t) override
+ {
+ return NVRenderBackendRenderbufferObject(1);
+ }
+ void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject) override {}
+
+ bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject,
+ NVRenderRenderBufferFormats::Enum, size_t, size_t) override
+ {
+ return false;
+ }
+ NVRenderBackendTextureObject CreateTexture() override { return NVRenderBackendTextureObject(1); }
+
+ void SetTextureData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum,
+ QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32,
+ NVRenderTextureFormats::Enum, const void *) override
+ {
+ }
+ void SetTextureDataCubeFace(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32,
+ NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32,
+ NVRenderTextureFormats::Enum, const void *) override
+ {
+ }
+ void CreateTextureStorage2D(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32,
+ NVRenderTextureFormats::Enum, size_t, size_t) override
+ {
+ }
+ void SetTextureSubData2D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum,
+ QT3DSU32, QT3DSI32, QT3DSI32, size_t, size_t,
+ NVRenderTextureFormats::Enum, const void *) override
+ {
+ }
+ void SetCompressedTextureData2D(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32,
+ NVRenderTextureFormats::Enum, size_t, size_t, QT3DSI32,
+ size_t, const void *) override
+ {
+ }
+ void SetCompressedTextureDataCubeFace(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32,
+ NVRenderTextureFormats::Enum, size_t, size_t,
+ QT3DSI32, size_t, const void *) override
+ {
+ }
+ void SetCompressedTextureSubData2D(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, QT3DSU32, QT3DSI32, QT3DSI32,
+ size_t, size_t, NVRenderTextureFormats::Enum, size_t,
+ const void *) override
+ {
+ }
+ void SetMultisampledTextureData2D(NVRenderBackendTextureObject,
+ NVRenderTextureTargetType::Enum, size_t,
+ NVRenderTextureFormats::Enum, size_t, size_t, bool) override
+ {
+ }
+ void SetTextureData3D(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum,
+ QT3DSU32, NVRenderTextureFormats::Enum, size_t, size_t, size_t,
+ QT3DSI32, NVRenderTextureFormats::Enum, const void *) override
+ {
+ }
+ void GenerateMipMaps(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum,
+ NVRenderHint::Enum) override
+ {
+ }
+ void BindTexture(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum, QT3DSU32) override
+ {
+ }
+ void BindImageTexture(NVRenderBackendTextureObject, QT3DSU32, QT3DSI32, bool, QT3DSI32,
+ NVRenderImageAccessType::Enum, NVRenderTextureFormats::Enum) override
+ {
+ }
+ void ReleaseTexture(NVRenderBackendTextureObject) override {}
+
+ virtual NVRenderTextureSwizzleMode::Enum
+ GetTextureSwizzleMode(const NVRenderTextureFormats::Enum) const override
+ {
+ return NVRenderTextureSwizzleMode::NoSwizzle;
+ }
+
+ virtual NVRenderBackendSamplerObject
+ CreateSampler(NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum,
+ NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum,
+ NVRenderTextureCoordOp::Enum, QT3DSI32, QT3DSI32, QT3DSF32,
+ NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum, QT3DSF32, QT3DSF32 *) override
+ {
+ return NVRenderBackendSamplerObject(1);
+ }
+
+ void UpdateSampler(NVRenderBackendSamplerObject, NVRenderTextureTargetType::Enum,
+ NVRenderTextureMinifyingOp::Enum, NVRenderTextureMagnifyingOp::Enum,
+ NVRenderTextureCoordOp::Enum, NVRenderTextureCoordOp::Enum,
+ NVRenderTextureCoordOp::Enum, QT3DSF32, QT3DSF32, QT3DSF32,
+ NVRenderTextureCompareMode::Enum, NVRenderTextureCompareOp::Enum,
+ QT3DSF32, QT3DSF32 *) override
+ {
+ }
+
+ void UpdateTextureObject(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum,
+ QT3DSI32, QT3DSI32) override
+ {
+ }
+
+ void UpdateTextureSwizzle(NVRenderBackendTextureObject, NVRenderTextureTargetType::Enum,
+ NVRenderTextureSwizzleMode::Enum) override
+ {
+ }
+
+ void ReleaseSampler(NVRenderBackendSamplerObject) override {}
+
+ virtual NVRenderBackendAttribLayoutObject
+ CreateAttribLayout(NVConstDataRef<NVRenderVertexBufferEntry>) override
+ {
+ return NVRenderBackendAttribLayoutObject(1);
+ }
+
+ void ReleaseAttribLayout(NVRenderBackendAttribLayoutObject) override {}
+
+ NVRenderBackendInputAssemblerObject CreateInputAssembler(
+ NVRenderBackendAttribLayoutObject, NVConstDataRef<NVRenderBackendBufferObject>,
+ const NVRenderBackendBufferObject, NVConstDataRef<QT3DSU32>, NVConstDataRef<QT3DSU32>, QT3DSU32) override
+ {
+ return NVRenderBackendInputAssemblerObject(1);
+ }
+ void ReleaseInputAssembler(NVRenderBackendInputAssemblerObject) override {}
+ bool SetInputAssembler(NVRenderBackendInputAssemblerObject,
+ NVRenderBackendShaderProgramObject) override
+ {
+ return false;
+ }
+ void SetPatchVertexCount(NVRenderBackendInputAssemblerObject, QT3DSU32) override {}
+ NVRenderBackendVertexShaderObject CreateVertexShader(NVConstDataRef<QT3DSI8>,
+ eastl::string &, bool) override
+ {
+ return NVRenderBackendVertexShaderObject(1);
+ }
+ void ReleaseVertexShader(NVRenderBackendVertexShaderObject) override {}
+ NVRenderBackendFragmentShaderObject CreateFragmentShader(NVConstDataRef<QT3DSI8>,
+ eastl::string &, bool) override
+ {
+ return NVRenderBackendFragmentShaderObject(1);
+ }
+ void ReleaseFragmentShader(NVRenderBackendFragmentShaderObject) override {}
+ NVRenderBackendTessControlShaderObject CreateTessControlShader(NVConstDataRef<QT3DSI8>,
+ eastl::string &, bool) override
+ {
+ return NVRenderBackendTessControlShaderObject(1);
+ }
+ void ReleaseTessControlShader(NVRenderBackendTessControlShaderObject) override {}
+ virtual NVRenderBackendTessEvaluationShaderObject
+ CreateTessEvaluationShader(NVConstDataRef<QT3DSI8>, eastl::string &, bool) override
+ {
+ return NVRenderBackendTessEvaluationShaderObject(1);
+ }
+ void ReleaseTessEvaluationShader(NVRenderBackendTessEvaluationShaderObject) override {}
+ NVRenderBackendGeometryShaderObject CreateGeometryShader(NVConstDataRef<QT3DSI8>,
+ eastl::string &, bool) override
+ {
+ return NVRenderBackendGeometryShaderObject(1);
+ }
+ void ReleaseGeometryShader(NVRenderBackendGeometryShaderObject) override {}
+ NVRenderBackendComputeShaderObject CreateComputeShader(NVConstDataRef<QT3DSI8>,
+ eastl::string &, bool) override
+ {
+ return NVRenderBackendComputeShaderObject(1);
+ }
+ void ReleaseComputeShader(NVRenderBackendComputeShaderObject) override {}
+ void AttachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override
+ {
+ }
+ void AttachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendFragmentShaderObject) override
+ {
+ }
+ void AttachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendTessControlShaderObject) override
+ {
+ }
+ void AttachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendTessEvaluationShaderObject) override
+ {
+ }
+ void AttachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendGeometryShaderObject) override
+ {
+ }
+ void AttachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendComputeShaderObject) override
+ {
+ }
+ void DetachShader(NVRenderBackendShaderProgramObject, NVRenderBackendVertexShaderObject) override
+ {
+ }
+ void DetachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendFragmentShaderObject) override
+ {
+ }
+ void DetachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendTessControlShaderObject) override
+ {
+ }
+ void DetachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendTessEvaluationShaderObject) override
+ {
+ }
+ void DetachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendGeometryShaderObject) override
+ {
+ }
+ void DetachShader(NVRenderBackendShaderProgramObject,
+ NVRenderBackendComputeShaderObject) override
+ {
+ }
+ NVRenderBackendShaderProgramObject CreateShaderProgram(bool) override
+ {
+ return NVRenderBackendShaderProgramObject(1);
+ }
+ void ReleaseShaderProgram(NVRenderBackendShaderProgramObject) override {}
+ NVRenderBackendProgramPipeline CreateProgramPipeline() override
+ {
+ return NVRenderBackendProgramPipeline(1);
+ }
+ void ReleaseProgramPipeline(NVRenderBackendProgramPipeline) override {}
+
+ bool LinkProgram(NVRenderBackendShaderProgramObject, eastl::string &) override { return false; }
+ void SetActiveProgram(NVRenderBackendShaderProgramObject) override {}
+ void SetActiveProgramPipeline(NVRenderBackendProgramPipeline) override {}
+ void SetProgramStages(NVRenderBackendProgramPipeline, NVRenderShaderTypeFlags,
+ NVRenderBackendShaderProgramObject) override {}
+ void DispatchCompute(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSU32) override {}
+ QT3DSI32 GetConstantCount(NVRenderBackendShaderProgramObject) override { return 0; }
+ QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject) override { return 0; }
+ QT3DSI32 GetConstantInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32, QT3DSI32 *,
+ NVRenderShaderDataTypes::Enum *, QT3DSI32 *, char *) override
+ {
+ return 0;
+ }
+
+ QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32,
+ QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override
+ {
+ return 0;
+ }
+
+ void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSI32 *) override
+ {
+ }
+ void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject, QT3DSU32,
+ QT3DSU32 *, QT3DSI32 *, QT3DSI32 *, QT3DSI32 *) override {}
+ void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32) override {}
+ void ProgramSetConstantBuffer(QT3DSU32, NVRenderBackendBufferObject) override {}
+
+ QT3DSI32 GetStorageBufferCount(NVRenderBackendShaderProgramObject) override { return 0; };
+ QT3DSI32 GetStorageBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32,
+ QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override
+ {
+ return -1;
+ }
+ void ProgramSetStorageBuffer(QT3DSU32, NVRenderBackendBufferObject) override {}
+
+ QT3DSI32 GetAtomicCounterBufferCount(NVRenderBackendShaderProgramObject) override { return 0; }
+ QT3DSI32 GetAtomicCounterBufferInfoByID(NVRenderBackendShaderProgramObject, QT3DSU32, QT3DSU32,
+ QT3DSI32 *, QT3DSI32 *, QT3DSI32 *, char *) override
+ {
+ return -1;
+ };
+ void ProgramSetAtomicCounterBuffer(QT3DSU32, NVRenderBackendBufferObject) override {}
+
+ void SetConstantValue(NVRenderBackendShaderProgramObject, QT3DSU32,
+ NVRenderShaderDataTypes::Enum, QT3DSI32, const void *, bool) override
+ {
+ }
+
+ void Draw(NVRenderDrawMode::Enum, QT3DSU32, QT3DSU32) override {}
+ void DrawIndirect(NVRenderDrawMode::Enum, const void *) override {}
+
+ void DrawIndexed(NVRenderDrawMode::Enum, QT3DSU32, NVRenderComponentTypes::Enum,
+ const void *) override
+ {
+ }
+ void DrawIndexedIndirect(NVRenderDrawMode::Enum, NVRenderComponentTypes::Enum,
+ const void *) override
+ {
+ }
+
+ void ReadPixel(NVRenderBackendRenderTargetObject, QT3DSI32, QT3DSI32, QT3DSI32, QT3DSI32,
+ NVRenderReadPixelFormats::Enum, void *) override
+ {
+ }
+
+ NVRenderBackendPathObject CreatePathNVObject(size_t) override
+ {
+ return NVRenderBackendPathObject(1);
+ };
+ void SetPathSpecification(NVRenderBackendPathObject, NVConstDataRef<QT3DSU8>,
+ NVConstDataRef<QT3DSF32>) override
+ {
+ }
+
+ ///< Bounds of the fill and stroke
+ NVBounds3 GetPathObjectBoundingBox(NVRenderBackendPathObject /*inPathObject*/) override
+ {
+ return NVBounds3();
+ }
+ NVBounds3 GetPathObjectFillBox(NVRenderBackendPathObject /*inPathObject*/) override
+ {
+ return NVBounds3();
+ }
+ NVBounds3 GetPathObjectStrokeBox(NVRenderBackendPathObject /*inPathObject*/) override
+ {
+ return NVBounds3();
+ }
+
+ /**
+ * Defaults to 0 if unset.
+ */
+ void SetStrokeWidth(NVRenderBackendPathObject /*inPathObject*/, QT3DSF32) override {}
+ void SetPathProjectionMatrix(const QT3DSMat44 /*inPathProjection*/) override {}
+ void SetPathModelViewMatrix(const QT3DSMat44 /*inPathModelview*/) override {}
+
+ void SetPathStencilDepthOffset(QT3DSF32 /*inSlope*/, QT3DSF32 /*inBias*/) override {}
+ void SetPathCoverDepthFunc(NVRenderBoolOp::Enum /*inDepthFunction*/) override {}
+ void StencilStrokePath(NVRenderBackendPathObject /*inPathObject*/) override {}
+ void StencilFillPath(NVRenderBackendPathObject /*inPathObject*/) override {}
+ void ReleasePathNVObject(NVRenderBackendPathObject, size_t) override {}
+
+ void LoadPathGlyphs(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum,
+ const void *, NVRenderPathFontStyleFlags, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject, QT3DSF32) override
+ {
+ }
+ virtual NVRenderPathReturnValues::Enum
+ LoadPathGlyphsIndexed(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum, const void *,
+ NVRenderPathFontStyleFlags, QT3DSU32, size_t, NVRenderBackendPathObject,
+ QT3DSF32) override
+ {
+ return NVRenderPathReturnValues::FontUnavailable;
+ }
+ NVRenderBackendPathObject LoadPathGlyphsIndexedRange(NVRenderPathFontTarget::Enum,
+ const void *,
+ NVRenderPathFontStyleFlags,
+ NVRenderBackendPathObject, QT3DSF32,
+ QT3DSU32 *) override
+ {
+ return NVRenderBackendPathObject(1);
+ }
+ void LoadPathGlyphRange(NVRenderBackendPathObject, NVRenderPathFontTarget::Enum,
+ const void *, NVRenderPathFontStyleFlags, QT3DSU32, size_t,
+ NVRenderPathMissingGlyphs::Enum, NVRenderBackendPathObject,
+ QT3DSF32) override
+ {
+ }
+ void GetPathMetrics(NVRenderBackendPathObject, size_t, NVRenderPathGlyphFontMetricFlags,
+ NVRenderPathFormatType::Enum, const void *, size_t, QT3DSF32 *) override
+ {
+ }
+ void GetPathMetricsRange(NVRenderBackendPathObject, size_t,
+ NVRenderPathGlyphFontMetricFlags, size_t, QT3DSF32 *) override
+ {
+ }
+ void GetPathSpacing(NVRenderBackendPathObject, size_t, NVRenderPathListMode::Enum,
+ NVRenderPathFormatType::Enum, const void *, QT3DSF32, QT3DSF32,
+ NVRenderPathTransformType::Enum, QT3DSF32 *) override
+ {
+ }
+
+ void StencilFillPathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathFillMode::Enum, QT3DSU32,
+ NVRenderPathTransformType::Enum, const QT3DSF32 *) override
+ {
+ }
+ void StencilStrokePathInstancedN(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *, QT3DSI32,
+ QT3DSU32, NVRenderPathTransformType::Enum, const QT3DSF32 *) override
+ {
+ }
+ void CoverFillPathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathCoverMode::Enum,
+ NVRenderPathTransformType::Enum, const QT3DSF32 *) override
+ {
+ }
+ void CoverStrokePathInstanced(NVRenderBackendPathObject, size_t,
+ NVRenderPathFormatType::Enum, const void *,
+ NVRenderPathCoverMode::Enum,
+ NVRenderPathTransformType::Enum, const QT3DSF32 *) override
+ {
+ }
+ QSurfaceFormat format() const override
+ {
+ return QSurfaceFormat();
+ }
+};
+}
+
+NVRenderBackend &NVRenderBackendNULL::CreateBackend(NVFoundationBase &foundation)
+{
+ return *QT3DS_NEW(foundation.getAllocator(), SNullBackend)(foundation);
+}
diff --git a/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h
new file mode 100644
index 00000000..397ecfb1
--- /dev/null
+++ b/src/Runtime/Source/render/backends/software/Qt3DSRenderBackendNULL.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_BACKEND_NULL_H
+#define QT3DS_RENDER_BACKEND_NULL_H
+#include "render/backends/Qt3DSRenderBackend.h"
+
+namespace qt3ds {
+namespace render {
+
+ class NVRenderBackendNULL : public NVRenderBackend
+ {
+ public:
+ static NVRenderBackend &CreateBackend(NVFoundationBase &foundation);
+ };
+}
+}
+
+#endif \ No newline at end of file
diff --git a/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h b/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h
new file mode 100644
index 00000000..28f246fd
--- /dev/null
+++ b/src/Runtime/Source/render/glg/Qt3DSGLImplObjects.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2012 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#ifndef QT3DS_RENDER_GL_IMPL_OBJECTS_H
+#define QT3DS_RENDER_GL_IMPL_OBJECTS_H
+#include "render/backends/gl/Qt3DSOpenGLUtil.h"
+#include "render/Qt3DSRenderTexture2D.h"
+#include "foundation/StringTable.h"
+#include "foundation/Qt3DSContainers.h"
+
+namespace qt3ds {
+namespace render {
+
+ // The set of all properties as they are currently set in hardware.
+ struct SNVGLHardPropertyContext
+ {
+ NVRenderFrameBuffer *m_FrameBuffer;
+ NVRenderShaderProgram *m_ActiveShader;
+ NVRenderProgramPipeline *m_ActiveProgramPipeline;
+ NVRenderInputAssembler *m_InputAssembler;
+ NVRenderBlendFunctionArgument m_BlendFunction;
+ NVRenderBlendEquationArgument m_BlendEquation;
+ bool m_CullingEnabled;
+ NVRenderBoolOp::Enum m_DepthFunction;
+ bool m_BlendingEnabled;
+ bool m_DepthWriteEnabled;
+ bool m_DepthTestEnabled;
+ bool m_StencilTestEnabled;
+ bool m_ScissorTestEnabled;
+ bool m_ColorWritesEnabled;
+ bool m_MultisampleEnabled;
+ NVRenderRect m_ScissorRect;
+ NVRenderRect m_Viewport;
+ QT3DSVec4 m_ClearColor;
+
+ SNVGLHardPropertyContext()
+ : m_FrameBuffer(NULL)
+ , m_ActiveShader(NULL)
+ , m_ActiveProgramPipeline(NULL)
+ , m_InputAssembler(NULL)
+ , m_CullingEnabled(true)
+ , m_DepthFunction(NVRenderBoolOp::Less)
+ , m_BlendingEnabled(true)
+ , m_DepthWriteEnabled(true)
+ , m_DepthTestEnabled(true)
+ , m_StencilTestEnabled(false)
+ , m_ScissorTestEnabled(true)
+ , m_ColorWritesEnabled(true)
+ , m_MultisampleEnabled(false)
+ , m_ClearColor(0, 0, 0, 1)
+ {
+ }
+ };
+}
+}
+#endif