diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/runtime/q3dsmaterial.cpp | 2 | ||||
-rw-r--r-- | src/runtime/q3dsmaterial_p.h | 1 | ||||
-rw-r--r-- | src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp | 152 |
3 files changed, 106 insertions, 49 deletions
diff --git a/src/runtime/q3dsmaterial.cpp b/src/runtime/q3dsmaterial.cpp index 6255248..468d448 100644 --- a/src/runtime/q3dsmaterial.cpp +++ b/src/runtime/q3dsmaterial.cpp @@ -311,6 +311,8 @@ PropertyElement parsePropertyElement(QXmlStreamReader *r) Q3DSMaterial::ClampType type; if (Q3DSMaterial::convertToClampType(attribute.value(), &type, "clamp type", r)) property.clampType = type; + } else if (attribute.name() == QStringLiteral("stage")) { + property.stage = attribute.value().toString(); } else if (attribute.name() == QStringLiteral("format")) { property.format = attribute.value().toString(); } else if (attribute.name() == QStringLiteral("binding")) { diff --git a/src/runtime/q3dsmaterial_p.h b/src/runtime/q3dsmaterial_p.h index 13b2a7e..45fd7b2 100644 --- a/src/runtime/q3dsmaterial_p.h +++ b/src/runtime/q3dsmaterial_p.h @@ -154,6 +154,7 @@ struct Q3DSV_PRIVATE_EXPORT PropertyElement FilterType magFilterType; FilterType minFilterType; ClampType clampType; + QString stage; // Buffers QString format; diff --git a/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp b/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp index e95aa33..0cc993c 100644 --- a/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp +++ b/src/runtime/shadergenerator/q3dscustommaterialvertexpipeline.cpp @@ -203,54 +203,104 @@ struct ShaderGenerator : public Q3DSCustomMaterialShaderGenerator } } - void generateVertexShader(const QString &shaderName) + bool generateVertexShader(const QString &shaderName) { - Q_UNUSED(shaderName); - // XXX TODO include vertex data (I dont think 3DS even supports this) + QString vertSource; + for (const auto &shader : m_currentMaterial->shaders()) { + if (shader.name == shaderName) + vertSource = shader.shared + shader.vertexShader; + } + if (vertSource.isEmpty() + && shaderName.isEmpty() + && m_currentMaterial->shaders().count() == 1) { + // fallback to first shader + auto shader = m_currentMaterial->shaders().first(); + vertSource = shader.vertexShader; + } - // the pipeline opens/closes up the shaders stages - // XXX add displacement map - vertexGenerator().beginVertexGeneration(nullptr); + if (vertSource.isEmpty() || !vertSource.contains(QStringLiteral("void main()"))) { + vertexGenerator().beginVertexGeneration(nullptr); + return false; + } + Q3DSShaderGeneratorStageFlags theStages(Q3DSAbstractShaderProgramGenerator::defaultFlags()); + programGenerator()->beginProgram(theStages); + vertexGenerator() << "#define VERTEX_SHADER"; + vertexGenerator() << vertSource.toUtf8().constData(); + return true; } - void addProperties(Q3DSAbstractShaderStageGenerator &fragmentShader) + void addProperties(Q3DSDefaultVertexPipeline &vertexShader, + Q3DSAbstractShaderStageGenerator &fragmentShader) { // Add Uniforms from material properties for (auto property : m_currentMaterial->properties()) { - switch (property.type) { - case Q3DS::Boolean: - fragmentShader.addUniform(property.name.toLocal8Bit(), "bool"); - break; - case Q3DS::Long: - fragmentShader.addUniform(property.name.toLocal8Bit(), "int"); - break; - case Q3DS::FloatRange: - case Q3DS::Float: - case Q3DS::FontSize: - fragmentShader.addUniform(property.name.toLocal8Bit(), "float"); - break; - case Q3DS::Float2: - fragmentShader.addUniform(property.name.toLocal8Bit(), "vec2"); - break; - case Q3DS::Vector: - case Q3DS::Scale: - case Q3DS::Rotation: - case Q3DS::Color: - fragmentShader.addUniform(property.name.toLocal8Bit(), "vec3"); - break; - case Q3DS::Texture: - fragmentShader.addUniform(property.name.toLocal8Bit(), "sampler2D"); - break; - case Q3DS::StringList: - fragmentShader.addUniform(property.name.toLocal8Bit(), "int"); - break; - default: - break; + if (property.stage == QStringLiteral("vertex")) { + switch (property.type) { + case Q3DS::Boolean: + vertexShader.addUniform(property.name.toLocal8Bit(), "bool"); + break; + case Q3DS::Long: + vertexShader.addUniform(property.name.toLocal8Bit(), "int"); + break; + case Q3DS::FloatRange: + case Q3DS::Float: + case Q3DS::FontSize: + vertexShader.addUniform(property.name.toLocal8Bit(), "float"); + break; + case Q3DS::Float2: + vertexShader.addUniform(property.name.toLocal8Bit(), "vec2"); + break; + case Q3DS::Vector: + case Q3DS::Scale: + case Q3DS::Rotation: + case Q3DS::Color: + vertexShader.addUniform(property.name.toLocal8Bit(), "vec3"); + break; + case Q3DS::Texture: + vertexShader.addUniform(property.name.toLocal8Bit(), "sampler2D"); + break; + case Q3DS::StringList: + vertexShader.addUniform(property.name.toLocal8Bit(), "int"); + break; + default: + break; + } + } else { + switch (property.type) { + case Q3DS::Boolean: + fragmentShader.addUniform(property.name.toLocal8Bit(), "bool"); + break; + case Q3DS::Long: + fragmentShader.addUniform(property.name.toLocal8Bit(), "int"); + break; + case Q3DS::FloatRange: + case Q3DS::Float: + case Q3DS::FontSize: + fragmentShader.addUniform(property.name.toLocal8Bit(), "float"); + break; + case Q3DS::Float2: + fragmentShader.addUniform(property.name.toLocal8Bit(), "vec2"); + break; + case Q3DS::Vector: + case Q3DS::Scale: + case Q3DS::Rotation: + case Q3DS::Color: + fragmentShader.addUniform(property.name.toLocal8Bit(), "vec3"); + break; + case Q3DS::Texture: + fragmentShader.addUniform(property.name.toLocal8Bit(), "sampler2D"); + break; + case Q3DS::StringList: + fragmentShader.addUniform(property.name.toLocal8Bit(), "int"); + break; + default: + break; + } } } } - void generateFragmentShader(const QString &shaderName) + void generateFragmentShader(const QString &shaderName, bool hasCustomVertexShader) { // Get the shader source from the Q3DSCustomMaterial based // on the name provided. If there is only 1 shader then @@ -291,9 +341,11 @@ struct ShaderGenerator : public Q3DSCustomMaterialShaderGenerator lightmapShadowImage = m_materialInstance->lightmapShadowMap(); hasLightmaps = lightmapIndirectImage || lightmapRadiosityImage || lightmapShadowImage; - vertexGenerator().generateUVCoords(0); - if (hasLightmaps) - vertexGenerator().generateUVCoords(1); + if (!hasCustomVertexShader) { + vertexGenerator().generateUVCoords(0); + if (hasLightmaps) + vertexGenerator().generateUVCoords(1); + } Q3DSDefaultVertexPipeline &vertexShader(vertexGenerator()); Q3DSAbstractShaderStageGenerator &fragmentShader(fragmentGenerator()); @@ -321,13 +373,15 @@ struct ShaderGenerator : public Q3DSCustomMaterialShaderGenerator // and we don't need to add anything. if (srcString.contains(QStringLiteral("void main()"))) { - // Nothing beyond the basics, anyway - vertexShader.generateWorldNormal(); - vertexShader.generateVarTangentAndBinormal(); - vertexShader.generateWorldPosition(); + if (!hasCustomVertexShader) { + // Nothing beyond the basics, anyway + vertexShader.generateWorldNormal(); + vertexShader.generateVarTangentAndBinormal(); + vertexShader.generateWorldPosition(); - vertexShader.generateViewVector(); - addProperties(fragmentShader); + vertexShader.generateViewVector(); + } + addProperties(vertexShader, fragmentShader); return; } @@ -369,7 +423,7 @@ struct ShaderGenerator : public Q3DSCustomMaterialShaderGenerator fragmentShader << "}\n\n"; } - addProperties(fragmentShader); + addProperties(vertexShader, fragmentShader); // setup main vertexGenerator().beginFragmentGeneration(); @@ -429,8 +483,8 @@ struct ShaderGenerator : public Q3DSCustomMaterialShaderGenerator Qt3DRender::QShaderProgram *generateCustomMaterialShader(const QString &shaderName) { - generateVertexShader(shaderName); - generateFragmentShader(shaderName); + bool hasCustomVertexShader = generateVertexShader(shaderName); + generateFragmentShader(shaderName, hasCustomVertexShader); vertexGenerator().endVertexGeneration(); vertexGenerator().endFragmentGeneration(); |