virtual void createMesh( CMesh& mesh ) { assert( !mesh.isCreated() ); int nverts = mParticleCount * 4; int ntris = mParticleCount * 2; CVertexFormat vformat( CVertexFormat::V_POSITION | CVertexFormat::V_NORMAL | CVertexFormat::COLOR_MASK ); mesh.createResource( nverts, ntris*3, vformat, 2, *RGET_VDECL(vformat), CMesh::BUF_STATIC ); unsigned short* pib = (unsigned short*)mesh.lockIBWrite(); assert( pib ); TVertex* pvb = (TVertex*)mesh.lockVBWrite(); assert( pvb ); for( int i = 0; i < mParticleCount; ++i ) { // IB pib[0] = i*4+0; pib[1] = i*4+1; pib[2] = i*4+2; pib[3] = i*4+0; pib[4] = i*4+2; pib[5] = i*4+3; pib += 6; // VB const SVector3& p = mParticles[i]; D3DCOLOR color = mParticleColor[i]; float ao = gRandom.getFloat(); pvb[0].p = p; pvb[0].n.x = -0.5f; pvb[0].n.y = -0.5f; pvb[0].n.z = ao; pvb[0].diffuse = color; pvb[1].p = p; pvb[1].n.x = 0.5f; pvb[1].n.y = -0.5f; pvb[1].n.z = ao; pvb[1].diffuse = color; pvb[2].p = p; pvb[2].n.x = 0.5f; pvb[2].n.y = 0.5f; pvb[2].n.z = ao; pvb[2].diffuse = color; pvb[3].p = p; pvb[3].n.x = -0.5f; pvb[3].n.y = 0.5f; pvb[3].n.z = ao; pvb[3].diffuse = color; pvb += 4; } mesh.unlockIBWrite(); mesh.unlockVBWrite(); mesh.computeAABBs(); }
bool CMeshBundle::loadMesh( const CResourceId& id, const CResourceId& fullName, CMesh& mesh ) const { // try to load with D3DX // obsolete case: .X files if( CStringHelper::endsWith( fullName.getUniqueName(), ".x" ) || CStringHelper::endsWith( fullName.getUniqueName(), ".X" ) ) { ID3DXBuffer* adjancency = NULL; ID3DXBuffer* material = NULL; ID3DXBuffer* effects = NULL; DWORD matCount; ID3DXMesh* dxmesh = NULL; HRESULT hres = D3DXLoadMeshFromX( fullName.getUniqueName().c_str(), D3DXMESH_SYSTEMMEM, &CD3DDevice::getInstance().getDevice(), &adjancency, &material, &effects, &matCount, &dxmesh ); if( !SUCCEEDED( hres ) ) return false; assert( dxmesh ); if( adjancency ) adjancency->Release(); if( material ) material->Release(); if( effects ) effects->Release(); // // init our mesh assert( !mesh.isCreated() ); // HACK - very limited int formatFlags = 0; DWORD dxFormat = dxmesh->GetFVF(); if( dxFormat & D3DFVF_XYZ ) formatFlags |= CVertexFormat::V_POSITION; if( dxFormat & D3DFVF_NORMAL ) formatFlags |= CVertexFormat::V_NORMAL; if( dxFormat & D3DFVF_TEX1 ) formatFlags |= CVertexFormat::V_UV0_2D; CVertexFormat vertFormat( formatFlags ); // HACK int indexStride = 2; CD3DVertexDecl* vertDecl = RGET_VDECL( CVertexDesc( vertFormat ) ); mesh.createResource( dxmesh->GetNumVertices(), dxmesh->GetNumFaces()*3, vertFormat, indexStride, *vertDecl, CMesh::BUF_STATIC ); // // now, copy data into our mesh void *dxvb, *dxib; dxmesh->LockVertexBuffer( 0, &dxvb ); dxmesh->LockIndexBuffer( 0, &dxib ); void* myvb = mesh.lockVBWrite(); void* myib = mesh.lockIBWrite(); memcpy( myvb, dxvb, mesh.getVertexCount() * mesh.getVertexStride() ); memcpy( myib, dxib, mesh.getIndexCount() * mesh.getIndexStride() ); dxmesh->UnlockVertexBuffer(); dxmesh->UnlockIndexBuffer(); mesh.unlockVBWrite(); mesh.unlockIBWrite(); // // create groups int ngroups; dxmesh->GetAttributeTable( 0, (DWORD*)&ngroups ); D3DXATTRIBUTERANGE *attrs = new D3DXATTRIBUTERANGE[ngroups]; dxmesh->GetAttributeTable( attrs, (DWORD*)&ngroups ); for( int i = 0; i < ngroups; ++i ) { const D3DXATTRIBUTERANGE& a = attrs[i]; mesh.addGroup( CMesh::CGroup( a.VertexStart, a.VertexCount, a.FaceStart, a.FaceCount ) ); } delete[] attrs; // release d3dx mesh dxmesh->Release(); } else { // our own format assert( !mesh.isCreated() ); bool ok = CMeshSerializer::loadMeshFromFile( fullName.getUniqueName().c_str(), mesh ); if( !ok ) return false; } mesh.computeAABBs(); CONSOLE.write( "mesh loaded '" + id.getUniqueName() + "'" ); return true; }