diff --git a/stepmania/src/Model.cpp b/stepmania/src/Model.cpp index 609a472004..38554d9867 100644 --- a/stepmania/src/Model.cpp +++ b/stepmania/src/Model.cpp @@ -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; } diff --git a/stepmania/src/ModelTypes.cpp b/stepmania/src/ModelTypes.cpp index 9b10547da3..14a95498a0 100644 --- a/stepmania/src/ModelTypes.cpp +++ b/stepmania/src/ModelTypes.cpp @@ -122,3 +122,4 @@ void AnimatedTexture::Unload() iCurState = 0; fSecsIntoFrame = 0; } + diff --git a/stepmania/src/ModelTypes.h b/stepmania/src/ModelTypes.h index c93bd8a642..3ae9476862 100644 --- a/stepmania/src/ModelTypes.h +++ b/stepmania/src/ModelTypes.h @@ -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 */ diff --git a/stepmania/src/RageTypes.h b/stepmania/src/RageTypes.h index f9b76e003e..c21548d3af 100644 --- a/stepmania/src/RageTypes.h +++ b/stepmania/src/RageTypes.h @@ -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