add 2-pass support for models

This commit is contained in:
Chris Danford
2004-01-28 08:53:40 +00:00
parent b6b982b4b8
commit 68ff50636d
4 changed files with 77 additions and 22 deletions
+52 -19
View File
@@ -244,8 +244,6 @@ bool Model::LoadMilkshapeAscii( CString sPath )
THROW
strcpy( Material.szName, szName );
Material.bSphereMapped = ((CString)Material.szName).Find("sphere") != -1;
// ambient
if( f.GetLine( sLine ) <= 0 )
THROW
@@ -307,7 +305,7 @@ bool Model::LoadMilkshapeAscii( CString sPath )
FixSlashesInPlace( sTexturePath );
CollapsePath( sTexturePath );
if( IsAFile(sTexturePath) )
Material.aniTexture.Load( sTexturePath );
Material.diffuse.Load( sTexturePath );
else
{
CString sError = ssprintf( "'%s' references a texture '%s' that does not exist", sPath.c_str(), sTexturePath.c_str() );
@@ -321,6 +319,20 @@ bool Model::LoadMilkshapeAscii( CString sPath )
strcpy (szName, "");
sscanf (sLine, "\"%[^\"]\"", szName);
strcpy( Material.szAlphaTexture, szName );
if( strcmp(Material.szAlphaTexture, "")!=0 )
{
CString sTexturePath = sDir + Material.szAlphaTexture;
FixSlashesInPlace( sTexturePath );
CollapsePath( sTexturePath );
if( IsAFile(sTexturePath) )
Material.alpha.Load( sTexturePath );
else
{
CString sError = ssprintf( "'%s' references a texture '%s' that does not exist", sPath.c_str(), sTexturePath.c_str() );
RageException::Throw( sError );
}
}
}
}
}
@@ -536,9 +548,9 @@ void Model::DrawPrimitives()
msMesh *pMesh = &m_Meshes[i];
RageModelVertexVector& TempVertices = m_vTempVerticesByBone[i];
// apply material
if( pMesh->nMaterialIndex != -1 )
if( pMesh->nMaterialIndex != -1 ) // has a material
{
// apply material
msMaterial& mat = m_Materials[ pMesh->nMaterialIndex ];
RageColor Emissive = mat.Emissive;
@@ -555,16 +567,33 @@ void Model::DrawPrimitives()
Diffuse,
mat.Specular,
mat.fShininess );
DISPLAY->SetTexture( mat.aniTexture.GetCurrentTexture() );
DISPLAY->SetSphereEnironmentMapping( mat.bSphereMapped );
// render the first pass with texture 1
DISPLAY->SetTexture( mat.diffuse.ani.GetCurrentTexture() );
DISPLAY->SetSphereEnironmentMapping( mat.diffuse.bSphereMapped );
// UGLY: This overrides the Actor's BlendMode
DISPLAY->SetBlendMode( mat.diffuse.blendMode );
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
// render the second pass with texture 2
if( mat.alpha.ani.GetCurrentTexture() )
{
DISPLAY->SetTexture( mat.alpha.ani.GetCurrentTexture() );
DISPLAY->SetSphereEnironmentMapping( mat.alpha.bSphereMapped );
// UGLY: This overrides the Actor's BlendMode
DISPLAY->SetBlendMode( mat.alpha.blendMode );
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
}
DISPLAY->SetSphereEnironmentMapping( false );
}
else
{
RageColor emissive( 0,0,0,0 );
RageColor ambient( 0.2f,0.2f,0.2f,1 );
RageColor diffuse( 0.7f,0.7f,0.7f,1 );
RageColor specular( 0.2f,0.2f,0.2f,1 );
float shininess = 1;
const static RageColor emissive( 0,0,0,0 );
const static RageColor ambient( 0.2f,0.2f,0.2f,1 );
const static RageColor diffuse( 0.7f,0.7f,0.7f,1 );
const static RageColor specular( 0.2f,0.2f,0.2f,1 );
const static float shininess = 1;
DISPLAY->SetMaterial(
emissive,
ambient,
@@ -573,10 +602,8 @@ void Model::DrawPrimitives()
shininess );
DISPLAY->SetTexture( NULL );
DISPLAY->SetSphereEnironmentMapping( false );
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
}
DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 );
DISPLAY->SetSphereEnironmentMapping( false );
}
}
@@ -611,7 +638,7 @@ void Model::DrawPrimitives()
Diffuse,
mat.Specular,
mat.fShininess );
DISPLAY->SetTexture( mat.aniTexture.GetCurrentTexture() );
DISPLAY->SetTexture( mat.diffuse.ani.GetCurrentTexture() );
}
else
{
@@ -854,20 +881,26 @@ void Model::Update( float fDelta )
AdvanceFrame( fDelta );
for( int i=0; i<(int)m_Materials.size(); i++ )
m_Materials[i].aniTexture.Update( fDelta );
{
m_Materials[i].diffuse.ani.Update( fDelta );
m_Materials[i].alpha.ani.Update( fDelta );
}
}
void Model::SetState( int iNewState )
{
for( int i=0; i<(int)m_Materials.size(); i++ )
m_Materials[i].aniTexture.SetState( iNewState );
{
m_Materials[i].diffuse.ani.SetState( iNewState );
m_Materials[i].alpha.ani.SetState( iNewState );
}
}
int Model::GetNumStates()
{
int iMaxStates = 0;
for( int i=0; i<(int)m_Materials.size(); i++ )
iMaxStates = max( iMaxStates, m_Materials[i].aniTexture.GetNumStates() );
iMaxStates = max( iMaxStates, m_Materials[i].diffuse.ani.GetNumStates() );
return iMaxStates;
}
+1
View File
@@ -122,3 +122,4 @@ void AnimatedTexture::Unload()
iCurState = 0;
fSecsIntoFrame = 0;
}
+23 -2
View File
@@ -81,6 +81,7 @@ typedef struct msMesh
/* msMaterial */
class RageTexture;
// merge this into Sprite?
struct AnimatedTexture
{
AnimatedTexture();
@@ -118,8 +119,28 @@ typedef struct msMaterial
char szDiffuseTexture[MS_MAX_PATH];
char szAlphaTexture[MS_MAX_PATH]; // not used in SM. Use alpha in diffuse texture instead
int nName; // not used in SM. What is this for anyway?
AnimatedTexture aniTexture;
bool bSphereMapped; // true of "sphere" appears in the material name
struct Texture
{
Texture()
{
bSphereMapped = false;
blendMode = BLEND_NORMAL;
}
void Load( CString sFile )
{
ani.Load( sFile );
bSphereMapped = sFile.Find("sphere") != -1;
if( sFile.Find("add") != -1 )
blendMode = BLEND_ADD;
else
blendMode = BLEND_NORMAL;
};
AnimatedTexture ani;
bool bSphereMapped; // true of "sphere" appears in the material name
BlendMode blendMode;
} diffuse, alpha;
} msMaterial;
/* msPositionKey */
+1 -1
View File
@@ -16,7 +16,7 @@
* depend on RageDisplay (since that'd boost RDisplay.h a lot), so let's just
* put this here. */
enum GlowMode { GLOW_BRIGHTEN, GLOW_WHITEN };
enum BlendMode { BLEND_NORMAL, BLEND_ADD, BLEND_NO_EFFECT };
enum BlendMode { BLEND_NORMAL, BLEND_ADD, BLEND_NO_EFFECT, BLEND_INVALID };
struct RageVector2