/**************************************************************************** ** ** Copyright (C) 2008-2012 NVIDIA Corporation. ** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Quick 3D. ** ** $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 #include #include #include #include #include QT_BEGIN_NAMESPACE QSSGRenderShadowMap::QSSGRenderShadowMap(const QSSGRef &inContext) : m_context(inContext) {} QSSGRenderShadowMap::~QSSGRenderShadowMap() { m_shadowMapList.clear(); } //static bool isDepthFormat(QSSGRenderTextureFormat format) //{ // switch (format.format) { // case QSSGRenderTextureFormat::Depth16: // case QSSGRenderTextureFormat::Depth24: // case QSSGRenderTextureFormat::Depth32: // case QSSGRenderTextureFormat::Depth24Stencil8: // return true; // default: // return false; // } //} void QSSGRenderShadowMap::addShadowMapEntry(qint32 index, qint32 width, qint32 height, QSSGRenderTextureFormat format, qint32 samples, ShadowMapModes mode, ShadowFilterValues filter) { const QSSGRef &theManager(m_context->resourceManager()); QSSGShadowMapEntry *pEntry = nullptr; if (index < m_shadowMapList.size()) pEntry = &m_shadowMapList[index]; if (pEntry) { if ((nullptr != pEntry->m_depthMap) && (mode == ShadowMapModes::CUBE)) { theManager->release(pEntry->m_depthMap); theManager->release(pEntry->m_depthCopy); theManager->release(pEntry->m_depthRender); pEntry->m_depthCube = theManager->allocateTextureCube(width, height, format, samples); pEntry->m_cubeCopy = theManager->allocateTextureCube(width, height, format, samples); pEntry->m_depthRender = theManager->allocateTexture2D(width, height, QSSGRenderTextureFormat::Depth24Stencil8, samples); pEntry->m_depthMap = nullptr; pEntry->m_depthCopy = nullptr; } else if ((nullptr != pEntry->m_depthCube) && (mode != ShadowMapModes::CUBE)) { theManager->release(pEntry->m_depthCube); theManager->release(pEntry->m_cubeCopy); theManager->release(pEntry->m_depthRender); pEntry->m_depthMap = theManager->allocateTexture2D(width, height, format, samples); pEntry->m_depthCopy = theManager->allocateTexture2D(width, height, format, samples); pEntry->m_depthCube = nullptr; pEntry->m_cubeCopy = nullptr; pEntry->m_depthRender = theManager->allocateTexture2D(width, height, QSSGRenderTextureFormat::Depth24Stencil8, samples); } else if (nullptr != pEntry->m_depthMap) { QSSGTextureDetails theDetails(pEntry->m_depthMap->textureDetails()); // If anything differs about the map we're looking for, let's recreate it. if (theDetails.format != format || theDetails.width != width || theDetails.height != height || theDetails.sampleCount != samples) { // release texture theManager->release(pEntry->m_depthMap); theManager->release(pEntry->m_depthCopy); theManager->release(pEntry->m_depthRender); pEntry->m_depthMap = theManager->allocateTexture2D(width, height, format, samples); pEntry->m_depthCopy = theManager->allocateTexture2D(width, height, format, samples); pEntry->m_depthCube = nullptr; pEntry->m_cubeCopy = nullptr; pEntry->m_depthRender = theManager->allocateTexture2D(width, height, QSSGRenderTextureFormat::Depth24Stencil8, samples); } } else { QSSGTextureDetails theDetails(pEntry->m_depthCube->textureDetails()); // If anything differs about the map we're looking for, let's recreate it. if (theDetails.format != format || theDetails.width != width || theDetails.height != height || theDetails.sampleCount != samples) { // release texture theManager->release(pEntry->m_depthCube); theManager->release(pEntry->m_cubeCopy); theManager->release(pEntry->m_depthRender); pEntry->m_depthCube = theManager->allocateTextureCube(width, height, format, samples); pEntry->m_cubeCopy = theManager->allocateTextureCube(width, height, format, samples); pEntry->m_depthRender = theManager->allocateTexture2D(width, height, QSSGRenderTextureFormat::Depth24Stencil8, samples); pEntry->m_depthMap = nullptr; pEntry->m_depthCopy = nullptr; } } pEntry->m_shadowMapMode = mode; pEntry->m_shadowFilterFlags = filter; } else if (mode == ShadowMapModes::CUBE) { QSSGRef theDepthTex = theManager->allocateTextureCube(width, height, format, samples); QSSGRef theDepthCopy = theManager->allocateTextureCube(width, height, format, samples); QSSGRef theDepthTemp = theManager->allocateTexture2D(width, height, QSSGRenderTextureFormat::Depth24Stencil8, samples); m_shadowMapList.push_back(QSSGShadowMapEntry(index, mode, filter, theDepthTex, theDepthCopy, theDepthTemp)); pEntry = &m_shadowMapList.back(); } else { QSSGRef theDepthMap = theManager->allocateTexture2D(width, height, format, samples); QSSGRef theDepthCopy = theManager->allocateTexture2D(width, height, format, samples); QSSGRef theDepthTemp = theManager->allocateTexture2D(width, height, QSSGRenderTextureFormat::Depth24Stencil8, samples); m_shadowMapList.push_back(QSSGShadowMapEntry(index, mode, filter, theDepthMap, theDepthCopy, theDepthTemp)); pEntry = &m_shadowMapList.back(); } if (pEntry) { // setup some texture settings if (pEntry->m_depthMap) { pEntry->m_depthMap->setMinFilter(QSSGRenderTextureMinifyingOp::Linear); pEntry->m_depthMap->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear); pEntry->m_depthMap->setTextureWrapS(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthMap->setTextureWrapT(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthCopy->setMinFilter(QSSGRenderTextureMinifyingOp::Linear); pEntry->m_depthCopy->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear); pEntry->m_depthCopy->setTextureWrapS(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthCopy->setTextureWrapT(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthRender->setMinFilter(QSSGRenderTextureMinifyingOp::Linear); pEntry->m_depthRender->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear); pEntry->m_depthRender->setTextureWrapS(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthRender->setTextureWrapT(QSSGRenderTextureCoordOp::ClampToEdge); } else { pEntry->m_depthCube->setMinFilter(QSSGRenderTextureMinifyingOp::Linear); pEntry->m_depthCube->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear); pEntry->m_depthCube->setTextureWrapS(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthCube->setTextureWrapT(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_cubeCopy->setMinFilter(QSSGRenderTextureMinifyingOp::Linear); pEntry->m_cubeCopy->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear); pEntry->m_cubeCopy->setTextureWrapS(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_cubeCopy->setTextureWrapT(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthRender->setMinFilter(QSSGRenderTextureMinifyingOp::Linear); pEntry->m_depthRender->setMagFilter(QSSGRenderTextureMagnifyingOp::Linear); pEntry->m_depthRender->setTextureWrapS(QSSGRenderTextureCoordOp::ClampToEdge); pEntry->m_depthRender->setTextureWrapT(QSSGRenderTextureCoordOp::ClampToEdge); } pEntry->m_lightIndex = index; } } QSSGShadowMapEntry *QSSGRenderShadowMap::getShadowMapEntry(int index) { if (index < 0) { Q_UNREACHABLE(); return nullptr; } QSSGShadowMapEntry *pEntry = nullptr; for (int i = 0; i < m_shadowMapList.size(); i++) { pEntry = &m_shadowMapList[i]; if (pEntry->m_lightIndex == quint32(index)) return pEntry; } return nullptr; } QSSGRef QSSGRenderShadowMap::create(const QSSGRef &inContext) { return QSSGRef(new QSSGRenderShadowMap(inContext)); } QT_END_NAMESPACE