FixedFunctionMaterial/FixedFunctionMaterial.cpp

//**************************************************************************/
// Copyright (c) 2008 Autodesk, Inc.
// All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
//**************************************************************************/
// DESCRIPTION:
// CREATED: October 2008
//**************************************************************************/

#include "FixedFunctionMaterial.h"

MB_PLUGIN( "FixedFunctionMaterial", "Fixed function material", "Autodesk", "http://www.mudbox3d.com", 0 );

IMPLEMENT_CLASS( FixedFunctionMaterial, Material, "Fixed Function Material" );

FixedFunctionMaterial::FixedFunctionMaterial( void ) : 
                m_sTexture(this, "Texture"),
                m_cDiffuse(this, "Diffuse"),
                m_cSpecular(this, "Specular"),
                m_cEmissive(this, "Emmissive"),
                m_fShiny(this, "Shininess"),
                m_iDiffuseTexture(-1)
{
    SetName( "Benchmark Material" );

    m_pTexturePool = CreateInstance<TexturePool>();

    m_cSpecular.SetValue(Color(0,0,0,0));
    m_cEmissive.SetValue(Color(0,0,0,0));
    m_cDiffuse.SetValue(Color(.2f, .02f, .8f));

    // Sets texture to diffuse color.
    m_pDiffuseTexture[0] = (GLubyte) (m_cDiffuse.Value().r * 255);
    m_pDiffuseTexture[1] = (GLubyte) (m_cDiffuse.Value().g * 255);
    m_pDiffuseTexture[2] = (GLubyte) (m_cDiffuse.Value().b * 255);

    // Create OpenGL texture ID.
    glGenTextures(1, &m_iDiffuseTexture);

    m_fShiny.SetMax(128);
    m_fShiny.SetMin(0);
    m_fShiny = 100;
};

FixedFunctionMaterial::~FixedFunctionMaterial( void )
{
    // Clean up
    delete m_pTexturePool;
    glDeleteTextures(1, &m_iDiffuseTexture);
};

bool FixedFunctionMaterial::Activate( const Mesh *pMesh, const AxisAlignedBoundingBox &cUVArea, const Color &cColor )
{
    // Render settings
    glEnable( GL_LIGHTING );
    glEnable( GL_CULL_FACE );

    glMaterialfv( GL_FRONT, GL_EMISSION, m_cEmissive.Value() );
    glMaterialfv( GL_FRONT, GL_SPECULAR, m_cSpecular.Value() );
    glMateriali(GL_FRONT, GL_SHININESS, (int) m_fShiny);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    // Get the correct texture for this tile.
    class Texture *pT = m_pTexturePool->Tile( cUVArea );
    if ( pT )
    {
        glEnable( GL_TEXTURE_2D );
        pT->Activate();
    }
    else
        glDisable( GL_TEXTURE_2D );

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_iDiffuseTexture);
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

    // Apply the texture
    glTexImage2D(GL_TEXTURE_2D, 0,
        GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &m_pDiffuseTexture);

    return true;
};

void FixedFunctionMaterial::Deactivate( void )
{
    glDisable(GL_TEXTURE_2D);
};

void FixedFunctionMaterial::OnNodeEvent( const Attribute &cAttribute, NodeEventType cType )
{
    // UI events.
    bool bRedraw = false;
    if ( cType == etValueChanged && cAttribute == m_sTexture )
    {
        m_pTexturePool->SetFileName( m_sTexture.Value() );
        bRedraw = true;
    };

    if (cAttribute == m_cDiffuse || cAttribute == m_cEmissive ||
        cAttribute == m_cSpecular || cAttribute == m_fShiny)
        bRedraw = true;

    if (cAttribute == m_cDiffuse)
    {
        m_pDiffuseTexture[0] = (GLubyte) (m_cDiffuse.Value().r * 255);
        m_pDiffuseTexture[1] = (GLubyte) (m_cDiffuse.Value().g * 255);
        m_pDiffuseTexture[2] = (GLubyte) (m_cDiffuse.Value().b * 255);
    }

    Material::OnNodeEvent( cAttribute, cType );

    if (bRedraw)
        Kernel()->Redraw();
};