/**************************************************************************** ** ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt3D module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "renderviewjobutils_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE using namespace Qt3DCore; namespace Qt3DRender { namespace Render { /*! \internal Searches the best matching Technique from \a effect specified. */ Technique *findTechniqueForEffect(NodeManagers *manager, const TechniqueFilter *techniqueFilter, Effect *effect) { if (!effect) return nullptr; std::vector matchingTechniques; const bool hasInvalidTechniqueFilter = (techniqueFilter == nullptr || techniqueFilter->filters().isEmpty()); // Iterate through the techniques in the effect const auto techniqueIds = effect->techniques(); for (const QNodeId techniqueId : techniqueIds) { Technique *technique = manager->techniqueManager()->lookupResource(techniqueId); // Should be valid, if not there likely a problem with node addition/destruction changes Q_ASSERT(technique); // Check if the technique is compatible with the rendering API // If no techniqueFilter is present, we return the technique as it satisfies OpenGL version if (technique->isCompatibleWithRenderer() && (hasInvalidTechniqueFilter || technique->isCompatibleWithFilters(techniqueFilter->filters()))) matchingTechniques.push_back(technique); } if (matchingTechniques.size() == 0) // We failed to find a suitable technique to use :( return nullptr; if (matchingTechniques.size() == 1) return matchingTechniques.front(); // Several compatible techniques, return technique with highest major and minor version Technique* highest = matchingTechniques.front(); GraphicsApiFilterData filter = *highest->graphicsApiFilter(); for (auto it = matchingTechniques.cbegin() + 1; it < matchingTechniques.cend(); ++it) { if (filter < *(*it)->graphicsApiFilter()) { filter = *(*it)->graphicsApiFilter(); highest = *it; } } return highest; } RenderPassList findRenderPassesForTechnique(NodeManagers *manager, const RenderPassFilter *passFilter, Technique *technique) { Q_ASSERT(manager); Q_ASSERT(technique); RenderPassList passes; const auto passIds = technique->renderPasses(); for (const QNodeId passId : passIds) { RenderPass *renderPass = manager->renderPassManager()->lookupResource(passId); if (renderPass && renderPass->isEnabled()) { bool foundMatch = (!passFilter || passFilter->filters().size() == 0); // A pass filter is present so we need to check for matching criteria if (!foundMatch && renderPass->filterKeys().size() >= passFilter->filters().size()) { // Iterate through the filter criteria and look for render passes with criteria that satisfy them const auto filterKeyIds = passFilter->filters(); for (const QNodeId filterKeyId : filterKeyIds) { foundMatch = false; FilterKey *filterFilterKey = manager->filterKeyManager()->lookupResource(filterKeyId); const auto passFilterKeyIds = renderPass->filterKeys(); for (const QNodeId passFilterKeyId : passFilterKeyIds) { FilterKey *passFilterKey = manager->filterKeyManager()->lookupResource(passFilterKeyId); if ((foundMatch = (*passFilterKey == *filterFilterKey))) break; } if (!foundMatch) { // No match for criterion in any of the render pass' criteria break; } } } if (foundMatch) { // Found a renderpass that satisfies our needs. Add it in order passes << renderPass; } } } return passes; } ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *params, const int nameId) { const ParameterInfoList::const_iterator end = params->cend(); ParameterInfoList::const_iterator it = std::lower_bound(params->cbegin(), end, nameId); if (it != end && it->nameId != nameId) return end; return it; } void addParametersForIds(ParameterInfoList *params, ParameterManager *manager, const Qt3DCore::QNodeIdVector ¶meterIds) { for (const QNodeId paramId : parameterIds) { const HParameter parameterHandle = manager->lookupHandle(paramId); const Parameter *param = manager->data(parameterHandle); ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->nameId()); if (it == params->end() || it->nameId != param->nameId()) params->insert(it, ParameterInfo(param->nameId(), parameterHandle)); } } void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, ParameterManager *manager, Material *material, Effect *effect, Technique *technique) { // The parameters are taken in the following priority order: // // 1) Material // 2) Effect // 3) Technique // // That way a user can override defaults in Effect's and Techniques on a // object manner and a Technique can override global defaults from the Effect. parametersFromParametersProvider(infoList, manager, material); parametersFromParametersProvider(infoList, manager, effect); parametersFromParametersProvider(infoList, manager, technique); } // Only add states with types we don't already have void addStatesToRenderStateSet(RenderStateSet *stateSet, const QList stateIds, RenderStateManager *manager) { for (const Qt3DCore::QNodeId &stateId : stateIds) { RenderStateNode *node = manager->lookupResource(stateId); if (node->isEnabled() && stateSet->canAddStateOfType(node->type())) { stateSet->addState(node->impl()); } } } ParameterInfo::ParameterInfo(const int nameId, const HParameter &handle) : nameId(nameId) , handle(handle) {} bool ParameterInfo::operator<(const ParameterInfo &other) const Q_DECL_NOEXCEPT { return nameId < other.nameId; } bool ParameterInfo::operator<(const int otherNameId) const Q_DECL_NOEXCEPT { return nameId < otherNameId; } } // namespace Render } // namespace Qt3DRender QT_END_NAMESPACE