Files
simgear/simgear/scene/sky/clouds3d/SkyMaterial.cpp
T

446 lines
14 KiB
C++

//------------------------------------------------------------------------------
// File : SkyMaterial.cpp
//------------------------------------------------------------------------------
// SkyWorks : Copyright 2002 Mark J. Harris and
// The University of North Carolina at Chapel Hill
//------------------------------------------------------------------------------
// Permission to use, copy, modify, distribute and sell this software and its
// documentation for any purpose is hereby granted without fee, provided that
// the above copyright notice appear in all copies and that both that copyright
// notice and this permission notice appear in supporting documentation.
// Binaries may be compiled with this software without any royalties or
// restrictions.
//
// The author(s) and The University of North Carolina at Chapel Hill make no
// representations about the suitability of this software for any purpose.
// It is provided "as is" without express or
// implied warranty.
/**
* @file SkyMaterial.cpp
*
* Implementation of class SkyMaterial, a meterial property object.
*/
#include "SkyMaterial.hpp"
#include "SkyContext.hpp"
//------------------------------------------------------------------------------
// Function : SkyMaterial::SkyMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::SkyMaterial()
* @brief Constructor.
*/
SkyMaterial::SkyMaterial()
: _iMaterialID(-1),
_vecDiffuse(Vec4f::ZERO),
_vecSpecular(Vec4f::ZERO),
_vecAmbient(Vec4f::ZERO),
_vecEmissive(Vec4f::ZERO),
_rSpecularPower(0),
_bLighting(true),
_eColorMaterialFace(GL_FRONT_AND_BACK),
_eColorMaterialMode(GL_AMBIENT_AND_DIFFUSE),
_bColorMaterial(false),
_vecFogColor(Vec4f::ZERO),
_eFogMode(GL_EXP),
_bFog(false),
_eDepthFunc(GL_LESS),
_bDepthMask(true),
_bDepthTest(true),
_eAlphaFunc(GL_ALWAYS),
_rAlphaRef(0),
_bAlphaTest(false),
_eBlendSrcFactor(GL_ONE),
_eBlendDstFactor(GL_ZERO),
_bBlending(false),
_bFaceCulling(false),
_eFaceCullingMode(GL_BACK),
_eTextureEnvMode(GL_MODULATE)
{
_rFogParams[SKY_FOG_DENSITY] = 1;
_rFogParams[SKY_FOG_START] = 0;
_rFogParams[SKY_FOG_END] = 1;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::~SkyMaterial
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::~SkyMaterial()
* @brief Destructor.
*/
SkyMaterial::~SkyMaterial()
{
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::SetFogParameter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::SetFogParameter(GLenum eParameter, float rValue)
*/
SKYRESULT SkyMaterial::SetFogParameter(GLenum eParameter, float rValue)
{
switch (eParameter)
{
case GL_FOG_DENSITY:
_rFogParams[SKY_FOG_DENSITY] = rValue;
break;
case GL_FOG_START:
_rFogParams[SKY_FOG_START] = rValue;
break;
case GL_FOG_END:
_rFogParams[SKY_FOG_END] = rValue;
break;
default:
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyMaterial::SetFogParameter(): Invalid parameter.");
break;
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::GetFogParameter
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::GetFogParameter(GLenum eParameter) const
*/
float SkyMaterial::GetFogParameter(GLenum eParameter) const
{
switch (eParameter)
{
case GL_FOG_DENSITY:
return _rFogParams[SKY_FOG_DENSITY];
break;
case GL_FOG_START:
return _rFogParams[SKY_FOG_START];
break;
case GL_FOG_END:
return _rFogParams[SKY_FOG_END];
break;
default:
FAIL_RETURN_MSG(SKYRESULT_FAIL, "SkyMaterial::GetFogParameter(): Invalid parameter.");
break;
}
return -1;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::Activate
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::Activate()
* @brief @todo <WRITE BRIEF SkyMaterial::SetMaterialPropertiesForDisplay DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMaterial::SetMaterialPropertiesForDisplay FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyMaterial::Activate()
{
// Update the cached current material, and only pass values that have changed to the GL.
SkyMaterial *pCurrentMaterial = GraphicsContext::InstancePtr()->GetCurrentMaterial();
assert(NULL != pCurrentMaterial);
// basic material properties
if (pCurrentMaterial->GetDiffuse() != GetDiffuse())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(GetDiffuse().x));
pCurrentMaterial->SetDiffuse(GetDiffuse());
}
if (pCurrentMaterial->GetSpecular() != GetSpecular())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(GetSpecular().x));
pCurrentMaterial->SetSpecular(GetSpecular());
}
if (pCurrentMaterial->GetAmbient() != GetAmbient())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(GetAmbient().x));
pCurrentMaterial->SetAmbient(GetAmbient());
}
if (pCurrentMaterial->GetEmissive() != GetEmissive())
{
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &(GetEmissive().x));
pCurrentMaterial->SetEmissive(GetEmissive());
}
if (pCurrentMaterial->GetSpecularPower() != GetSpecularPower())
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GetSpecularPower());
pCurrentMaterial->SetSpecularPower(GetSpecularPower());
}
// lighting
if (pCurrentMaterial->IsLightingEnabled() != IsLightingEnabled())
{
if (IsLightingEnabled())
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
pCurrentMaterial->EnableLighting(IsLightingEnabled());
}
// color material (which material property tracks color calls)
if (pCurrentMaterial->GetColorMaterialFace() != GetColorMaterialFace() ||
pCurrentMaterial->GetColorMaterialMode() != GetColorMaterialMode())
{
glColorMaterial(GetColorMaterialFace(), GetColorMaterialMode());
pCurrentMaterial->SetColorMaterialFace(GetColorMaterialFace());
pCurrentMaterial->SetColorMaterialMode(GetColorMaterialMode());
}
if (pCurrentMaterial->IsColorMaterialEnabled() != IsColorMaterialEnabled())
{
if (IsColorMaterialEnabled())
glEnable(GL_COLOR_MATERIAL);
else
glDisable(GL_COLOR_MATERIAL);
pCurrentMaterial->EnableColorMaterial(IsColorMaterialEnabled());
}
// fog
if (pCurrentMaterial->GetFogMode() != GetFogMode())
{
glFogf(GL_FOG_MODE, GetFogMode());
pCurrentMaterial->SetFogMode(GetFogMode());
}
if (pCurrentMaterial->GetFogColor() != GetFogColor())
{
glFogfv(GL_FOG_COLOR, GetFogColor());
pCurrentMaterial->SetFogColor(GetFogColor());
}
if (pCurrentMaterial->GetFogParameter(GL_FOG_DENSITY) != GetFogParameter(GL_FOG_DENSITY))
{
glFogf(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
pCurrentMaterial->SetFogParameter(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
}
if (pCurrentMaterial->GetFogParameter(GL_FOG_START) != GetFogParameter(GL_FOG_START))
{
glFogf(GL_FOG_START, GetFogParameter(GL_FOG_START));
pCurrentMaterial->SetFogParameter(GL_FOG_START, GetFogParameter(GL_FOG_START));
}
if (pCurrentMaterial->GetFogParameter(GL_FOG_END) != GetFogParameter(GL_FOG_END))
{
glFogf(GL_FOG_END, GetFogParameter(GL_FOG_END));
pCurrentMaterial->SetFogParameter(GL_FOG_END, GetFogParameter(GL_FOG_END));
}
if (pCurrentMaterial->IsFogEnabled() != IsFogEnabled())
{
if (IsFogEnabled())
glEnable(GL_FOG);
else
glDisable(GL_FOG);
pCurrentMaterial->EnableFog(IsFogEnabled());
}
// depth test
if (pCurrentMaterial->GetDepthFunc() != GetDepthFunc())
{
glDepthFunc(GetDepthFunc());
pCurrentMaterial->SetDepthFunc(GetDepthFunc());
}
if (pCurrentMaterial->GetDepthMask() != GetDepthMask())
{
glDepthMask(GetDepthMask());
pCurrentMaterial->SetDepthMask(GetDepthMask());
}
if (pCurrentMaterial->IsDepthTestEnabled() != IsDepthTestEnabled())
{
if (IsDepthTestEnabled())
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
pCurrentMaterial->EnableDepthTest(IsDepthTestEnabled());
}
// alpha test
if (pCurrentMaterial->GetAlphaFunc() != GetAlphaFunc() ||
pCurrentMaterial->GetAlphaRef() != GetAlphaRef())
{
glAlphaFunc(GetAlphaFunc(), GetAlphaRef());
pCurrentMaterial->SetAlphaFunc(GetAlphaFunc());
pCurrentMaterial->SetAlphaRef(GetAlphaRef());
}
if (pCurrentMaterial->IsAlphaTestEnabled() != IsAlphaTestEnabled())
{
if (IsAlphaTestEnabled())
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
pCurrentMaterial->EnableAlphaTest(IsAlphaTestEnabled());
}
// blending
if (pCurrentMaterial->GetBlendingSourceFactor() != GetBlendingSourceFactor() ||
pCurrentMaterial->GetBlendingDestFactor() != GetBlendingDestFactor())
{
glBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
pCurrentMaterial->SetBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
}
if (pCurrentMaterial->IsBlendingEnabled() != IsBlendingEnabled())
{
if (IsBlendingEnabled())
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
pCurrentMaterial->EnableBlending(IsBlendingEnabled());
}
if (pCurrentMaterial->GetFaceCullingMode() != GetFaceCullingMode())
{
glCullFace(GetFaceCullingMode());
pCurrentMaterial->SetFaceCullingMode(GetFaceCullingMode());
}
if (pCurrentMaterial->IsFaceCullingEnabled() != IsFaceCullingEnabled())
{
if (IsFaceCullingEnabled())
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
pCurrentMaterial->EnableFaceCulling(IsFaceCullingEnabled());
}
// texturing
FAIL_RETURN(_textureState.Activate());
if (pCurrentMaterial->GetTextureApplicationMode() != GetTextureApplicationMode())
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GetTextureApplicationMode());
pCurrentMaterial->SetTextureApplicationMode(GetTextureApplicationMode());
}
return SKYRESULT_OK;
}
//------------------------------------------------------------------------------
// Function : SkyMaterial::Force
// Description :
//------------------------------------------------------------------------------
/**
* @fn SkyMaterial::Force()
* @brief @todo <WRITE BRIEF SkyMaterial::SetMaterialPropertiesForDisplay DOCUMENTATION>
*
* @todo <WRITE EXTENDED SkyMaterial::SetMaterialPropertiesForDisplay FUNCTION DOCUMENTATION>
*/
SKYRESULT SkyMaterial::Force()
{
// Update the cached current material, and only pass values that have changed to the GL.
SkyMaterial *pCurrentMaterial = GraphicsContext::InstancePtr()->GetCurrentMaterial();
assert(NULL != pCurrentMaterial);
// basic material properties
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &(GetDiffuse().x));
pCurrentMaterial->SetDiffuse(GetDiffuse());
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &(GetSpecular().x));
pCurrentMaterial->SetSpecular(GetSpecular());
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &(GetAmbient().x));
pCurrentMaterial->SetAmbient(GetAmbient());
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &(GetEmissive().x));
pCurrentMaterial->SetEmissive(GetEmissive());
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GetSpecularPower());
pCurrentMaterial->SetSpecularPower(GetSpecularPower());
// lighting
if (IsLightingEnabled())
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
pCurrentMaterial->EnableLighting(IsLightingEnabled());
// color material (which material property tracks color calls)
glColorMaterial(GetColorMaterialFace(), GetColorMaterialMode());
pCurrentMaterial->SetColorMaterialFace(GetColorMaterialFace());
pCurrentMaterial->SetColorMaterialMode(GetColorMaterialMode());
if (IsColorMaterialEnabled())
glEnable(GL_COLOR_MATERIAL);
else
glDisable(GL_COLOR_MATERIAL);
pCurrentMaterial->EnableColorMaterial(IsColorMaterialEnabled());
// fog
glFogf(GL_FOG_MODE, GetFogMode());
pCurrentMaterial->SetFogMode(GetFogMode());
glFogfv(GL_FOG_COLOR, GetFogColor());
pCurrentMaterial->SetFogColor(GetFogColor());
glFogf(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
pCurrentMaterial->SetFogParameter(GL_FOG_DENSITY, GetFogParameter(GL_FOG_DENSITY));
glFogf(GL_FOG_START, GetFogParameter(GL_FOG_START));
pCurrentMaterial->SetFogParameter(GL_FOG_START, GetFogParameter(GL_FOG_START));
glFogf(GL_FOG_END, GetFogParameter(GL_FOG_END));
pCurrentMaterial->SetFogParameter(GL_FOG_END, GetFogParameter(GL_FOG_END));
if (IsFogEnabled())
glEnable(GL_FOG);
else
glDisable(GL_FOG);
pCurrentMaterial->EnableFog(IsFogEnabled());
// depth test
glDepthFunc(GetDepthFunc());
pCurrentMaterial->SetDepthFunc(GetDepthFunc());
glDepthMask(GetDepthMask());
pCurrentMaterial->SetDepthMask(GetDepthMask());
if (IsDepthTestEnabled())
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
pCurrentMaterial->EnableDepthTest(IsDepthTestEnabled());
// alpha test
glAlphaFunc(GetAlphaFunc(), GetAlphaRef());
pCurrentMaterial->SetAlphaFunc(GetAlphaFunc());
pCurrentMaterial->SetAlphaRef(GetAlphaRef());
if (IsAlphaTestEnabled())
glEnable(GL_ALPHA_TEST);
else
glDisable(GL_ALPHA_TEST);
// blending
glBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
pCurrentMaterial->SetBlendFunc(GetBlendingSourceFactor(), GetBlendingDestFactor());
if (IsBlendingEnabled())
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
pCurrentMaterial->EnableBlending(IsBlendingEnabled());
glCullFace(GetFaceCullingMode());
pCurrentMaterial->SetFaceCullingMode(GetFaceCullingMode());
if (IsFaceCullingEnabled())
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
pCurrentMaterial->EnableFaceCulling(IsFaceCullingEnabled());
// texturing
FAIL_RETURN(_textureState.Force());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GetTextureApplicationMode());
pCurrentMaterial->SetTextureApplicationMode(GetTextureApplicationMode());
return SKYRESULT_OK;
}