Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3D] Unify some some shader code #58114

Merged
merged 5 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 30 additions & 27 deletions src/3d/materials/qgsgoochmaterialsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "qgsgoochmaterialsettings.h"
#include "qgscolorutils.h"
#include "qgs3dutils.h"

#include <Qt3DExtras/QGoochMaterial>
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Expand Down Expand Up @@ -113,24 +114,7 @@ Qt3DRender::QMaterial *QgsGoochMaterialSettings::toMaterial( QgsMaterialSettings
case QgsMaterialSettingsRenderingTechnique::TrianglesWithFixedTexture:
case QgsMaterialSettingsRenderingTechnique::TrianglesFromModel:
{
if ( dataDefinedProperties().hasActiveProperties() )
return dataDefinedMaterial();
Qt3DExtras::QGoochMaterial *material = new Qt3DExtras::QGoochMaterial;
material->setDiffuse( mDiffuse );
material->setWarm( mWarm );
material->setCool( mCool );

material->setSpecular( mSpecular );
material->setShininess( mShininess );
material->setAlpha( mAlpha );
material->setBeta( mBeta );

if ( context.isSelected() )
{
// update the material with selection colors
material->setDiffuse( context.selectionColor() );
}
return material;
return buildMaterial( context );
}

case QgsMaterialSettingsRenderingTechnique::Lines:
Expand Down Expand Up @@ -234,11 +218,11 @@ void QgsGoochMaterialSettings::applyDataDefinedToGeometry( Qt3DQGeometry *geomet
dataBuffer->setData( data );
}

Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const
Qt3DRender::QMaterial *QgsGoochMaterialSettings::buildMaterial( const QgsMaterialContext &context ) const
{
Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial;

Qt3DRender::QEffect *eff = new Qt3DRender::QEffect( material );
Qt3DRender::QEffect *effect = new Qt3DRender::QEffect( material );

Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
Expand All @@ -253,11 +237,30 @@ Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const
Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram();

//Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/goochDataDefined.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
const QUrl urlFrag( QStringLiteral( "qrc:/shaders/goochDataDefined.frag" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) );
const QByteArray fragmentShaderCode = Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/gooch.frag" ) ) );

if ( dataDefinedProperties().hasActiveProperties() )
{
//Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/goochDataDefined.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );

const QByteArray finalFragmentShaderCode = Qgs3DUtils::addDefinesToShaderCode( fragmentShaderCode, QStringList( {"DATA_DEFINED"} ) );
shaderProgram->setFragmentShaderCode( finalFragmentShaderCode );
}
else
{
//Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/default.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
shaderProgram->setFragmentShaderCode( fragmentShaderCode );

const QColor diffuseColor = context.isSelected() ? context.selectionColor() : mDiffuse;
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "kd" ), diffuseColor ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "ks" ), mSpecular ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "kblue" ), mCool ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "kyellow" ), mWarm ) );
}

renderPass->setShaderProgram( shaderProgram );
technique->addRenderPass( renderPass );
Expand All @@ -266,8 +269,8 @@ Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const
technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "alpha" ), mAlpha ) );
technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "beta" ), mBeta ) );

eff->addTechnique( technique );
material->setEffect( eff );
effect->addTechnique( technique );
material->setEffect( effect );

return material;
}
2 changes: 1 addition & 1 deletion src/3d/materials/qgsgoochmaterialsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings
float mBeta = 0.5f;

//! Constructs a material from shader files
Qt3DRender::QMaterial *dataDefinedMaterial() const;
Qt3DRender::QMaterial *buildMaterial( const QgsMaterialContext &context ) const;
};


Expand Down
22 changes: 2 additions & 20 deletions src/3d/materials/qgsmetalroughmaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
***************************************************************************/

#include "qgsmetalroughmaterial.h"
#include "qgs3dutils.h"
#include <Qt3DRender/QParameter>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QTechnique>
Expand Down Expand Up @@ -198,25 +199,6 @@ void QgsMetalRoughMaterial::setTextureScale( float textureScale )
mTextureScaleParameter->setValue( textureScale );
}

QByteArray addDefinesToShaderCode( const QByteArray &shaderCode, const QStringList &defines )
{
// There is one caveat to take care of - GLSL source code needs to start with #version as
// a first directive, otherwise we get the old GLSL 100 version. So we can't just prepend the
// shader source code, but insert our defines at the right place.

QStringList defineLines;
for ( const QString &define : defines )
defineLines += "#define " + define + "\n";

QString definesText = defineLines.join( QString() );

QByteArray newShaderCode = shaderCode;
int versionIndex = shaderCode.indexOf( "#version " );
int insertionIndex = versionIndex == -1 ? 0 : shaderCode.indexOf( '\n', versionIndex + 1 ) + 1;
newShaderCode.insert( insertionIndex, definesText.toLatin1() );
return newShaderCode;
}

void QgsMetalRoughMaterial::init()
{
QObject::connect( mBaseColorParameter, &Qt3DRender::QParameter::valueChanged,
Expand Down Expand Up @@ -282,7 +264,7 @@ void QgsMetalRoughMaterial::updateFragmentShader()
if ( mFlatShading )
defines += "FLAT_SHADING";

QByteArray finalShaderCode = addDefinesToShaderCode( fragmentShaderCode, defines );
QByteArray finalShaderCode = Qgs3DUtils::addDefinesToShaderCode( fragmentShaderCode, defines );
mMetalRoughGL3Shader->setFragmentShaderCode( finalShaderCode );
}

Expand Down
106 changes: 40 additions & 66 deletions src/3d/materials/qgsphongmaterialsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "qgsphongmaterialsettings.h"
#include "qgscolorutils.h"
#include "qgs3dutils.h"

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <Qt3DRender/QAttribute>
Expand Down Expand Up @@ -113,10 +114,7 @@ Qt3DRender::QMaterial *QgsPhongMaterialSettings::toMaterial( QgsMaterialSettings
case QgsMaterialSettingsRenderingTechnique::TrianglesWithFixedTexture:
case QgsMaterialSettingsRenderingTechnique::TrianglesFromModel:
{
if ( dataDefinedProperties().hasActiveProperties() )
return dataDefinedMaterial();
else
return constantColorMaterial( context );
return buildMaterial( context );
}

case QgsMaterialSettingsRenderingTechnique::Lines:
Expand Down Expand Up @@ -255,11 +253,11 @@ void QgsPhongMaterialSettings::applyDataDefinedToGeometry( Qt3DQGeometry *geomet
dataBuffer->setData( data );
}

Qt3DRender::QMaterial *QgsPhongMaterialSettings::constantColorMaterial( const QgsMaterialContext &context ) const
Qt3DRender::QMaterial *QgsPhongMaterialSettings::buildMaterial( const QgsMaterialContext &context ) const
{
Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial;

Qt3DRender::QEffect *eff = new Qt3DRender::QEffect( material );
Qt3DRender::QEffect *effect = new Qt3DRender::QEffect( material );

Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
Expand All @@ -274,72 +272,48 @@ Qt3DRender::QMaterial *QgsPhongMaterialSettings::constantColorMaterial( const Qg
Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram();

//Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/phongConstant.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
const QUrl urlFrag( QStringLiteral( "qrc:/shaders/phongConstant.frag" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) );

renderPass->setShaderProgram( shaderProgram );
technique->addRenderPass( renderPass );

const QColor ambient = context.isSelected() ? context.selectionColor().darker() : mAmbient;
const QColor diffuse = context.isSelected() ? context.selectionColor() : mDiffuse;

eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "shininess" ), static_cast< float >( mShininess ) ) );
eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "opacity" ), static_cast< float >( mOpacity ) ) );
eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "ambientColor" ),
QColor::fromRgbF( ambient.redF() * mAmbientCoefficient,
ambient.greenF() * mAmbientCoefficient,
ambient.blueF() * mAmbientCoefficient ) ) );
eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "diffuseColor" ),
QColor::fromRgbF( diffuse.redF() * mDiffuseCoefficient,
diffuse.greenF() * mDiffuseCoefficient,
diffuse.blueF() * mDiffuseCoefficient ) ) );
eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "specularColor" ),
QColor::fromRgbF( mSpecular.redF() * mSpecularCoefficient,
mSpecular.greenF() * mSpecularCoefficient,
mSpecular.blueF() * mSpecularCoefficient ) ) );

eff->addTechnique( technique );
material->setEffect( eff );

return material;
}

Qt3DRender::QMaterial *QgsPhongMaterialSettings::dataDefinedMaterial() const
{
Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial;

Qt3DRender::QEffect *eff = new Qt3DRender::QEffect( material );
const QByteArray fragmentShaderCode = Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/phong.frag" ) ) );

Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique;
technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
technique->graphicsApiFilter()->setMajorVersion( 3 );
technique->graphicsApiFilter()->setMinorVersion( 3 );
Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey();
filterKey->setName( QStringLiteral( "renderingStyle" ) );
filterKey->setValue( QStringLiteral( "forward" ) );
technique->addFilterKey( filterKey );

Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass();
Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram();

//Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/phongDataDefined.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
const QUrl urlFrag( QStringLiteral( "qrc:/shaders/phongDataDefined.frag" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) );

renderPass->setShaderProgram( shaderProgram );
technique->addRenderPass( renderPass );
if ( dataDefinedProperties().hasActiveProperties() )
{
// Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/phongDataDefined.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
const QByteArray finalFragmentShaderCode = Qgs3DUtils::addDefinesToShaderCode( fragmentShaderCode, QStringList( {"DATA_DEFINED"} ) );
shaderProgram->setFragmentShaderCode( finalFragmentShaderCode );
}
else
{
// Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/default.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
shaderProgram->setFragmentShaderCode( fragmentShaderCode );

const QColor ambient = context.isSelected() ? context.selectionColor().darker() : mAmbient;
const QColor diffuse = context.isSelected() ? context.selectionColor() : mDiffuse;

effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "ambientColor" ),
QColor::fromRgbF( ambient.redF() * mAmbientCoefficient,
ambient.greenF() * mAmbientCoefficient,
ambient.blueF() * mAmbientCoefficient ) ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "diffuseColor" ),
QColor::fromRgbF( diffuse.redF() * mDiffuseCoefficient,
diffuse.greenF() * mDiffuseCoefficient,
diffuse.blueF() * mDiffuseCoefficient ) ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "specularColor" ),
QColor::fromRgbF( mSpecular.redF() * mSpecularCoefficient,
mSpecular.greenF() * mSpecularCoefficient,
mSpecular.blueF() * mSpecularCoefficient ) ) );
}

eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "shininess" ), static_cast< float >( mShininess ) ) );
eff->addParameter( new Qt3DRender::QParameter( QStringLiteral( "opacity" ), static_cast< float >( mOpacity ) ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "shininess" ), static_cast< float >( mShininess ) ) );
effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "opacity" ), static_cast< float >( mOpacity ) ) );

eff->addTechnique( technique );
material->setEffect( eff );
effect->addTechnique( technique );
material->setEffect( effect );

return material;
}
3 changes: 1 addition & 2 deletions src/3d/materials/qgsphongmaterialsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@ class _3D_EXPORT QgsPhongMaterialSettings : public QgsAbstractMaterialSettings
double mOpacity = 1.0;

//! Constructs a material from shader files
Qt3DRender::QMaterial *constantColorMaterial( const QgsMaterialContext &context ) const;
Qt3DRender::QMaterial *dataDefinedMaterial() const;
Qt3DRender::QMaterial *buildMaterial( const QgsMaterialContext &context ) const;
};


Expand Down
2 changes: 1 addition & 1 deletion src/3d/materials/qgsphongtexturedmaterialsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Qt3DRender::QMaterial *QgsPhongTexturedMaterialSettings::toMaterial( QgsMaterial
Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram();

//Load shader programs
const QUrl urlVert( QStringLiteral( "qrc:/shaders/diffuseSpecular.vert" ) );
ptitjano marked this conversation as resolved.
Show resolved Hide resolved
const QUrl urlVert( QStringLiteral( "qrc:/shaders/default.vert" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) );
const QUrl urlFrag( QStringLiteral( "qrc:/shaders/diffuseSpecular.frag" ) );
shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) );
Expand Down
20 changes: 20 additions & 0 deletions src/3d/qgs3dutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,3 +902,23 @@ Qt3DRender::QCullFace::CullingMode Qgs3DUtils::qt3DcullingMode( Qgs3DTypes::Cull
}
return Qt3DRender::QCullFace::NoCulling;
}


QByteArray Qgs3DUtils::addDefinesToShaderCode( const QByteArray &shaderCode, const QStringList &defines )
{
// There is one caveat to take care of - GLSL source code needs to start with #version as
// a first directive, otherwise we get the old GLSL 100 version. So we can't just prepend the
// shader source code, but insert our defines at the right place.

QStringList defineLines;
for ( const QString &define : defines )
defineLines += "#define " + define + "\n";

QString definesText = defineLines.join( QString() );

QByteArray newShaderCode = shaderCode;
int versionIndex = shaderCode.indexOf( "#version " );
int insertionIndex = versionIndex == -1 ? 0 : shaderCode.indexOf( '\n', versionIndex + 1 ) + 1;
newShaderCode.insert( insertionIndex, definesText.toLatin1() );
return newShaderCode;
}
10 changes: 10 additions & 0 deletions src/3d/qgs3dutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ class _3D_EXPORT Qgs3DUtils
* \since QGIS 3.34
*/
static Qt3DRender::QCullFace::CullingMode qt3DcullingMode( Qgs3DTypes::CullingMode mode );

/**
* Inserts some define macros into a shader source code.
*
* \param shaderCode shader code
* \param defines list of defines to add
*
* \since QGIS 3.40
*/
static QByteArray addDefinesToShaderCode( const QByteArray &shaderCode, const QStringList &defines );
};

#endif // QGS3DUTILS_H
7 changes: 2 additions & 5 deletions src/3d/shaders.qrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<RCC>
<qresource prefix="/">
<file>shaders/diffuseSpecular.frag</file>
<file>shaders/diffuseSpecular.vert</file>
<file>shaders/instanced.vert</file>
<file>shaders/light.inc.frag</file>
<file>shaders/lines.vert</file>
Expand All @@ -24,17 +23,15 @@
<file>shaders/preview.vert</file>
<file>shaders/preview.frag</file>
<file>shaders/phongDataDefined.vert</file>
<file>shaders/phongDataDefined.frag</file>
<file>shaders/goochDataDefined.frag</file>
nyalldawson marked this conversation as resolved.
Show resolved Hide resolved
<file>shaders/phong.frag</file>
<file>shaders/gooch.frag</file>
<file>shaders/goochDataDefined.vert</file>
<file>shaders/depth_render.frag</file>
<file>shaders/depth_render.vert</file>
<file>shaders/ssao_factor_render.frag</file>
<file>shaders/ssao_factor_render.vert</file>
<file>shaders/ssao_factor_blur.frag</file>
<file>shaders/ssao_factor_blur.vert</file>
<file>shaders/phongConstant.frag</file>
<file>shaders/phongConstant.vert</file>
<file>shaders/metalrough.frag</file>
<file>shaders/default.vert</file>
</qresource>
Expand Down
Loading
Loading