diff options
author | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-08-06 16:09:47 +0200 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-08-08 12:55:44 +0000 |
commit | 038ab21c9811351f632a457ff5a931e55d21f17a (patch) | |
tree | 41c963b49584df0b1510c25472169bb625361c9c /src/plugins/sceneparsers/gltf/gltfparser.cpp | |
parent | a3fc4b556c6cac9a7e048493f5136a4ee75e1459 (diff) |
glTF: Support generating and using Core profile and GL2 shaders
This change effects both the qgltf tool and the gltfparser.
For the qgltf tool I change the way core profile shaders are defined.
Rather than adding an additional property to the shader object, I create
the necessary shaders, programs, and techniques, as well as add an
additional two properties to the Material so that that multiple
techniques can be used. By default the shaders support OpenGL ES2 and
is compatible with the glTF 0.8 standard.
For the gltfparser, I now create additional QTechniques from the two new
properties attached to the material object when they exist. This allows
for the use of OpenGLFilters to choose which technique to use under
certain situations. So now it is possible to render modules processed
with qgltf in the OpenGL Core profile senario.
Change-Id: Iae10f93a03c29a7bb6fe0a3dfd0d568ba0043f12
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/plugins/sceneparsers/gltf/gltfparser.cpp')
-rw-r--r-- | src/plugins/sceneparsers/gltf/gltfparser.cpp | 84 |
1 files changed, 72 insertions, 12 deletions
diff --git a/src/plugins/sceneparsers/gltf/gltfparser.cpp b/src/plugins/sceneparsers/gltf/gltfparser.cpp index ba39e74ba..711a03c86 100644 --- a/src/plugins/sceneparsers/gltf/gltfparser.cpp +++ b/src/plugins/sceneparsers/gltf/gltfparser.cpp @@ -63,6 +63,7 @@ #include <Qt3DRenderer/QGeometry> #include <Qt3DRenderer/QGeometryRenderer> #include <Qt3DRenderer/QMaterial> +#include <Qt3DRenderer/QOpenGLFilter> #include <Qt3DRenderer/QParameter> #include <Qt3DRenderer/QParameterMapping> #include <Qt3DRenderer/QPolygonOffset> @@ -142,6 +143,8 @@ const QString KEY_ASPECT_RATIO = QStringLiteral("aspect_ratio"); const QString KEY_VALUE = QStringLiteral("value"); const QString KEY_ENABLE = QStringLiteral("enable"); const QString KEY_FUNCTIONS = QStringLiteral("functions"); +const QString KEY_TECHNIQUE_CORE = QStringLiteral("techniqueCore"); +const QString KEY_TECHNIQUE_GL2 = QStringLiteral("techniqueGL2"); } // of anonymous namespace @@ -443,6 +446,17 @@ QString GLTFParser::standardAttributeNameFromSemantic(const QString &semantic) return QString(); } +QParameter *GLTFParser::parameterFromTechnique(QTechnique *technique, const QString ¶meterName) +{ + Q_FOREACH (QParameter *parameter, technique->parameters()) { + if (parameter->name() == parameterName) { + return parameter; + } + } + + return Q_NULLPTR; +} + QEntity* GLTFParser::defaultScene() { if (m_defaultScene.isEmpty()) { @@ -467,22 +481,65 @@ QMaterial* GLTFParser::material(const QString &id) QJsonObject jsonObj = mats.value(id).toObject(); QJsonObject tech = jsonObj.value(KEY_INSTANCE_TECHNIQUE).toObject(); - QString tname = tech.value(KEY_TECHNIQUE).toString(); - if (!m_techniques.contains(tname)) { - qCWarning(GLTFParserLog) << "unknown technique" << tname + + //Default ES2 Technique + QString techniqueName = tech.value(KEY_TECHNIQUE).toString(); + if (!m_techniques.contains(techniqueName)) { + qCWarning(GLTFParserLog) << "unknown technique" << techniqueName << "for material" << id << "in GLTF file" << m_basePath; return NULL; } + QTechnique *technique = m_techniques.value(techniqueName); + technique->openGLFilter()->setApi(QOpenGLFilter::ES); + technique->openGLFilter()->setMajorVersion(2); + technique->openGLFilter()->setMinorVersion(0); + technique->openGLFilter()->setProfile(QOpenGLFilter::None); + + + //Optional Core technique + QTechnique *coreTechnique = Q_NULLPTR; + QTechnique *gl2Technique = Q_NULLPTR; + QString coreTechniqueName = tech.value(KEY_TECHNIQUE_CORE).toString(); + if (!coreTechniqueName.isNull()) { + if (!m_techniques.contains(coreTechniqueName)) { + qCWarning(GLTFParserLog) << "unknown technique" << coreTechniqueName + << "for material" << id << "in GLTF file" << m_basePath; + } else { + coreTechnique = m_techniques.value(coreTechniqueName); + coreTechnique->openGLFilter()->setApi(QOpenGLFilter::Desktop); + coreTechnique->openGLFilter()->setMajorVersion(3); + coreTechnique->openGLFilter()->setMinorVersion(1); + coreTechnique->openGLFilter()->setProfile(QOpenGLFilter::Core); + } + } + //Optional GL2 technique + QString gl2TechniqueName = tech.value(KEY_TECHNIQUE_GL2).toString(); + if (!gl2TechniqueName.isNull()) { + if (!m_techniques.contains(gl2TechniqueName)) { + qCWarning(GLTFParserLog) << "unknown technique" << gl2TechniqueName + << "for material" << id << "in GLTF file" << m_basePath; + } else { + gl2Technique = m_techniques.value(gl2TechniqueName); + gl2Technique->openGLFilter()->setApi(QOpenGLFilter::Desktop); + gl2Technique->openGLFilter()->setMajorVersion(2); + gl2Technique->openGLFilter()->setMinorVersion(0); + gl2Technique->openGLFilter()->setProfile(QOpenGLFilter::None); + } + } + - QTechnique *technique = m_techniques.value(tname); // glTF doesn't deal in effects, but we need a trivial one to wrap // up our techniques // However we need to create a unique effect for each material instead // of caching because QMaterial does not keep up with effects // its not the parent of. QEffect* effect = new QEffect; - effect->setObjectName(tname); + effect->setObjectName(techniqueName); effect->addTechnique(technique); + if (coreTechnique != Q_NULLPTR) + effect->addTechnique(coreTechnique); + if (gl2Technique != Q_NULLPTR) + effect->addTechnique(gl2Technique); QMaterial* mat = new QMaterial; mat->setEffect(effect); @@ -491,15 +548,18 @@ QMaterial* GLTFParser::material(const QString &id) QJsonObject values = tech.value(KEY_VALUES).toObject(); Q_FOREACH (QString vName, values.keys()) { - QParameter *param = Q_NULLPTR; - Q_FOREACH (QParameter *parameter, technique->parameters()) { - if (parameter->name() == vName) { - param = parameter; - break; - } + QParameter *param = parameterFromTechnique(technique, vName); + + if (param == Q_NULLPTR && coreTechnique != Q_NULLPTR) { + param = parameterFromTechnique(coreTechnique, vName); } + + if (param == Q_NULLPTR && gl2Technique != Q_NULLPTR) { + param = parameterFromTechnique(gl2Technique, vName); + } + if (param == Q_NULLPTR) { - qCWarning(GLTFParserLog) << "unknown parameter:" << vName << "in technique" << tname + qCWarning(GLTFParserLog) << "unknown parameter:" << vName << "in technique" << techniqueName << "processing material" << id; continue; } |