/****************************************************************************
**
** 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 "qquick3ddefaultmaterial_p.h"
#include "qquick3dobject_p_p.h"

#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>

QT_BEGIN_NAMESPACE


/*!
    \qmltype DefaultMaterial
    \inherits Material
    \inqmlmodule QtQuick3D
    \brief Defines a Material generated depending on which properties are set.

    Before a Model can be rendered in a scene, it must have at least one
    material to define how the mesh is shaded. The DefaultMaterial is the
    easiest way to define such a material. Even if you define a
    DefaultMaterial with no properties set, a valid mesh will be rendered,
    because the mesh defines some sensible defaults.

    As you change the properties of the DefaultMaterial, behind the scenes
    new shaders are generated, and the property values are bound. The
    complexity of a shader depends on a combination of the properties that
    are set on it, and the context of the scene itself.
*/

/*!
    \qmlproperty enumeration DefaultMaterial::lighting

    This property defines which lighting method is used when generating this
    material.

    The default value is \c DefaultMaterial.FragmentLighting

    When using \c DefaultMaterial.FragmentLighting, diffuse and specular lighting are
    calculated for each rendered pixel. Certain effects (such as a Fresnel or bump map) require
    \c DefaultMaterial.FragmentLighting to work.

    When using \c DefaultMaterial.NoLighting no lighting is calculated. This
    mode is (predictably) very fast, and quite effective when image maps are
    used that do not need to be shaded by lighting.

    \value DefaultMaterial.NoLighting No lighting is calculated.
    \value DefaultMaterial.FragmentLighting Per-fragment lighting is calculated.
*/

/*!
    \qmlproperty enumeration DefaultMaterial::blendMode

    This property determines how the colors of the model rendered blend with
    those behind it.

    \value DefaultMaterial.SourceOver Default blend mode. Opaque objects occlude
        objects behind them.
    \value DefaultMaterial.Screen Colors are blended using an inverted multiply,
        producing a lighter result. This blend mode is order-independent; if you are
        using semi-opaque objects and experiencing \e popping as faces or models sort
        differently, using Screen blending is one way to produce results without
        popping.
    \value DefaultMaterial.Multiply Colors are blended using a multiply,
        producing a darker result. This blend mode is also order-independent.
    \value DefaultMaterial.Overlay A mix of Multiply and Screen modes, producing
        a result with higher contrast.
    \value DefaultMaterial.ColorBurn Colors are blended by inverted division where
        the result also is inverted, producing a darker result. Darker than Multiply.
    \value DefaultMaterial.ColorDodge Colors are blended by inverted division,
        producing a lighter result. Lighter than Screen.

*/

/*!
    \qmlproperty color DefaultMaterial::diffuseColor

    This property determines the base color for the material. Set to black to
    create a purely-specular material (e.g. metals or mirrors).
 */

/*!
    \qmlproperty Texture DefaultMaterial::diffuseMap

    This property defines a Texture to apply to the material. Using Texture
    with transparency will also apply the alpha channel as an opacity map.
 */

/*!
    \qmlproperty real DefaultMaterial::emissiveFactor

    This property determines the amount of self-illumination from the material.
    In a scene with black ambient lighting, a material with an emissive factor of 0
    will appear black wherever the light does not shine on it. Turning the emissive
    factor to 1 will cause the material to appear in its diffuse color instead.

    \note When you want a material to not be affected by lighting, instead of
    using 100% emissiveFactor consider setting the lightingMode to
    /c DefaultMaterial.NoLighting for a performance benefit.
*/

/*!
    \qmlproperty Texture DefaultMaterial::emissiveMap

    This property sets a Texture to be used to set the emissive factor for
    different parts of the material. Using a grayscale image will not affect the
    color of the result, while using a color image will produce glowing regions
    with the color affected by the emissive map.
*/

/*!
    \qmlproperty color DefaultMaterial::emissiveColor

    This property determines the color of self-illumination for this material.
*/

/*!
    \qmlproperty Texture DefaultMaterial::specularReflectionMap

    This property sets a Texture used for specular highlights on the material.
    By default the Texture is applied using environmental mapping (not UV
    mapping): as you rotate the model the map will appear as though it is
    reflecting from the environment. Specular Reflection maps are an easy way to
    add a high-quality look with relatively low cost.

    \note Using a Light Probe in your SceneEnvironment for image-based lighting
    will automatically use that image as the specular reflection.

    \note Crisp images cause your material to look very glossy. The more you
    blur your image, the softer your material will appear.
*/

/*!
    \qmlproperty Texture DefaultMaterial::specularMap

    This property defines a RGB Texture to modulate the amount and the color of
    specularity across the surface of the material. These values are multiplied
    by the specularAmount.
*/

/*!
    \qmlproperty enumeration DefaultMaterial::specularModel

    This property determines which functions are used to calculate specular
    highlights for lights in the scene.

    \value DefaultMaterial::Default Specular lighting uses default lighting model.
    \value DefaultMaterial::KGGX Specular lighting uses GGX lighting model.
    \value DefaultMaterial::KWard Specular lighting uses Ward lighting model.
*/

/*!
    \qmlproperty real DefaultMaterial::specularTint

    This property defines a color used to adjust the specular reflections.
    Use white for no effect
*/

/*!
    \qmlproperty real DefaultMaterial::indexOfRefraction

    This property controls what angles of reflections are affected by the
    fresnelPower.
*/

/*!
    \qmlproperty real DefaultMaterial::fresnelPower

    This property decreases head-on reflections (looking directly at the
    surface) while maintaining reflections seen at grazing angles.

*/

/*!
    \qmlproperty real DefaultMaterial::specularAmount

    This property controls the strength of specularity (highlights and
    reflections).

    \note This property does not affect the \l specularReflectionMap, but does
    affect the amount of reflections from a scene's SceneEnvironment::lightProbe.

    \note Unless your mesh is high resolution, you may need to use
    \c DefaultMaterial.FragmentLighting to get good specular highlights from scene
    lights.
*/

/*!
    \qmlproperty real DefaultMaterial::specularRoughness

    This property controls the size of the specular highlight generated from
    lights, and the clarity of reflections in general. Larger values increase
    the roughness, softening specular highlights and blurring reflections.
*/

/*!
    \qmlproperty Texture DefaultMaterial::roughnessMap

    This property defines a Texture to control the specular roughness of the
    material.
*/

/*!
    \qmlproperty real DefaultMaterial::opacity

    This property drops the opacity of just this material, separate from the
    model.
*/

/*!
    \qmlproperty Texture DefaultMaterial::opacityMap

    This property defines a Texture used to control the opacity differently for
    different parts of the material.

    \note This must be an image format with transparency for the opacity to be
     applied.
*/

/*!
    \qmlproperty Texture DefaultMaterial::bumpMap

    This property defines a grayscale Texture to simulate fine geometry
    displacement across the surface of the material. Brighter pixels indicate
    raised regions. The amount of the effect is controlled by the
    \l bumpAmount property.

    \note bump maps will not affect the silhouette of a model. Use a
    displacementMap if this is required.

*/

/*!
    \qmlproperty real DefaultMaterial::bumpAmount

    This property controls the amount of simulated displacement for the
    \l bumpMap or \l normalMap.

*/

/*!
    \qmlproperty Texture DefaultMaterial::normalMap

    This property defines a RGB image used to simulate fine geometry
    displacement across the surface of the material. The RGB channels indicate
    XYZ normal deviations. The amount of the effect is controlled by the
    \l bumpAmount property.

    \note Normal maps will not affect the silhouette of a model. Use a
    displacementMap if this is required.
*/

/*!
    \qmlproperty Texture DefaultMaterial::translucencyMap

    This property defines a grayscale Texture controlling how much light can
    pass through the material from behind.
*/

/*!
    \qmlproperty real DefaultMaterial::translucentFalloff

    This property defines the amount of falloff for the translucency based on the
    angle of the normals of the object to the light source.
*/

/*!
    \qmlproperty real DefaultMaterial::diffuseLightWrap

    This property determines the amount of light wrap for the translucency map.
    A value of 0 will not wrap the light at all, while a value of 1 will wrap
    the light all around the object.
*/

/*!
    \qmlproperty bool DefaultMaterial::vertexColorsEnabled

    When this property is enabled, the material will use vertex colors from the
    mesh. These will be multiplied by any other colors specified for the
    material.
*/

QQuick3DDefaultMaterial::QQuick3DDefaultMaterial()
    : m_diffuseColor(Qt::white)
    , m_emissiveColor(Qt::white)
    , m_specularTint(Qt::white)
{}

QQuick3DDefaultMaterial::~QQuick3DDefaultMaterial()
{
    for(auto connection : m_connections.values())
        disconnect(connection);
}

static void updatePropertyListener(QQuick3DObject *newO, QQuick3DObject *oldO, QQuick3DSceneManager *window, QQuick3DDefaultMaterial::ConnectionMap &connections, std::function<void(QQuick3DObject *o)> callFn) {
    // disconnect previous destruction listern
    if (oldO) {
        if (window)
            QQuick3DObjectPrivate::get(oldO)->derefSceneManager();

        auto connection = connections.find(oldO);
        if (connection != connections.end()) {
            QObject::disconnect(connection.value());
            connections.erase(connection);
        }
    }

    // listen for new map's destruction
    if (newO) {
        if (window)
            QQuick3DObjectPrivate::get(newO)->refSceneManager(window);
        auto connection = QObject::connect(newO, &QObject::destroyed, [callFn](){
            callFn(nullptr);
        });
        connections.insert(newO, connection);
    }
}

QQuick3DObject::Type QQuick3DDefaultMaterial::type() const
{
    return QQuick3DObject::DefaultMaterial;
}

QQuick3DDefaultMaterial::Lighting QQuick3DDefaultMaterial::lighting() const
{
    return m_lighting;
}

QQuick3DDefaultMaterial::BlendMode QQuick3DDefaultMaterial::blendMode() const
{
    return m_blendMode;
}

QColor QQuick3DDefaultMaterial::diffuseColor() const
{
    return m_diffuseColor;
}

QQuick3DTexture *QQuick3DDefaultMaterial::diffuseMap() const
{
    return m_diffuseMap;
}

float QQuick3DDefaultMaterial::emissiveFactor() const
{
    return m_emissiveFactor;
}

QQuick3DTexture *QQuick3DDefaultMaterial::emissiveMap() const
{
    return m_emissiveMap;
}

QColor QQuick3DDefaultMaterial::emissiveColor() const
{
    return m_emissiveColor;
}

QQuick3DTexture *QQuick3DDefaultMaterial::specularReflectionMap() const
{
    return m_specularReflectionMap;
}

QQuick3DTexture *QQuick3DDefaultMaterial::specularMap() const
{
    return m_specularMap;
}

QQuick3DDefaultMaterial::SpecularModel QQuick3DDefaultMaterial::specularModel() const
{
    return m_specularModel;
}

QColor QQuick3DDefaultMaterial::specularTint() const
{
    return m_specularTint;
}

float QQuick3DDefaultMaterial::indexOfRefraction() const
{
    return m_indexOfRefraction;
}

float QQuick3DDefaultMaterial::fresnelPower() const
{
    return m_fresnelPower;
}

float QQuick3DDefaultMaterial::specularAmount() const
{
    return m_specularAmount;
}

float QQuick3DDefaultMaterial::specularRoughness() const
{
    return m_specularRoughness;
}

QQuick3DTexture *QQuick3DDefaultMaterial::roughnessMap() const
{
    return m_roughnessMap;
}

float QQuick3DDefaultMaterial::opacity() const
{
    return m_opacity;
}

QQuick3DTexture *QQuick3DDefaultMaterial::opacityMap() const
{
    return m_opacityMap;
}

QQuick3DTexture *QQuick3DDefaultMaterial::bumpMap() const
{
    return m_bumpMap;
}

float QQuick3DDefaultMaterial::bumpAmount() const
{
    return m_bumpAmount;
}

QQuick3DTexture *QQuick3DDefaultMaterial::normalMap() const
{
    return m_normalMap;
}

QQuick3DTexture *QQuick3DDefaultMaterial::translucencyMap() const
{
    return m_translucencyMap;
}

float QQuick3DDefaultMaterial::translucentFalloff() const
{
    return m_translucentFalloff;
}

float QQuick3DDefaultMaterial::diffuseLightWrap() const
{
    return m_diffuseLightWrap;
}

bool QQuick3DDefaultMaterial::vertexColorsEnabled() const
{
    return m_vertexColorsEnabled;
}

void QQuick3DDefaultMaterial::markAllDirty()
{
    m_dirtyAttributes = 0xffffffff;
    QQuick3DMaterial::markAllDirty();
}

void QQuick3DDefaultMaterial::setLighting(QQuick3DDefaultMaterial::Lighting lighting)
{
    if (m_lighting == lighting)
        return;

    m_lighting = lighting;
    emit lightingChanged(m_lighting);
    markDirty(LightingModeDirty);
}

void QQuick3DDefaultMaterial::setBlendMode(QQuick3DDefaultMaterial::BlendMode blendMode)
{
    if (m_blendMode == blendMode)
        return;

    m_blendMode = blendMode;
    emit blendModeChanged(m_blendMode);
    markDirty(BlendModeDirty);
}

void QQuick3DDefaultMaterial::setDiffuseColor(QColor diffuseColor)
{
    if (m_diffuseColor == diffuseColor)
        return;

    m_diffuseColor = diffuseColor;
    emit diffuseColorChanged(m_diffuseColor);
    markDirty(DiffuseDirty);
}

void QQuick3DDefaultMaterial::setDiffuseMap(QQuick3DTexture *diffuseMap)
{
    if (m_diffuseMap == diffuseMap)
        return;

    updatePropertyListener(diffuseMap, m_diffuseMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setDiffuseMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_diffuseMap = diffuseMap;
    emit diffuseMapChanged(m_diffuseMap);
    markDirty(DiffuseDirty);
}

void QQuick3DDefaultMaterial::setEmissiveFactor(float emissiveFactor)
{
    emissiveFactor = qBound(0.0f, emissiveFactor, 1.0f);
    if (qFuzzyCompare(m_emissiveFactor, emissiveFactor))
        return;

    m_emissiveFactor = emissiveFactor;
    emit emissiveFactorChanged(m_emissiveFactor);
    markDirty(EmissiveDirty);
}

void QQuick3DDefaultMaterial::setEmissiveMap(QQuick3DTexture *emissiveMap)
{
    if (m_emissiveMap == emissiveMap)
        return;


    updatePropertyListener(emissiveMap, m_emissiveMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setEmissiveMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_emissiveMap = emissiveMap;
    emit emissiveMapChanged(m_emissiveMap);
    markDirty(EmissiveDirty);
}

void QQuick3DDefaultMaterial::setEmissiveColor(QColor emissiveColor)
{
    if (m_emissiveColor == emissiveColor)
        return;

    m_emissiveColor = emissiveColor;
    emit emissiveColorChanged(m_emissiveColor);
    markDirty(EmissiveDirty);
}

void QQuick3DDefaultMaterial::setSpecularReflectionMap(QQuick3DTexture *specularReflectionMap)
{
    if (m_specularReflectionMap == specularReflectionMap)
        return;

    updatePropertyListener(specularReflectionMap, m_specularReflectionMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setSpecularReflectionMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_specularReflectionMap = specularReflectionMap;
    emit specularReflectionMapChanged(m_specularReflectionMap);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setSpecularMap(QQuick3DTexture *specularMap)
{
    if (m_specularMap == specularMap)
        return;

    updatePropertyListener(specularMap, m_specularMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setSpecularMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_specularMap = specularMap;
    emit specularMapChanged(m_specularMap);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setSpecularModel(QQuick3DDefaultMaterial::SpecularModel specularModel)
{
    if (m_specularModel == specularModel)
        return;

    m_specularModel = specularModel;
    emit specularModelChanged(m_specularModel);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setSpecularTint(QColor specularTint)
{
    if (m_specularTint == specularTint)
        return;

    m_specularTint = specularTint;
    emit specularTintChanged(m_specularTint);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setIndexOfRefraction(float indexOfRefraction)
{
    if (qFuzzyCompare(m_indexOfRefraction, indexOfRefraction))
        return;

    m_indexOfRefraction = indexOfRefraction;
    emit indexOfRefractionChanged(m_indexOfRefraction);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setFresnelPower(float fresnelPower)
{
    if (qFuzzyCompare(m_fresnelPower, fresnelPower))
        return;

    m_fresnelPower = fresnelPower;
    emit fresnelPowerChanged(m_fresnelPower);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setSpecularAmount(float specularAmount)
{
    if (qFuzzyCompare(m_specularAmount, specularAmount))
        return;

    m_specularAmount = specularAmount;
    emit specularAmountChanged(m_specularAmount);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setSpecularRoughness(float specularRoughness)
{
    if (qFuzzyCompare(m_specularRoughness, specularRoughness))
        return;

    m_specularRoughness = specularRoughness;
    emit specularRoughnessChanged(m_specularRoughness);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setRoughnessMap(QQuick3DTexture *roughnessMap)
{
    if (m_roughnessMap == roughnessMap)
        return;

    updatePropertyListener(roughnessMap, m_roughnessMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setRoughnessMap(qobject_cast<QQuick3DTexture *>(n));
    });


    m_roughnessMap = roughnessMap;
    emit roughnessMapChanged(m_roughnessMap);
    markDirty(SpecularDirty);
}

void QQuick3DDefaultMaterial::setOpacity(float opacity)
{
    if (qFuzzyCompare(m_opacity, opacity))
        return;

    if (opacity > 1.0f)
        opacity = 1.0f;

    if (opacity < 0.0f)
        opacity = 0.0f;

    m_opacity = opacity;
    emit opacityChanged(m_opacity);
    markDirty(OpacityDirty);
}

void QQuick3DDefaultMaterial::setOpacityMap(QQuick3DTexture *opacityMap)
{
    if (m_opacityMap == opacityMap)
        return;

    updatePropertyListener(opacityMap, m_opacityMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setOpacityMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_opacityMap = opacityMap;
    emit opacityMapChanged(m_opacityMap);
    markDirty(OpacityDirty);
}

void QQuick3DDefaultMaterial::setBumpMap(QQuick3DTexture *bumpMap)
{
    if (m_bumpMap == bumpMap)
        return;

    updatePropertyListener(bumpMap, m_bumpMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setBumpMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_bumpMap = bumpMap;
    emit bumpMapChanged(m_bumpMap);
    markDirty(BumpDirty);
}

void QQuick3DDefaultMaterial::setBumpAmount(float bumpAmount)
{
    if (qFuzzyCompare(m_bumpAmount, bumpAmount))
        return;

    m_bumpAmount = bumpAmount;
    emit bumpAmountChanged(m_bumpAmount);
    markDirty(BumpDirty);
}

void QQuick3DDefaultMaterial::setNormalMap(QQuick3DTexture *normalMap)
{
    if (m_normalMap == normalMap)
        return;

    updatePropertyListener(normalMap, m_normalMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setNormalMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_normalMap = normalMap;
    emit normalMapChanged(m_normalMap);
    markDirty(NormalDirty);
}

void QQuick3DDefaultMaterial::setTranslucencyMap(QQuick3DTexture *translucencyMap)
{
    if (m_translucencyMap == translucencyMap)
        return;

    updatePropertyListener(translucencyMap, m_translucencyMap, sceneManager(), m_connections, [this](QQuick3DObject *n) {
        setTranslucencyMap(qobject_cast<QQuick3DTexture *>(n));
    });

    m_translucencyMap = translucencyMap;
    emit translucencyMapChanged(m_translucencyMap);
    markDirty(TranslucencyDirty);
}

void QQuick3DDefaultMaterial::setTranslucentFalloff(float translucentFalloff)
{
    if (qFuzzyCompare(m_translucentFalloff, translucentFalloff))
        return;

    m_translucentFalloff = translucentFalloff;
    emit translucentFalloffChanged(m_translucentFalloff);
    markDirty(TranslucencyDirty);
}

void QQuick3DDefaultMaterial::setDiffuseLightWrap(float diffuseLightWrap)
{
    if (qFuzzyCompare(m_diffuseLightWrap, diffuseLightWrap))
        return;

    m_diffuseLightWrap = diffuseLightWrap;
    emit diffuseLightWrapChanged(m_diffuseLightWrap);
    markDirty(DiffuseDirty);
}

void QQuick3DDefaultMaterial::setVertexColorsEnabled(bool vertexColors)
{
    if (m_vertexColorsEnabled == vertexColors)
        return;

    m_vertexColorsEnabled = vertexColors;
    emit vertexColorsEnabledChanged(m_vertexColorsEnabled);
    markDirty(VertexColorsDirty);
}

QSSGRenderGraphObject *QQuick3DDefaultMaterial::updateSpatialNode(QSSGRenderGraphObject *node)
{
    if (!node) {
        markAllDirty();
        node = new QSSGRenderDefaultMaterial(QSSGRenderGraphObject::Type::DefaultMaterial);
    }

    // Set common material properties
    QQuick3DMaterial::updateSpatialNode(node);

    QSSGRenderDefaultMaterial *material = static_cast<QSSGRenderDefaultMaterial *>(node);

    if (m_dirtyAttributes & LightingModeDirty) {
        material->lighting = QSSGRenderDefaultMaterial::MaterialLighting(m_lighting);
        // If the lighthing mode changes it affects the emissive property
        m_dirtyAttributes |= EmissiveDirty;
    }

    if (m_dirtyAttributes & BlendModeDirty)
        material->blendMode = QSSGRenderDefaultMaterial::MaterialBlendMode(m_blendMode);

    if (m_dirtyAttributes & DiffuseDirty) {
        material->color = QVector4D(m_diffuseColor.redF(), m_diffuseColor.greenF(), m_diffuseColor.blueF(), m_diffuseColor.alphaF());
        if (!m_diffuseMap)
            material->colorMap = nullptr;
        else
            material->colorMap = m_diffuseMap->getRenderImage();

        material->diffuseLightWrap = m_diffuseLightWrap;
    }

    if (m_dirtyAttributes & EmissiveDirty) {
        if (!m_emissiveMap)
            material->emissiveMap = nullptr;
        else
            material->emissiveMap = m_emissiveMap->getRenderImage();

        const float emissiveFactor = (m_lighting == NoLighting) ? 1.0f : m_emissiveFactor;
        material->emissiveColor = QVector3D(m_emissiveColor.redF(), m_emissiveColor.greenF(), m_emissiveColor.blueF()) * emissiveFactor;
    }

    if (m_dirtyAttributes & SpecularDirty) {
        if (!m_specularReflectionMap)
            material->specularReflection = nullptr;
        else
            material->specularReflection = m_specularReflectionMap->getRenderImage();

        if (!m_specularMap)
            material->specularMap = nullptr;
        else
            material->specularMap = m_specularMap->getRenderImage();

        material->specularModel = QSSGRenderDefaultMaterial::MaterialSpecularModel(m_specularModel);
        material->specularTint = QVector3D(m_specularTint.redF(), m_specularTint.greenF(), m_specularTint.blueF());
        material->ior = m_indexOfRefraction;
        material->fresnelPower = m_fresnelPower;
        material->specularAmount = m_specularAmount;
        material->specularRoughness = m_specularRoughness;

        if (!m_roughnessMap)
            material->roughnessMap = nullptr;
        else
            material->roughnessMap = m_roughnessMap->getRenderImage();
    }

    if (m_dirtyAttributes & OpacityDirty) {
        material->opacity = m_opacity;
        if (!m_opacityMap)
            material->opacityMap = nullptr;
        else
            material->opacityMap = m_opacityMap->getRenderImage();
    }

    if (m_dirtyAttributes & BumpDirty) {
        if (!m_bumpMap)
            material->bumpMap = nullptr;
        else
            material->bumpMap = m_bumpMap->getRenderImage();
        material->bumpAmount = m_bumpAmount;
    }

    if (m_dirtyAttributes & NormalDirty) {
        if (!m_normalMap)
            material->normalMap = nullptr;
        else
            material->normalMap = m_normalMap->getRenderImage();
    }

    if (m_dirtyAttributes & TranslucencyDirty) {
        if (!m_translucencyMap)
            material->translucencyMap = nullptr;
        else
            material->translucencyMap = m_translucencyMap->getRenderImage();
        material->translucentFalloff = m_translucentFalloff;
    }

    if (m_dirtyAttributes & VertexColorsDirty)
        material->vertexColorsEnabled = m_vertexColorsEnabled;

    m_dirtyAttributes = 0;

    return node;
}

void QQuick3DDefaultMaterial::itemChange(QQuick3DObject::ItemChange change, const QQuick3DObject::ItemChangeData &value)
{
    if (change == QQuick3DObject::ItemSceneChange)
        updateSceneManager(value.sceneManager);
}

void QQuick3DDefaultMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
{
    // Check all the resource value's windows, and update as necessary
    if (sceneManager) {
        if (m_diffuseMap)
            QQuick3DObjectPrivate::get(m_diffuseMap)->refSceneManager(sceneManager);
        if (m_emissiveMap)
            QQuick3DObjectPrivate::get(m_emissiveMap)->refSceneManager(sceneManager);
        if (m_specularReflectionMap)
            QQuick3DObjectPrivate::get(m_specularReflectionMap)->refSceneManager(sceneManager);
        if (m_specularMap)
            QQuick3DObjectPrivate::get(m_specularMap)->refSceneManager(sceneManager);
        if (m_roughnessMap)
            QQuick3DObjectPrivate::get(m_roughnessMap)->refSceneManager(sceneManager);
        if (m_opacityMap)
            QQuick3DObjectPrivate::get(m_opacityMap)->refSceneManager(sceneManager);
        if (m_bumpMap)
            QQuick3DObjectPrivate::get(m_bumpMap)->refSceneManager(sceneManager);
        if (m_normalMap)
            QQuick3DObjectPrivate::get(m_normalMap)->refSceneManager(sceneManager);
        if (m_translucencyMap)
            QQuick3DObjectPrivate::get(m_translucencyMap)->refSceneManager(sceneManager);
    } else {
        if (m_diffuseMap)
            QQuick3DObjectPrivate::get(m_diffuseMap)->derefSceneManager();
        if (m_emissiveMap)
            QQuick3DObjectPrivate::get(m_emissiveMap)->derefSceneManager();
        if (m_specularReflectionMap)
            QQuick3DObjectPrivate::get(m_specularReflectionMap)->derefSceneManager();
        if (m_specularMap)
            QQuick3DObjectPrivate::get(m_specularMap)->derefSceneManager();
        if (m_roughnessMap)
            QQuick3DObjectPrivate::get(m_roughnessMap)->derefSceneManager();
        if (m_opacityMap)
            QQuick3DObjectPrivate::get(m_opacityMap)->derefSceneManager();
        if (m_bumpMap)
            QQuick3DObjectPrivate::get(m_bumpMap)->derefSceneManager();
        if (m_normalMap)
            QQuick3DObjectPrivate::get(m_normalMap)->derefSceneManager();
        if (m_translucencyMap)
            QQuick3DObjectPrivate::get(m_translucencyMap)->derefSceneManager();
    }
}

void QQuick3DDefaultMaterial::markDirty(QQuick3DDefaultMaterial::DirtyType type)
{
    if (!(m_dirtyAttributes & quint32(type))) {
        m_dirtyAttributes |= quint32(type);
        update();
    }
}

QT_END_NAMESPACE
