mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
469 lines
13 KiB
C++
469 lines
13 KiB
C++
/*
|
|
Copyright (C) 2007 StrmnNrmn
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "RenderSettings.h"
|
|
#include "BlendConstant.h"
|
|
|
|
|
|
/**
|
|
* Set how textures are applied
|
|
*
|
|
* Key for the apply-modes:
|
|
* - Cv - Color value result
|
|
* - Ct - Texture color
|
|
* - Cf - Fragment color
|
|
* - Cc - Constant color (specified by sceGuTexEnvColor())
|
|
*
|
|
* Available apply-modes are: (TFX)
|
|
* - GU_TFX_MODULATE - Cv=Ct*Cf TCC_RGB: Av=Af TCC_RGBA: Av=At*Af
|
|
* - GU_TFX_DECAL - TCC_RGB: Cv=Ct,Av=Af TCC_RGBA: Cv=Cf*(1-At)+Ct*At Av=Af
|
|
* - GU_TFX_BLEND - Cv=(Cf*(1-Ct))+(Cc*Ct) TCC_RGB: Av=Af TCC_RGBA: Av=At*Af
|
|
* - GU_TFX_REPLACE - Cv=Ct TCC_RGB: Av=Af TCC_RGBA: Av=At
|
|
* - GU_TFX_ADD - Cv=Cf+Ct TCC_RGB: Av=Af TCC_RGBA: Av=At*Af
|
|
*
|
|
* The fields TCC_RGB and TCC_RGBA specify components that differ between
|
|
* the two different component modes.
|
|
*
|
|
* - GU_TFX_MODULATE - The texture is multiplied with the current diffuse fragment
|
|
* - GU_TFX_REPLACE - The texture replaces the fragment
|
|
* - GU_TFX_ADD - The texture is added on-top of the diffuse fragment
|
|
*
|
|
* Available component-modes are: (TCC)
|
|
* - GU_TCC_RGB - The texture alpha does not have any effect
|
|
* - GU_TCC_RGBA - The texture alpha is taken into account
|
|
*
|
|
* @param tfx - Which apply-mode to use
|
|
* @param tcc - Which component-mode to use
|
|
**/
|
|
|
|
///* Texture Effect */
|
|
//#define GU_TFX_MODULATE (0)
|
|
//#define GU_TFX_DECAL (1)
|
|
//#define GU_TFX_BLEND (2)
|
|
//#define GU_TFX_REPLACE (3)
|
|
//#define GU_TFX_ADD (4)
|
|
//
|
|
///* Texture Color Component */
|
|
//#define GU_TCC_RGB (0)
|
|
//#define GU_TCC_RGBA (1)
|
|
//
|
|
//
|
|
///* Blending Op */
|
|
//#define GU_ADD (0)
|
|
//#define GU_SUBTRACT (1)
|
|
//#define GU_REVERSE_SUBTRACT (2)
|
|
//#define GU_MIN (3)
|
|
//#define GU_MAX (4)
|
|
//#define GU_ABS (5)
|
|
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CAlphaRenderSettings::CAlphaRenderSettings( const char * description )
|
|
: mDescription( description )
|
|
, mInexact( false )
|
|
, mUsesTexel0( false )
|
|
, mUsesTexel1( false )
|
|
, mConstantExpression( NULL )
|
|
{
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CAlphaRenderSettings::~CAlphaRenderSettings()
|
|
{
|
|
delete mConstantExpression;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CAlphaRenderSettings::AddTermTexel0()
|
|
{
|
|
if( mUsesTexel0 || mUsesTexel1 )
|
|
{
|
|
mInexact = true;
|
|
}
|
|
mUsesTexel0 = true;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CAlphaRenderSettings::AddTermTexel1()
|
|
{
|
|
if( mUsesTexel0 || mUsesTexel1 )
|
|
{
|
|
mInexact = true;
|
|
}
|
|
mUsesTexel1 = true;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CAlphaRenderSettings::AddTermConstant( const CBlendConstantExpression * constant_expression )
|
|
{
|
|
if( mConstantExpression != NULL )
|
|
{
|
|
mConstantExpression = new CBlendConstantExpressionMul( mConstantExpression, constant_expression );
|
|
}
|
|
else
|
|
{
|
|
mConstantExpression = constant_expression;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CAlphaRenderSettings::Finalise()
|
|
{
|
|
if( mConstantExpression == NULL )
|
|
{
|
|
mConstantExpression = new CBlendConstantExpressionValue( BC_1 );
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CAlphaRenderSettings::Apply( bool texture_installed, const SRenderState & state, SRenderStateOut & out ) const
|
|
{
|
|
out.VertexExpressionA = mConstantExpression;
|
|
|
|
if( mUsesTexel0 || mUsesTexel1 )
|
|
{
|
|
#ifdef DAEDALUS_ENABLE_ASSERTS
|
|
DAEDALUS_ASSERT( texture_installed, "We have a texture, but it's not installed?" );
|
|
#endif
|
|
out.BlendAlphaMode = PBAM_RGBA;
|
|
}
|
|
else
|
|
{
|
|
out.BlendAlphaMode = PBAM_RGB;
|
|
}
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CAlphaRenderSettings::Print( bool texture_installed ) const
|
|
{
|
|
DAEDALUS_ASSERT( mConstantExpression != NULL, "Should always have settings" );
|
|
|
|
if( mUsesTexel0 || mUsesTexel1 )
|
|
{
|
|
// Replace vertex shade colour with modulate_colour
|
|
printf( " GU_TCC_RGBA, diffuse_a := %s\n", mConstantExpression->ToString().c_str() );
|
|
}
|
|
else
|
|
{
|
|
// Texel alpha ignored
|
|
// Replace vertex shade colour with modulate_colour
|
|
printf( " GU_TCC_RGB, diffuse_a := %s\n", mConstantExpression->ToString().c_str() );
|
|
}
|
|
}
|
|
|
|
#endif
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CRenderSettingsModulate::CRenderSettingsModulate( const char * description )
|
|
: CRenderSettings( description )
|
|
, mConstantExpression( NULL )
|
|
, mUsesTexel0( false )
|
|
, mUsesTexel1( false )
|
|
, mInexact( false )
|
|
{
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CRenderSettingsModulate::~CRenderSettingsModulate()
|
|
{
|
|
delete mConstantExpression;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsModulate::AddTermTexel0()
|
|
{
|
|
if( mUsesTexel0 )
|
|
{
|
|
mInexact = true;
|
|
}
|
|
mUsesTexel0 = true;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsModulate::AddTermTexel1()
|
|
{
|
|
if( mUsesTexel0 || mUsesTexel1 )
|
|
{
|
|
mInexact = true;
|
|
}
|
|
mUsesTexel1 = true;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsModulate::AddTermConstant( const CBlendConstantExpression * constant_expression )
|
|
{
|
|
if( mConstantExpression != NULL )
|
|
{
|
|
mConstantExpression = new CBlendConstantExpressionMul( mConstantExpression, constant_expression );
|
|
}
|
|
else
|
|
{
|
|
mConstantExpression = constant_expression;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsModulate::Finalise()
|
|
{
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsModulate::Apply( bool texture_installed, const SRenderState & state, SRenderStateOut & out ) const
|
|
{
|
|
out.VertexExpressionRGB = mConstantExpression;
|
|
|
|
if( texture_installed )
|
|
{
|
|
//
|
|
// Enable texturing
|
|
//
|
|
|
|
if( !mUsesTexel0 && !mUsesTexel1 )
|
|
{
|
|
// Make a white texture with the existing alpha channel
|
|
out.MakeTextureWhite = true;
|
|
}
|
|
|
|
if( mConstantExpression != NULL )
|
|
{
|
|
out.BlendMode = PBM_MODULATE;
|
|
}
|
|
else
|
|
{
|
|
out.BlendMode = PBM_REPLACE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Disable texturing
|
|
//
|
|
#ifdef DAEDALUS_ENABLE_ASSERTS
|
|
DAEDALUS_ASSERT( mConstantExpression != NULL, "No texture or diffuse" );
|
|
#endif
|
|
}
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsModulate::Print( bool texture_installed ) const
|
|
{
|
|
if( texture_installed )
|
|
{
|
|
// Enable texturing
|
|
if( !mUsesTexel0 && !mUsesTexel1 )
|
|
{
|
|
printf( " Need white texture\n" );
|
|
}
|
|
|
|
if( mConstantExpression != NULL )
|
|
{
|
|
// Replace vertex shade colour with modulate_colour
|
|
printf( " GU_TFX_MODULATE, diffuse_rgb := %s\n", mConstantExpression->ToString().c_str() );
|
|
}
|
|
else
|
|
{
|
|
printf( " GU_TFX_REPLACE, diffuse_rgb ignored\n" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Disable texturing
|
|
if( mConstantExpression != NULL )
|
|
{
|
|
// Replace vertex shade colour with modulate_colour
|
|
printf( " No tex, diffuse_rgb := %s\n", mConstantExpression->ToString().c_str() );
|
|
}
|
|
else
|
|
{
|
|
// What are we using
|
|
printf( " No texture or diffuse?\n" );
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CRenderSettingsBlend::CRenderSettingsBlend( const char * description, const CBlendConstantExpression * a, const CBlendConstantExpression * b )
|
|
: CRenderSettings( description )
|
|
, mConstantExpressionA( a )
|
|
, mConstantExpressionB( b )
|
|
, mInexact( false )
|
|
{
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CRenderSettingsBlend::~CRenderSettingsBlend()
|
|
{
|
|
delete mConstantExpressionA;
|
|
delete mConstantExpressionB;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsBlend::Apply( bool texture_installed, const SRenderState & state, SRenderStateOut & out ) const
|
|
{
|
|
#ifdef DAEDALUS_ENABLE_ASSERTS
|
|
DAEDALUS_ASSERT( texture_installed, "No texture for blend?" );
|
|
#endif
|
|
//
|
|
// Apply expression A as a function of shade.
|
|
// Evaluate expression A as a constant
|
|
//
|
|
out.VertexExpressionRGB = mConstantExpressionA;
|
|
out.TextureFactor = mConstantExpressionB->EvaluateConstant( state.PrimitiveColour, state.EnvironmentColour );
|
|
out.BlendMode = PBM_BLEND;
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CRenderSettingsBlend::Print( bool texture_installed ) const
|
|
{
|
|
std::string mod_str_a( mConstantExpressionA->ToString() );
|
|
std::string mod_str_b( mConstantExpressionB->ToString() );
|
|
|
|
// Replace vertex shade colour with modulate_colour
|
|
printf( " GU_TFX_BLEND, shade(a) := %s, factor(b) := %s\n", mod_str_a.c_str(), mod_str_b.c_str() );
|
|
}
|
|
|
|
#endif
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CBlendStates::CBlendStates()
|
|
: mAlphaSettings( NULL )
|
|
{
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
CBlendStates::~CBlendStates()
|
|
{
|
|
delete mAlphaSettings;
|
|
for( u32 i = 0; i < mColourSettings.size(); ++i )
|
|
{
|
|
delete mColourSettings[ i ];
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
bool CBlendStates::IsInexact() const
|
|
{
|
|
if(mAlphaSettings->IsInexact())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
for( u32 i = 0; i < mColourSettings.size(); ++i )
|
|
{
|
|
const CRenderSettings * settings( mColourSettings[ i ] );
|
|
|
|
if( settings->IsInexact() )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#ifdef DAEDALUS_DEBUG_DISPLAYLIST
|
|
//*****************************************************************************
|
|
//
|
|
//*****************************************************************************
|
|
void CBlendStates::Print() const
|
|
{
|
|
if(mAlphaSettings->IsInexact())
|
|
{
|
|
printf( "Alpha: INEXACT: %s\n", mAlphaSettings->GetDescription() );
|
|
}
|
|
else
|
|
{
|
|
printf( "Alpha: %s\n", mAlphaSettings->GetDescription() );
|
|
}
|
|
|
|
for( u32 i = 0; i < mColourSettings.size(); ++i )
|
|
{
|
|
const CRenderSettings * settings( mColourSettings[ i ] );
|
|
|
|
bool install_texture0( settings->UsesTexture0() || mAlphaSettings->UsesTexture0() );
|
|
bool install_texture1( settings->UsesTexture1() || mAlphaSettings->UsesTexture1() );
|
|
|
|
if( settings->IsInexact() || (install_texture0 && install_texture1) )
|
|
{
|
|
printf( "Stage %d: INEXACT = %s", i, settings->GetDescription() );
|
|
if(install_texture0 && install_texture1)
|
|
{
|
|
printf( " Uses T0 and T1" );
|
|
}
|
|
printf( "\n" );
|
|
}
|
|
else
|
|
{
|
|
printf( "Stage %d: %s\n", i, settings->GetDescription() );
|
|
}
|
|
|
|
settings->Print( install_texture0 || install_texture1 );
|
|
mAlphaSettings->Print( install_texture0 || install_texture1 );
|
|
}
|
|
|
|
}
|
|
#endif
|