summaryrefslogtreecommitdiffstats
path: root/src/render/backends
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/backends')
-rw-r--r--src/render/backends/Qt3DSRenderBackend.h2245
-rw-r--r--src/render/backends/gl/Q3DSRenderBackendGLES2.cpp902
-rw-r--r--src/render/backends/gl/Q3DSRenderBackendGLES2.h195
-rw-r--r--src/render/backends/gl/Qt3DSOpenGLExtensions.cpp170
-rw-r--r--src/render/backends/gl/Qt3DSOpenGLExtensions.h392
-rw-r--r--src/render/backends/gl/Qt3DSOpenGLPrefix.h48
-rw-r--r--src/render/backends/gl/Qt3DSOpenGLTokens.h408
-rw-r--r--src/render/backends/gl/Qt3DSOpenGLUtil.h2201
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendGL3.cpp796
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendGL3.h173
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendGL4.cpp875
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendGL4.h205
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp2230
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendGLBase.h531
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h146
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h173
-rw-r--r--src/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h105
-rw-r--r--src/render/backends/gl/Qt3DSRenderContextGL.cpp91
-rw-r--r--src/render/backends/software/Qt3DSRenderBackendNULL.cpp588
-rw-r--r--src/render/backends/software/Qt3DSRenderBackendNULL.h46
20 files changed, 12520 insertions, 0 deletions
diff --git a/src/render/backends/Qt3DSRenderBackend.h b/src/render/backends/Qt3DSRenderBackend.h
new file mode 100644
index 0000000..12de5d8
--- /dev/null
+++ b/src/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/render/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/render/backends/gl/Q3DSRenderBackendGLES2.cpp
new file mode 100644
index 0000000..ac5b992
--- /dev/null
+++ b/src/render/backends/gl/Q3DSRenderBackendGLES2.cpp
@@ -0,0 +1,902 @@
+/****************************************************************************
+**
+** 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"
+
+#include <QtGui/qopenglcontext.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::ReleaseInputAssembler(
+ NVRenderBackend::NVRenderBackendInputAssemblerObject iao)
+{
+ NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao;
+ if (inputAssembler->m_VaoID)
+ GL_CALL_EXTENSION_FUNCTION(glDeleteVertexArraysOES(1, &inputAssembler->m_VaoID));
+ NVDelete(m_Foundation.getAllocator(), inputAssembler);
+}
+
+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);
+ if (!fboID)
+ fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject();
+
+ GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
+}
+
+void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+ if (!fboID)
+ fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject();
+
+ 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/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/render/backends/gl/Q3DSRenderBackendGLES2.h
new file mode 100644
index 0000000..2c7a355
--- /dev/null
+++ b/src/render/backends/gl/Q3DSRenderBackendGLES2.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** 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 ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) 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/render/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/render/backends/gl/Qt3DSOpenGLExtensions.cpp
new file mode 100644
index 0000000..564ecd5
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/render/backends/gl/Qt3DSOpenGLExtensions.h
new file mode 100644
index 0000000..c9ba76a
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/render/backends/gl/Qt3DSOpenGLPrefix.h
new file mode 100644
index 0000000..0e6dc6d
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSOpenGLTokens.h b/src/render/backends/gl/Qt3DSOpenGLTokens.h
new file mode 100644
index 0000000..882e276
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSOpenGLUtil.h b/src/render/backends/gl/Qt3DSOpenGLUtil.h
new file mode 100644
index 0000000..32f7dad
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/render/backends/gl/Qt3DSRenderBackendGL3.cpp
new file mode 100644
index 0000000..c4d8b64
--- /dev/null
+++ b/src/render/backends/gl/Qt3DSRenderBackendGL3.cpp
@@ -0,0 +1,796 @@
+/****************************************************************************
+**
+** 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,
+ qMin(anisotropy, m_maxAnisotropy)));
+ }
+ }
+
+ 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::ReleaseInputAssembler(
+ NVRenderBackend::NVRenderBackendInputAssemblerObject iao)
+ {
+ NVRenderBackendInputAssemblerGL *inputAssembler = (NVRenderBackendInputAssemblerGL *)iao;
+ if (inputAssembler->m_VaoID)
+ GL_CALL_EXTRA_FUNCTION(glDeleteVertexArrays(1, &inputAssembler->m_VaoID));
+ NVDelete(m_Foundation.getAllocator(), inputAssembler);
+ }
+
+ 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);
+ if (!fboID)
+ fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject();
+
+ 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/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/render/backends/gl/Qt3DSRenderBackendGL3.h
new file mode 100644
index 0000000..ea77270
--- /dev/null
+++ b/src/render/backends/gl/Qt3DSRenderBackendGL3.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_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 ReleaseInputAssembler(NVRenderBackendInputAssemblerObject iao) 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/render/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/render/backends/gl/Qt3DSRenderBackendGL4.cpp
new file mode 100644
index 0000000..083fc35
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSRenderBackendGL4.h b/src/render/backends/gl/Qt3DSRenderBackendGL4.h
new file mode 100644
index 0000000..bfdc03b
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp
new file mode 100644
index 0000000..0fe6e0f
--- /dev/null
+++ b/src/render/backends/gl/Qt3DSRenderBackendGLBase.cpp
@@ -0,0 +1,2230 @@
+/****************************************************************************
+**
+** 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)();
+
+ m_glFunctions->glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &m_maxAnisotropy);
+}
+/// 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 == nullptr)
+ 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)
+ return;
+ 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 nullptr;
+}
+
+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);
+ if (!fboID)
+ fboID = QT_PREPEND_NAMESPACE(QOpenGLContext)::currentContext()->defaultFramebufferObject();
+
+ 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,
+ qMin(m_maxAnisotropy, 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 = nullptr;
+ 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 = nullptr;
+ }
+
+ 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 successfully linked get the attribute information
+ if (linkStatus) {
+ // release old stuff
+ if (pProgram->m_shaderInput) {
+ NVDelete(m_Foundation.getAllocator(), pProgram->m_shaderInput);
+ pProgram->m_shaderInput = nullptr;
+ }
+
+ 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, nullptr, &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, nullptr, 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 == nullptr)
+ return "";
+
+ return retval;
+}
+
+const char *NVRenderBackendGLBase::getVendorString()
+{
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_VENDOR));
+ if (retval == nullptr)
+ return "";
+
+ return retval;
+}
+
+const char *NVRenderBackendGLBase::getRendererString()
+{
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER));
+ if (retval == nullptr)
+ return "";
+
+ return retval;
+}
+
+const char *NVRenderBackendGLBase::getExtensionString()
+{
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS));
+ if (retval == nullptr)
+ 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/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/render/backends/gl/Qt3DSRenderBackendGLBase.h
new file mode 100644
index 0000000..28e4dbb
--- /dev/null
+++ b/src/render/backends/gl/Qt3DSRenderBackendGLBase.h
@@ -0,0 +1,531 @@
+/****************************************************************************
+**
+** 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;
+ GLfloat m_maxAnisotropy;
+ };
+}
+}
+
+#endif
diff --git a/src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h b/src/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h
new file mode 100644
index 0000000..e14111a
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h b/src/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h
new file mode 100644
index 0000000..3a74a8e
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h b/src/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h
new file mode 100644
index 0000000..f7caffd
--- /dev/null
+++ b/src/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/render/backends/gl/Qt3DSRenderContextGL.cpp b/src/render/backends/gl/Qt3DSRenderContextGL.cpp
new file mode 100644
index 0000000..88670ef
--- /dev/null
+++ b/src/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/render/backends/software/Qt3DSRenderBackendNULL.cpp b/src/render/backends/software/Qt3DSRenderBackendNULL.cpp
new file mode 100644
index 0000000..af93e92
--- /dev/null
+++ b/src/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/render/backends/software/Qt3DSRenderBackendNULL.h b/src/render/backends/software/Qt3DSRenderBackendNULL.h
new file mode 100644
index 0000000..397ecfb
--- /dev/null
+++ b/src/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