summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Runtime/Qt3DSRuntimeStatic.pro6
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h11
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h8
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h8
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h10
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h193
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h32
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h6
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h111
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h2
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h12
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp2
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp873
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp12
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp38
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp62
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp61
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp7
-rw-r--r--src/Runtime/Source/UICRender/Include/UICRenderDefaultMaterialShaderGenerator.h4
-rw-r--r--src/Runtime/Source/UICRender/RendererImpl/UICRendererImpl.cpp11
-rw-r--r--src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderData.cpp16
-rw-r--r--src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderPreparationData.cpp9
-rw-r--r--src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.cpp73
-rw-r--r--src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.h2
-rw-r--r--src/Runtime/Source/UICRender/ResourceManager/UICRenderBufferManager.cpp11
-rw-r--r--src/Runtime/Source/UICRender/ResourceManager/UICRenderLoadedTextureHDR.cpp4
-rw-r--r--src/Runtime/Source/UICRender/Source/UICRenderDefaultMaterialShaderGenerator.cpp429
-rw-r--r--src/Runtime/Source/UICRender/Source/UICRenderPixelGraphicsRenderer.cpp4
-rw-r--r--src/Runtime/Source/UICRender/Source/UICRenderShaderCache.cpp39
-rw-r--r--src/Runtime/Source/UICRender/Source/UICRenderShaderCodeGeneratorV2.cpp9
-rw-r--r--src/Runtime/Source/UICRender/Source/UICRenderTextTextureAtlas.cpp7
-rw-r--r--src/Runtime/commoninclude.pri2
-rw-r--r--src/Runtime/res.qrc9
-rw-r--r--src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib43
-rw-r--r--src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib22
-rw-r--r--src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib2
-rw-r--r--src/Runtime/res/effectlib/funcspecularBSDF.glsllib14
-rw-r--r--src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib100
-rw-r--r--src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib52
-rw-r--r--src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib29
-rw-r--r--src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib27
-rw-r--r--src/Runtime/res/effectlib/gles2/monoChannel.glsllib58
-rw-r--r--src/Runtime/res/effectlib/gles2/sampleProbe.glsllib482
-rw-r--r--src/Runtime/res/effectlib/gles2/shadowMapping.glsllib106
-rw-r--r--src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib97
-rw-r--r--src/Runtime/res/effectlib/monoChannel.glsllib6
-rw-r--r--src/Runtime/res/effectlib/physGlossyBSDF.glsllib4
-rw-r--r--src/Runtime/res/effectlib/rotationTranslationScale.glsllib18
-rw-r--r--src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib10
-rw-r--r--src/Runtime/res/effectlib/transformCoordinate.glsllib8
-rw-r--r--tests/auto/runtime/Qt3DSRenderTestBase.cpp26
-rw-r--r--tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp2
-rw-r--r--tests/auto/runtime/tst_qt3dsruntime.cpp81
-rw-r--r--tests/auto/runtime/tst_qt3dsruntime.h22
54 files changed, 3025 insertions, 267 deletions
diff --git a/src/Runtime/Qt3DSRuntimeStatic.pro b/src/Runtime/Qt3DSRuntimeStatic.pro
index 072eaa3a..92fead0c 100644
--- a/src/Runtime/Qt3DSRuntimeStatic.pro
+++ b/src/Runtime/Qt3DSRuntimeStatic.pro
@@ -241,7 +241,8 @@ SOURCES += \
Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp \
Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp \
Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp \
- Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp
+ Source/Qt3DSRender/Source/backends/software/Qt3DSRenderBackendNULL.cpp \
+ Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp
HEADERS += \
Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h \
@@ -254,7 +255,8 @@ HEADERS += \
Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h \
Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h \
Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h \
- Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h
+ Source/Qt3DSRender/Include/render/backends/software/Qt3DSRenderBackendNULL.h \
+ Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h
# UICDM
SOURCES += \
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h
index 34b2eb73..bee5811a 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderContext.h
@@ -37,6 +37,7 @@
#include "foundation/Qt3DSDataRef.h"
#include "foundation/Qt3DSMemoryBuffer.h"
#include "render/glg/Qt3DSGLImplObjects.h"
+#include "render/backends/gl/Q3DSRenderBackendGLES2.h"
#include "render/backends/gl/Qt3DSRenderBackendGL3.h"
#include "render/backends/gl/Qt3DSRenderBackendGL4.h"
#include "render/backends/software/Qt3DSRenderBackendNULL.h"
@@ -149,6 +150,8 @@ namespace render {
virtual bool IsBlendCoherencySupported() const = 0;
virtual bool IsAdvancedBlendHwSupported() const = 0;
virtual bool IsAdvancedBlendHwSupportedKHR() const = 0;
+ virtual bool IsStandardDerivativesSupported() const = 0;
+ virtual bool IsTextureLodSupported() const = 0;
virtual void SetDefaultRenderTarget(QT3DSU64 targetID) = 0;
virtual void SetDefaultDepthBufferBitCount(QT3DSI32 depthBits) = 0;
@@ -763,6 +766,14 @@ namespace render {
{
return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::BlendCoherency);
}
+ bool IsStandardDerivativesSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::StandardDerivatives);
+ }
+ bool IsTextureLodSupported() const override
+ {
+ return GetRenderBackendCap(NVRenderBackend::NVRenderBackendCaps::TextureLod);
+ }
void SetDefaultRenderTarget(QT3DSU64 targetID) override
{
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h
index ffbbda72..8fd89bac 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h
@@ -215,7 +215,7 @@ namespace render {
virtual void Release() = 0;
virtual void Validate(NVRenderShaderProgram *inShader) = 0;
- virtual void BindToPorgram(NVRenderShaderProgram *inShader) = 0;
+ virtual void BindToProgram(NVRenderShaderProgram *inShader) = 0;
virtual void Update() = 0;
};
@@ -271,7 +271,7 @@ namespace render {
m_pCB->Update();
}
- void BindToPorgram(NVRenderShaderProgram *inShader) override
+ void BindToProgram(NVRenderShaderProgram *inShader) override
{
if (m_pCB)
m_pCB->BindToShaderProgram(inShader, m_Location, m_Binding);
@@ -329,7 +329,7 @@ namespace render {
m_pSB->Update();
}
- void BindToPorgram(NVRenderShaderProgram * /*inShader*/) override
+ void BindToProgram(NVRenderShaderProgram * /*inShader*/) override
{
if (m_pSB)
m_pSB->BindToShaderProgram(m_Location);
@@ -388,7 +388,7 @@ namespace render {
m_pAcB->Update();
}
- void BindToPorgram(NVRenderShaderProgram * /*inShader*/) override
+ void BindToProgram(NVRenderShaderProgram * /*inShader*/) override
{
if (m_pAcB)
m_pAcB->BindToShaderProgram(m_Location);
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h
index 73e123c1..ae737ba2 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h
@@ -407,6 +407,11 @@ namespace render {
NVRenderShaderProgram *m_Shader; ///< pointer to shader program
NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object
+ NVRenderCachedShaderProperty(const QString &inConstantName, NVRenderShaderProgram &inShader)
+ : NVRenderCachedShaderProperty(qPrintable(inConstantName), inShader)
+ {
+ }
+
NVRenderCachedShaderProperty(const char *inConstantName, NVRenderShaderProgram &inShader)
: m_Shader(&inShader)
, m_Constant(NULL)
@@ -424,6 +429,7 @@ namespace render {
}
}
}
+
NVRenderCachedShaderProperty()
: m_Shader(NULL)
, m_Constant(NULL)
@@ -468,7 +474,7 @@ namespace render {
if (m_ShaderBuffer) {
m_ShaderBuffer->Validate(m_Shader);
m_ShaderBuffer->Update();
- m_ShaderBuffer->BindToPorgram(m_Shader);
+ m_ShaderBuffer->BindToProgram(m_Shader);
}
}
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h
index 00811539..12de5d88 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/Qt3DSRenderBackend.h
@@ -126,6 +126,9 @@ namespace render {
BlendCoherency, ///< Hardware supports blend coherency
gpuShader5, // for high precision sampling
AdvancedBlendKHR, ///< Driver supports advanced blend modes
+ VertexArrayObject,
+ StandardDerivatives,
+ TextureLod
};
} NVRenderBackendCaps;
@@ -2213,8 +2216,8 @@ namespace render {
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 bAtomicCounterBufferSupported : 1; ///< Atomic counter buffers are
+ /// supported
bool bShaderImageLoadStoreSupported : 1; ///< Shader image load / store
///operations are supported
bool bProgramPipelineSupported : 1; ///< Driver supports separate programs
@@ -2225,6 +2228,9 @@ namespace render {
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;
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h
new file mode 100644
index 00000000..eefc7996
--- /dev/null
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Q3DSRenderBackendGLES2.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DS_RENDER_BACKEND_GLES2_H
+#define QT3DS_RENDER_BACKEND_GLES2_H
+
+#include "foundation/Qt3DSAtomic.h"
+#include "render/backends/gl/Qt3DSRenderBackendGLBase.h"
+#include "render/backends/gl/Qt3DSOpenGLExtensions.h"
+
+#include <QtGui/qopenglextrafunctions.h>
+#include <QtOpenGLExtensions/QtOpenGLExtensions>
+
+namespace qt3ds {
+namespace render {
+
+ ///< forward declaration
+ class NVRenderBackendMiscStateGL;
+
+ using namespace foundation;
+
+ class NVRenderBackendGLES2Impl : public NVRenderBackendGLBase
+ {
+ public:
+ /// constructor
+ NVRenderBackendGLES2Impl(NVFoundationBase &fnd,
+ qt3ds::foundation::IStringTable &stringTable,
+ const QSurfaceFormat &format);
+ /// destructor
+ virtual ~NVRenderBackendGLES2Impl();
+
+ QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(m_Foundation)
+
+ public:
+ QT3DSU32 GetDepthBits() const override;
+ QT3DSU32 GetStencilBits() const override;
+ void GenerateMipMaps(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderHint::Enum genType) override;
+
+ void SetMultisampledTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ size_t samples,
+ NVRenderTextureFormats::Enum internalFormat,
+ size_t width, size_t height,
+ bool fixedsamplelocations) override;
+
+ void SetTextureData3D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, size_t depth, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = nullptr) override;
+
+ void SetTextureData2D(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSU32 level,
+ NVRenderTextureFormats::Enum internalFormat, size_t width,
+ size_t height, QT3DSI32 border,
+ NVRenderTextureFormats::Enum format,
+ const void *hostPtr = nullptr) override;
+
+ void UpdateSampler(
+ NVRenderBackendSamplerObject so, NVRenderTextureTargetType::Enum target,
+ NVRenderTextureMinifyingOp::Enum minFilter = NVRenderTextureMinifyingOp::Linear,
+ NVRenderTextureMagnifyingOp::Enum magFilter = NVRenderTextureMagnifyingOp::Linear,
+ NVRenderTextureCoordOp::Enum wrapS = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapT = NVRenderTextureCoordOp::ClampToEdge,
+ NVRenderTextureCoordOp::Enum wrapR = NVRenderTextureCoordOp::ClampToEdge,
+ QT3DSF32 minLod = -1000.0f, QT3DSF32 maxLod = 1000.0f, QT3DSF32 lodBias = 0.0f,
+ NVRenderTextureCompareMode::Enum compareMode = NVRenderTextureCompareMode::NoCompare,
+ NVRenderTextureCompareOp::Enum compareFunc = NVRenderTextureCompareOp::LessThanOrEqual,
+ QT3DSF32 anisotropy = 1.0f, QT3DSF32 *borderColor = nullptr) override;
+
+ void UpdateTextureObject(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target, QT3DSI32 baseLevel,
+ QT3DSI32 maxLevel) override;
+
+ void UpdateTextureSwizzle(NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target,
+ NVRenderTextureSwizzleMode::Enum swizzleMode) override;
+
+ bool SetInputAssembler(NVRenderBackendInputAssemblerObject iao,
+ NVRenderBackendShaderProgramObject po) override;
+
+ void SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet) override;
+ void SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace) override;
+
+ void BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1, QT3DSI32 srcY1,
+ QT3DSI32 dstX0, QT3DSI32 dstY0, QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter) override;
+
+
+ NVRenderBackendRenderTargetObject CreateRenderTarget() override;
+ void ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target
+ = NVRenderTextureTargetType::Texture2D) override;
+ void RenderTargetAttach(NVRenderBackendRenderTargetObject rto,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level,
+ QT3DSI32 layer) override;
+ void SetRenderTarget(NVRenderBackendRenderTargetObject rto) override;
+ bool RenderTargetIsValid(NVRenderBackendRenderTargetObject rto) override;
+
+ virtual NVRenderBackendRenderbufferObject
+ CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat, size_t width,
+ size_t height) override;
+ void SetReadTarget(NVRenderBackendRenderTargetObject rto) override;
+ void ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo) override;
+ bool ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height) override;
+
+ void *MapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags,
+ size_t offset, size_t length,
+ NVRenderBufferAccessFlags accessFlags) override;
+ bool UnmapBuffer(NVRenderBackendBufferObject bo, NVRenderBufferBindFlags bindFlags) override;
+
+ QT3DSI32 GetConstantBufferCount(NVRenderBackendShaderProgramObject po) override;
+ QT3DSI32 GetConstantBufferInfoByID(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSU32 nameBufSize, QT3DSI32 *paramCount,
+ QT3DSI32 *bufferSize, QT3DSI32 *length,
+ char *nameBuf) override;
+ void GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po, QT3DSU32 id,
+ QT3DSI32 *indices) override;
+ void GetConstantBufferParamInfoByIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 count, QT3DSU32 *indices,
+ QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset) override;
+ void ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding) override;
+ void ProgramSetConstantBuffer(QT3DSU32 index, NVRenderBackendBufferObject bo) override;
+
+ NVRenderBackendQueryObject CreateQuery() override;
+ void ReleaseQuery(NVRenderBackendQueryObject qo) override;
+ void BeginQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void EndQuery(NVRenderBackendQueryObject qo, NVRenderQueryType::Enum type) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU32 *params) override;
+ void GetQueryResult(NVRenderBackendQueryObject qo,
+ NVRenderQueryResultType::Enum resultType, QT3DSU64 *params) override;
+ void SetQueryTimer(NVRenderBackendQueryObject qo) override;
+
+ NVRenderBackendSyncObject CreateSync(NVRenderSyncType::Enum tpye,
+ NVRenderSyncFlags syncFlags) override;
+ void ReleaseSync(NVRenderBackendSyncObject so) override;
+ void WaitSync(NVRenderBackendSyncObject so, NVRenderCommandFlushFlags syncFlags,
+ QT3DSU64 timeout) override;
+
+ protected:
+ NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state
+#if defined(QT_OPENGL_ES)
+ Qt3DSOpenGLES2Extensions *m_qt3dsExtensions;
+#endif
+ };
+}
+}
+
+#endif
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h
index 4fae0a46..fd8680e5 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLExtensions.h
@@ -77,6 +77,10 @@ public:
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
};
@@ -180,6 +184,10 @@ public:
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;
};
@@ -355,6 +363,30 @@ inline void Qt3DSOpenGLES2Extensions::glGetPathSpacingNV(GLenum pathListMode,
advanceScale, kerningScale, transformType, returnedSpacing);
}
+inline void Qt3DSOpenGLES2Extensions::glBindVertexArrayOES(GLuint array)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->BindVertexArrayOES(array);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->DeleteVertexArraysOES(n, arrays);
+}
+
+inline void Qt3DSOpenGLES2Extensions::glGenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ d->GenVertexArraysOES(n, arrays);
+}
+
+inline GLboolean Qt3DSOpenGLES2Extensions::glIsVertexArrayOES(GLuint array)
+{
+ Q_D(Qt3DSOpenGLExtensions);
+ return d->IsVertexArrayOES(array);
+}
+
#endif // QT_OPENGL_ES
#endif // QT3DSOPENGLEXTENSIONS_H
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h
index 2cbc8b6a..0e6dc6d4 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLPrefix.h
@@ -33,13 +33,13 @@
#include <QtGui/qtguiglobal.h>
#if defined(QT_OPENGL_ES)
#define GL_GLEXT_PROTOTYPES
-// We require a minimum of GLES 3.1 for Qt3DStudio when building against a
-// non-desktop OpenGL target
#if defined(QT_OPENGL_ES_3_2)
#include <GLES3/gl32.h>
#else
-#include <GLES3/gl31.h>
+#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>
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h
index ebfb20c2..71162a56 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSOpenGLUtil.h
@@ -46,6 +46,38 @@
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
+
#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) \
@@ -156,7 +188,7 @@ namespace render {
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) \
@@ -165,6 +197,15 @@ namespace render {
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) \
@@ -324,8 +365,7 @@ namespace render {
}
}
- // TODO: Why aren't these defined?
-#ifndef __APPLE__
+#if defined(GL_KHR_blend_equation_advanced)
if (khrAdvancedBlendSupported) {
switch (value) {
case NVRenderBlendEquation::Overlay:
@@ -619,12 +659,14 @@ namespace render {
retval = GL_ELEMENT_ARRAY_BUFFER;
else if (value & NVRenderBufferBindValues::Constant)
retval = GL_UNIFORM_BUFFER;
+#if defined(GL_ARB_shader_storage_buffer_object)
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;
+#endif
else
QT3DS_ASSERT(false);
@@ -641,12 +683,14 @@ namespace render {
retval |= NVRenderBufferBindValues::Index;
else if (value == GL_UNIFORM_BUFFER)
retval |= NVRenderBufferBindValues::Constant;
+#if defined(GL_ARB_shader_storage_buffer_object)
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;
+#endif
else
QT3DS_ASSERT(false);
@@ -688,8 +732,13 @@ namespace render {
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);
@@ -796,8 +845,13 @@ namespace render {
{
switch (value) {
case NVRenderTextureFormats::R8:
- outFormat = GL_RED;
- outInternalFormat = GL_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:
@@ -859,6 +913,7 @@ namespace render {
// check extented texture formats
if (!(type & contextFlags)) {
switch (value) {
+#if !defined(QT_OPENGL_ES)
case NVRenderTextureFormats::R16: {
if (IsGlEsContext(type)) {
outFormat = GL_RED_INTEGER;
@@ -870,6 +925,7 @@ namespace render {
outDataType = GL_UNSIGNED_SHORT;
return true;
}
+#endif
case NVRenderTextureFormats::R16F:
outFormat = GL_RED;
outInternalFormat = GL_R16F;
@@ -1240,8 +1296,10 @@ namespace render {
return GL_INVALID_ENUM;
}
+
static GLenum fromImageAccessToGL(NVRenderImageAccessType::Enum value)
{
+#if defined(GL_READ_ONLY)
switch (value) {
case NVRenderImageAccessType::Read:
return GL_READ_ONLY;
@@ -1252,7 +1310,7 @@ namespace render {
default:
break;
}
-
+#endif
QT3DS_ASSERT(false);
return GL_INVALID_ENUM;
}
@@ -1279,7 +1337,7 @@ namespace render {
{
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)
@@ -1306,7 +1364,7 @@ namespace render {
retval |= GL_UNIFORM_BARRIER_BIT;
if (value & NVRenderBufferBarrierValues::VertexAttribArray)
retval |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
-
+#endif
QT3DS_ASSERT(retval);
return retval;
}
@@ -1315,7 +1373,7 @@ namespace render {
{
QT3DSU32 value = flags;
GLbitfield retval = 0;
-
+#if !defined(QT_OPENGL_ES)
if (value & NVRenderShaderTypeValue::Vertex)
retval |= GL_VERTEX_SHADER_BIT;
if (value & NVRenderShaderTypeValue::Fragment)
@@ -1325,12 +1383,12 @@ namespace render {
if (value & NVRenderShaderTypeValue::TessEvaluation)
retval |= GL_TESS_EVALUATION_SHADER_BIT;
if (value & NVRenderShaderTypeValue::Geometry)
-#if defined(QT_OPENGL_ES)
+#if defined(QT_OPENGL_ES_3_1)
retval |= GL_GEOMETRY_SHADER_BIT_EXT;
#else
retval |= GL_GEOMETRY_SHADER_BIT;
#endif
-
+#endif
QT3DS_ASSERT(retval || !value);
return retval;
}
@@ -1360,10 +1418,12 @@ namespace render {
#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;
}
@@ -1644,6 +1704,7 @@ namespace render {
GLenum glFillMode;
switch (inMode) {
+#if !defined(QT_OPENGL_ES)
case NVRenderPathFillMode::Fill:
glFillMode = GL_PATH_FILL_MODE_NV;
break;
@@ -1656,9 +1717,9 @@ namespace render {
case NVRenderPathFillMode::Invert:
glFillMode = GL_INVERT;
break;
+#endif
default:
QT3DS_ASSERT(false);
- glFillMode = GL_PATH_FILL_MODE_NV;
break;
}
@@ -1670,6 +1731,7 @@ namespace render {
GLenum glFontTarget;
switch (inFontTarget) {
+#if !defined(QT_OPENGL_ES)
case NVRenderPathFontTarget::StandardFont:
glFontTarget = GL_STANDARD_FONT_NAME_NV;
break;
@@ -1679,9 +1741,9 @@ namespace render {
case NVRenderPathFontTarget::FileFont:
glFontTarget = GL_FILE_NAME_NV;
break;
+#endif
default:
QT3DS_ASSERT(false);
- glFontTarget = GL_STANDARD_FONT_NAME_NV;
break;
}
@@ -1693,6 +1755,7 @@ namespace render {
NVRenderPathReturnValues::Enum returnValue;
switch (inReturnValue) {
+#if !defined(QT_OPENGL_ES)
case GL_FONT_GLYPHS_AVAILABLE_NV:
returnValue = NVRenderPathReturnValues::FontGlypsAvailable;
break;
@@ -1705,6 +1768,7 @@ namespace render {
case GL_FONT_UNINTELLIGIBLE_NV:
returnValue = NVRenderPathReturnValues::FontUnintelligible;
break;
+#endif
case GL_INVALID_ENUM:
case GL_INVALID_VALUE:
returnValue = NVRenderPathReturnValues::InvalidEnum;
@@ -1726,15 +1790,16 @@ namespace render {
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);
- glMissingGlyphs = GL_SKIP_MISSING_GLYPH_NV;
break;
}
@@ -1746,6 +1811,7 @@ namespace render {
GLenum glListMode;
switch (inListMode) {
+#if !defined(QT_OPENGL_ES)
case NVRenderPathListMode::AccumAdjacentPairs:
glListMode = GL_ACCUM_ADJACENT_PAIRS_NV;
break;
@@ -1755,9 +1821,9 @@ namespace render {
case NVRenderPathListMode::FirstToRest:
glListMode = GL_FIRST_TO_REST_NV;
break;
+#endif
default:
QT3DS_ASSERT(false);
- glListMode = GL_ACCUM_ADJACENT_PAIRS_NV;
break;
}
@@ -1769,6 +1835,7 @@ namespace render {
GLenum glCoverMode;
switch (inMode) {
+#if !defined(QT_OPENGL_ES)
case NVRenderPathCoverMode::ConvexHull:
glCoverMode = GL_CONVEX_HULL_NV;
break;
@@ -1784,9 +1851,9 @@ namespace render {
case NVRenderPathCoverMode::PathStrokeCover:
glCoverMode = GL_PATH_STROKE_COVER_MODE_NV;
break;
+#endif
default:
QT3DS_ASSERT(false);
- glCoverMode = GL_BOUNDING_BOX_NV;
break;
}
@@ -1815,11 +1882,11 @@ namespace render {
return GL_3_BYTES_NV;
case NVRenderPathFormatType::Bytes4:
return GL_4_BYTES_NV;
-#endif
case NVRenderPathFormatType::Utf8:
return GL_UTF8_NV;
case NVRenderPathFormatType::Utf16:
return GL_UTF16_NV;
+#endif
default:
break;
}
@@ -1831,12 +1898,12 @@ namespace render {
{
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;
}
@@ -1846,6 +1913,7 @@ namespace render {
switch (value) {
case NVRenderPathTransformType::NoTransform:
return GL_NONE;
+#if !defined(QT_OPENGL_ES)
case NVRenderPathTransformType::TranslateX:
return GL_TRANSLATE_X_NV;
case NVRenderPathTransformType::TranslateY:
@@ -1862,6 +1930,7 @@ namespace render {
return GL_TRANSPOSE_AFFINE_2D_NV;
case NVRenderPathTransformType::TransposeAffine3D:
return GL_TRANSPOSE_AFFINE_3D_NV;
+#endif
default:
break;
}
@@ -1873,7 +1942,7 @@ namespace render {
{
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)
@@ -1921,7 +1990,7 @@ namespace render {
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;
}
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h
index 088a279f..7147b341 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGL3.h
@@ -156,7 +156,7 @@ namespace render {
protected:
NVRenderBackendMiscStateGL *m_pCurrentMiscState; ///< this holds the current misc state
-#if defined(QT_OPENGL_ES)
+#if defined(QT_OPENGL_ES_2)
Qt3DSOpenGLES2Extensions *m_qt3dsExtensions;
#else
QOpenGLExtension_ARB_timer_query *m_timerExtension;
diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h
index 6cde45ef..9048a9c4 100644
--- a/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h
+++ b/src/Runtime/Source/Qt3DSRender/Include/render/backends/gl/Qt3DSRenderBackendGLBase.h
@@ -46,6 +46,9 @@
#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 {
@@ -492,7 +495,8 @@ namespace render {
eastl::string &errorMessage, bool binary);
virtual const char *getVersionString();
virtual const char *getVendorString();
- virtual const char *geRendererString();
+ virtual const char *getRendererString();
+ virtual const char *getExtensionString();
virtual void setAndInspectHardwareCaps();
@@ -502,7 +506,7 @@ namespace render {
NVScopedRefCounted<qt3ds::foundation::IStringTable>
m_StringTable; ///< pointer to a string table
GLConversion m_Conversion; ///< Class for conversion from base type to GL types
- nvvector<TContextStr> m_Extensions; ///< contains the OpenGL extension string
+ 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;
@@ -512,7 +516,11 @@ namespace render {
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;
};
diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp
index 33c8f271..b404a972 100644
--- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp
+++ b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderConstantBuffer.cpp
@@ -86,7 +86,7 @@ namespace render {
NVRenderConstantBuffer::~NVRenderConstantBuffer()
{
- // chekc if we should release memory
+ // check if we should release memory
if (m_ShadowCopy.size()) {
m_Foundation.getAllocator().deallocate(m_ShadowCopy.begin());
}
diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp
new file mode 100644
index 00000000..fbe75b6f
--- /dev/null
+++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Q3DSRenderBackendGLES2.cpp
@@ -0,0 +1,873 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render/backends/gl/Q3DSRenderBackendGLES2.h"
+#include "render/backends/gl/Qt3DSRenderBackendInputAssemblerGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h"
+#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h"
+
+#ifdef RENDER_BACKEND_LOG_GL_ERRORS
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError(#x, __FILE__, __LINE__)
+#else
+#define RENDER_LOG_ERROR_PARAMS(x) checkGLError()
+#endif
+
+#if defined(QT_OPENGL_ES)
+#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 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_ANGLE_depth_texture");
+ 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) {
+ 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)
+ 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)
+ 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);
+
+ 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);
+ 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]));
+#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;
+
+ UICBASE_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
+ UICBASE_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) {
+ UICBASE_FOREACH(idx, shaderAttribBuffer.size())
+ {
+ const NVRenderBackendShaderInputEntryGL &attrib(shaderAttribBuffer[idx]);
+ NVRenderBackendLayoutEntryGL *entry =
+ attribLayout->getEntryByName(attrib.m_AttribName);
+
+ if (entry) {
+ NVRenderBackendLayoutEntryGL &entryData(*entry);
+ if (entryData.m_Type != attrib.m_Type
+ || entryData.m_NumComponents != attrib.m_NumComponents
+ || entryData.m_AttribIndex != attrib.m_AttribLocation) {
+ qCCritical(INVALID_OPERATION, "Attrib %s dn't match vertex layout",
+ attrib.m_AttribName.c_str());
+ QT3DS_ASSERT(false);
+ }
+ } else {
+ qCWarning(WARNING, "Failed to Bind attribute %s", attrib.m_AttribName.c_str());
+ }
+ }
+ }
+#endif // _DEBUG
+
+ return true;
+}
+
+void NVRenderBackendGLES2Impl::SetDrawBuffers(NVRenderBackendRenderTargetObject rto,
+ NVConstDataRef<QT3DSI32> inDrawBufferSet)
+{
+ NVRENDER_BACKEND_UNUSED(rto);
+
+ m_DrawBuffersArray.clear();
+
+ for (QT3DSU32 idx = 0, end = inDrawBufferSet.size(); idx < end; ++idx) {
+ if (inDrawBufferSet[idx] < 0)
+ m_DrawBuffersArray.push_back(GL_NONE);
+ else
+ m_DrawBuffersArray.push_back(GL_COLOR_ATTACHMENT0 + inDrawBufferSet[idx]);
+ }
+
+ GL_CALL_EXTRA_FUNCTION(glDrawBuffers((int)m_DrawBuffersArray.size(),
+ m_DrawBuffersArray.data()));
+}
+
+void NVRenderBackendGLES2Impl::SetReadBuffer(NVRenderBackendRenderTargetObject rto,
+ NVReadFaces::Enum inReadFace)
+{
+ NVRENDER_BACKEND_UNUSED(rto);
+
+}
+
+void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to, QT3DSI32 level,
+ QT3DSI32 layer)
+{
+ Q_ASSERT(false);
+}
+
+void NVRenderBackendGLES2Impl::BlitFramebuffer(QT3DSI32 srcX0, QT3DSI32 srcY0, QT3DSI32 srcX1,
+ QT3DSI32 srcY1, QT3DSI32 dstX0, QT3DSI32 dstY0,
+ QT3DSI32 dstX1, QT3DSI32 dstY1,
+ NVRenderClearFlags flags,
+ NVRenderTextureMagnifyingOp::Enum filter)
+{
+ GL_CALL_EXTRA_FUNCTION(glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
+ dstY1,
+ m_Conversion.fromClearFlagsToGL(flags),
+ m_Conversion.fromTextureMagnifyingOpToGL(filter)));
+}
+
+
+NVRenderBackend::NVRenderBackendRenderTargetObject NVRenderBackendGLES2Impl::CreateRenderTarget()
+{
+ GLuint fboID = 0;
+ GL_CALL_EXTRA_FUNCTION(glGenFramebuffers(1, &fboID));
+ return (NVRenderBackend::NVRenderBackendRenderTargetObject)fboID;
+}
+
+void NVRenderBackendGLES2Impl::ReleaseRenderTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ if (fboID)
+ GL_CALL_EXTRA_FUNCTION(glDeleteFramebuffers(1, &fboID));
+}
+
+void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendRenderbufferObject rbo)
+{
+ // rto must be the current render target
+ GLuint rbID = HandleToID_cast(GLuint, size_t, rbo);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+
+ GL_CALL_EXTRA_FUNCTION(glFramebufferRenderbuffer(GL_FRAMEBUFFER, glAttach, GL_RENDERBUFFER,
+ rbID));
+}
+
+void NVRenderBackendGLES2Impl::RenderTargetAttach(NVRenderBackendRenderTargetObject /* rto */,
+ NVRenderFrameBufferAttachments::Enum attachment,
+ NVRenderBackendTextureObject to,
+ NVRenderTextureTargetType::Enum target)
+{
+ // rto must be the current render target
+ GLuint texID = HandleToID_cast(GLuint, size_t, to);
+
+ QT3DS_ASSERT(target == NVRenderTextureTargetType::Texture2D
+ || m_backendSupport.caps.bits.bMsTextureSupported);
+
+ GLenum glAttach = GLConversion::fromFramebufferAttachmentsToGL(attachment);
+ GLenum glTarget = m_Conversion.fromTextureTargetToGL(target);
+
+ if (attachment == NVRenderFrameBufferAttachments::DepthStencil) {
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ glTarget, texID, 0));
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ glTarget, texID, 0));
+ } else {
+ GL_CALL_EXTRA_FUNCTION(glFramebufferTexture2D(GL_FRAMEBUFFER, glAttach, glTarget, texID,
+ 0));
+ }
+}
+
+void NVRenderBackendGLES2Impl::SetRenderTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_FRAMEBUFFER, fboID));
+}
+
+void NVRenderBackendGLES2Impl::SetReadTarget(NVRenderBackendRenderTargetObject rto)
+{
+ GLuint fboID = HandleToID_cast(GLuint, size_t, rto);
+
+ GL_CALL_EXTRA_FUNCTION(glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID));
+}
+
+bool NVRenderBackendGLES2Impl::RenderTargetIsValid(NVRenderBackendRenderTargetObject /* rto */)
+{
+ GLenum completeStatus = GL_CALL_EXTRA_FUNCTION(glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ switch (completeStatus) {
+#define HANDLE_INCOMPLETE_STATUS(x) \
+ case x: \
+ qCCritical(INTERNAL_ERROR, "Framebuffer is not complete: %s", #x); \
+ return false;
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
+ HANDLE_INCOMPLETE_STATUS(GL_FRAMEBUFFER_UNSUPPORTED)
+ #undef HANDLE_INCOMPLETE_STATUS
+ }
+ return true;
+}
+
+NVRenderBackend::NVRenderBackendRenderbufferObject
+NVRenderBackendGLES2Impl::CreateRenderbuffer(NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height)
+{
+ GLuint bufID = 0;
+
+ GL_CALL_EXTRA_FUNCTION(glGenRenderbuffers(1, &bufID));
+ GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID));
+ GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER,
+ GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat),
+ (GLsizei)width, (GLsizei)height));
+
+ // check for error
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR, GLConversion::processGLError(error));
+ QT3DS_ASSERT(false);
+ GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID));
+ bufID = 0;
+ }
+
+ GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, 0));
+
+ return (NVRenderBackend::NVRenderBackendRenderbufferObject)bufID;
+}
+
+void NVRenderBackendGLES2Impl::ReleaseRenderbuffer(NVRenderBackendRenderbufferObject rbo)
+{
+ GLuint bufID = HandleToID_cast(GLuint, size_t, rbo);
+
+ if (bufID)
+ GL_CALL_EXTRA_FUNCTION(glDeleteRenderbuffers(1, &bufID));
+}
+
+bool NVRenderBackendGLES2Impl::ResizeRenderbuffer(NVRenderBackendRenderbufferObject rbo,
+ NVRenderRenderBufferFormats::Enum storageFormat,
+ size_t width, size_t height)
+{
+ bool success = true;
+ GLuint bufID = HandleToID_cast(GLuint, size_t, rbo);
+
+ QT3DS_ASSERT(bufID);
+
+ GL_CALL_EXTRA_FUNCTION(glBindRenderbuffer(GL_RENDERBUFFER, bufID));
+ GL_CALL_EXTRA_FUNCTION(glRenderbufferStorage(GL_RENDERBUFFER,
+ GLConversion::fromRenderBufferFormatsToRenderBufferGL(storageFormat),
+ (GLsizei)width, (GLsizei)height));
+
+ // check for error
+ GLenum error = m_glFunctions->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCCritical(GL_ERROR, GLConversion::processGLError(error));
+ QT3DS_ASSERT(false);
+ success = false;
+ }
+
+ return success;
+}
+
+void *NVRenderBackendGLES2Impl::MapBuffer(NVRenderBackendBufferObject,
+ NVRenderBufferBindFlags bindFlags, size_t offset,
+ size_t length, NVRenderBufferAccessFlags accessFlags)
+{
+ void *ret = nullptr;
+ ret = GL_CALL_EXTRA_FUNCTION(
+ glMapBufferRange(m_Conversion.fromBindBufferFlagsToGL(bindFlags), offset,
+ length, m_Conversion.fromBufferAccessBitToGL(accessFlags)));
+
+ return ret;
+}
+
+bool NVRenderBackendGLES2Impl::UnmapBuffer(NVRenderBackendBufferObject,
+ NVRenderBufferBindFlags bindFlags)
+{
+ GLboolean ret;
+
+ ret = GL_CALL_EXTRA_FUNCTION(glUnmapBuffer(m_Conversion.fromBindBufferFlagsToGL(bindFlags)));
+
+ return (ret) ? true : false;
+}
+
+QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferCount(NVRenderBackendShaderProgramObject po)
+{
+ QT3DS_ASSERT(po);
+ GLint numUniformBuffers = 0;
+ if (GetRenderBackendCap(NVRenderBackendCaps::ConstantBuffer)) {
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_EXTRA_FUNCTION(glGetProgramiv(programID, GL_ACTIVE_UNIFORM_BLOCKS,
+ &numUniformBuffers));
+ }
+ return numUniformBuffers;
+}
+
+QT3DSI32 NVRenderBackendGLES2Impl::GetConstantBufferInfoByID(
+ NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSU32 nameBufSize,
+ QT3DSI32 *paramCount, QT3DSI32 *bufferSize,
+ QT3DSI32 *length, char *nameBuf)
+{
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(length);
+ QT3DS_ASSERT(nameBuf);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+ GLuint blockIndex = GL_INVALID_INDEX;
+
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockName(programID, id, nameBufSize, length,
+ nameBuf));
+
+ if (*length > 0) {
+ blockIndex = GL_CALL_EXTRA_FUNCTION(glGetUniformBlockIndex(programID, nameBuf));
+ if (blockIndex != GL_INVALID_INDEX) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex,
+ GL_UNIFORM_BLOCK_DATA_SIZE, bufferSize));
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, blockIndex,
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, paramCount));
+ }
+ }
+
+ return blockIndex;
+}
+
+void NVRenderBackendGLES2Impl::GetConstantBufferParamIndices(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 id, QT3DSI32 *indices)
+{
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(indices);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ if (indices) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformBlockiv(programID, id,
+ GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
+ indices));
+ }
+}
+
+void NVRenderBackendGLES2Impl::GetConstantBufferParamInfoByIndices(
+ NVRenderBackendShaderProgramObject po, QT3DSU32 count, QT3DSU32 *indices, QT3DSI32 *type,
+ QT3DSI32 *size, QT3DSI32 *offset)
+{
+ QT3DS_ASSERT(po);
+ QT3DS_ASSERT(count);
+ QT3DS_ASSERT(indices);
+
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ if (count && indices) {
+ if (type) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices,
+ GL_UNIFORM_TYPE, type));
+ // convert to UIC types
+ UICBASE_FOREACH(idx, count)
+ {
+ type[idx] = m_Conversion.fromShaderGLToPropertyDataTypes(type[idx]);
+ }
+ }
+ if (size) {
+ GL_CALL_EXTRA_FUNCTION(glGetActiveUniformsiv(programID, count, indices,
+ GL_UNIFORM_SIZE, size));
+ }
+ if (offset) {
+ GL_CALL_EXTRA_FUNCTION(
+ glGetActiveUniformsiv(programID, count, indices, GL_UNIFORM_OFFSET, offset));
+ }
+ }
+}
+
+void NVRenderBackendGLES2Impl::ProgramSetConstantBlock(NVRenderBackendShaderProgramObject po,
+ QT3DSU32 blockIndex, QT3DSU32 binding)
+{
+ NVRenderBackendShaderProgramGL *pProgram = (NVRenderBackendShaderProgramGL *)po;
+ GLuint programID = static_cast<GLuint>(pProgram->m_ProgramID);
+
+ GL_CALL_EXTRA_FUNCTION(glUniformBlockBinding(programID, blockIndex, binding));
+}
+
+void NVRenderBackendGLES2Impl::ProgramSetConstantBuffer(QT3DSU32 index,
+ NVRenderBackendBufferObject bo)
+{
+ QT3DS_ASSERT(bo);
+
+ GLuint bufID = HandleToID_cast(GLuint, size_t, bo);
+ GL_CALL_EXTRA_FUNCTION(glBindBufferBase(GL_UNIFORM_BUFFER, index, bufID));
+}
+
+NVRenderBackend::NVRenderBackendQueryObject NVRenderBackendGLES2Impl::CreateQuery()
+{
+ QT3DSU32 glQueryID = 0;
+
+ return (NVRenderBackendQueryObject)glQueryID;
+}
+
+void NVRenderBackendGLES2Impl::ReleaseQuery(NVRenderBackendQueryObject)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::BeginQuery(NVRenderBackendQueryObject,
+ NVRenderQueryType::Enum)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::EndQuery(NVRenderBackendQueryObject, NVRenderQueryType::Enum)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject,
+ NVRenderQueryResultType::Enum,
+ QT3DSU32 *)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::GetQueryResult(NVRenderBackendQueryObject,
+ NVRenderQueryResultType::Enum,
+ QT3DSU64 *)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::SetQueryTimer(NVRenderBackendQueryObject)
+{
+
+}
+
+NVRenderBackend::NVRenderBackendSyncObject
+NVRenderBackendGLES2Impl::CreateSync(NVRenderSyncType::Enum, NVRenderSyncFlags)
+{
+ GLsync syncID = 0;
+ return NVRenderBackendSyncObject(syncID);
+}
+
+void NVRenderBackendGLES2Impl::ReleaseSync(NVRenderBackendSyncObject)
+{
+
+}
+
+void NVRenderBackendGLES2Impl::WaitSync(NVRenderBackendSyncObject, NVRenderCommandFlushFlags,
+ QT3DSU64)
+{
+
+}
+}
+}
diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp
index 71c4e41a..ac493c68 100644
--- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp
+++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSOpenGLExtensions.cpp
@@ -151,6 +151,18 @@ bool Qt3DSOpenGLES2Extensions::initializeOpenGLFunctions()
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;
diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp
index c8a99cb2..8d9640bb 100644
--- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp
+++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL3.cpp
@@ -33,15 +33,21 @@
#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h"
#include "render/backends/gl/Qt3DSRenderBackendShaderProgramGL.h"
-#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; checkGLError();
+#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; checkGLError();
-#define GL_CALL_TESSELATION_EXT(x) m_qt3dsExtensions->x; checkGLError();
+#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; checkGLError();
-#define GL_CALL_TESSELATION_EXT(x) m_tessellationShader->x; checkGLError();
-#define GL_CALL_MULTISAMPLE_EXT(x) m_multiSample->x; checkGLError();
+#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 {
@@ -71,7 +77,7 @@ namespace render {
eastl::string apiVendor(getVendorString());
qCInfo(TRACE_INFO, "HW vendor: %s", apiVendor.c_str());
- eastl::string apiRenderer(geRendererString());
+ eastl::string apiRenderer(getRendererString());
qCInfo(TRACE_INFO, "Vendor renderer: %s", apiRenderer.c_str());
// clear support bits
@@ -85,11 +91,8 @@ namespace render {
for (QT3DSI32 i = 0; i < numExtensions; i++) {
char *extensionString = (char *)GL_CALL_EXTRA_FUNCTION(glGetStringi(GL_EXTENSIONS, i));
- const TContextStr::value_type *thePtr =
- reinterpret_cast<TContextStr::value_type *>(extensionString);
- m_Extensions.push_back(
- TContextStr(ForwardingAllocator(m_Foundation.getAllocator(), "ExtensionStr")));
- m_Extensions.back().assign(thePtr);
+
+ m_extensions.push_back(QString::fromLocal8Bit(extensionString));
if (extensionBuffer.size())
extensionBuffer.append(" ");
@@ -123,6 +126,9 @@ namespace render {
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
@@ -143,7 +149,7 @@ namespace render {
setAndInspectHardwareCaps();
// Initialize extensions
-#if defined(QT_OPENGL_ES)
+#if defined(QT_OPENGL_ES_2)
m_qt3dsExtensions = new Qt3DSOpenGLES2Extensions;
m_qt3dsExtensions->initializeOpenGLFunctions();
#else
@@ -162,7 +168,7 @@ namespace render {
{
if (m_pCurrentMiscState)
NVDelete(m_Foundation.getAllocator(), m_pCurrentMiscState);
-#if !defined(QT_OPENGL_ES)
+#if !defined(QT_OPENGL_ES_2)
if (m_timerExtension)
delete m_timerExtension;
if (m_tessellationShader)
@@ -393,7 +399,9 @@ namespace render {
&& m_pCurrentMiscState->m_PatchVertexCount != inputAssembler->m_PatchVertexCount) {
m_pCurrentMiscState->m_PatchVertexCount = inputAssembler->m_PatchVertexCount;
#if defined(QT_OPENGL_ES)
+#if !defined (QT_OPENGL_ES_2)
GL_CALL_TESSELATION_EXT(glPatchParameteriEXT(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount));
+#endif
#else
GL_CALL_TESSELATION_EXT(glPatchParameteri(GL_PATCH_VERTICES, inputAssembler->m_PatchVertexCount));
#endif
@@ -736,7 +744,7 @@ namespace render {
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));
+ GL_CALL_TIMER_EXT(glQueryCounterEXT(queryID, GL_TIMESTAMP_EXT));
#else
GL_CALL_TIMER_EXT(glQueryCounter(queryID, GL_TIMESTAMP));
#endif
diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp
index ef383f6d..467534f5 100644
--- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp
+++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp
@@ -34,15 +34,25 @@
#define NVRENDER_BACKEND_UNUSED(arg) (void)arg;
-#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; checkGLError();
+#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; checkGLError();
-#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; checkGLError();
+#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; checkGLError();
-#define GL_CALL_DIRECTSTATE_EXT(x) m_directStateAccess->x; checkGLError();
-#define GL_CALL_QT3DS_EXT(x) m_qt3dsExtensions->x; checkGLError();
+#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 {
@@ -233,8 +243,11 @@ namespace render {
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;
@@ -247,7 +260,11 @@ namespace render {
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));
@@ -307,9 +324,11 @@ namespace render {
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;
}
@@ -329,7 +348,7 @@ namespace render {
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));
@@ -351,14 +370,17 @@ namespace render {
*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)
@@ -367,10 +389,11 @@ namespace render {
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;
}
@@ -390,7 +413,7 @@ namespace render {
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
@@ -419,14 +442,17 @@ namespace render {
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,
@@ -494,13 +520,15 @@ namespace render {
NVRenderBackendGL4Impl::CreateComputeShader(NVConstDataRef<QT3DSI8> source,
eastl::string &errorMessage, bool binary)
{
- GLuint shaderID = m_glExtraFunctions->glCreateShader(GL_COMPUTE_SHADER);
+ GLuint shaderID = 0;
+#if defined(GL_VERSION_4_3) || defined (QT_OPENGL_ES_3_1)
+ 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;
}
@@ -583,35 +611,43 @@ namespace render {
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)
@@ -649,8 +685,10 @@ namespace render {
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)
diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp
index ee496c61..30049e76 100644
--- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp
+++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp
@@ -34,12 +34,30 @@
#include "render/backends/gl/Qt3DSRenderBackendRenderStatesGL.h"
#include "foundation/StringTable.h"
-#define GL_CALL_FUNCTION(x) m_glFunctions->x; checkGLError();
-#define GL_CALL_EXTRA_FUNCTION(x) m_glExtraFunctions->x; checkGLError();
+#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,
@@ -48,7 +66,6 @@ namespace render {
, m_Foundation(fnd)
, m_StringTable(stringTable)
, m_Conversion()
- , m_Extensions(m_Foundation.getAllocator(), "NVRenderBackendGLBase::m_Extensions")
, m_MaxAttribCount(0)
, m_DrawBuffersArray(m_Foundation.getAllocator(),
"NVRenderBackendGLBase::m_DrawBuffersArray")
@@ -213,6 +230,15 @@ namespace render {
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;
@@ -849,7 +875,6 @@ namespace render {
GLuint texID = 0;
GL_CALL_FUNCTION(glGenTextures(1, &texID));
-
return (NVRenderBackend::NVRenderBackendTextureObject)texID;
}
@@ -940,6 +965,7 @@ namespace render {
m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), internalFormat,
glformat, gltype, glInternalFormat);
+
if (conversionRequired) {
GLenum dummy;
m_Conversion.fromUncompressedTextureFormatToGL(GetRenderContextType(), format, glformat,
@@ -951,7 +977,9 @@ namespace render {
} else if (NVRenderTextureFormats::isDepthTextureFormat(format))
m_Conversion.fromDepthTextureFormatToGL(GetRenderContextType(), format, glformat,
gltype, glInternalFormat);
-
+#ifdef QT_OPENGL_ES_2
+ glInternalFormat = glformat;
+#endif
GL_CALL_FUNCTION(glTexImage2D(glTarget, level, glInternalFormat, (GLsizei)width, (GLsizei)height,
border, glformat, gltype, hostPtr));
@@ -2115,7 +2143,7 @@ namespace render {
return retval;
}
- const char *NVRenderBackendGLBase::geRendererString()
+ const char *NVRenderBackendGLBase::getRendererString()
{
const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_RENDERER));
if (retval == NULL)
@@ -2124,6 +2152,15 @@ namespace render {
return retval;
}
+ const char *NVRenderBackendGLBase::getExtensionString()
+ {
+ const char *retval = (const char *)GL_CALL_FUNCTION(glGetString(GL_EXTENSIONS));
+ if (retval == NULL)
+ return "";
+
+ return retval;
+ }
+
/**
* @brief This function inspects the various strings to setup
* HW capabilities of the device.
@@ -2145,6 +2182,17 @@ namespace render {
}
}
+#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)
@@ -2155,6 +2203,7 @@ namespace render {
}
#endif
}
+#endif
}
}
diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp
index ec0445b3..93229199 100644
--- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp
+++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderContextGL.cpp
@@ -54,7 +54,12 @@ namespace render {
NVScopedRefCounted<IStringTable> theStringTable(inStringTable);
NVScopedRefCounted<NVRenderBackend> theBackend;
bool isES = format.renderableType() == QSurfaceFormat::OpenGLES;
- if (format.majorVersion() == 3 && format.minorVersion() >= 1 && !isES) {
+ 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);
diff --git a/src/Runtime/Source/UICRender/Include/UICRenderDefaultMaterialShaderGenerator.h b/src/Runtime/Source/UICRender/Include/UICRenderDefaultMaterialShaderGenerator.h
index 105ffc64..fe80eb68 100644
--- a/src/Runtime/Source/UICRender/Include/UICRenderDefaultMaterialShaderGenerator.h
+++ b/src/Runtime/Source/UICRender/Include/UICRenderDefaultMaterialShaderGenerator.h
@@ -36,6 +36,8 @@ namespace uic {
namespace render {
class UICShadowMap;
+ struct SShaderGeneratorGeneratedShader;
+ struct SLightConstantProperties;
class IDefaultMaterialVertexPipeline : public IShaderStageGenerator
{
@@ -110,6 +112,8 @@ namespace render {
static IDefaultMaterialShaderGenerator &
CreateDefaultMaterialShaderGenerator(IUICRenderContext &inRenderContext);
+
+ SLightConstantProperties *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader);
};
}
}
diff --git a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImpl.cpp b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImpl.cpp
index 592b41d5..a6f90c43 100644
--- a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImpl.cpp
+++ b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImpl.cpp
@@ -1172,9 +1172,14 @@ namespace render {
m_UICContext.GetRenderContext().SetRenderTarget(theAtlasFB);
// this texture contains our single entries
- NVRenderTexture2D *theTexture = m_UICContext.GetResourceManager().AllocateTexture2D(
- 32, 32, NVRenderTextureFormats::Alpha8);
-
+ NVRenderTexture2D *theTexture = nullptr;
+ if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) {
+ theTexture = m_UICContext.GetResourceManager()
+ .AllocateTexture2D(32, 32, NVRenderTextureFormats::RGBA8);
+ } else {
+ theTexture = m_UICContext.GetResourceManager()
+ .AllocateTexture2D(32, 32, NVRenderTextureFormats::Alpha8);
+ }
m_Context->SetClearColor(QT3DSVec4(0, 0, 0, 0));
m_Context->Clear(NVRenderClearValues::Color);
m_Context->SetDepthTestEnabled(false);
diff --git a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderData.cpp b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderData.cpp
index 12dab8a9..d8dc4cee 100644
--- a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderData.cpp
+++ b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderData.cpp
@@ -254,6 +254,8 @@ namespace render {
shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform);
shader->m_DepthTexture.Set(m_LayerDepthTexture);
+ shader->m_DepthSamplerSize.Set(QT3DSVec2(m_LayerDepthTexture->GetTextureDetails().m_Width,
+ m_LayerDepthTexture->GetTextureDetails().m_Height));
// Important uniforms for AO calculations
QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar);
@@ -290,6 +292,8 @@ namespace render {
shader->m_DepthTexture.Set(theDepthTex);
shader->m_CubeTexture.Set(theDepthCube);
+ shader->m_DepthSamplerSize.Set(QT3DSVec2(theDepthTex->GetTextureDetails().m_Width,
+ theDepthTex->GetTextureDetails().m_Height));
// Important uniforms for AO calculations
QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar);
@@ -721,7 +725,9 @@ namespace render {
*pEntry->m_DepthRender);
(*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0,
*pEntry->m_DepthCube, curFace);
+ (*theFB)->IsComplete();
theRenderContext.Clear(clearFlags);
+
RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i,
theCameras[k]);
}
@@ -787,7 +793,6 @@ namespace render {
qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Stencil
| qt3ds::render::NVRenderClearValues::Depth);
-
theRenderContext.Clear(clearFlags);
RunRenderPass(RenderRenderableDepthPass, false, true, inEnableTransparentDepthWrite, 0,
@@ -1201,7 +1206,8 @@ namespace render {
SWindowDimensions theLayerOriginalTextureDimensions = theLayerTextureDimensions;
NVRenderTextureFormats::Enum DepthTextureFormat = NVRenderTextureFormats::Depth24Stencil8;
NVRenderTextureFormats::Enum ColorTextureFormat = NVRenderTextureFormats::RGBA8;
- if (thePrepResult.m_LastEffect) {
+ if (thePrepResult.m_LastEffect
+ && theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) {
if (m_Layer.m_Background != LayerBackground::Transparent)
ColorTextureFormat = NVRenderTextureFormats::R11G11B10;
else
@@ -1216,8 +1222,10 @@ namespace render {
&& theRenderContext.AreMultisampleTexturesSupported())
sampleCount = (QT3DSU32)m_Layer.m_MultisampleAAMode;
- bool isMultisamplePass =
- (sampleCount > 1) || (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA);
+ bool isMultisamplePass = false;
+ if (theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2)
+ isMultisamplePass =
+ (sampleCount > 1) || (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA);
qt3ds::render::NVRenderTextureTargetType::Enum thFboAttachTarget =
qt3ds::render::NVRenderTextureTargetType::Texture2D;
diff --git a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderPreparationData.cpp b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderPreparationData.cpp
index d06a7678..e496fbfc 100644
--- a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderPreparationData.cpp
+++ b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplLayerRenderPreparationData.cpp
@@ -1169,7 +1169,8 @@ namespace render {
thePrepResult.m_Flags.SetRequiresDepthTexture(requiresDepthPrepass
|| NeedsWidgetTexture());
thePrepResult.m_Flags.SetShouldRenderToTexture(shouldRenderToTexture);
- thePrepResult.m_Flags.SetRequiresSsaoPass(SSAOEnabled);
+ if (m_Renderer.GetContext().GetRenderContextType() != NVRenderContextValues::GLES2)
+ thePrepResult.m_Flags.SetRequiresSsaoPass(SSAOEnabled);
if (thePrepResult.IsLayerVisible()) {
if (shouldRenderToTexture) {
@@ -1248,8 +1249,9 @@ namespace render {
if (theLight->m_Flags.IsGloballyActive()) {
if (theLight->m_Scope == NULL) {
m_Lights.push_back(theLight);
-
- if (theLight->m_CastShadow && GetShadowMapManager()) {
+ if (m_Renderer.GetContext().GetRenderContextType()
+ != NVRenderContextValues::GLES2
+ && theLight->m_CastShadow && GetShadowMapManager()) {
// PKC -- use of "res" as an exponent of two is an annoying
// artifact of the XML interface
// I'll change this with an enum interface later on, but that's
@@ -1263,7 +1265,6 @@ namespace render {
m_Lights.size() - 1, mapSize, mapSize,
NVRenderTextureFormats::R16, 1, mapMode,
ShadowFilterValues::NONE);
-
thePrepResult.m_Flags.SetRequiresShadowMapPass(true);
SetShaderFeature("UIC_ENABLE_SSM", true);
}
diff --git a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.cpp b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.cpp
index a9a9a947..a752e021 100644
--- a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.cpp
+++ b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.cpp
@@ -1880,13 +1880,20 @@ namespace render {
// fragmentGenerator.AddInclude( "SSAOCustomMaterial.glsllib" );
theFragmentGenerator.AddInclude("viewProperties.glsllib");
theFragmentGenerator.AddInclude("screenSpaceAO.glsllib");
-
- theFragmentGenerator
- << "layout (std140) uniform cbAoShadow { " << Endl << " vec4 ao_properties;"
- << Endl << " vec4 ao_properties2;" << Endl << " vec4 shadow_properties;"
- << Endl << " vec4 aoScreenConst;" << Endl << " vec4 UvToEyeConst;" << Endl
- << "};" << Endl;
-
+ if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) {
+ theFragmentGenerator
+ << "\tuniform vec4 ao_properties;" << Endl
+ << "\tuniform vec4 ao_properties2;" << Endl
+ << "\tuniform vec4 shadow_properties;" << Endl
+ << "\tuniform vec4 aoScreenConst;" << Endl
+ << "\tuniform vec4 UvToEyeConst;" << Endl;
+ } else {
+ theFragmentGenerator
+ << "layout (std140) uniform cbAoShadow { " << Endl << "\tvec4 ao_properties;"
+ << Endl << "\tvec4 ao_properties2;" << Endl << "\tvec4 shadow_properties;"
+ << Endl << "\tvec4 aoScreenConst;" << Endl << "\tvec4 UvToEyeConst;" << Endl
+ << "};" << Endl;
+ }
theFragmentGenerator.AddUniform("camera_direction", "vec3");
theFragmentGenerator.AddUniform("depth_sampler", "sampler2D");
theFragmentGenerator.Append("void main() {");
@@ -1899,22 +1906,42 @@ namespace render {
// values at the edges
// surrounding objects, and this also ends up giving us weird AO values.
// If we had a proper screen-space normal map, that would also do the trick.
- theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );");
- theFragmentGenerator.Append("\tfloat depth = getDepthValue( "
- "texelFetch(depth_sampler, iCoords, 0), "
- "camera_properties );");
- theFragmentGenerator.Append(
- "\tdepth = depthValueToLinearDistance( depth, camera_properties );");
- theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / "
- "(camera_properties.y - camera_properties.x);");
- theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( "
- "texelFetch(depth_sampler, iCoords+ivec2(1), 0), "
- "camera_properties );");
- theFragmentGenerator.Append(
- "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );");
- theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( "
- "texelFetch(depth_sampler, iCoords-ivec2(1), 0), "
- "camera_properties );");
+ if (m_Context->GetRenderContextType() == NVRenderContextValues::GLES2) {
+ theFragmentGenerator.AddUniform("depth_sampler_size", "vec2");
+ theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );");
+ theFragmentGenerator.Append("\tfloat depth = getDepthValue( "
+ "texture2D(depth_sampler, vec2(iCoords)"
+ " / depth_sampler_size), camera_properties );");
+ theFragmentGenerator.Append(
+ "\tdepth = depthValueToLinearDistance( depth, camera_properties );");
+ theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / "
+ "(camera_properties.y - camera_properties.x);");
+ theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( "
+ "texture2D(depth_sampler, vec2(iCoords+ivec2(1))"
+ " / depth_sampler_size), camera_properties );");
+ theFragmentGenerator.Append(
+ "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );");
+ theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( "
+ "texture2D(depth_sampler, vec2(iCoords-ivec2(1))"
+ " / depth_sampler_size), camera_properties );");
+ } else {
+ theFragmentGenerator.Append("\tivec2 iCoords = ivec2( gl_FragCoord.xy );");
+ theFragmentGenerator.Append("\tfloat depth = getDepthValue( "
+ "texelFetch(depth_sampler, iCoords, 0), "
+ "camera_properties );");
+ theFragmentGenerator.Append(
+ "\tdepth = depthValueToLinearDistance( depth, camera_properties );");
+ theFragmentGenerator.Append("\tdepth = (depth - camera_properties.x) / "
+ "(camera_properties.y - camera_properties.x);");
+ theFragmentGenerator.Append("\tfloat depth2 = getDepthValue( "
+ "texelFetch(depth_sampler, iCoords+ivec2(1), 0), "
+ "camera_properties );");
+ theFragmentGenerator.Append(
+ "\tdepth2 = depthValueToLinearDistance( depth, camera_properties );");
+ theFragmentGenerator.Append("\tfloat depth3 = getDepthValue( "
+ "texelFetch(depth_sampler, iCoords-ivec2(1), 0), "
+ "camera_properties );");
+ }
theFragmentGenerator.Append(
"\tdepth3 = depthValueToLinearDistance( depth, camera_properties );");
theFragmentGenerator.Append("\tvec3 tanU = vec3(10, 0, dFdx(depth));");
diff --git a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.h b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.h
index fd5e2a1f..fe5af0d0 100644
--- a/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.h
+++ b/src/Runtime/Source/UICRender/RendererImpl/UICRendererImplShaders.h
@@ -215,6 +215,7 @@ namespace render {
NVRenderCachedShaderProperty<QT3DSVec3> m_CameraDirection;
NVRenderCachedShaderProperty<NVRenderTexture2D *> m_DepthTexture;
NVRenderCachedShaderProperty<NVRenderTextureCube *> m_CubeTexture;
+ NVRenderCachedShaderProperty<QT3DSVec2> m_DepthSamplerSize;
NVRenderCachedShaderBuffer<qt3ds::render::NVRenderShaderConstantBuffer *> m_AoShadowParams;
QT3DSI32 m_RefCount;
@@ -227,6 +228,7 @@ namespace render {
, m_CameraDirection("camera_direction", inShader)
, m_DepthTexture("depth_sampler", inShader)
, m_CubeTexture("depth_cube", inShader)
+ , m_DepthSamplerSize("depth_sampler_size", inShader)
, m_AoShadowParams("cbAoShadow", inShader)
, m_RefCount(0)
{
diff --git a/src/Runtime/Source/UICRender/ResourceManager/UICRenderBufferManager.cpp b/src/Runtime/Source/UICRender/ResourceManager/UICRenderBufferManager.cpp
index b6230707..1082a532 100644
--- a/src/Runtime/Source/UICRender/ResourceManager/UICRenderBufferManager.cpp
+++ b/src/Runtime/Source/UICRender/ResourceManager/UICRenderBufferManager.cpp
@@ -249,12 +249,17 @@ struct SBufferManager : public IBufferManager
NVRenderTexture2D *theTexture = m_Context->CreateTexture2D();
if (inLoadedImage.data) {
qt3ds::render::NVRenderTextureFormats::Enum destFormat = inLoadedImage.format;
- if (inBsdfMipmaps)
- destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F;
- else
+ if (inBsdfMipmaps) {
+ if (m_Context->GetRenderContextType() == render::NVRenderContextValues::GLES2)
+ destFormat = qt3ds::render::NVRenderTextureFormats::RGBA8;
+ else
+ destFormat = qt3ds::render::NVRenderTextureFormats::RGBA16F;
+ }
+ else {
theTexture->SetTextureData(
NVDataRef<QT3DSU8>((QT3DSU8 *)inLoadedImage.data, inLoadedImage.dataSizeInBytes), 0,
inLoadedImage.width, inLoadedImage.height, inLoadedImage.format, destFormat);
+ }
if (inBsdfMipmaps
&& NVRenderTextureFormats::isUncompressedTextureFormat(inLoadedImage.format)) {
diff --git a/src/Runtime/Source/UICRender/ResourceManager/UICRenderLoadedTextureHDR.cpp b/src/Runtime/Source/UICRender/ResourceManager/UICRenderLoadedTextureHDR.cpp
index 91cd9cb5..5f9b3558 100644
--- a/src/Runtime/Source/UICRender/ResourceManager/UICRenderLoadedTextureHDR.cpp
+++ b/src/Runtime/Source/UICRender/ResourceManager/UICRenderLoadedTextureHDR.cpp
@@ -240,7 +240,11 @@ static FIBITMAP *DoLoadHDR(FreeImageIO *io, fi_handle handle,
SLoadedTexture *SLoadedTexture::LoadHDR(ISeekableIOStream &inStream, NVFoundationBase &inFnd)
{
FreeImageIO theIO(inFnd.getAllocator(), inFnd);
+#ifdef QT_OPENGL_ES_2
+ SLoadedTexture *retval = DoLoadHDR(&theIO, &inStream, NVRenderTextureFormats::RGBA8);
+#else
SLoadedTexture *retval = DoLoadHDR(&theIO, &inStream, NVRenderTextureFormats::RGBA16F);
+#endif
// Let's just assume we don't support this just yet.
// if ( retval )
diff --git a/src/Runtime/Source/UICRender/Source/UICRenderDefaultMaterialShaderGenerator.cpp b/src/Runtime/Source/UICRender/Source/UICRenderDefaultMaterialShaderGenerator.cpp
index fa5c9e5b..8b962ca4 100644
--- a/src/Runtime/Source/UICRender/Source/UICRenderDefaultMaterialShaderGenerator.cpp
+++ b/src/Runtime/Source/UICRender/Source/UICRenderDefaultMaterialShaderGenerator.cpp
@@ -40,6 +40,7 @@
#include "UICRenderShadowMap.h"
#include "UICRenderCustomMaterial.h"
#include "UICRenderDynamicObjectSystem.h"
+#include "render/Qt3DSRenderShaderProgram.h"
using namespace uic::render;
using qt3ds::render::NVRenderCachedShaderProperty;
@@ -81,11 +82,14 @@ struct SShaderTextureProperties
NVRenderCachedShaderProperty<NVRenderTexture2D *> m_Sampler;
NVRenderCachedShaderProperty<QT3DSVec3> m_Offsets;
NVRenderCachedShaderProperty<QT3DSVec4> m_Rotations;
+ NVRenderCachedShaderProperty<QT3DSVec2> m_Size;
SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName,
+ const char *sizeName,
NVRenderShaderProgram &inShader)
: m_Sampler(sampName, inShader)
, m_Offsets(offName, inShader)
, m_Rotations(rotName, inShader)
+ , m_Size(sizeName, inShader)
{
}
SShaderTextureProperties() {}
@@ -124,6 +128,45 @@ struct SShadowMapProperties
}
};
+struct SShaderGeneratorGeneratedShader;
+
+struct SLightConstantProperties
+{
+ struct LightConstants
+ {
+ NVRenderCachedShaderProperty<QT3DSVec4> m_position;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_direction;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_up;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_right;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_diffuse;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_ambient;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_specular;
+ NVRenderCachedShaderProperty<QT3DSF32> m_spotExponent;
+ NVRenderCachedShaderProperty<QT3DSF32> m_spotCutoff;
+ NVRenderCachedShaderProperty<QT3DSF32> m_constantAttenuation;
+ NVRenderCachedShaderProperty<QT3DSF32> m_linearAttenuation;
+ NVRenderCachedShaderProperty<QT3DSF32> m_quadraticAttenuation;
+ NVRenderCachedShaderProperty<QT3DSF32> m_range;
+ NVRenderCachedShaderProperty<QT3DSF32> m_width;
+ NVRenderCachedShaderProperty<QT3DSF32> m_height;
+ NVRenderCachedShaderProperty<QT3DSVec4> m_shadowControls;
+ NVRenderCachedShaderProperty<QT3DSMat44> m_shadowView;
+ NVRenderCachedShaderProperty<QT3DSI32> m_shadowIdx;
+ NVRenderCachedShaderProperty<QT3DSVec3> m_attenuation;
+
+ LightConstants(const QString &lightRef, NVRenderShaderProgram &shader);
+
+ void updateLights(int lIdx, SShaderGeneratorGeneratedShader &shader);
+ };
+
+ SLightConstantProperties(SShaderGeneratorGeneratedShader &shader, bool packed);
+ ~SLightConstantProperties();
+ void updateLights(SShaderGeneratorGeneratedShader &shader);
+
+ QVector<LightConstants *> m_constants;
+ NVRenderCachedShaderProperty<QT3DSI32> m_lightCount;
+};
+
/**
* The results of generating a shader. Caches all possible variable names into
* typesafe objects.
@@ -161,12 +204,16 @@ struct SShaderGeneratorGeneratedShader
NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeOpts;
NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeRot;
NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeOfs;
+ NVRenderCachedShaderProperty<QT3DSVec2> m_LightProbeSize;
NVRenderCachedShaderProperty<NVRenderTexture2D *> m_LightProbe2;
NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbe2Props;
+ NVRenderCachedShaderProperty<QT3DSVec2> m_LightProbe2Size;
NVRenderCachedShaderBuffer<qt3ds::render::NVRenderShaderConstantBuffer *> m_AoShadowParams;
NVRenderCachedShaderBuffer<qt3ds::render::NVRenderShaderConstantBuffer *> m_LightsBuffer;
+ SLightConstantProperties *m_lightConstantProperties;
+
// Cache the image property name lookups
nvvector<SShaderTextureProperties> m_Images;
nvvector<SShaderLightProperties> m_Lights;
@@ -203,10 +250,13 @@ struct SShaderGeneratorGeneratedShader
, m_LightProbeOpts("light_probe_opts", inShader)
, m_LightProbeRot("light_probe_rotation", inShader)
, m_LightProbeOfs("light_probe_offset", inShader)
+ , m_LightProbeSize("light_probe_size", inShader)
, m_LightProbe2("light_probe2", inShader)
, m_LightProbe2Props("light_probe2_props", inShader)
+ , m_LightProbe2Size("light_probe2_size", inShader)
, m_AoShadowParams("cbAoShadow", inShader)
, m_LightsBuffer("cbBufferLights", inShader)
+ , m_lightConstantProperties(NULL)
, m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images")
, m_Lights(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Lights")
, m_ShadowMaps(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_ShadowMaps")
@@ -214,7 +264,12 @@ struct SShaderGeneratorGeneratedShader
{
m_Shader.addRef();
}
- ~SShaderGeneratorGeneratedShader() { m_Shader.release(); }
+ ~SShaderGeneratorGeneratedShader()
+ {
+ if (m_lightConstantProperties)
+ delete m_lightConstantProperties;
+ m_Shader.release();
+ }
void addRef() { ++m_RefCount; }
void release()
@@ -227,6 +282,109 @@ struct SShaderGeneratorGeneratedShader
}
};
+static const QStringList lconstantnames = {
+ QStringLiteral("position"),
+ QStringLiteral("direction"),
+ QStringLiteral("up"),
+ QStringLiteral("right"),
+ QStringLiteral("diffuse"),
+ QStringLiteral("ambient"),
+ QStringLiteral("specular"),
+ QStringLiteral("spotExponent"),
+ QStringLiteral("spotCutoff"),
+ QStringLiteral("constantAttenuation"),
+ QStringLiteral("linearAttenuation"),
+ QStringLiteral("quadraticAttenuation"),
+ QStringLiteral("range"),
+ QStringLiteral("width"),
+ QStringLiteral("height"),
+ QStringLiteral("shadowControls"),
+ QStringLiteral("shadowView"),
+ QStringLiteral("shadowIdx"),
+ QStringLiteral("attenuation")
+};
+
+SLightConstantProperties::LightConstants::LightConstants(const QString &lightRef,
+ NVRenderShaderProgram &shader)
+ : m_position(QString("%1%2").arg(lightRef, lconstantnames[0]), shader)
+ , m_direction(QString("%1%2").arg(lightRef).arg(lconstantnames[1]), shader)
+ , m_up(QString("%1%2").arg(lightRef, lconstantnames[2]), shader)
+ , m_right(QString("%1%2").arg(lightRef, lconstantnames[3]), shader)
+ , m_diffuse(QString("%1%2").arg(lightRef, lconstantnames[4]), shader)
+ , m_ambient(QString("%1%2").arg(lightRef, lconstantnames[5]), shader)
+ , m_specular(QString("%1%2").arg(lightRef, lconstantnames[6]), shader)
+ , m_spotExponent(QString("%1%2").arg(lightRef, lconstantnames[7]), shader)
+ , m_spotCutoff(QString("%1%2").arg(lightRef, lconstantnames[8]), shader)
+ , m_constantAttenuation(QString("%1%2").arg(lightRef, lconstantnames[9]), shader)
+ , m_linearAttenuation(QString("%1%2").arg(lightRef, lconstantnames[10]), shader)
+ , m_quadraticAttenuation(QString("%1%2").arg(lightRef, lconstantnames[11]), shader)
+ , m_range(QString("%1%2").arg(lightRef, lconstantnames[12]), shader)
+ , m_width(QString("%1%2").arg(lightRef, lconstantnames[13]), shader)
+ , m_height(QString("%1%2").arg(lightRef, lconstantnames[14]), shader)
+ , m_shadowControls(QString("%1%2").arg(lightRef, lconstantnames[15]), shader)
+ , m_shadowView(QString("%1%2").arg(lightRef, lconstantnames[16]), shader)
+ , m_shadowIdx(QString("%1%2").arg(lightRef, lconstantnames[17]), shader)
+ , m_attenuation(QString("%1%2").arg(lightRef, lconstantnames[18]), shader)
+{
+
+}
+
+void SLightConstantProperties::LightConstants::updateLights(int lIdx,
+ SShaderGeneratorGeneratedShader &shader)
+{
+ m_position.Set(shader.m_Lights[lIdx].m_LightData.m_position);
+ m_direction.Set(shader.m_Lights[lIdx].m_LightData.m_direction);
+ m_up.Set(shader.m_Lights[lIdx].m_LightData.m_up);
+ m_right.Set(shader.m_Lights[lIdx].m_LightData.m_right);
+ m_diffuse.Set(shader.m_Lights[lIdx].m_LightData.m_diffuse);
+ m_ambient.Set(shader.m_Lights[lIdx].m_LightData.m_ambient);
+ m_specular.Set(shader.m_Lights[lIdx].m_LightData.m_specular);
+ m_spotExponent.Set(shader.m_Lights[lIdx].m_LightData.m_spotExponent);
+ m_spotCutoff.Set(shader.m_Lights[lIdx].m_LightData.m_spotCutoff);
+ m_constantAttenuation.Set(shader.m_Lights[lIdx].m_LightData.m_constantAttenuation);
+ m_linearAttenuation.Set(shader.m_Lights[lIdx].m_LightData.m_linearAttenuation);
+ m_quadraticAttenuation.Set(shader.m_Lights[lIdx].m_LightData.m_quadraticAttenuation);
+ m_range.Set(shader.m_Lights[lIdx].m_LightData.m_range);
+ m_width.Set(shader.m_Lights[lIdx].m_LightData.m_width);
+ m_height.Set(shader.m_Lights[lIdx].m_LightData.m_height);
+ m_shadowControls.Set(shader.m_Lights[lIdx].m_LightData.m_shadowControls);
+ m_shadowView.Set(shader.m_Lights[lIdx].m_LightData.m_shadowView);
+ m_shadowIdx.Set(shader.m_Lights[lIdx].m_LightData.m_shadowIdx);
+ m_attenuation.Set(QT3DSVec3(shader.m_Lights[lIdx].m_LightData.m_constantAttenuation,
+ shader.m_Lights[lIdx].m_LightData.m_linearAttenuation,
+ shader.m_Lights[lIdx].m_LightData.m_quadraticAttenuation));
+}
+
+
+SLightConstantProperties::SLightConstantProperties(SShaderGeneratorGeneratedShader &shader,
+ bool packed)
+ : m_lightCount("uNumLights", shader.m_Shader)
+{
+ m_constants.resize(shader.m_Lights.size());
+ for (unsigned int i = 0; i < shader.m_Lights.size(); ++i) {
+ QString lref;
+ if (packed)
+ lref = QStringLiteral("light_%1_");
+ else
+ lref = QStringLiteral("lights[%1].");
+ lref = lref.arg(i);
+ m_constants[i] = new LightConstants(lref, shader.m_Shader);
+ }
+ m_lightCount.Set(shader.m_Lights.size());
+}
+
+SLightConstantProperties::~SLightConstantProperties()
+{
+ qDeleteAll(m_constants);
+}
+
+void SLightConstantProperties::updateLights(SShaderGeneratorGeneratedShader &shader)
+{
+ for (int i = 0; i < m_constants.size(); ++i)
+ m_constants[i]->updateLights(i, shader);
+}
+
+
#ifndef EA_PLATFORM_WINDOWS
#define _snprintf snprintf
#endif
@@ -251,6 +409,7 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
NVDataRef<SLight *> m_Lights;
SRenderableImage *m_FirstImage;
bool m_HasTransparency;
+ bool m_LightsAsSeparateUniforms;
TStrType m_ImageStem;
TStrType m_ImageSampler;
@@ -258,13 +417,14 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
TStrType m_ImageRotations;
TStrType m_ImageFragCoords;
TStrType m_ImageTemp;
+ TStrType m_ImageSamplerSize;
TStrType m_TexCoordTemp;
TStrType m_LightStem;
TStrType m_LightColor;
TStrType m_LightSpecularColor;
- TStrType m_LightAttenutation;
+ TStrType m_LightAttenuation;
TStrType m_LightConstantAttenuation;
TStrType m_LightLinearAttenuation;
TStrType m_LightQuadraticAttenuation;
@@ -301,6 +461,7 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
, m_ShadowMapManager(NULL)
, m_CurrentPipeline(NULL)
, m_FirstImage(NULL)
+ , m_LightsAsSeparateUniforms(false)
, m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap")
, m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers")
, m_RefCount(0)
@@ -348,6 +509,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
m_ImageRotations.append("rotations");
m_ImageFragCoords = m_ImageStem;
m_ImageFragCoords.append("uv_coords");
+ m_ImageSamplerSize = m_ImageStem;
+ m_ImageSamplerSize.append("size");
}
void SetupTexCoordVariableName(size_t uvSet)
@@ -500,7 +663,6 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
void OutputDiffuseAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos,
TStrType inLightPrefix)
{
- m_LightAttenutation = inLightPrefix + "_attenuation";
m_NormalizedDirection = inLightPrefix + "_areaDir";
AddLocalVariable(infragmentShader, m_NormalizedDirection, "vec3");
infragmentShader << "\tlightAttenuation = calculateDiffuseAreaOld( " << m_LightDirection
@@ -635,13 +797,16 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
}
bool MaybeAddMaterialFresnel(IShaderStageGenerator &fragmentShader, NVConstDataRef<QT3DSU32> inKey,
- bool inFragmentHasSpecularAmount)
+ bool inFragmentHasSpecularAmount, bool supportStandardDerivates)
{
if (m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey)) {
if (inFragmentHasSpecularAmount == false)
fragmentShader << "\tfloat specularAmount = 1.0;" << Endl;
inFragmentHasSpecularAmount = true;
- fragmentShader.AddInclude("defaultMaterialFresnel.glsllib");
+ if (supportStandardDerivates)
+ fragmentShader.AddInclude("defaultMaterialFresnel.glsllib");
+ else
+ fragmentShader.AddInclude("defaultMaterialFresnelNoDvn.glsllib");
fragmentShader.AddUniform("fresnelPower", "float");
fragmentShader.AddUniform("material_specular", "vec4");
fragmentShader << "\tfloat fresnelRatio = defaultMaterialSimpleFresnel( world_normal, "
@@ -653,33 +818,58 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
}
void SetupLightVariableNames(size_t lightIdx, SLight &inLight)
{
- m_LightStem = "lights";
- char buf[16];
- _snprintf(buf, 16, "[%lu].", lightIdx);
- m_LightStem.append(buf);
-
- m_LightColor = m_LightStem;
- m_LightColor.append("diffuse");
- m_LightDirection = m_LightStem;
- m_LightDirection.append("direction");
- m_LightSpecularColor = m_LightStem;
- m_LightSpecularColor.append("specular");
- if (inLight.m_LightType == RenderLightTypes::Point) {
- m_LightPos = m_LightStem;
- m_LightPos.append("position");
- m_LightConstantAttenuation = m_LightStem;
- m_LightConstantAttenuation.append("constantAttenuation");
- m_LightLinearAttenuation = m_LightStem;
- m_LightLinearAttenuation.append("linearAttenuation");
- m_LightQuadraticAttenuation = m_LightStem;
- m_LightQuadraticAttenuation.append("quadraticAttenuation");
- } else if (inLight.m_LightType == RenderLightTypes::Area) {
- m_LightPos = m_LightStem;
- m_LightPos.append("position");
- m_LightUp = m_LightStem;
- m_LightUp.append("up");
- m_LightRt = m_LightStem;
- m_LightRt.append("right");
+ if (m_LightsAsSeparateUniforms) {
+ char buf[16];
+ _snprintf(buf, 16, "light_%u", lightIdx);
+ m_LightStem = buf;
+ m_LightColor = m_LightStem;
+ m_LightColor.append("_diffuse");
+ m_LightDirection = m_LightStem;
+ m_LightDirection.append("_direction");
+ m_LightSpecularColor = m_LightStem;
+ m_LightSpecularColor.append("_specular");
+ if (inLight.m_LightType == RenderLightTypes::Point) {
+ m_LightPos = m_LightStem;
+ m_LightPos.append("_position");
+ m_LightAttenuation = m_LightStem;
+ m_LightAttenuation.append("_attenuation");
+ } else if (inLight.m_LightType == RenderLightTypes::Area) {
+ m_LightPos = m_LightStem;
+ m_LightPos.append("_position");
+ m_LightUp = m_LightStem;
+ m_LightUp.append("_up");
+ m_LightRt = m_LightStem;
+ m_LightRt.append("_right");
+ }
+ } else {
+ m_LightStem = "lights";
+ char buf[16];
+ _snprintf(buf, 16, "[%u].", lightIdx);
+ m_LightStem.append(buf);
+
+ m_LightColor = m_LightStem;
+ m_LightColor.append("diffuse");
+ m_LightDirection = m_LightStem;
+ m_LightDirection.append("direction");
+ m_LightSpecularColor = m_LightStem;
+ m_LightSpecularColor.append("specular");
+ if (inLight.m_LightType == RenderLightTypes::Point) {
+ m_LightPos = m_LightStem;
+ m_LightPos.append("position");
+ m_LightConstantAttenuation = m_LightStem;
+ m_LightConstantAttenuation.append("constantAttenuation");
+ m_LightLinearAttenuation = m_LightStem;
+ m_LightLinearAttenuation.append("linearAttenuation");
+ m_LightQuadraticAttenuation = m_LightStem;
+ m_LightQuadraticAttenuation.append("quadraticAttenuation");
+ } else if (inLight.m_LightType == RenderLightTypes::Area) {
+ m_LightPos = m_LightStem;
+ m_LightPos.append("position");
+ m_LightUp = m_LightStem;
+ m_LightUp.append("up");
+ m_LightRt = m_LightStem;
+ m_LightRt.append("right");
+ }
}
}
@@ -784,7 +974,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
SetupImageVariableNames(idx);
inShader.m_Images.push_back(
SShaderTextureProperties(m_ImageSampler.c_str(), m_ImageOffsets.c_str(),
- m_ImageRotations.c_str(), inShader.m_Shader));
+ m_ImageRotations.c_str(), m_ImageSamplerSize.c_str(),
+ inShader.m_Shader));
}
SShaderTextureProperties &theShaderProps = inShader.m_Images[idx];
const QT3DSMat44 &textureTransform = inImage.m_Image.m_TextureTransform;
@@ -804,13 +995,16 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
// on the shader.
// because setting the image on the texture forces the textue to bind and immediately apply
// any tex params.
+ NVRenderTexture2D *imageTexture = inImage.m_Image.m_TextureData.m_Texture;
inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapS(
inImage.m_Image.m_HorizontalTilingMode);
inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapT(
inImage.m_Image.m_VerticalTilingMode);
- theShaderProps.m_Sampler.Set(inImage.m_Image.m_TextureData.m_Texture);
+ theShaderProps.m_Sampler.Set(imageTexture);
theShaderProps.m_Offsets.Set(offsets);
theShaderProps.m_Rotations.Set(rotations);
+ theShaderProps.m_Size.Set(QT3DSVec2(imageTexture->GetTextureDetails().m_Width,
+ imageTexture->GetTextureDetails().m_Height));
}
void GenerateShadowMapOcclusion(QT3DSU32 lightIdx, bool inShadowEnabled,
@@ -884,6 +1078,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
QT3DSU32 lightmapRadiosityImageIdx = 0;
SRenderableImage *lightmapShadowImage = NULL;
QT3DSU32 lightmapShadowImageIdx = 0;
+ const bool supportStandardDerivatives
+ = m_RenderContext.GetRenderContext().IsStandardDerivativesSupported();
for (SRenderableImage *img = m_FirstImage; img != NULL;
img = img->m_NextImage, ++imageIdx) {
@@ -923,6 +1119,7 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
bool enableSSAO = false;
bool enableSSDO = false;
bool enableShadowMaps = false;
+ bool enableBumpNormal = normalImage || bumpImage;
for (QT3DSU32 idx = 0; idx < FeatureSet().size(); ++idx) {
eastl::string name(FeatureSet()[idx].m_Name.c_str());
@@ -957,7 +1154,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
}
if (hasLighting) {
- addFunction(fragmentShader, "sampleLightVars");
+ if (!m_LightsAsSeparateUniforms)
+ addFunction(fragmentShader, "sampleLightVars");
addFunction(fragmentShader, "diffuseReflectionBSDF");
}
@@ -975,12 +1173,13 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
fragmentShader.Append("\tvec3 vTransform;");
}
- if (includeSSAOSSDOVars || hasSpecMap || hasLighting || hasEnvMap || enableFresnel || hasIblProbe) {
+ if (includeSSAOSSDOVars || hasSpecMap || hasLighting || hasEnvMap || enableFresnel
+ || hasIblProbe || enableBumpNormal) {
vertexShader.GenerateViewVector();
vertexShader.GenerateWorldNormal();
vertexShader.GenerateWorldPosition();
}
- if (includeSSAOSSDOVars || bumpImage || normalImage || specularEnabled || hasIblProbe)
+ if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal)
vertexShader.GenerateVarTangentAndBinormal();
// You do bump or normal mapping but not both
@@ -988,13 +1187,23 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
GenerateImageUVCoordinates(bumpImageIdx, *bumpImage);
fragmentShader.AddUniform("bumpAmount", "float");
- fragmentShader.AddInclude("uicDefaultMaterialFileBumpTexture.glsllib");
- // vec3 simplerFileBumpTexture( in sampler2D sampler, in float factor, vec2
- // texCoord, vec3 tangent, vec3 binormal, vec3 normal )
+ if (m_RenderContext.GetRenderContext().GetRenderContextType()
+ == NVRenderContextValues::GLES2) {
+ fragmentShader.AddUniform(m_ImageSamplerSize, "vec2");
+ fragmentShader.AddInclude("defaultMaterialBumpNoLod.glsllib");
+ fragmentShader << "\tworld_normal = defaultMaterialBumpNoLod( " << m_ImageSampler
+ << ", bumpAmount, " << m_ImageFragCoords
+ << ", tangent, binormal, world_normal, "
+ << m_ImageSamplerSize << ");" << Endl;
+ } else {
+ fragmentShader.AddInclude("uicDefaultMaterialFileBumpTexture.glsllib");
+ // vec3 simplerFileBumpTexture( in sampler2D sampler, in float factor, vec2
+ // texCoord, vec3 tangent, vec3 binormal, vec3 normal )
- fragmentShader << "\tworld_normal = simplerFileBumpTexture( " << m_ImageSampler
- << ", bumpAmount, " << m_ImageFragCoords
- << ", tangent, binormal, world_normal );" << Endl;
+ fragmentShader << "\tworld_normal = simplerFileBumpTexture( " << m_ImageSampler
+ << ", bumpAmount, " << m_ImageFragCoords
+ << ", tangent, binormal, world_normal );" << Endl;
+ }
// Do gram schmidt
fragmentShader << "\tbinormal = normalize(cross(world_normal, tangent) );\n";
fragmentShader << "\ttangent = normalize(cross(binormal, world_normal) );\n";
@@ -1010,7 +1219,7 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
<< ", tangent, binormal );" << Endl;
}
- if (includeSSAOSSDOVars || specularEnabled || hasIblProbe)
+ if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal)
fragmentShader << "\tmat3 tanFrame = mat3(tangent, binormal, world_normal);" << Endl;
bool fragmentHasSpecularAmount = false;
@@ -1099,7 +1308,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
}
fragmentHasSpecularAmount =
- MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount);
+ MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount,
+ supportStandardDerivatives);
// Iterate through all lights
for (QT3DSU32 lightIdx = 0; lightIdx < m_Lights.size(); ++lightIdx) {
@@ -1120,6 +1330,11 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
fragmentShader << "\tlightAttenuation = 1.0;" << Endl;
if (isDirectional) {
+ if (m_LightsAsSeparateUniforms) {
+ fragmentShader.AddUniform(m_LightDirection, "vec4");
+ fragmentShader.AddUniform(m_LightColor, "vec4");
+ }
+
if (enableSSDO) {
fragmentShader << "\tshadowFac = customMaterialShadow( " << m_LightDirection
<< ".xyz, varWorldPos );" << Endl;
@@ -1139,12 +1354,22 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
<< m_LightColor << ".rgb, 0.0 ).rgb;" << Endl;
if (specularEnabled) {
+ if (m_LightsAsSeparateUniforms)
+ fragmentShader.AddUniform(m_LightSpecularColor, "vec4");
OutputSpecularEquation(Material().m_SpecularModel, fragmentShader,
m_LightDirection.c_str(),
m_LightSpecularColor.c_str());
}
} else if (isArea) {
- addFunction(fragmentShader, "areaLightVars");
+ if (m_LightsAsSeparateUniforms) {
+ fragmentShader.AddUniform(m_LightColor, "vec4");
+ fragmentShader.AddUniform(m_LightPos, "vec4");
+ fragmentShader.AddUniform(m_LightDirection, "vec4");
+ fragmentShader.AddUniform(m_LightUp, "vec4");
+ fragmentShader.AddUniform(m_LightRt, "vec4");
+ } else {
+ addFunction(fragmentShader, "areaLightVars");
+ }
addFunction(fragmentShader, "calculateDiffuseAreaOld");
vertexShader.GenerateWorldPosition();
GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow,
@@ -1171,6 +1396,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
if (specularEnabled) {
vertexShader.GenerateViewVector();
+ if (m_LightsAsSeparateUniforms)
+ fragmentShader.AddUniform(m_LightSpecularColor, "vec4");
OutputSpecularAreaLighting(fragmentShader, "varWorldPos", "view_vector",
m_LightSpecularColor.c_str());
}
@@ -1190,6 +1417,11 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow,
lightNode->m_LightType);
+ if (m_LightsAsSeparateUniforms) {
+ fragmentShader.AddUniform(m_LightColor, "vec4");
+ fragmentShader.AddUniform(m_LightPos, "vec4");
+ }
+
m_RelativeDirection = m_TempStr;
m_RelativeDirection.append("_relativeDirection");
@@ -1216,11 +1448,23 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
addFunction(fragmentShader, "calculatePointLightAttenuation");
- fragmentShader
- << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation( vec3( "
- << m_LightConstantAttenuation << ", " << m_LightLinearAttenuation << ", "
- << m_LightQuadraticAttenuation << "), " << m_RelativeDistance << ");"
- << Endl;
+ if (m_LightsAsSeparateUniforms) {
+ fragmentShader.AddUniform(m_LightAttenuation, "vec3");
+ fragmentShader
+ << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation("
+ << "vec3( " << m_LightAttenuation << ".x, " << m_LightAttenuation
+ << ".y, " << m_LightAttenuation << ".z), " << m_RelativeDistance
+ << ");" << Endl;
+ } else {
+ fragmentShader
+ << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation("
+ << "vec3( " << m_LightConstantAttenuation << ", "
+ << m_LightLinearAttenuation << ", " << m_LightQuadraticAttenuation
+ << "), " << m_RelativeDistance << ");"
+ << Endl;
+ }
+
+
AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, false);
@@ -1230,6 +1474,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
<< m_LightColor << ".rgb, 0.0 ).rgb;" << Endl;
if (specularEnabled) {
+ if (m_LightsAsSeparateUniforms)
+ fragmentShader.AddUniform(m_LightSpecularColor, "vec4");
OutputSpecularEquation(Material().m_SpecularModel, fragmentShader,
m_NormalizedDirection.c_str(),
m_LightSpecularColor.c_str());
@@ -1255,7 +1501,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
// We still have specular maps and such that could potentially use the fresnel variable.
fragmentHasSpecularAmount =
- MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount);
+ MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount,
+ supportStandardDerivatives);
}
// Fresnel also modulates alpha.
@@ -1400,6 +1647,8 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
SShaderDefaultMaterialKey theKey(Key());
theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties);
+ m_LightsAsSeparateUniforms = !m_RenderContext.GetRenderContext().GetConstantBufferSupport();
+
GenerateVertexShader();
GenerateFragmentShader(theKey);
@@ -1636,16 +1885,15 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f));
shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f));
}
- shader.m_LightProbe.Set(theLightProbe->m_TextureData.m_Texture);
+ NVRenderTexture2D *textureImage = theLightProbe->m_TextureData.m_Texture;
+ shader.m_LightProbe.Set(textureImage);
+ shader.m_LightProbeSize.Set(QT3DSVec2(textureImage->GetTextureDetails().m_Width,
+ textureImage->GetTextureDetails().m_Height));
} else {
shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f));
shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f));
}
- NVRenderConstantBuffer *pLightCb = GetLightConstantBuffer(shader.m_Lights.size());
- // if we have lights we need a light buffer
- QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightCb);
-
QT3DSF32 emissivePower = 1.0;
QT3DSU32 hasLighting = inMaterial.m_Lighting != DefaultMaterialLighting::NoLighting;
@@ -1663,22 +1911,45 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
shader.m_MaterialSpecular.Set(material_specular);
shader.m_CameraProperties.Set(inCameraVec);
shader.m_FresnelPower.Set(inMaterial.m_FresnelPower);
- for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); idx < end && pLightCb; ++idx) {
- shader.m_Lights[idx].m_LightData.m_diffuse =
- QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x,
- shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y,
- shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0);
-
- // this is our final change update memory
- pLightCb->UpdateRaw(idx * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)),
- NVDataRef<QT3DSU8>((QT3DSU8 *)&shader.m_Lights[idx].m_LightData,
- sizeof(SLightSourceShader)));
- }
- // update light buffer to hardware
- if (pLightCb) {
- QT3DSI32 cgLights = shader.m_Lights.size();
- pLightCb->UpdateRaw(0, NVDataRef<QT3DSU8>((QT3DSU8 *)&cgLights, sizeof(QT3DSI32)));
- shader.m_LightsBuffer.Set();
+
+ if (context.GetConstantBufferSupport()) {
+ NVRenderConstantBuffer *pLightCb = GetLightConstantBuffer(shader.m_Lights.size());
+ // if we have lights we need a light buffer
+ QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightCb);
+
+ for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); idx < end && pLightCb; ++idx) {
+ shader.m_Lights[idx].m_LightData.m_diffuse =
+ QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x,
+ shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y,
+ shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0);
+
+ // this is our final change update memory
+ pLightCb->UpdateRaw(idx * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)),
+ NVDataRef<QT3DSU8>((QT3DSU8 *)&shader.m_Lights[idx].m_LightData,
+ sizeof(SLightSourceShader)));
+ }
+ // update light buffer to hardware
+ if (pLightCb) {
+ QT3DSI32 cgLights = shader.m_Lights.size();
+ pLightCb->UpdateRaw(0, NVDataRef<QT3DSU8>((QT3DSU8 *)&cgLights, sizeof(QT3DSI32)));
+ shader.m_LightsBuffer.Set();
+ }
+ } else {
+ SLightConstantProperties *pLightConstants = GetLightConstantProperties(shader);
+
+ // if we have lights we need a light buffer
+ QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightConstants);
+
+ for (QT3DSU32 idx = 0, end = shader.m_Lights.size();
+ idx < end && pLightConstants; ++idx) {
+ shader.m_Lights[idx].m_LightData.m_diffuse =
+ QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x,
+ shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y,
+ shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0);
+ }
+ // update light buffer to hardware
+ if (pLightConstants)
+ pLightConstants->updateLights(shader);
}
shader.m_MaterialDiffuseLightAmbientTotal.Set(
@@ -1773,6 +2044,18 @@ struct SShaderGenerator : public IDefaultMaterialShaderGenerator
inRenderProperties.m_Probe2Window, inRenderProperties.m_Probe2Pos,
inRenderProperties.m_Probe2Fade, inRenderProperties.m_ProbeFOV);
}
+
+ SLightConstantProperties *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader)
+ {
+ if (!shader.m_lightConstantProperties
+ || shader.m_Lights.size() > !shader.m_lightConstantProperties->m_constants.size()) {
+ if (shader.m_lightConstantProperties)
+ delete shader.m_lightConstantProperties;
+ shader.m_lightConstantProperties
+ = new SLightConstantProperties(shader, m_LightsAsSeparateUniforms);
+ }
+ return shader.m_lightConstantProperties;
+ }
};
}
diff --git a/src/Runtime/Source/UICRender/Source/UICRenderPixelGraphicsRenderer.cpp b/src/Runtime/Source/UICRender/Source/UICRenderPixelGraphicsRenderer.cpp
index 0a832321..b58b6352 100644
--- a/src/Runtime/Source/UICRender/Source/UICRenderPixelGraphicsRenderer.cpp
+++ b/src/Runtime/Source/UICRender/Source/UICRenderPixelGraphicsRenderer.cpp
@@ -119,8 +119,8 @@ struct SPGRenderer : public IPixelGraphicsRenderer
m_FragmentGenerator.Begin();
m_VertexGenerator.AddAttribute("attr_pos", "vec2");
m_VertexGenerator.AddUniform("model_view_projection", "mat4");
- m_VertexGenerator.AddUniform("leftright", "float[2]");
- m_VertexGenerator.AddUniform("bottomtop", "float[2]");
+ m_VertexGenerator.AddUniform("leftright[2]", "float");
+ m_VertexGenerator.AddUniform("bottomtop[2]", "float");
m_FragmentGenerator.AddVarying("rect_uvs", "vec2");
m_FragmentGenerator.AddUniform("rect_color", "vec4");
m_VertexGenerator << "void main() {" << Endl
diff --git a/src/Runtime/Source/UICRender/Source/UICRenderShaderCache.cpp b/src/Runtime/Source/UICRender/Source/UICRenderShaderCache.cpp
index 1db2e77b..850c81ed 100644
--- a/src/Runtime/Source/UICRender/Source/UICRenderShaderCache.cpp
+++ b/src/Runtime/Source/UICRender/Source/UICRenderShaderCache.cpp
@@ -287,8 +287,12 @@ struct ShaderCache : public IShaderCache
void AddShaderExtensionStrings(ShaderType::Enum shaderType, bool isGLES)
{
- if (isGLES)
- m_InsertStr += "#extension GL_OES_standard_derivatives : enable\n";
+ if (isGLES) {
+ if (m_RenderContext.IsStandardDerivativesSupported())
+ m_InsertStr += "#extension GL_OES_standard_derivatives : enable\n";
+ else
+ m_InsertStr += "#extension GL_OES_standard_derivatives : disable\n";
+ }
if (IUICRenderer::IsGlEs3Context(m_RenderContext.GetRenderContextType())) {
if (shaderType == ShaderType::TessControl || shaderType == ShaderType::TessEval) {
@@ -304,20 +308,20 @@ struct ShaderCache : public IShaderCache
} else {
if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment
|| shaderType == ShaderType::Geometry) {
- m_InsertStr += "#extension GL_ARB_gpu_shader5 : enable\n";
- m_InsertStr += "#extension GL_ARB_shading_language_420pack : enable\n";
- if (m_RenderContext.IsShaderImageLoadStoreSupported()) {
- m_InsertStr += "#extension GL_ARB_shader_image_load_store : enable\n";
+ if (m_RenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) {
+ m_InsertStr += "#extension GL_ARB_gpu_shader5 : enable\n";
+ m_InsertStr += "#extension GL_ARB_shading_language_420pack : enable\n";
}
- if (m_RenderContext.IsAtomicCounterBufferSupported()) {
+ if (isGLES && m_RenderContext.IsTextureLodSupported())
+ m_InsertStr += "#extension GL_EXT_shader_texture_lod : enable\n";
+ if (m_RenderContext.IsShaderImageLoadStoreSupported())
+ m_InsertStr += "#extension GL_ARB_shader_image_load_store : enable\n";
+ if (m_RenderContext.IsAtomicCounterBufferSupported())
m_InsertStr += "#extension GL_ARB_shader_atomic_counters : enable\n";
- }
- if (m_RenderContext.IsStorageBufferSupported()) {
+ if (m_RenderContext.IsStorageBufferSupported())
m_InsertStr += "#extension GL_ARB_shader_storage_buffer_object : enable\n";
- }
- if (m_RenderContext.IsAdvancedBlendHwSupportedKHR()) {
+ if (m_RenderContext.IsAdvancedBlendHwSupportedKHR())
m_InsertStr += "#extension GL_KHR_blend_equation_advanced : enable\n";
- }
}
}
}
@@ -338,7 +342,7 @@ struct ShaderCache : public IShaderCache
const QT3DSU32 type = (QT3DSU32)m_RenderContext.GetRenderContextType();
switch (type) {
case NVRenderContextValues::GLES2:
- stream << "1" << minor << "0 es\n";
+ stream << "1" << minor << "0\n";
break;
case NVRenderContextValues::GL2:
stream << "1" << minor << "0\n";
@@ -390,11 +394,14 @@ struct ShaderCache : public IShaderCache
AddBackwardCompatibilityDefines(shaderType);
} else {
+ // GLES2
m_InsertStr.append("precision mediump float;\n"
"precision mediump int;\n"
- "precision mediump sampler2D;\n"
- "precision mediump sampler2DArray;\n"
- "precision mediump sampler2DShadow;\n");
+ "#define texture texture2D\n");
+ if (m_RenderContext.IsTextureLodSupported())
+ m_InsertStr.append("#define textureLod texture2DLodEXT\n");
+ else
+ m_InsertStr.append("#define textureLod(s, co, lod) texture2D(s, co)\n");
}
} else {
if (!IUICRenderer::IsGl2Context(m_RenderContext.GetRenderContextType())) {
diff --git a/src/Runtime/Source/UICRender/Source/UICRenderShaderCodeGeneratorV2.cpp b/src/Runtime/Source/UICRender/Source/UICRenderShaderCodeGeneratorV2.cpp
index 6d72d322..f7855c74 100644
--- a/src/Runtime/Source/UICRender/Source/UICRenderShaderCodeGeneratorV2.cpp
+++ b/src/Runtime/Source/UICRender/Source/UICRenderShaderCodeGeneratorV2.cpp
@@ -37,6 +37,8 @@
#include "UICRenderContext.h"
#include "UICRenderDynamicObjectSystem.h"
+#include <QtGui/qopengl.h>
+
using namespace uic::render;
namespace {
@@ -92,8 +94,10 @@ struct SStageGeneratorBase : public IShaderStageGenerator
{
m_Incoming.insert(eastl::make_pair(Str(name), Str(type)));
}
-
- virtual const char8_t *GetIncomingVariableName() { return "in"; }
+ virtual const char8_t *GetIncomingVariableName()
+ {
+ return "in";
+ }
void AddIncoming(const TStrType &name, const char8_t *type) override
{
@@ -334,6 +338,7 @@ struct SFragmentShaderGenerator : public SStageGeneratorBase
: SStageGeneratorBase(inFnd, strTable, ShaderGeneratorStages::Fragment)
{
}
+ void AddShaderIncomingMap() override { AddShaderItemMap("varying", m_Incoming); }
void AddShaderOutgoingMap() override {}
};
diff --git a/src/Runtime/Source/UICRender/Source/UICRenderTextTextureAtlas.cpp b/src/Runtime/Source/UICRender/Source/UICRenderTextTextureAtlas.cpp
index 2f11944d..cc027f8d 100644
--- a/src/Runtime/Source/UICRender/Source/UICRenderTextTextureAtlas.cpp
+++ b/src/Runtime/Source/UICRender/Source/UICRenderTextTextureAtlas.cpp
@@ -89,8 +89,13 @@ struct STextTextureAtlas : public ITextTextureAtlas
m_TextureAtlasInitialized = true;
m_textureAtlas->addRef();
// if you change the size you need to adjust UICOnscreenTextRenderer too
- m_textureAtlas->SetTextureData(NVDataRef<QT3DSU8>(), 0, TEXTURE_ATLAS_DIM,
+ if (m_RenderContext->GetRenderContextType() == NVRenderContextValues::GLES2) {
+ m_textureAtlas->SetTextureData(NVDataRef<QT3DSU8>(), 0, TEXTURE_ATLAS_DIM,
+ TEXTURE_ATLAS_DIM, NVRenderTextureFormats::RGBA8);
+ } else {
+ m_textureAtlas->SetTextureData(NVDataRef<QT3DSU8>(), 0, TEXTURE_ATLAS_DIM,
TEXTURE_ATLAS_DIM, NVRenderTextureFormats::Alpha8);
+ }
m_textureAtlas->SetMagFilter(qt3ds::render::NVRenderTextureMagnifyingOp::Linear);
m_textureAtlas->SetMinFilter(qt3ds::render::NVRenderTextureMinifyingOp::Linear);
m_textureAtlas->SetTextureWrapS(NVRenderTextureCoordOp::ClampToEdge);
diff --git a/src/Runtime/commoninclude.pri b/src/Runtime/commoninclude.pri
index 14fca023..3a10070e 100644
--- a/src/Runtime/commoninclude.pri
+++ b/src/Runtime/commoninclude.pri
@@ -37,7 +37,7 @@ INCLUDEPATH += \
$$PWD/../Authoring/UICDM \
$$PWD/../Authoring/UICDM/Systems \
$$PWD/../Authoring/UICDM/Systems/Cores \
- ../3rdparty/EASTL/UnknownVersion/include \
+ $$PWD/../3rdparty/EASTL/UnknownVersion/include \
../3rdparty/Lua/UnknownVersion/src \
../3rdparty/utf8cpp/2.3.2/source \
../3rdparty/color \
diff --git a/src/Runtime/res.qrc b/src/Runtime/res.qrc
index 8941190d..b505c08b 100644
--- a/src/Runtime/res.qrc
+++ b/src/Runtime/res.qrc
@@ -88,6 +88,15 @@
<file>res/effectlib/viewProperties.glsllib</file>
<file>res/effectlib/weightedLayer.glsllib</file>
<file>res/effectlib/wireframeCM.glsllib</file>
+ <file>res/effectlib/defaultMaterialFresnelNoDvn.glsllib</file>
+ <file>res/effectlib/gles2/funcsampleLightVars.glsllib</file>
+ <file>res/effectlib/gles2/sampleProbe.glsllib</file>
+ <file>res/effectlib/gles2/SSAOCustomMaterial.glsllib</file>
+ <file>res/effectlib/gles2/funcareaLightVars.glsllib</file>
+ <file>res/effectlib/gles2/monoChannel.glsllib</file>
+ <file>res/effectlib/gles2/shadowMapping.glsllib</file>
+ <file>res/effectlib/gles2/tangentSpaceNormalTexture.glsllib</file>
+ <file>res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib</file>
<file>res/primitives/Cone.mesh</file>
<file>res/primitives/Cube.mesh</file>
<file>res/primitives/Cylinder.mesh</file>
diff --git a/src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib b/src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib
new file mode 100644
index 00000000..90958a3f
--- /dev/null
+++ b/src/Runtime/res/effectlib/defaultMaterialFresnelNoDvn.glsllib
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DEFAULT_MATERIAL_FRESNEL_NO_DVN_GLSLLIB
+#define DEFAULT_MATERIAL_FRESNEL_NO_DVN_GLSLLIB
+
+float defaultMaterialSimpleFresnel( in vec3 N, in vec3 viewDir, in float ior, float fresnelPower )
+{
+ float F = ((1.0-ior) * (1.0-ior)) / ((1.0+ior) * (1.0+ior));
+ float VdotN = dot(viewDir, N);
+ VdotN = clamp( VdotN, 0.0, 1.0 );
+ float ratio = F + (1.0 - F) * pow(1.0 - VdotN, fresnelPower);
+ return clamp( ratio * pow( VdotN, fresnelPower ), 0.0, 1.0 );
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib b/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib
index 250056af..bda0ea60 100644
--- a/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib
+++ b/src/Runtime/res/effectlib/funcdiffuseReflectionBSDF.glsllib
@@ -1,31 +1,31 @@
#ifndef PI
-#define PI 3.14159265358979f
+#define PI 3.14159265358979
#define PI_SQUARE ( PI * PI )
#endif
vec4 diffuseReflectionBSDF(in vec3 N, in vec3 L, in vec3 viewDir,
in vec3 lightDiffuse, in float roughness)
{
- float cosThetaI = max( 0.0f, dot( N, L ) );
+ float cosThetaI = max( 0.0, dot( N, L ) );
float factor = cosThetaI;
- if ( ( 0.0f < factor ) && ( 0.0f < roughness ) )
+ if ( ( 0.0 < factor ) && ( 0.0 < roughness ) )
{
// see http://en.wikipedia.org/wiki/Oren%E2%80%93Nayar_reflectance_model
- float sigmaSquare = 0.25f * PI_SQUARE * roughness * roughness;
- float A = 1.0f - 0.5f * sigmaSquare / ( sigmaSquare + 0.33f );
- float B = 0.45f * sigmaSquare / ( sigmaSquare + 0.09f );
+ float sigmaSquare = 0.25 * PI_SQUARE * roughness * roughness;
+ float A = 1.0 - 0.5 * sigmaSquare / ( sigmaSquare + 0.33 );
+ float B = 0.45 * sigmaSquare / ( sigmaSquare + 0.09 );
// project L and viewDir on surface to get the azimuthal angle between them
// as we don't really need the projections, but the angle between them,
// it's enough to just use the cross instead
vec3 pl = normalize( cross( L, N ) );
vec3 pv = normalize( cross( viewDir, N ) );
- float cosPhi = max( 0.0f, dot( pl, pv ) );
+ float cosPhi = max( 0.0, dot( pl, pv ) );
float sinAlpha, tanBeta;
- float cosThetaO = max( 0.0f, dot( N, viewDir ) );
- float sinThetaI = sqrt( max( 0.0f, 1.0f - cosThetaI * cosThetaI ) );
- float sinThetaO = sqrt( max( 0.0f, 1.0f - cosThetaO * cosThetaO ) );
+ float cosThetaO = max( 0.0, dot( N, viewDir ) );
+ float sinThetaI = sqrt( max( 0.0, 1.0 - cosThetaI * cosThetaI ) );
+ float sinThetaO = sqrt( max( 0.0, 1.0 - cosThetaO * cosThetaO ) );
if ( cosThetaI < cosThetaO )
{ // -> thetaO < thetaI
sinAlpha = sinThetaI;
@@ -39,5 +39,5 @@ vec4 diffuseReflectionBSDF(in vec3 N, in vec3 L, in vec3 viewDir,
factor *= A + B * cosPhi * sinAlpha * tanBeta;
}
- return( vec4( factor * lightDiffuse, 1.0f ) );
+ return( vec4( factor * lightDiffuse, 1.0 ) );
}
diff --git a/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib b/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib
index 3b8f2d9f..9afc58b4 100644
--- a/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib
+++ b/src/Runtime/res/effectlib/funcdiffuseReflectionWrapBSDF.glsllib
@@ -1,5 +1,5 @@
vec4 diffuseReflectionWrapBSDF(vec3 normalDir, in vec3 L, in vec3 lightDiffuse, float wrap)
{
float I = max( 0.0, ((dot(L, normalDir) + wrap)/ (1.0 + wrap)) ); //diffuseIntensity
- return vec4( I * lightDiffuse, 1.0f );
+ return vec4( I * lightDiffuse, 1.0 );
}
diff --git a/src/Runtime/res/effectlib/funcspecularBSDF.glsllib b/src/Runtime/res/effectlib/funcspecularBSDF.glsllib
index 44e81966..e9450bfe 100644
--- a/src/Runtime/res/effectlib/funcspecularBSDF.glsllib
+++ b/src/Runtime/res/effectlib/funcspecularBSDF.glsllib
@@ -9,14 +9,14 @@
vec4 specularBSDF(in vec3 N, in vec3 L, in vec3 viewDir, in vec3 lightSpecular,
in float ior, in float shininess, in vec3 tint, int mode)
{
- vec4 rgba = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+ vec4 rgba = vec4( 0.0, 0.0, 0.0, 1.0 );
float cosTheta = dot( N, L );
- if ( 0.0f < cosTheta )
+ if ( 0.0 < cosTheta )
{
if ( ( mode == scatter_reflect ) || ( mode == scatter_reflect_transmit ) )
{
vec3 R = reflect( -L, N );
- float cosAlpha = max( 0.0f, dot( R, viewDir ) );
+ float cosAlpha = max( 0.0, dot( R, viewDir ) );
float shine = pow( cosAlpha, shininess );
rgba.rgb = shine * lightSpecular;
}
@@ -25,17 +25,17 @@ vec4 specularBSDF(in vec3 N, in vec3 L, in vec3 viewDir, in vec3 lightSpecular,
{
// check against total reflection
vec3 R = refract( -viewDir, N, ior );
- if ( R == vec3( 0.0f, 0.0f, 0.0f ) )
+ if ( R == vec3( 0.0, 0.0, 0.0 ) )
{
- rgba.a = 1.0f;
+ rgba.a = 1.0;
}
else if ( mode == scatter_transmit )
{
- rgba.a = 0.0f;
+ rgba.a = 0.0;
}
else
{
- rgba.a = 1.0f - luminance( tint );
+ rgba.a = 1.0 - luminance( tint );
}
}
return( rgba );
diff --git a/src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib b/src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib
new file mode 100644
index 00000000..d3994a61
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/SSAOCustomMaterial.glsllib
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SSAO_CUSTOM_MATERIAL_GLSLLIB
+#define SSAO_CUSTOM_MATERIAL_GLSLLIB
+
+#ifndef UIC_ENABLE_SSAO
+#define UIC_ENABLE_SSAO 0
+#endif
+
+#ifndef UIC_ENABLE_SSDO
+#define UIC_ENABLE_SSDO 0
+#endif
+
+#if UIC_ENABLE_SSAO || UIC_ENABLE_SSDO
+
+#include "viewProperties.glsllib"
+#if UIC_ENABLE_SSDO
+#include "screenSpaceDO.glsllib"
+
+
+uniform vec4 ao_properties;
+uniform vec4 ao_properties2;
+uniform vec4 shadow_properties;
+uniform vec4 aoScreenConst;
+uniform vec4 UvToEyeConst;
+
+
+uniform sampler2D depth_sampler;
+#endif
+uniform sampler2D ao_sampler;
+uniform vec2 ao_sampler_size;
+
+#endif // UIC_ENABLE_SSAO || UIC_ENABLE_SSDO
+
+#if UIC_ENABLE_SSAO
+
+float customMaterialAO()
+{
+#if UIC_ENABLE_SSDO
+ vec2 smpUV = (gl_FragCoord.xy) * aoScreenConst.zw;
+#else
+ vec2 smpUV = gl_FragCoord.xy / ao_sampler_size;
+#endif
+ return texture(ao_sampler, smpUV).x;
+}
+
+#else
+
+float customMaterialAO()
+{
+ return 1.0;
+}
+
+#endif
+
+#if UIC_ENABLE_SSDO
+
+float customMaterialShadow( vec3 lightDir, vec3 varWorldPos )
+{
+ return shadowOcclusion( depth_sampler, lightDir, varWorldPos, view_matrix, view_projection_matrix, shadow_properties, camera_properties, aoScreenConst, UvToEyeConst );
+}
+
+#else
+
+float customMaterialShadow( vec3 lightDir, vec3 varWorldPos )
+{
+ return 1.0;
+}
+
+#endif
+
+#endif // #ifndef SSAO_CUSTOM_MATERIAL_GLSLLIB
diff --git a/src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib b/src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib
new file mode 100644
index 00000000..2f3bd150
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/defaultMaterialBumpNoLod.glsllib
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+float calcRGBAvg(in vec4 rgba)
+{
+ return (rgba.r + rgba.g + rgba.b) / 3.0;
+}
+
+vec3 defaultMaterialBumpNoLod(in sampler2D sampler, in float factor,
+ in vec2 texCoord, in vec3 tangent, in vec3 binormal,
+ in vec3 normal, in vec2 bumpSize )
+{
+ // invert factor
+ float invFactor = -factor;
+
+ vec2 unitStep = 1.0 / bumpSize;
+
+ float du = calcRGBAvg(texture2D( sampler, vec2( texCoord.x + unitStep.x, texCoord.y )))
+ - calcRGBAvg(texture2D( sampler, vec2( texCoord.x, texCoord.y )));
+ float dv = calcRGBAvg(texture2D( sampler, vec2( texCoord.x, texCoord.y + unitStep.y )))
+ - calcRGBAvg(texture2D( sampler, vec2( texCoord.x, texCoord.y )));
+
+ vec3 n = normalize(vec3(invFactor * du, invFactor * dv, 1.0));
+ n = n.x * normalize(tangent) + n.y * normalize(binormal) + n.z * normal;
+ return normalize(normal + n);
+}
diff --git a/src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib b/src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib
new file mode 100644
index 00000000..cdb8c92a
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/funcareaLightVars.glsllib
@@ -0,0 +1,29 @@
+#define MAX_AREA_LIGHTS 16
+
+// note this struct must exactly match the memory layout of the
+// struct SLightSourceShader in the source code. If you make changes here you need
+// to adjust the struct SLightSourceShader as well
+struct AreaLight
+{
+ vec4 position;
+ vec4 direction; // Specifies the light direction in world coordinates.
+ vec4 up;
+ vec4 right;
+ vec4 diffuse;
+ vec4 ambient;
+ vec4 specular;
+ float spotExponent; // Specifies the intensity distribution of the light.
+ float spotCutoff; // Specifies the maximum spread angle of the light.
+ float constantAttenuation; // Specifies the constant light attenuation factor.
+ float linearAttenuation; // Specifies the linear light attenuation factor.
+ float quadraticAttenuation; // Specifies the quadratic light attenuation factor.
+ float range; // Specifies the maximum distance of the light influence
+ float width; // Specifies the width of the area light surface.
+ float height; // Specifies the height of the area light surface;
+ vec4 shadowControls;
+ mat4 shadowView;
+ int shadowIdx;
+};
+
+uniform int uNumAreaLights;
+uniform AreaLight arealights[MAX_AREA_LIGHTS];
diff --git a/src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib b/src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib
new file mode 100644
index 00000000..6cb0d831
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/funcsampleLightVars.glsllib
@@ -0,0 +1,27 @@
+
+#define MAX_NUM_LIGHTS 16
+
+struct LightSource
+{
+ vec4 position;
+ vec4 direction; // Specifies the light direction in world coordinates.
+ vec4 up;
+ vec4 right;
+ vec4 diffuse;
+ vec4 ambient;
+ vec4 specular;
+ float spotExponent; // Specifies the intensity distribution of the light.
+ float spotCutoff; // Specifies the maximum spread angle of the light.
+ float constantAttenuation; // Specifies the constant light attenuation factor.
+ float linearAttenuation; // Specifies the linear light attenuation factor.
+ float quadraticAttenuation; // Specifies the quadratic light attenuation factor.
+ float range; // Specifies the maximum distance of the light influence
+ float width; // Specifies the width of the area light surface.
+ float height; // Specifies the height of the area light surface;
+ vec4 shadowControls;
+ mat4 shadowView;
+ int shadowIdx;
+};
+
+uniform int uNumLights;
+uniform LightSource lights[MAX_NUM_LIGHTS];
diff --git a/src/Runtime/res/effectlib/gles2/monoChannel.glsllib b/src/Runtime/res/effectlib/gles2/monoChannel.glsllib
new file mode 100644
index 00000000..1460aae1
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/monoChannel.glsllib
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MONO_CHANNEL_GLSLLIB
+#define MONO_CHANNEL_GLSLLIB
+
+#ifdef UIC_DEFINE_API
+#define mono_alpha 0
+#define mono_average 1
+#define mono_luminance 2
+#define mono_maximum 3
+#endif
+
+float monoChannel( in vec4 t, const in int monoSource )
+{
+ if ( monoSource == mono_alpha )
+ return( t.w );
+
+ if ( monoSource == mono_average )
+ return( ( t.x + t.y + t.z ) / 3.0 );
+
+ if ( monoSource == mono_luminance )
+ return( luminance( t.xyz ) );
+
+ if ( monoSource == mono_maximum )
+ return( max( t.x, max( t.y, t.z ) ) );
+
+ return( 1.0 );
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/gles2/sampleProbe.glsllib b/src/Runtime/res/effectlib/gles2/sampleProbe.glsllib
new file mode 100644
index 00000000..4b328183
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/sampleProbe.glsllib
@@ -0,0 +1,482 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SAMPLE_PROBE_GLSLLIB
+#define SAMPLE_PROBE_GLSLLIB 1
+
+#ifndef UIC_ENABLE_LIGHT_PROBE_2
+#define UIC_ENABLE_LIGHT_PROBE_2 0
+#endif
+
+#ifndef UIC_ENABLE_IBL_FOV
+#define UIC_ENABLE_IBL_FOV 0
+#endif
+
+uniform sampler2D light_probe;
+uniform vec4 light_probe_props;
+uniform vec4 light_probe_rotation;
+uniform vec4 light_probe_offset; // light_probe_offset.w = number of mipmaps
+uniform vec2 light_probe_size;
+
+#if UIC_ENABLE_LIGHT_PROBE_2
+uniform sampler2D light_probe2;
+uniform vec4 light_probe2_props;
+uniform vec2 light_probe2_size;
+#endif
+
+#if UIC_ENABLE_IBL_FOV
+uniform vec4 light_probe_opts;
+#endif
+
+float noise1d(vec2 n)
+{
+ return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
+}
+
+mat3 orthoNormalize( in mat3 tanFrame )
+{
+ mat3 outMat;
+ outMat[0] = normalize( cross( tanFrame[1], tanFrame[2] ) );
+ outMat[1] = normalize( cross( tanFrame[2], outMat[0] ) );
+ outMat[2] = tanFrame[2];
+
+ return outMat;
+}
+
+mat3 tangentFrame( vec3 N, vec3 p )
+{
+ // get edge vectors of the pixel triangle
+ vec3 dp1 = dFdx( p );
+ vec3 dp2 = dFdy( p );
+ // Using dPdu and dPdv would be nicer, but the nature of our materials
+ // are not ones with intrinsic UVs, so we can't really go there.
+// vec2 duv1 = dFdx( uv );
+// vec2 duv2 = dFdy( uv );
+
+ // solve the linear system
+ vec3 dp2perp = cross( dp2, N );
+ vec3 dp1perp = cross( N, dp1 );
+// vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
+// vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
+
+ vec3 T = normalize(dp1perp);
+ vec3 B = normalize(dp2perp);
+ return mat3( T , B , N );
+}
+
+vec2 transformSample( vec2 origUV, vec4 probeRot, vec2 probeOfs )
+{
+ vec2 retUV;
+ retUV.x = dot( vec3(origUV, 1.0), vec3(probeRot.xy, probeOfs.x) );
+ retUV.y = dot( vec3(origUV, 1.0), vec3(probeRot.zw, probeOfs.y) );
+ return retUV;
+}
+
+// This is broken out into its own routine so that if we get some other
+// format image than a lat-long, then we can account for that by changing
+// the code here alone.
+vec2 getProbeSampleUV( vec3 smpDir, vec4 probeRot, vec2 probeOfs )
+{
+ vec2 smpUV;
+
+#if UIC_ENABLE_IBL_FOV
+ smpUV.x = (2.0 * atan(-smpDir.z, smpDir.x) + 3.14159265358 ) / light_probe_opts.x;
+ smpUV.y = (2.0 * atan(-smpDir.z, smpDir.y) + 3.14159265358 ) / light_probe_opts.x;
+#else
+ smpUV.x = atan( smpDir.x, -smpDir.z) / 3.14159265359;
+ smpUV.y = 1.0 - (acos(smpDir.y) / 1.57079632679);
+#endif
+ smpUV = transformSample( smpUV.xy * 0.5, probeRot, probeOfs ) + vec2(0.5, 0.5);
+
+ return smpUV;
+}
+
+vec4 getTopLayerSample( vec3 inDir, float lodShift, vec3 lodOffsets )
+{
+#if UIC_ENABLE_LIGHT_PROBE_2
+ if ( light_probe2_props.w < 0.5 )
+ return vec4(0.0, 0.0, 0.0, 0.0);
+
+ vec2 smpUV = getProbeSampleUV( inDir, vec4(1.0, 0.0, 0.0, 1.0), light_probe_props.xy );
+ smpUV.x -= 0.5;
+ smpUV.x *= light_probe2_props.x;
+ smpUV.x += light_probe2_props.y;
+
+ vec4 retVal = 0.4 * textureLod( light_probe2, smpUV , lodShift );
+ retVal += 0.2 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.x );
+ retVal += 0.3 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.y );
+ retVal += 0.1 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.z );
+ return retVal;
+#else
+ return vec4(0.0, 0.0, 0.0, 0.0);
+#endif
+}
+
+vec3 getProbeSample( vec3 smpDir, float lodShift, vec3 normal )
+{
+ vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy );
+ return textureLod( light_probe, smpUV , lodShift ).xyz;
+}
+
+vec3 getProbeWeightedSample( vec3 smpDir, float lodShift, float roughness, vec3 normal )
+{
+ // This gives us a weighted sum that approximates the total filter support
+ // of the full-blown convolution.
+ vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy );
+ float wt = 1.0;
+
+#if UIC_ENABLE_IBL_FOV
+ wt = min(wt, smoothstep(roughness * -0.25, roughness * 0.25, smpUV.x));
+ wt = min(wt, smoothstep(roughness * -0.25, roughness * 0.25, smpUV.y));
+ wt = min(wt, 1.0 - smoothstep(1.0 - roughness*0.25, 1.0 + roughness*0.25, smpUV.x));
+ wt = min(wt, 1.0 - smoothstep(1.0 - roughness*0.25, 1.0 + roughness*0.25, smpUV.y));
+#endif
+
+ vec3 lodOffsets;
+ lodOffsets.x = mix(-2.0, -0.70710678, roughness);
+ lodOffsets.y = min( 2.0 * smoothstep(0.0, 0.1, roughness), 2.0 - 1.29289 * smoothstep(0.1, 1.0, roughness) );
+ lodOffsets.z = min( 6.0 * smoothstep(0.0, 0.1, roughness), 6.0 - 4.585786 * smoothstep(0.1, 1.0, roughness) );
+
+ ivec2 iSize = ivec2(light_probe_size);
+ vec3 ddx = dFdx( smpDir ) * float(iSize.x);
+ vec3 ddy = dFdy( smpDir ) * float(iSize.y);
+// vec2 ddxUV = dFdx( smpUV ) * float(iSize.x);
+// vec2 ddyUV = dFdy( smpUV ) * float(iSize.y);
+
+ vec2 deriv;
+ deriv.x = max( dot(ddx, ddx), dot(ddy, ddy) );
+// deriv.y = max( dot(ddxUV, ddxUV), dot(ddyUV, ddyUV) );
+ deriv = clamp( deriv, vec2(1.0), vec2(iSize.x * iSize.y) );
+ vec2 lodBound = 0.5 * log2( deriv ) - vec2(1.0);
+
+// float minLod = 0.5 * (lodBound.x + lodBound.y);
+ float minLod = lodBound.x;
+ float maxLod = log2( max(float(iSize.x), float(iSize.y)) );
+ minLod = clamp( minLod / maxLod, 0.0, 1.0 );
+ minLod *= minLod * maxLod;
+
+ lodShift = max( lodShift, minLod );
+
+ vec3 retVal = 0.4 * textureLod( light_probe, smpUV , lodShift ).xyz;
+ retVal += 0.2 * textureLod( light_probe, smpUV , max(minLod, lodShift+lodOffsets.x) ).xyz;
+ retVal += 0.3 * textureLod( light_probe, smpUV , lodShift+lodOffsets.y ).xyz;
+ retVal += 0.1 * textureLod( light_probe, smpUV , lodShift+lodOffsets.z ).xyz;
+
+#if UIC_ENABLE_LIGHT_PROBE_2
+ vec4 topSmp = getTopLayerSample( smpDir, lodShift, lodOffsets );
+ vec3 tempVal = mix( retVal, topSmp.xyz, topSmp.w );
+ retVal = mix( retVal, tempVal, light_probe2_props.z );
+#endif
+
+ if (light_probe_props.z > -1.0) {
+ float ctr = 0.5 + 0.5 * light_probe_props.z;
+ float vertWt = smoothstep(ctr-roughness*0.25, ctr+roughness*0.25, smpUV.y);
+ float wtScaled = mix(1.0, vertWt, light_probe_props.z + 1.0);
+ retVal *= wtScaled;
+ }
+
+ return retVal * wt;
+}
+
+vec2 textureSizeLod( vec2 size, int level )
+{
+ return size / pow(2.0, float(level));
+}
+
+vec3 getProbeAnisoSample( vec3 smpDir, float roughU, float roughV, mat3 tanFrame )
+{
+ float minRough = min(roughU, roughV);
+ float maxRough = max(roughU, roughV);
+
+ float lodMin = log2( (minRough*3.0 + maxRough)*0.25 ) + (light_probe_offset.w - 2.0);
+
+ float ratio = clamp( maxRough / minRough, 1.01, 27.0);
+ vec2 texSize = textureSizeLod( light_probe_size, int(floor( lodMin )) );
+ texSize = mix( texSize, texSize * 0.5, fract(lodMin) );
+
+ // Boundary of 1.0..9.0 is just to keep the number of samples to within a
+ // reasonable number of samples in the filter. Similarly, with the clamping
+ // of the ratio to a max of 27.0 is just to prevent the step size in the filter
+ // to be no bigger than 3 texels (beyond which, there are some artifacts at high
+ // roughness, aka low texture res).
+ float stepFig = clamp(floor( ratio ), 1.0, 9.0);
+
+ // numSteps is half the number of samples we need to take, which makes it
+ // the number of steps to take on each side.
+ int numSteps = int( floor(stepFig * 0.5) );
+
+ vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy );
+ vec4 result = vec4(0.0);
+
+ vec3 smpDirOfs = (maxRough == roughU) ? 0.01 * tanFrame[0] : 0.01 * tanFrame[1];
+ vec2 stepPos = getProbeSampleUV(normalize(smpDir + smpDirOfs), light_probe_rotation, light_probe_offset.xy);
+ vec2 stepNeg = getProbeSampleUV(normalize(smpDir - smpDirOfs), light_probe_rotation, light_probe_offset.xy);
+ stepPos -= smpUV; stepNeg -= smpUV;
+ stepPos *= texSize; stepNeg *= texSize;
+
+ // This ensures that we step along a size that makes sense even if one of the two
+ // sammpling directions wraps around the edges of the IBL texture.
+ smpDirOfs /= min( length(stepPos), length(stepNeg) );
+ smpDirOfs *= ratio / stepFig;
+
+ float sigma = mix(0.0, 2.0, ratio / 27.0);
+ sigma *= sigma;
+
+ float wt = (1.0 / (ratio - 1.0)) + 1.0;
+ result.xyz += wt * getProbeWeightedSample( smpDir, lodMin, minRough, tanFrame[2] );
+ result.w += wt;
+ for (int i = 0; i < numSteps; ++i)
+ {
+ wt = sigma / (sigma + float(i * i));
+ vec2 uv0 = getProbeSampleUV(normalize(smpDir + smpDirOfs * float(i)), light_probe_rotation, light_probe_offset.xy);
+ vec2 uv1 = getProbeSampleUV(normalize(smpDir - smpDirOfs * float(i)), light_probe_rotation, light_probe_offset.xy);
+ result.xyz += wt * textureLod( light_probe, uv0 , lodMin ).xyz;
+ result.w += wt;
+ result.xyz += wt * textureLod( light_probe, uv1 , lodMin ).xyz;
+ result.w += wt;
+ }
+
+ result /= result.w;
+ return result.xyz;
+}
+
+vec4 sampleDiffuse( mat3 tanFrame )
+{
+ if ( light_probe_props.w < 0.005 )
+ return vec4( 0.0 );
+
+// if ( light_probe_offset.w > 0.5 )
+// {
+ // The LOD offset comes from the assumption that a full diffuse convolution
+ // has a support of pi/2, which translates into x pixels, and the base 2 log
+ // gives us this LOD... Technically, "x" pixels depends on what the original
+ // texture resolution was, which is why we use light_probe_offset.w, which holds
+ // the number of mip levels the texture has.
+
+ return vec4( light_probe_props.w * getProbeWeightedSample( tanFrame[2], light_probe_offset.w - 2.65149613, 1.0, tanFrame[2] ), 1.0 );
+// }
+
+ /*
+ // PKC -- the code below is for full-blown IBL, which we'll skip for now
+
+ // Hand-calculated Hammersley points for t = 2, n = 33
+ // I exclude the 0,0 first point, hence why n=33 and not 32
+ // Nice thing about 2d Hammersley points is that any subset is
+ // also stratified, so even if I have 1000 points and truncate
+ // anywhere, I'm fine. Each of these represent the y of an xy
+ // while x for the kth point is always (k+1)/n.
+ float kernel[32];
+ kernel[0] = 0.5; kernel[1] = 0.25;
+ kernel[2] = 0.75; kernel[3] = 0.125;
+ kernel[4] = 0.625; kernel[5] = 0.375;
+ kernel[6] = 0.875; kernel[7] = 0.0625;
+ kernel[8] = 0.5625; kernel[9] = 0.3125;
+ kernel[10] = 0.8125; kernel[11] = 0.1875;
+ kernel[12] = 0.6875; kernel[13] = 0.4375;
+ kernel[14] = 0.9375; kernel[15] = 0.03125;
+ kernel[16] = 0.53125; kernel[17] = 0.28125;
+ kernel[18] = 0.78125; kernel[19] = 0.15625;
+ kernel[20] = 0.65625; kernel[21] = 0.40625;
+ kernel[22] = 0.90625; kernel[23] = 0.09375;
+ kernel[24] = 0.59375; kernel[25] = 0.34375;
+ kernel[26] = 0.84375; kernel[27] = 0.28175;
+ kernel[28] = 0.71875; kernel[29] = 0.46875;
+ kernel[30] = 0.96875; kernel[31] = 0.015625;
+
+ float phiShift = noise1d(gl_FragCoord.xy) - 0.5;
+
+ vec3 ret = vec3(0, 0, 0);
+
+ int ct = 24;
+ float step = 25.0;
+
+ // Importance sampling a cosine-weighted distribution. Since this
+ // matches the BSDF exactly, we are just going to assume that the PDF
+ // and the BSDF cancel out in sampling, so we just need to accumulate
+ // texture colors. The noise function puts randomized "twist" into
+ // the sampled directions.
+ for( int i = 0; i < ct; ++i )
+ {
+ vec3 localDir;
+ float phi = 6.28318530718 * (kernel[i] + phiShift);
+ float cosTheta = sqrt( float(i+1) / step);
+ localDir.z = sqrt(1.0 - cosTheta*cosTheta);
+ localDir.x = cos(phi) * cosTheta;
+ localDir.y = sin(phi) * cosTheta;
+ vec3 smpDir = tanFrame[0]*localDir.x + tanFrame[1]*localDir.y + tanFrame[2]*localDir.z;
+
+
+ float lodShift = light_probe_offset.w - 2 + log2( 3.1415926535 / (localDir.z * step) );
+ vec3 smpColor = getProbeSample( smpDir, lodShift, tanFrame[2] );
+
+ // The assumption here is that the BSDF and the sampling PDF are identical
+ // so they cancel out and therefore, we don't need to include it here.
+ ret += smpColor;
+ }
+
+ ret *= aoFactor / 24.0;
+ return ret;
+ */
+}
+
+vec4 sampleDiffuseCustomMaterial( vec3 normal, vec3 worldPos, float aoFactor )
+{
+
+ mat3 tanFrame = tangentFrame( normal, worldPos );
+ return sampleDiffuse( tanFrame );
+}
+
+vec4 sampleGlossyAniso( mat3 tanFrame, vec3 viewDir, float roughU, float roughV )
+{
+ if ( light_probe_props.w < 0.005 )
+ return vec4( 0.0 );
+
+ // PKC : If we do the full IBL sampling, it's useful to square the roughnesses because
+ // it makes the effect of roughness feel more linear in the low end. This isn't necessary
+ // for fast IBL.
+// float sigmaU = clamp(roughU*roughU, 0.0001, 1.0);
+// float sigmaV = clamp(roughV*roughV, 0.0001, 1.0);
+ float sigmaU = smoothstep( 0.0, 1.0, clamp(roughU, 0.0001, 1.0) );
+ float sigmaV = smoothstep( 0.0, 1.0, clamp(roughV, 0.0001, 1.0) );
+ vec3 ret = vec3(0, 0, 0);
+
+// if ( light_probe_offset.w > 0.5 )
+// {
+ vec3 smpDir = reflect( -viewDir, tanFrame[2] );
+ float sigma = sqrt(sigmaU * sigmaV);
+
+ // Compute the Geometric occlusion/self-shadowing term
+ float NdotL = clamp( dot( smpDir, tanFrame[2] ), 0.0, 0.999995);
+ float k = sigma * 0.31830988618; // roughness / pi
+ float Gl = clamp( (NdotL / (NdotL*(1.0-k) + k) + (1.0 - k*k)) * 0.5, 0.0, 1.0 );
+
+ vec3 outColor;
+
+ outColor = getProbeAnisoSample( smpDir, sigmaU, sigmaV, tanFrame );
+
+ return vec4( light_probe_props.w * Gl * outColor, 1.0 );
+// }
+
+ // PKC -- the code below is for full-blown IBL, which we'll skip for now
+
+/*
+ float step = clamp( ceil(32.0 * sqrt(max(sigmaU, sigmaV))), 4.0, 32.0 );
+ int actualCt = int(step);
+ float phiShift = noise1d(gl_FragCoord.xy) - 0.5;
+
+ // Hand-calculated Hammersley points for t = 2, n = 33
+ // I exclude the 0,0 first point, hence why n=33 and not 32
+ // Nice thing about 2d Hammersley points is that any subset is
+ // also stratified, so even if I have 1000 points and truncate
+ // anywhere, I'm fine. Each of these represent the y of an xy
+ // while x for the kth point is always (k+1)/n.
+ float kernel[32];
+ kernel[0] = 0.5; kernel[1] = 0.25;
+ kernel[2] = 0.75; kernel[3] = 0.125;
+ kernel[4] = 0.625; kernel[5] = 0.375;
+ kernel[6] = 0.875; kernel[7] = 0.0625;
+ kernel[8] = 0.5625; kernel[9] = 0.3125;
+ kernel[10] = 0.8125; kernel[11] = 0.1875;
+ kernel[12] = 0.6875; kernel[13] = 0.4375;
+ kernel[14] = 0.9375; kernel[15] = 0.03125;
+ kernel[16] = 0.53125; kernel[17] = 0.28125;
+ kernel[18] = 0.78125; kernel[19] = 0.15625;
+ kernel[20] = 0.65625; kernel[21] = 0.40625;
+ kernel[22] = 0.90625; kernel[23] = 0.09375;
+ kernel[24] = 0.59375; kernel[25] = 0.34375;
+ kernel[26] = 0.84375; kernel[27] = 0.28175;
+ kernel[28] = 0.71875; kernel[29] = 0.46875;
+ kernel[30] = 0.96875; kernel[31] = 0.015625;
+
+ float thetaI = acos( dot(viewDir, tanFrame[2]) );
+
+ // NOTE : The model I'm using here is actually based on the KGGX model used in
+ // physGlossyBSDF. This is my own variation on the original GGX which uses something
+ // closer to a pure Cauchy distribution in tangent space, but also supports anisotropy.
+ for (int i = 0; i < actualCt; ++i)
+ {
+ vec3 localDir;
+
+ float phi = 6.28318530718 * (kernel[i] + phiShift);
+ float u = float(i + 1) / (step + 1.0);
+ float rU = cos(phi) * sigmaU;
+ float rV = sin(phi) * sigmaV;
+ float sigma = sqrt(rU * rU + rV * rV);
+
+ float boundA = atan( ((thetaI - 1.57079632679) * 0.5) / sigma );
+ float boundB = atan( ((thetaI + 1.57079632679) * 0.5) / sigma );
+ float t = (1.0 - u) * boundA + u * boundB;
+ float thetaH = tan( t ) * sigma;
+
+ float cosThetaH = cos( thetaH );
+ float sinThetaH = sin( thetaH );
+ localDir.z = cosThetaH;
+ localDir.y = sin(phi) * sinThetaH;
+ localDir.x = cos(phi) * sinThetaH;
+
+ vec3 halfDir = tanFrame[0]*localDir.x + tanFrame[1]*localDir.y + tanFrame[2]*localDir.z;
+ halfDir = normalize(halfDir);
+ vec3 smpDir = reflect( -viewDir, halfDir );
+
+ vec2 scaledXY = localDir.xy / vec2(sigmaU, sigmaV);
+ float PDF = (sigmaU*sigmaV) / (sigmaU*sigmaV + dot(scaledXY, scaledXY));
+ vec3 Haf = smpDir + viewDir; // We need the unnormalized half vecter as well as the normalized one
+ float HdotL = dot(halfDir, smpDir);
+ // normalize the PDF to compute the filter support
+ // This gives us the ideal miplevel at which to sample the texture map.
+ PDF *= dot(Haf, Haf) / (4.0 * dot(Haf, smpDir) * HdotL * sigmaU*sigmaV * (boundB-boundA)*(boundB-boundA));
+
+ // Again assuming that the pdf and BSDF are equivalent -- that's not generally valid,
+ // but it saves a lot of ALU cycles.
+ float lodShift = log2( 512.0 * sigma / PDF );
+
+ float k = sigma * 0.31830988618; // roughness / pi
+ float Gl = clamp( (HdotL / (HdotL*(1.0-k) + k) + (1.0 - k*k)) * 0.5, 0.0, 1.0 );
+
+ vec3 smpColor = Gl * getProbeSample( smpDir, lodShift, tanFrame[2] );
+ ret += smpColor;
+ }
+ ret /= float(actualCt);
+ return vec4(ret, 1.0);
+*/
+}
+
+vec4 sampleGlossy( mat3 tanFrame, vec3 viewDir, float roughness )
+{
+ return sampleGlossyAniso( tanFrame, viewDir, roughness, roughness );
+}
+
+vec4 sampleGlossyCustomMaterial( vec3 normal, vec3 worldPos, vec3 viewDir, float roughness )
+{
+ mat3 tanFrame = tangentFrame( normal, worldPos );
+ return sampleGlossy( tanFrame, viewDir, roughness );
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/gles2/shadowMapping.glsllib b/src/Runtime/res/effectlib/gles2/shadowMapping.glsllib
new file mode 100644
index 00000000..183ef974
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/shadowMapping.glsllib
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SHADOW_MAPPING_GLSLLIB
+#define SHADOW_MAPPING_GLSLLIB
+
+#include "depthpass.glsllib"
+
+float sampleParaboloid( in sampler2D shadowMap, in vec4 shadowControls, in mat4 shadowMatrix, in vec3 worldPos, in vec2 cameraProps, out vec2 smpUV )
+{
+ vec4 projCoord = shadowMatrix * vec4( worldPos, 1.0 );
+ vec3 smpCoord = projCoord.xyz / projCoord.w;
+
+ float ptDepth = depthValueToLinearDistance( 1.0 - smpCoord.z, cameraProps );
+ ptDepth = (ptDepth - cameraProps.x) / (cameraProps.y - cameraProps.x);
+ smpCoord = normalize( smpCoord.xyz );
+ smpCoord.xy /= -( smpCoord.z + 1.0 );
+ smpCoord.xy = vec2(1.0) - smpCoord.xy;
+ smpCoord.xy *= 0.5;
+
+ smpUV = smpCoord.xy; // This is just for debug purposes to ensure what the sampled UV cooord is.
+
+ float sampleDepth = texture( shadowMap, smpCoord.xy ).x + shadowControls.x;
+ sampleDepth *= sampleDepth;
+ ptDepth *= ptDepth;
+ float shadowFac = min(1.0, exp(shadowControls.y * sampleDepth * sampleDepth) / exp(shadowControls.y * ptDepth * ptDepth));
+
+ smpUV.xy *= shadowFac;
+ return shadowFac;
+}
+
+float sampleCubemap( in samplerCube shadowCube, in vec4 shadowControls, in mat4 shadowViewMat, in vec3 lightPos, in vec3 worldPos, in vec2 cameraProps )
+{
+ vec3 viewDir = worldPos - vec3(lightPos.x, lightPos.y, lightPos.z);
+ float ptDepth = length(viewDir.xyz);
+ vec4 viewCoord = shadowViewMat * vec4( viewDir.xyz, 0.0 );
+ viewCoord.xyz /= ptDepth;
+ ptDepth = clamp((ptDepth - 1.0) / (cameraProps.y - 1.0), 0.0, 1.0);
+
+ float smpDepth = textureCube( shadowCube, viewDir.xyz ).x + shadowControls.x;
+
+ float shadowFac = min(1.0, exp(shadowControls.y * smpDepth) / exp(shadowControls.y * ptDepth));
+ return shadowFac;
+}
+
+float sampleOrthographic( in sampler2D shadowMap, in vec4 shadowControls, in mat4 shadowMatrix, in vec3 worldPos, in vec2 cameraProps )
+{
+ vec4 projCoord = shadowMatrix * vec4( worldPos, 1.0 );
+ vec3 smpCoord = projCoord.xyz / projCoord.w;
+
+ float sampleDepth = texture( shadowMap, smpCoord.xy ).x + shadowControls.x;
+
+ return min(1.0, exp(shadowControls.y * sampleDepth) / exp(shadowControls.y * smpCoord.z));
+}
+
+
+struct ParaboloidMapResult
+{
+ vec4 m_Position;
+ vec4 m_WorldPos;
+};
+
+ParaboloidMapResult VertexParaboloidDepth(vec3 pos, mat4 inMVP)
+{
+ vec4 glPos = inMVP * vec4( pos, 1.0 );
+ glPos /= glPos.w;
+ glPos.xyz = normalize( glPos.xyz );
+ vec4 world_pos;
+ world_pos.w = glPos.z;
+ glPos.xy /= glPos.z + 1.0;
+ world_pos.xyz = pos.xyz;
+
+ ParaboloidMapResult retval;
+ retval.m_Position = glPos;
+ retval.m_WorldPos = world_pos;
+ return retval;
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib b/src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib
new file mode 100644
index 00000000..fd0a1415
--- /dev/null
+++ b/src/Runtime/res/effectlib/gles2/tangentSpaceNormalTexture.glsllib
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILE_NORMAL_TEXTURE_GLSLLIB
+#define FILE_NORMAL_TEXTURE_GLSLLIB
+
+#ifdef UIC_DEFINE_API
+
+#include "luminance.glsllib"
+#include "monoChannel.glsllib"
+#include "textureCoordinateInfo.glsllib"
+#define wrap_clamp 0
+#define wrap_repeat 1
+#define wrap_mirrored_repeat 2
+#include "rotationTranslationScale.glsllib"
+#include "transformCoordinate.glsllib"
+
+#endif
+
+int modulo(int a, int b)
+{
+ int k = (a / b);
+ return a - k*b;
+}
+
+//interpreting the color values of a bitmap as a vector in tangent space
+vec3 tangentSpaceNormalTexture( in sampler2D tex, in float factor, in bool flipTangentU, in bool flipTangentV
+ , in texture_coordinate_info uvw, in vec2 cropU, in vec2 cropV, in int wrapU, in int wrapV )
+{
+ // if we mirror repeat a tangent space texture, tangent space needs to be flipped for every other tile
+ bool flipU = flipTangentU;
+ bool flipV = flipTangentV;
+ if ( wrapU == wrap_mirrored_repeat )
+ {
+ if ( ( ( 0.0 < uvw.position.x ) && ( modulo(int( uvw.position.x ), 2) == 1 ) )
+ || ( ( uvw.position.x < 0.0 ) && ( modulo(int( uvw.position.x ), 2) == 0 ) ) )
+ {
+ flipU = !flipU;
+ }
+ if ( ( ( 0.0 < uvw.position.y ) && ( modulo(int( uvw.position.y ), 2) == 1 ) )
+ || ( ( uvw.position.y < 0.0 ) && ( modulo(int( uvw.position.y ), 2) == 0 ) ) )
+ {
+ flipV = !flipV;
+ }
+ }
+
+ vec3 tangent = 2.0 * texture( tex, uvw.position.xy ).xyz - 1.0;
+
+ vec3 tangentU = normalize( flipU ? -uvw.tangent_u : uvw.tangent_u );
+ vec3 tangentV = normalize( flipV ? -uvw.tangent_v : uvw.tangent_v );
+ vec3 normal = normalize( cross( tangentU, tangentV ) );
+
+ return( mix( normal, normalize( tangent.x * tangentU - tangent.y * tangentV + tangent.z * normal ), factor ) );
+}
+
+#include "textureCoordinateInfo.glsllib"
+
+//Simpler version built to run from UIC image data
+//In our case, we have already generated the texture coordinate x,y position
+//TODO - figure out if we need to manipulate tangent_u, tangent_v.
+vec3 uicDefaultMaterialFileNormalTexture( in sampler2D sampler, in float factor, vec2 texCoord, vec3 tangent, vec3 binormal )
+{
+ // factor should be in [0,1] range
+ return tangentSpaceNormalTexture( sampler, clamp(factor, 0.0, 1.0), false, false
+ , textureCoordinateInfo( vec3( texCoord.x, texCoord.y, 0.0 ), tangent, binormal )
+ , vec2( 0.000000, 1.000000 ), vec2( 0.000000, 1.000000 )
+ , wrap_repeat, wrap_repeat);
+}
+
+#endif
diff --git a/src/Runtime/res/effectlib/monoChannel.glsllib b/src/Runtime/res/effectlib/monoChannel.glsllib
index 1ae6d529..e609e68c 100644
--- a/src/Runtime/res/effectlib/monoChannel.glsllib
+++ b/src/Runtime/res/effectlib/monoChannel.glsllib
@@ -45,14 +45,14 @@ float monoChannel( in vec4 t, in int monoSource )
case mono_alpha :
return( t.w );
case mono_average :
- return( ( t.x + t.y + t.z ) / 3.0f );
+ return( ( t.x + t.y + t.z ) / 3.0 );
case mono_luminance :
return( luminance( t.xyz ) );
case mono_maximum :
return( max( t.x, max( t.y, t.z ) ) );
default :
- return( 1.0f );
+ return( 1.0 );
}
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/Runtime/res/effectlib/physGlossyBSDF.glsllib b/src/Runtime/res/effectlib/physGlossyBSDF.glsllib
index d94bc26a..ad805960 100644
--- a/src/Runtime/res/effectlib/physGlossyBSDF.glsllib
+++ b/src/Runtime/res/effectlib/physGlossyBSDF.glsllib
@@ -53,7 +53,7 @@ float Gterm( float cosTheta, float roughness )
vec4 kggxGlossyBSDF( in mat3 tanFrame, in vec3 L, in vec3 V, in vec3 lightSpecular, float ior,
in float roughnessU, in float roughnessV, int mode )
{
- vec4 rgba = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+ vec4 rgba = vec4( 0.0, 0.0, 0.0, 1.0 );
vec3 H = normalize(L + V);
// NOTE : This BSDF allows roughness up to 2.0 which allows it
@@ -113,7 +113,7 @@ vec4 kggxGlossyDefaultMtl( in vec3 normal, in vec3 tangent, in vec3 L, in vec3 V
vec4 wardGlossyBSDF( in mat3 tanFrame, in vec3 L, in vec3 V, in vec3 lightSpecular, in float ior,
in float roughnessU, in float roughnessV, int mode )
{
- vec4 rgba = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+ vec4 rgba = vec4( 0.0, 0.0, 0.0, 1.0 );
vec3 H = normalize(L + V);
// specular
diff --git a/src/Runtime/res/effectlib/rotationTranslationScale.glsllib b/src/Runtime/res/effectlib/rotationTranslationScale.glsllib
index 8abc8c9e..78bb8dd1 100644
--- a/src/Runtime/res/effectlib/rotationTranslationScale.glsllib
+++ b/src/Runtime/res/effectlib/rotationTranslationScale.glsllib
@@ -33,18 +33,18 @@
mat4 rotationTranslationScale( in vec3 rotation, in vec3 translation, in vec3 scaling )
{
- mat4 st = mat4( scaling.x, 0.0f, 0.0f, 0.0f
- , 0.0f, scaling.y, 0.0f, 0.0f
- , 0.0f, 0.0f, scaling.z, 0.0f
- , translation.x - 0.5f, translation.y - 0.5f, translation.z - 0.5f, 1.0f );
+ mat4 st = mat4( scaling.x, 0.0, 0.0, 0.0
+ , 0.0, scaling.y, 0.0, 0.0
+ , 0.0, 0.0, scaling.z, 0.0
+ , translation.x - 0.5, translation.y - 0.5, translation.z - 0.5, 1.0 );
vec3 s = sin( rotation );
vec3 c = cos( rotation );
- mat4 r = mat4( c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0f
- , c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0f
- , -s.y , s.x * c.y , c.x * c.y , 0.0f
- , 0.5f , 0.5f , 0.5f , 1.0f );
+ mat4 r = mat4( c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0
+ , c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0
+ , -s.y , s.x * c.y , c.x * c.y , 0.0
+ , 0.5 , 0.5 , 0.5 , 1.0 );
return( st * r );
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib b/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib
index 853a8601..2b7aacdc 100644
--- a/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib
+++ b/src/Runtime/res/effectlib/tangentSpaceNormalTexture.glsllib
@@ -53,19 +53,19 @@ vec3 tangentSpaceNormalTexture( in sampler2D tex, in float factor, in bool flipT
bool flipV = flipTangentV;
if ( wrapU == wrap_mirrored_repeat )
{
- if ( ( ( 0.0f < uvw.position.x ) && ( int( uvw.position.x ) % 2 == 1 ) )
- || ( ( uvw.position.x < 0.0f ) && ( int( uvw.position.x ) % 2 == 0 ) ) )
+ if ( ( ( 0.0 < uvw.position.x ) && ( int( uvw.position.x ) % 2 == 1 ) )
+ || ( ( uvw.position.x < 0.0 ) && ( int( uvw.position.x ) % 2 == 0 ) ) )
{
flipU = !flipU;
}
- if ( ( ( 0.0f < uvw.position.y ) && ( int( uvw.position.y ) % 2 == 1 ) )
- || ( ( uvw.position.y < 0.0f ) && ( int( uvw.position.y ) % 2 == 0 ) ) )
+ if ( ( ( 0.0 < uvw.position.y ) && ( int( uvw.position.y ) % 2 == 1 ) )
+ || ( ( uvw.position.y < 0.0 ) && ( int( uvw.position.y ) % 2 == 0 ) ) )
{
flipV = !flipV;
}
}
- vec3 tangent = 2.0f * texture( tex, uvw.position.xy ).xyz - 1.0f;
+ vec3 tangent = 2.0 * texture( tex, uvw.position.xy ).xyz - 1.0;
vec3 tangentU = normalize( flipU ? -uvw.tangent_u : uvw.tangent_u );
vec3 tangentV = normalize( flipV ? -uvw.tangent_v : uvw.tangent_v );
diff --git a/src/Runtime/res/effectlib/transformCoordinate.glsllib b/src/Runtime/res/effectlib/transformCoordinate.glsllib
index 53237d02..ccdf7d0a 100644
--- a/src/Runtime/res/effectlib/transformCoordinate.glsllib
+++ b/src/Runtime/res/effectlib/transformCoordinate.glsllib
@@ -34,10 +34,10 @@
texture_coordinate_info transformCoordinate( in mat4 transform, in texture_coordinate_info coordinate )
{
texture_coordinate_info tci;
- tci.position = ( transform * vec4( coordinate.position, 1.0f ) ).xyz;
- tci.tangent_u = ( transform * vec4( coordinate.tangent_u, 0.0f ) ).xyz;
- tci.tangent_v = ( transform * vec4( coordinate.tangent_v, 0.0f ) ).xyz;
+ tci.position = ( transform * vec4( coordinate.position, 1.0 ) ).xyz;
+ tci.tangent_u = ( transform * vec4( coordinate.tangent_u, 0.0 ) ).xyz;
+ tci.tangent_v = ( transform * vec4( coordinate.tangent_v, 0.0 ) ).xyz;
return( tci );
}
-#endif \ No newline at end of file
+#endif
diff --git a/tests/auto/runtime/Qt3DSRenderTestBase.cpp b/tests/auto/runtime/Qt3DSRenderTestBase.cpp
index 24712ec8..99748916 100644
--- a/tests/auto/runtime/Qt3DSRenderTestBase.cpp
+++ b/tests/auto/runtime/Qt3DSRenderTestBase.cpp
@@ -46,6 +46,32 @@ bool NVRenderTestBase::initializeUICRenderer(QSurfaceFormat format)
m_rc = m_factory->GetUICRenderContext();
m_renderImpl = new uic::render::CUICRendererImpl(*m_rc);
+ QString versionString;
+ switch ((QT3DSU32)m_rc->GetRenderContext().GetRenderContextType()) {
+ case NVRenderContextValues::GLES2:
+ versionString = QLatin1Literal("gles2");
+ break;
+ case NVRenderContextValues::GL2:
+ versionString = QLatin1Literal("gl2");
+ break;
+ case NVRenderContextValues::GLES3:
+ versionString = QLatin1Literal("gles3");
+ break;
+ case NVRenderContextValues::GL3:
+ versionString = QLatin1Literal("gl3");
+ break;
+ case NVRenderContextValues::GLES3PLUS:
+ versionString = QLatin1Literal("gles3x");
+ break;
+ case NVRenderContextValues::GL4:
+ versionString = QLatin1Literal("gl4");
+ break;
+ default:
+ break;
+ }
+
+ m_rc->GetDynamicObjectSystem().setShaderCodeLibraryVersion(versionString);
+
return true;
}
diff --git a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp
index a76a2de8..6e5dcf00 100644
--- a/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp
+++ b/tests/auto/runtime/shadergenerator/Qt3DSRenderTestCustomMaterialGenerator.cpp
@@ -224,7 +224,7 @@ struct CustomTestKey
#define MAX_TEST_KEY ((1llu<<20)-1)
-CustomTestKey randomizeTestKey()
+static CustomTestKey randomizeTestKey()
{
uint64_t v = (uint64_t(qrand()))%MAX_TEST_KEY;
return *reinterpret_cast<CustomTestKey*>(&v);
diff --git a/tests/auto/runtime/tst_qt3dsruntime.cpp b/tests/auto/runtime/tst_qt3dsruntime.cpp
index f272d7ea..32a5fb96 100644
--- a/tests/auto/runtime/tst_qt3dsruntime.cpp
+++ b/tests/auto/runtime/tst_qt3dsruntime.cpp
@@ -168,7 +168,9 @@ bool tst_qt3dsruntime::init(QSurfaceFormat format)
bool tst_qt3dsruntime::init()
{
-#if defined(Q_OS_ANDROID)
+#if defined(QT_OPENGL_ES_2)
+ return init(makeFormat(2, 0, true, false));
+#elif defined(Q_OS_ANDROID) || defined(QT_OPENGL_ES_3)
return init(makeFormat(3, 2, true, false));
#else
return init(makeFormat(4, 3));
@@ -459,7 +461,67 @@ void tst_qt3dsruntime::testNVRenderTestProgramPipeline()
cleanup();
}
-#if !defined(Q_OS_ANDROID)
+#if defined(QT_OPENGL_ES_2)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_200es()
+{
+ if (init(makeFormat(2, 0, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_200es()
+{
+ runCustomShaderGeneratorTest(makeFormat(2, 0, true, false));
+ cleanup();
+}
+#endif
+
+#if defined(QT_OPENGL_ES_3)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_300es()
+{
+ if (init(makeFormat(3, 0, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_300es()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 0, true, false));
+ cleanup();
+}
+
+#if defined(QT_FEATURE_opengles31)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_310es()
+{
+ if (init(makeFormat(3, 1, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_310es()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 1, true, false));
+ cleanup();
+}
+#endif
+#if defined(QT_FEATURE_opengles32)
+void tst_qt3dsruntime::testRenderDefaultShaderGenerator_320es()
+{
+ if (init(makeFormat(3, 1, true, false))) {
+ runDefaultShaderGeneratorTest();
+ cleanup();
+ }
+}
+void tst_qt3dsruntime::testRenderCustomShaderGenerator_320es()
+{
+ runCustomShaderGeneratorTest(makeFormat(3, 1, true, false));
+ cleanup();
+}
+
+#endif
+#endif
+
+#if defined(QT_OPENGL_DYNAMIC)
void tst_qt3dsruntime::testRenderDefaultShaderGenerator_300()
{
QSKIP("OpenGL 3.0 is not supported");
@@ -566,21 +628,6 @@ void tst_qt3dsruntime::testRenderCustomShaderGenerator_430()
runCustomShaderGeneratorTest(makeFormat(4, 3));
}
-#else
-
-void tst_qt3dsruntime::testRenderDefaultShaderGenerator_320es()
-{
- if (init(makeFormat(3, 2, true, false))) {
- runDefaultShaderGeneratorTest();
- cleanup();
- }
-}
-
-void tst_qt3dsruntime::testRenderCustomShaderGenerator_320es()
-{
- runCustomShaderGeneratorTest(makeFormat(3, 2, true, false));
-}
-
#endif
void tst_qt3dsruntime::runDefaultShaderGeneratorTest()
diff --git a/tests/auto/runtime/tst_qt3dsruntime.h b/tests/auto/runtime/tst_qt3dsruntime.h
index a6370d75..1f5b943e 100644
--- a/tests/auto/runtime/tst_qt3dsruntime.h
+++ b/tests/auto/runtime/tst_qt3dsruntime.h
@@ -85,7 +85,24 @@ private Q_SLOTS:
void testRenderEffectGenerator();
-#if !defined(Q_OS_ANDROID)
+#if defined(QT_OPENGL_ES_2)
+ void testRenderDefaultShaderGenerator_200es();
+ void testRenderCustomShaderGenerator_200es();
+#endif
+#if defined(QT_OPENGL_ES_3)
+ void testRenderDefaultShaderGenerator_300es();
+ void testRenderCustomShaderGenerator_300es();
+#if defined(QT_FEATURE_opengles31)
+ void testRenderDefaultShaderGenerator_310es();
+ void testRenderCustomShaderGenerator_310es();
+#endif
+#if defined(QT_FEATURE_opengles32)
+ void testRenderDefaultShaderGenerator_320es();
+ void testRenderCustomShaderGenerator_320es();
+#endif
+#endif
+
+#if defined(QT_OPENGL_DYNAMIC)
void testRenderDefaultShaderGenerator_300();
void testRenderDefaultShaderGenerator_310();
void testRenderDefaultShaderGenerator_320();
@@ -103,9 +120,6 @@ private Q_SLOTS:
void testRenderCustomShaderGenerator_410();
void testRenderCustomShaderGenerator_420();
void testRenderCustomShaderGenerator_430();
-#else
- void testRenderDefaultShaderGenerator_320es();
- void testRenderCustomShaderGenerator_320es();
#endif