From ef998e5e84b5fa48bf01a1100fbd4c9815532a01 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Thu, 8 Apr 2004 08:35:38 +0000 Subject: [PATCH] move vertex buffers into a separate object in perparation for HW vertex buffers --- stepmania/src/Milkshape.h | 169 ---------------------------- stepmania/src/Model.cpp | 90 +++++++++------ stepmania/src/Model.h | 5 +- stepmania/src/ModelTypes.cpp | 14 +++ stepmania/src/ModelTypes.h | 10 +- stepmania/src/RageDisplay.h | 38 ++++--- stepmania/src/RageDisplay_D3D.cpp | 108 +++++++++++++++--- stepmania/src/RageDisplay_D3D.h | 5 +- stepmania/src/RageDisplay_Null.cpp | 10 ++ stepmania/src/RageDisplay_Null.h | 5 +- stepmania/src/RageDisplay_OGL.cpp | 155 +++++++++++++++++-------- stepmania/src/RageDisplay_OGL.h | 6 +- stepmania/src/RageModelGeometry.cpp | 49 ++++---- stepmania/src/RageTypes.h | 28 ++--- 14 files changed, 368 insertions(+), 324 deletions(-) delete mode 100644 stepmania/src/Milkshape.h diff --git a/stepmania/src/Milkshape.h b/stepmania/src/Milkshape.h deleted file mode 100644 index 4ad7fcdf59..0000000000 --- a/stepmania/src/Milkshape.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef Milkshape_H -#define Milkshape_H -/* ------------------------------------------------------------------------------ - Class: Milkshape - - Desc: Types defined in msLib.h. C arrays converted to use std::vector - - Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. - Chris Danford ------------------------------------------------------------------------------ -*/ - -/********************************************************************** - * - * Constants - * - **********************************************************************/ - -#define MS_MAX_NAME 32 -#define MS_MAX_PATH 256 - - - -/********************************************************************** - * - * Types - * - **********************************************************************/ - -#ifndef byte -typedef unsigned char byte; -#endif /* byte */ - -#ifndef word -typedef unsigned short word; -#endif /* word */ - - -typedef struct msVec2 { - float v[2]; - operator float* () { return v; }; - operator const float* () const { return v; }; -} msVec2; -typedef struct msVec3 { - float v[3]; - operator float* () { return v; }; - operator const float* () const { return v; }; -} msVec3; -typedef struct msVec4 { - float v[4]; - operator float* () { return v; }; - operator const float* () const { return v; }; -} msVec4; - - -/* msFlag */ -typedef enum { - eSelected = 1, eSelected2 = 2, eHidden = 4, eDirty = 8, eAveraged = 16, eUnused = 32 -} msFlag; - -/* msVertex */ -typedef struct msVertex -{ -// byte nFlags; - msVec3 Vertex; - msVec2 uv; - msVec3 Normal; - char nBoneIndex; -} msVertex; - -/* msTriangle */ -typedef struct -{ -// word nFlags; - word nVertexIndices[3]; -// word nNormalIndices[3]; -// msVec3 Normal; -// byte nSmoothingGroup; -} msTriangle; - -/* msMesh */ -typedef struct msMesh -{ -// byte nFlags; - char szName[MS_MAX_NAME]; - char nMaterialIndex; - - vector Vertices; - -// vector Normals; - - vector Triangles; -} msMesh; - -/* msMaterial */ -class RageTexture; - -typedef struct msMaterial -{ - int nFlags; - char szName[MS_MAX_NAME]; - msVec4 Ambient; - msVec4 Diffuse; - msVec4 Specular; - msVec4 Emissive; - float fShininess; - float fTransparency; - 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? - RageTexture* pTexture; -} msMaterial; - -/* msPositionKey */ -typedef struct msPositionKey -{ - float fTime; - msVec3 Position; -} msPositionKey; - -/* msRotationKey */ -typedef struct msRotationKey -{ - float fTime; - msVec3 Rotation; -} msRotationKey; - -/* msBone */ -typedef struct msBone -{ - int nFlags; - char szName[MS_MAX_NAME]; - char szParentName[MS_MAX_NAME]; - msVec3 Position; - msVec3 Rotation; - - vector PositionKeys; - - int nNumRotationKeys; - int nNumAllocedRotationKeys; - vector RotationKeys; -} msBone; - -/* msModel */ -typedef struct msModel -{ - vector Meshes; - - vector Materials; - - vector Bones; - - int FindBoneByName( const char* szName ) - { - for( unsigned i=0; iDeleteRageModelVertexArray( pTemp ); + } + m_vpTempVerticesByMesh.clear(); } void Model::Load( CString sFile ) @@ -115,10 +122,9 @@ void Model::LoadPieces( CString sMeshesPath, CString sMaterialsPath, CString sBo for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++) { msMesh& mesh = m_pGeometry->m_Meshes[i]; - for (int j = 0; j < (int)mesh.Vertices.size(); j++) + for (int j = 0; j < (int)mesh.Vertices->sizeVerts(); j++) { - RageModelVertex &vert = mesh.Vertices[j]; - if( vert.boneIndex != -1 ) + if( mesh.Vertices->Bone(j) != -1 ) { bHasAnyPerVertexBones = true; break; @@ -129,11 +135,19 @@ void Model::LoadPieces( CString sMeshesPath, CString sMaterialsPath, CString sBo m_bUseTempVertices = bHasAnyPerVertexBones; if( m_bUseTempVertices ) { - m_vTempVerticesByMesh.resize( m_pGeometry->m_Meshes.size() ); - for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++) + m_vpTempVerticesByMesh.resize( m_pGeometry->m_Meshes.size() ); + for (unsigned i = 0; i < m_pGeometry->m_Meshes.size(); i++) { - msMesh& Mesh = m_pGeometry->m_Meshes[i]; - m_vTempVerticesByMesh[i].resize( Mesh.Vertices.size() ); + msMesh &mesh = m_pGeometry->m_Meshes[i]; + RageModelVertexArray *&pOrig = mesh.Vertices; + RageModelVertexArray *&pTemp = m_vpTempVerticesByMesh[i]; + pTemp = DISPLAY->CreateRageModelVertexArray(); + pTemp->resizeVerts( pOrig->sizeVerts() ); + pTemp->resizeTriangles( pOrig->sizeTriangles() ); + + // copy triangles + for (unsigned j = 0; j < pOrig->sizeTriangles(); j++) + pTemp->Triangle(j) = pOrig->Triangle(j); } } } @@ -455,7 +469,7 @@ void Model::DrawPrimitives() for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++) { msMesh *pMesh = &m_pGeometry->m_Meshes[i]; - RageModelVertexVector& TempVertices = m_bUseTempVertices ? m_vTempVerticesByMesh[i] : pMesh->Vertices; + const RageModelVertexArray* TempVertices = m_bUseTempVertices ? m_vpTempVerticesByMesh[i] : pMesh->Vertices; if( pMesh->nMaterialIndex != -1 ) // has a material { @@ -518,7 +532,7 @@ void Model::DrawPrimitives() DISPLAY->PreMultMatrix( mat ); } - DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 ); + DISPLAY->DrawIndexedTriangles( TempVertices ); DISPLAY->SetSphereEnironmentMapping( false ); if( pMesh->nBoneIndex != -1 ) @@ -538,7 +552,7 @@ void Model::DrawPrimitives() for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++) { msMesh *pMesh = &m_pGeometry->m_Meshes[i]; - RageModelVertexVector& TempVertices = m_bUseTempVertices ? m_vTempVerticesByMesh[i] : pMesh->Vertices; + const RageModelVertexArray* pTempVertices = m_bUseTempVertices ? m_vpTempVerticesByMesh[i] : pMesh->Vertices; // apply material if( pMesh->nMaterialIndex != -1 ) @@ -578,9 +592,8 @@ void Model::DrawPrimitives() DISPLAY->ClearAllTextures(); } - DISPLAY->DrawIndexedTriangles( &TempVertices[0], pMesh->Vertices.size(), (Uint16*)&pMesh->Triangles[0], pMesh->Triangles.size()*3 ); + DISPLAY->DrawIndexedTriangles( pTempVertices ); } - } } @@ -610,7 +623,7 @@ void Model::PlayAnimation( CString sAniName, float fPlayRate ) int nBoneCount = (int)m_pCurAnimation->Bones.size(); m_vpBones.resize( nBoneCount ); - int i, j; + int i; for (i = 0; i < nBoneCount; i++) { msBone *pBone = &m_pCurAnimation->Bones[i]; @@ -643,22 +656,25 @@ void Model::PlayAnimation( CString sAniName, float fPlayRate ) for (i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++) { msMesh *pMesh = &m_pGeometry->m_Meshes[i]; - for (j = 0; j < (int)pMesh->Vertices.size(); j++) + RageModelVertexArray* Vertices = pMesh->Vertices; + for (unsigned j = 0; j < Vertices->sizeVerts(); j++) { - RageModelVertex *pVertex = &pMesh->Vertices[j]; -// int nBoneIndex = (pMesh->nBoneIndex!=-1) ? pMesh->nBoneIndex : pVertex->boneIndex; - if (pVertex->boneIndex != -1) +// int nBoneIndex = (pMesh->nBoneIndex!=-1) ? pMesh->nBoneIndex : bone; + RageVector3 &pos = Vertices->Position(j); + Sint8 bone = Vertices->Bone(j); + if (bone != -1) { - pVertex->p[0] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][0]; - pVertex->p[1] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][1]; - pVertex->p[2] -= m_vpBones[pVertex->boneIndex].mAbsolute.m[3][2]; + pos[0] -= m_vpBones[bone].mAbsolute.m[3][0]; + pos[1] -= m_vpBones[bone].mAbsolute.m[3][1]; + pos[2] -= m_vpBones[bone].mAbsolute.m[3][2]; + RageVector3 vTmp; RageMatrix inverse; - RageMatrixTranspose( &inverse, &m_vpBones[pVertex->boneIndex].mAbsolute ); // transpose = inverse for rotation matrices - RageVec3TransformNormal( &vTmp, &pVertex->p, &inverse ); + RageMatrixTranspose( &inverse, &m_vpBones[bone].mAbsolute ); // transpose = inverse for rotation matrices + RageVec3TransformNormal( &vTmp, &pos, &inverse ); - pVertex->p = vTmp; + pos = vTmp; } } } @@ -822,24 +838,30 @@ void Model::Update( float fDelta ) for (int i = 0; i < (int)m_pGeometry->m_Meshes.size(); i++) { msMesh *pMesh = &m_pGeometry->m_Meshes[i]; - RageModelVertexVector& TempVertices = m_vTempVerticesByMesh[i]; - for (int j = 0; j < (int)pMesh->Vertices.size(); j++) + RageModelVertexArray* pOrigVertices = pMesh->Vertices; + RageModelVertexArray* pTempVertices = m_vpTempVerticesByMesh[i]; + for (unsigned j = 0; j < pOrigVertices->sizeVerts(); j++) { - RageModelVertex& tempVert = TempVertices[j]; - RageModelVertex& originalVert = pMesh->Vertices[j]; - tempVert.t = originalVert.t; + RageVector3& tempPos = pTempVertices->Position(j); + RageVector3& originalPos = pOrigVertices->Position(j); + RageVector3& tempNormal = pTempVertices->Normal(j); + RageVector3& originalNormal = pOrigVertices->Normal(j); + RageVector2& tempTex = pTempVertices->TexCoord(j); + RageVector2& originalTex = pOrigVertices->TexCoord(j); + Sint8 bone = pOrigVertices->Bone(j); + + tempTex = originalTex; - if( originalVert.boneIndex == -1 ) + if( bone == -1 ) { - tempVert.n = originalVert.n; - tempVert.p = originalVert.p; + tempNormal = originalNormal; + tempPos = originalPos; } else { - int bone = originalVert.boneIndex; - RageVec3TransformNormal( &tempVert.n, &originalVert.n, &m_vpBones[bone].mFinal ); - RageVec3TransformCoord( &tempVert.p, &originalVert.p, &m_vpBones[bone].mFinal ); + RageVec3TransformNormal( &tempNormal, &originalNormal, &m_vpBones[bone].mFinal ); + RageVec3TransformCoord( &tempPos, &originalPos, &m_vpBones[bone].mFinal ); } } } diff --git a/stepmania/src/Model.h b/stepmania/src/Model.h index 9fb30b6acd..f0e4ced559 100644 --- a/stepmania/src/Model.h +++ b/stepmania/src/Model.h @@ -69,9 +69,8 @@ private: // If true, then render from m_vTempVerticesByBone. // Otherwise, render directly from the mesh's vertices bool m_bUseTempVertices; - - typedef vector RageModelVertexVector; - vector m_vTempVerticesByMesh; + + vector m_vpTempVerticesByMesh; float m_fCurrFrame; CString m_sDefaultAnimation; diff --git a/stepmania/src/ModelTypes.cpp b/stepmania/src/ModelTypes.cpp index 14a95498a0..c75f0610c0 100644 --- a/stepmania/src/ModelTypes.cpp +++ b/stepmania/src/ModelTypes.cpp @@ -16,6 +16,7 @@ #include "RageTexture.h" #include "RageTextureManager.h" #include "RageLog.h" +#include "RageDisplay.h" AnimatedTexture::AnimatedTexture() { @@ -123,3 +124,16 @@ void AnimatedTexture::Unload() fSecsIntoFrame = 0; } + +msMesh::msMesh() +{ + ZERO( szName ); + Vertices = NULL; +} + +msMesh::~msMesh() +{ + Vertices = NULL; +} + + diff --git a/stepmania/src/ModelTypes.h b/stepmania/src/ModelTypes.h index 360e7196cf..ae102fb99e 100644 --- a/stepmania/src/ModelTypes.h +++ b/stepmania/src/ModelTypes.h @@ -66,14 +66,20 @@ typedef struct // byte nSmoothingGroup; // we don't care about this, so don't save it } msTriangle; + +class RageModelVertexArray; + /* msMesh */ typedef struct msMesh { + msMesh(); + ~msMesh(); + // byte nFlags; // we don't care about saving this flag char szName[MS_MAX_NAME]; char nMaterialIndex; - vector Vertices; + RageModelVertexArray* Vertices; // vector Vertices; // vector Normals; // each vertex holds its own normal @@ -83,7 +89,7 @@ typedef struct msMesh // of transforming each vertex on the CPU; char nBoneIndex; // -1 = no bone - vector Triangles; +// vector Triangles; } msMesh; /* msMaterial */ diff --git a/stepmania/src/RageDisplay.h b/stepmania/src/RageDisplay.h index 155994f37a..1c4cfb23a2 100644 --- a/stepmania/src/RageDisplay.h +++ b/stepmania/src/RageDisplay.h @@ -13,6 +13,7 @@ #include "SDL_types.h" #include "RageTypes.h" +#include "ModelTypes.h" const int REFRESH_DEFAULT = 0; struct SDL_Surface; @@ -20,23 +21,27 @@ const int MAX_TEXTURE_UNITS = 2; // VertexArray holds vertex data in a format that is most efficient for // the graphics API. -/*struct VertexArray +class RageModelVertexArray { - VertexArray(); - ~VertexArray(); - unsigned size(); - void resize( unsigned new_size ); - RageVector2& TexCoord( int index ); - RageColor& Color( int index ); - RageVector3& Normal( int index ); - RageVector3& Position( int index ); - // convenience. Remove this later! - void Set( int index, const RageSpriteVertex& v ); +public: + virtual ~RageModelVertexArray() { } + + virtual size_t sizeVerts() const = 0; + virtual void resizeVerts( size_t size ) = 0; + + virtual size_t sizeTriangles() const = 0; + virtual void resizeTriangles( size_t size ) = 0; - struct Impl; - Impl* pImpl; + virtual RageVector3& Position( int index ) = 0; + virtual RageVector3& Normal ( int index ) = 0; + virtual RageVector2& TexCoord( int index ) = 0; + virtual Sint8& Bone ( int index ) = 0; + + virtual msTriangle& Triangle( int index ) = 0; + + virtual void SendVertices() const = 0; }; -*/ + class RageDisplay { @@ -200,12 +205,15 @@ public: virtual void SetSphereEnironmentMapping( bool b ) = 0; + virtual RageModelVertexArray* CreateRageModelVertexArray() = 0; + virtual void DeleteRageModelVertexArray( RageModelVertexArray* p ) = 0; + void DrawQuad( const RageSpriteVertex v[] ) { DrawQuads(v,4); } /* alias. upper-left, upper-right, lower-left, lower-right */ virtual void DrawQuads( const RageSpriteVertex v[], int iNumVerts ) = 0; virtual void DrawFan( const RageSpriteVertex v[], int iNumVerts ) = 0; virtual void DrawStrip( const RageSpriteVertex v[], int iNumVerts ) = 0; virtual void DrawTriangles( const RageSpriteVertex v[], int iNumVerts ) = 0; - virtual void DrawIndexedTriangles( const RageModelVertex v[], int iNumVerts, const Uint16* pIndices, int iNumIndices ) = 0; + virtual void DrawIndexedTriangles( const RageModelVertexArray *p ) = 0; virtual void DrawLineStrip( const RageSpriteVertex v[], int iNumVerts, float LineWidth ); void DrawCircle( const RageSpriteVertex &v, float radius ); diff --git a/stepmania/src/RageDisplay_D3D.cpp b/stepmania/src/RageDisplay_D3D.cpp index 4473f1c7fc..5d36c8523a 100644 --- a/stepmania/src/RageDisplay_D3D.cpp +++ b/stepmania/src/RageDisplay_D3D.cpp @@ -734,6 +734,94 @@ RageDisplay::VideoModeParams RageDisplay_D3D::GetVideoModeParams() const { retur g_pd3dDevice->SetTransform( D3DTS_WORLD, (D3DMATRIX*)&m ); +class RageModelVertexArraySW : public RageModelVertexArray +{ +public: + RageModelVertexArraySW() + { + m_sizeVerts = 0; + m_sizeTriangles = 0; + m_pVertex = NULL; + m_pTriangles = NULL; + } + + ~RageModelVertexArraySW() + { + m_sizeVerts = 0; + m_sizeTriangles = 0; + SAFE_DELETE( m_pVertex ); + SAFE_DELETE( m_pTriangles ); + } + + size_t sizeVerts() const + { + return m_sizeVerts; + } + void resizeVerts( size_t size ) + { + SAFE_DELETE( m_pVertex ); + + m_sizeVerts = size; + m_pVertex = new Vertex[size]; + } + + size_t sizeTriangles() const + { + return m_sizeTriangles; + } + void resizeTriangles( size_t size ) + { + SAFE_DELETE( m_pTriangles ); + + m_sizeTriangles = size; + m_pTriangles = new msTriangle[size]; + } + + RageVector3& Position ( int index ) { return m_pVertex[index].p; } + RageVector2& TexCoord ( int index ) { return m_pVertex[index].t; } + RageVector3& Normal ( int index ) { return m_pVertex[index].n; } + Sint8& Bone ( int index ) { return m_pVertex[index].bone; } + msTriangle& Triangle ( int index ) { return m_pTriangles[index]; } + + void SendVertices() const + { + g_pd3dDevice->SetVertexShader( D3DFVF_RageModelVertex ); + g_pd3dDevice->DrawIndexedPrimitiveUP( + D3DPT_TRIANGLELIST, // PrimitiveType + 0, // MinIndex + m_sizeVerts, // NumVertices + m_sizeTriangles, // PrimitiveCount, + m_pTriangles, // pIndexData, + D3DFMT_INDEX16, // IndexDataFormat, + m_pVertex, // pVertexStreamZeroData, + sizeof(Vertex) // VertexStreamZeroStride + ); + } +protected: + size_t m_sizeVerts; + size_t m_sizeTriangles; + + struct Vertex + { + RageVector3 p; // position + RageVector3 n; // normal + RageVector2 t; // texture coordinates + Sint8 bone; + } *m_pVertex; + + msTriangle *m_pTriangles; +}; + +RageModelVertexArray* RageDisplay_D3D::CreateRageModelVertexArray() +{ + return new RageModelVertexArraySW; +} + +void RageDisplay_D3D::DeleteRageModelVertexArray( RageModelVertexArray* p ) +{ + delete p; +} + void RageDisplay_D3D::DrawQuads( const RageSpriteVertex v[], int iNumVerts ) { ASSERT( (iNumVerts%4) == 0 ); @@ -820,23 +908,13 @@ void RageDisplay_D3D::DrawTriangles( const RageSpriteVertex v[], int iNumVerts ) StatsAddVerts( iNumVerts ); } -void RageDisplay_D3D::DrawIndexedTriangles( const RageModelVertex v[], int iNumVerts, const Uint16 pIndices[], int iNumIndices ) +void RageDisplay_D3D::DrawIndexedTriangles( const RageModelVertexArray *p ) { - if( iNumIndices == 0 ) - return; - g_pd3dDevice->SetVertexShader( D3DFVF_RageModelVertex ); SEND_CURRENT_MATRICES; - g_pd3dDevice->DrawIndexedPrimitiveUP( - D3DPT_TRIANGLELIST, // PrimitiveType - 0, // MinIndex - iNumVerts, // NumVertices - iNumIndices/3, // PrimitiveCount, - pIndices, // pIndexData, - D3DFMT_INDEX16, // IndexDataFormat, - v, // pVertexStreamZeroData, - sizeof(RageModelVertex) // VertexStreamZeroStride - ); - StatsAddVerts( iNumIndices ); + + p->SendVertices(); + + StatsAddVerts( p->sizeTriangles()*3 ); } /* Use the default poly-based implementation. D3D lines apparently don't support diff --git a/stepmania/src/RageDisplay_D3D.h b/stepmania/src/RageDisplay_D3D.h index a9d80738d3..05c19ff549 100644 --- a/stepmania/src/RageDisplay_D3D.h +++ b/stepmania/src/RageDisplay_D3D.h @@ -75,11 +75,14 @@ public: void SetSphereEnironmentMapping( bool b ); + RageModelVertexArray* CreateRageModelVertexArray(); + void DeleteRageModelVertexArray( RageModelVertexArray* p ); + void DrawQuads( const RageSpriteVertex v[], int iNumVerts ); void DrawFan( const RageSpriteVertex v[], int iNumVerts ); void DrawStrip( const RageSpriteVertex v[], int iNumVerts ); void DrawTriangles( const RageSpriteVertex v[], int iNumVerts ); - void DrawIndexedTriangles( const RageModelVertex v[], int iNumVerts, const Uint16* pIndices, int iNumIndices ); + void DrawIndexedTriangles( const RageModelVertexArray *p ); // void DrawLineStrip( const RageSpriteVertex v[], int iNumVerts, float LineWidth ); protected: diff --git a/stepmania/src/RageDisplay_Null.cpp b/stepmania/src/RageDisplay_Null.cpp index 40e9a250ae..a79a0cab70 100644 --- a/stepmania/src/RageDisplay_Null.cpp +++ b/stepmania/src/RageDisplay_Null.cpp @@ -125,3 +125,13 @@ void RageDisplay_Null::EndFrame() ProcessStatsOnFlip(); } + +RageModelVertexArray* RageDisplay_Null::CreateRageModelVertexArray() +{ + ASSERT( 0 ); + return NULL; +} + +void RageDisplay_Null::DeleteRageModelVertexArray( RageModelVertexArray* p ) +{ +} diff --git a/stepmania/src/RageDisplay_Null.h b/stepmania/src/RageDisplay_Null.h index 87f07082f7..a3043f0dd9 100644 --- a/stepmania/src/RageDisplay_Null.h +++ b/stepmania/src/RageDisplay_Null.h @@ -59,12 +59,15 @@ public: const RageVector3 &dir ) { } void SetSphereEnironmentMapping( bool b ) { } + + RageModelVertexArray* CreateRageModelVertexArray(); + void DeleteRageModelVertexArray( RageModelVertexArray* p ); void DrawQuads( const RageSpriteVertex v[], int iNumVerts ) { } void DrawFan( const RageSpriteVertex v[], int iNumVerts ) { } void DrawStrip( const RageSpriteVertex v[], int iNumVerts ) { } void DrawTriangles( const RageSpriteVertex v[], int iNumVerts ) { } - void DrawIndexedTriangles( const RageModelVertex v[], int iNumVerts, const Uint16* pIndices, int iNumIndices ) { } + void DrawIndexedTriangles( const RageModelVertexArray *p ) { } void DrawLineStrip( const RageSpriteVertex v[], int iNumVerts, float LineWidth ) { } protected: diff --git a/stepmania/src/RageDisplay_OGL.cpp b/stepmania/src/RageDisplay_OGL.cpp index ada4ed9512..0fb7553798 100644 --- a/stepmania/src/RageDisplay_OGL.cpp +++ b/stepmania/src/RageDisplay_OGL.cpp @@ -883,51 +883,111 @@ static void SetupVertices( const RageSpriteVertex v[], int iNumVerts ) glNormalPointer(GL_FLOAT, 0, Normal); } -#define SEND_CURRENT_MATRICES \ - glMatrixMode( GL_PROJECTION ); \ - glLoadMatrixf( (const float*)GetProjectionTop() ); \ - RageMatrix modelView; \ - RageMatrixMultiply( &modelView, GetCentering(), GetViewTop() ); \ - RageMatrixMultiply( &modelView, &modelView, GetWorldTop() ); \ - glMatrixMode( GL_MODELVIEW ); \ - glLoadMatrixf( (const float*)&modelView ); \ - -static void SetupVertices( const RageModelVertex v[], int iNumVerts ) +void RageDisplay_OGL::SendCurrentMatrices() { - static float *Vertex, *Texture, *Normal; - static int Size = 0; - if(iNumVerts > Size) + glMatrixMode( GL_PROJECTION ); + glLoadMatrixf( (const float*)GetProjectionTop() ); + RageMatrix modelView; + RageMatrixMultiply( &modelView, GetCentering(), GetViewTop() ); + RageMatrixMultiply( &modelView, &modelView, GetWorldTop() ); + glMatrixMode( GL_MODELVIEW ); + glLoadMatrixf( (const float*)&modelView ); +} + +class RageModelVertexArraySW : public RageModelVertexArray +{ +public: + RageModelVertexArraySW() { - Size = iNumVerts; - delete [] Vertex; - delete [] Texture; - delete [] Normal; - Vertex = new float[Size*3]; - Texture = new float[Size*2]; - Normal = new float[Size*3]; + m_sizeVerts = 0; + m_sizeTriangles = 0; + m_pPosition = NULL; + m_pTexture = NULL; + m_pNormal = NULL; + m_pBone = NULL; + m_pTriangles = NULL; } - for(unsigned i = 0; i < unsigned(iNumVerts); ++i) + ~RageModelVertexArraySW() { - Vertex[i*3+0] = v[i].p[0]; - Vertex[i*3+1] = v[i].p[1]; - Vertex[i*3+2] = v[i].p[2]; - Texture[i*2+0] = v[i].t[0]; - Texture[i*2+1] = v[i].t[1]; - Normal[i*3+0] = v[i].n[0]; - Normal[i*3+1] = v[i].n[1]; - Normal[i*3+2] = v[i].n[2]; + m_sizeVerts = 0; + m_sizeTriangles = 0; + SAFE_DELETE( m_pPosition ); + SAFE_DELETE( m_pTexture ); + SAFE_DELETE( m_pNormal ); + SAFE_DELETE( m_pBone ); + SAFE_DELETE( m_pTriangles ); } - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, Vertex); + + size_t sizeVerts() const + { + return m_sizeVerts; + } + void resizeVerts( size_t size ) + { + SAFE_DELETE( m_pPosition ); + SAFE_DELETE( m_pTexture ); + SAFE_DELETE( m_pNormal ); + SAFE_DELETE( m_pBone ); - glDisableClientState(GL_COLOR_ARRAY); + m_sizeVerts = size; + m_pPosition = new RageVector3[size]; + m_pTexture = new RageVector2[size]; + m_pNormal = new RageVector3[size]; + m_pBone = new Sint8[size]; + } - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, Texture); + size_t sizeTriangles() const + { + return m_sizeTriangles; + } + void resizeTriangles( size_t size ) + { + SAFE_DELETE( m_pTriangles ); - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, Normal); + m_sizeTriangles = size; + m_pTriangles = new msTriangle[size]; + } + + RageVector3& Position ( int index ) { return m_pPosition[index]; } + RageVector2& TexCoord ( int index ) { return m_pTexture[index]; } + RageVector3& Normal ( int index ) { return m_pNormal[index]; } + Sint8& Bone ( int index ) { return m_pBone[index]; } + msTriangle& Triangle ( int index ) { return m_pTriangles[index]; } + + void SendVertices() const + { + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, m_pPosition); + + glDisableClientState(GL_COLOR_ARRAY); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, m_pTexture); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, m_pNormal); + + glDrawElements( GL_TRIANGLES, m_sizeTriangles*3, GL_UNSIGNED_SHORT, m_pTriangles ); + } +protected: + size_t m_sizeVerts; + size_t m_sizeTriangles; + RageVector3 *m_pPosition; + RageVector2 *m_pTexture; + RageVector3 *m_pNormal; + Sint8 *m_pBone; + msTriangle *m_pTriangles; +}; + +RageModelVertexArray* RageDisplay_OGL::CreateRageModelVertexArray() +{ + return new RageModelVertexArraySW; +} + +void RageDisplay_OGL::DeleteRageModelVertexArray( RageModelVertexArray* p ) +{ + delete p; } void RageDisplay_OGL::DrawQuads( const RageSpriteVertex v[], int iNumVerts ) @@ -937,7 +997,7 @@ void RageDisplay_OGL::DrawQuads( const RageSpriteVertex v[], int iNumVerts ) if(iNumVerts == 0) return; - SEND_CURRENT_MATRICES; + SendCurrentMatrices(); SetupVertices( v, iNumVerts ); glDrawArrays( GL_QUADS, 0, iNumVerts ); @@ -950,7 +1010,7 @@ void RageDisplay_OGL::DrawFan( const RageSpriteVertex v[], int iNumVerts ) ASSERT( iNumVerts >= 3 ); glMatrixMode( GL_PROJECTION ); - SEND_CURRENT_MATRICES; + SendCurrentMatrices(); SetupVertices( v, iNumVerts ); glDrawArrays( GL_TRIANGLE_FAN, 0, iNumVerts ); @@ -961,7 +1021,7 @@ void RageDisplay_OGL::DrawStrip( const RageSpriteVertex v[], int iNumVerts ) { ASSERT( iNumVerts >= 3 ); - SEND_CURRENT_MATRICES; + SendCurrentMatrices(); SetupVertices( v, iNumVerts ); glDrawArrays( GL_TRIANGLE_STRIP, 0, iNumVerts ); @@ -974,25 +1034,20 @@ void RageDisplay_OGL::DrawTriangles( const RageSpriteVertex v[], int iNumVerts ) return; ASSERT( (iNumVerts%3) == 0 ); - SEND_CURRENT_MATRICES; + SendCurrentMatrices(); SetupVertices( v, iNumVerts ); glDrawArrays( GL_TRIANGLES, 0, iNumVerts ); StatsAddVerts( iNumVerts ); } -void RageDisplay_OGL::DrawIndexedTriangles( const RageModelVertex v[], int iNumVerts, const Uint16 pIndices[], int iNumIndices ) +void RageDisplay_OGL::DrawIndexedTriangles( const RageModelVertexArray *p ) { - if( iNumIndices == 0 ) - return; - ASSERT( (iNumIndices%3) == 0 ); + SendCurrentMatrices(); - SEND_CURRENT_MATRICES; + p->SendVertices(); - SetupVertices( v, iNumVerts ); -// glInterleavedArrays( RageSpriteVertexFormat, sizeof(RageSpriteVertex), v ); - glDrawElements( GL_TRIANGLES, iNumIndices, GL_UNSIGNED_SHORT, pIndices ); - StatsAddVerts( iNumIndices ); + StatsAddVerts( p->sizeTriangles()*3 ); } void RageDisplay_OGL::DrawLineStrip( const RageSpriteVertex v[], int iNumVerts, float LineWidth ) @@ -1005,7 +1060,7 @@ void RageDisplay_OGL::DrawLineStrip( const RageSpriteVertex v[], int iNumVerts, return; } - SEND_CURRENT_MATRICES; + SendCurrentMatrices(); /* Draw a nice AA'd line loop. One problem with this is that point and line * sizes don't always precisely match, which doesn't look quite right. diff --git a/stepmania/src/RageDisplay_OGL.h b/stepmania/src/RageDisplay_OGL.h index 651c8c1db2..6bdf925778 100644 --- a/stepmania/src/RageDisplay_OGL.h +++ b/stepmania/src/RageDisplay_OGL.h @@ -61,11 +61,14 @@ public: void SetSphereEnironmentMapping( bool b ); + RageModelVertexArray* CreateRageModelVertexArray(); + void DeleteRageModelVertexArray( RageModelVertexArray* p ); + void DrawQuads( const RageSpriteVertex v[], int iNumVerts ); void DrawFan( const RageSpriteVertex v[], int iNumVerts ); void DrawStrip( const RageSpriteVertex v[], int iNumVerts ); void DrawTriangles( const RageSpriteVertex v[], int iNumVerts ); - void DrawIndexedTriangles( const RageModelVertex v[], int iNumVerts, const Uint16* pIndices, int iNumIndices ); + void DrawIndexedTriangles( const RageModelVertexArray *p ); void DrawLineStrip( const RageSpriteVertex v[], int iNumVerts, float LineWidth ); CString GetTextureDiagnostics( unsigned id ) const; @@ -77,6 +80,7 @@ protected: RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf ); PixelFormat GetImgPixelFormat( SDL_Surface* &img, bool &FreeImg, int width, int height ); bool SupportsSurfaceFormat( PixelFormat pixfmt ); + void SendCurrentMatrices(); }; #endif diff --git a/stepmania/src/RageModelGeometry.cpp b/stepmania/src/RageModelGeometry.cpp index 5d54a633a7..236eb266c4 100644 --- a/stepmania/src/RageModelGeometry.cpp +++ b/stepmania/src/RageModelGeometry.cpp @@ -13,6 +13,7 @@ #include "RageUtil.h" #include "RageFile.h" #include "RageMath.h" +#include "RageDisplay.h" RageModelGeometry::RageModelGeometry () @@ -22,6 +23,13 @@ RageModelGeometry::RageModelGeometry () RageModelGeometry::~RageModelGeometry () { + for (unsigned i = 0; i < m_Meshes.size(); i++) + { + msMesh& mesh = m_Meshes[i]; + RageModelVertexArray *&pVertices = mesh.Vertices; + DISPLAY->DeleteRageModelVertexArray( pVertices ); + pVertices = NULL; + } } void RageModelGeometry::OptimizeBones() @@ -32,13 +40,12 @@ void RageModelGeometry::OptimizeBones() // check to see if all vertices have the same bone index bool bAllVertsUseSameBone = true; - char nBoneIndex = !mesh.Vertices.empty() ? mesh.Vertices[0].boneIndex : (char) -1; + char nBoneIndex = !mesh.Vertices->sizeVerts()==0 ? mesh.Vertices->Bone(0) : (char) -1; if( nBoneIndex != -1 ) { - for (unsigned j = 1; j < mesh.Vertices.size(); j++) + for (unsigned j = 1; j < mesh.Vertices->sizeVerts(); j++) { - RageModelVertex& vertex = mesh.Vertices[j]; - if( vertex.boneIndex != nBoneIndex ) + if( mesh.Vertices->Bone(j) != nBoneIndex ) { bAllVertsUseSameBone = false; break; @@ -50,10 +57,9 @@ void RageModelGeometry::OptimizeBones() mesh.nBoneIndex = nBoneIndex; // clear all vertex/bone associations; - for (unsigned j = 0; j < mesh.Vertices.size(); j++) + for (unsigned j = 0; j < mesh.Vertices->sizeVerts(); j++) { - RageModelVertex& vertex = mesh.Vertices[j]; - vertex.boneIndex = -1; + mesh.Vertices->Bone(j) = -1; } } } @@ -99,11 +105,14 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath ) int nNumMeshes = 0; if (sscanf (sLine, "Meshes: %d", &nNumMeshes) == 1) { + ASSERT( m_Meshes.empty() ); m_Meshes.resize( nNumMeshes ); for (i = 0; i < nNumMeshes; i++) { msMesh& mesh = m_Meshes[i]; + RageModelVertexArray *&pVertices = mesh.Vertices; + pVertices = DISPLAY->CreateRageModelVertexArray(); if( f.GetLine( sLine ) <= 0 ) THROW @@ -128,18 +137,18 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath ) if (sscanf (sLine, "%d", &nNumVertices) != 1) THROW - mesh.Vertices.resize( nNumVertices ); + pVertices->resizeVerts( nNumVertices ); for (j = 0; j < nNumVertices; j++) { if( f.GetLine( sLine ) <= 0 ) THROW - RageVector3 Vertex; + RageVector3 pos; RageVector2 uv; if (sscanf (sLine, "%d %f %f %f %f %f %d", &nFlags, - &Vertex[0], &Vertex[1], &Vertex[2], + &pos[0], &pos[1], &pos[2], &uv[0], &uv[1], &nIndex ) != 7) @@ -147,12 +156,11 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath ) THROW } - RageModelVertex& vertex = mesh.Vertices[j]; // vertex.nFlags = nFlags; - memcpy( vertex.p, Vertex, sizeof(vertex.p) ); - memcpy( vertex.t, uv, sizeof(vertex.t) ); - vertex.boneIndex = (byte)nIndex; - RageVec3AddToBounds( RageVector3(Vertex), m_vMins, m_vMaxs ); + pVertices->Position(j) = pos; + pVertices->TexCoord(j) = uv; + pVertices->Bone(j) = (byte)nIndex; + RageVec3AddToBounds( RageVector3(pos), m_vMins, m_vMaxs ); } @@ -193,7 +201,7 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath ) if (sscanf (sLine, "%d", &nNumTriangles) != 1) THROW - mesh.Triangles.resize( nNumTriangles ); + pVertices->resizeTriangles( nNumTriangles ); for (j = 0; j < nNumTriangles; j++) { @@ -215,12 +223,13 @@ void RageModelGeometry::LoadMilkshapeAscii( CString sPath ) // deflate the normals into vertices for( int k=0; k<3; k++ ) { - RageModelVertex& vertex = mesh.Vertices[ nIndices[k] ]; - RageVector3& normal = Normals[ nNormalIndices[k] ]; - vertex.n = normal; + //RageModelVertex& vertex = mesh.Vertices[ nIndices[k] ]; + //RageVector3& normal = Normals[ nNormalIndices[k] ]; + //vertex.n = normal; + mesh.Vertices->Normal( nIndices[k] ) = Normals[ nNormalIndices[k] ]; } - msTriangle& Triangle = mesh.Triangles[j]; + msTriangle& Triangle = pVertices->Triangle(j); // Triangle.nFlags = nFlags; memcpy( &Triangle.nVertexIndices, nIndices, sizeof(Triangle.nVertexIndices) ); // Triangle.nSmoothingGroup = nIndex; diff --git a/stepmania/src/RageTypes.h b/stepmania/src/RageTypes.h index 333d14ec68..13802cbfa9 100644 --- a/stepmania/src/RageTypes.h +++ b/stepmania/src/RageTypes.h @@ -218,19 +218,21 @@ struct RageSpriteVertex // has color RageVector2 t; // texture coordinates }; -struct RageModelVertex // doesn't have color. Relies on material color -{ - /* Zero out by default. */ - RageModelVertex(): - p(0,0,0), - n(0,0,0), - t(0,0) - { } - RageVector3 p; // position - RageVector3 n; // normal - RageVector2 t; // texture coordinates - Sint8 boneIndex; -}; + +//struct RageModelVertex // doesn't have color. Relies on material color +//{ +// /* Zero out by default. */ +// RageModelVertex(): +// p(0,0,0), +// n(0,0,0), +// t(0,0) +// { } +// RageVector3 p; // position +// RageVector3 n; // normal +// RageVector2 t; // texture coordinates +// Sint8 bone; +//}; + // RageMatrix elements are specified in row-major order. This // means that the translate terms are located in the fourth row and the