0001: // ----------------------------------------------------------------------------
0002: //
0003: // load.cpp - 読み込み部分
0004: // 
0005: // Copyright (c) 2001 IF (if@kun-desu.ne.jp)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: #define STRICT
0010: 
0011: #include "main.h"
0012: #include "load.h"
0013: 
0014: // ----------------------------------------------------------------------------
0015: // 頂点の定義
0016: // ----------------------------------------------------------------------------
0017: // 元モデル
0018: typedef struct {
0019:     float x,y,z;
0020:     float nx,ny,nz;
0021:     float tu0,tv0;
0022: }D3DVERTEX;
0023: #define D3DFVF_VERTEX       (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0024: 
0025: // D3D_CUSTOMVERTEX
0026: DWORD dwDecl[] = {
0027:     D3DVSD_STREAM(0),
0028:     D3DVSD_REG( D3DVSDE_POSITION,   D3DVSDT_FLOAT3 ),           // D3DVSDE_POSITION = 0
0029:     D3DVSD_REG( D3DVSDE_BLENDWEIGHT,D3DVSDT_FLOAT4 ),           // D3DVSDE_BLENDWEIGHT = 1
0030:     D3DVSD_REG( D3DVSDE_NORMAL,     D3DVSDT_FLOAT3 ),           // D3DVSDE_NORMAL,  = 3
0031:     D3DVSD_REG( D3DVSDE_TEXCOORD0,  D3DVSDT_FLOAT2 ),           // D3DVSDE_TEXCOORD0= 7
0032:     D3DVSD_END()
0033: };
0034: 
0035: // ----------------------------------------------------------------------------
0036: // モデル
0037: // ----------------------------------------------------------------------------
0038: HRESULT CMyMesh::Load(LPDIRECT3DDEVICE8 lpD3DDev, char *filename)
0039: {
0040:     LPD3DXMESH pMesh, pMeshOpt;
0041:     LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0042:     DWORD i;
0043:     HRESULT hr;
0044:     
0045:     this->Release();
0046:     hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0047:                                 lpD3DDev, NULL,
0048:                                 &pD3DXMtrlBuffer, &this->dwNumMaterials,
0049:                                 &pMesh);
0050:     if(FAILED(hr)) return E_FAIL;
0051: 
0052:     //並び替えておく
0053:     pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0054:     RELEASE(pMesh);
0055: 
0056:     // 大きさを調べておく
0057:     LPDIRECT3DVERTEXBUFFER8 pVB;
0058:     BYTE* pVByte;
0059:     pMeshOpt->GetVertexBuffer(&pVB);
0060:     pVB->Lock(0,0,&pVByte,0);
0061:     D3DXComputeBoundingSphere(pVByte, pMeshOpt->GetNumVertices(), pMeshOpt->GetFVF(), &this->center, &this->radius);
0062:     pVB->Unlock();
0063:     pVB->Release();
0064: 
0065:     //アトリビュートテーブル
0066:     pMeshOpt->GetAttributeTable(NULL,&this->dwNumMaterials);
0067:     this->pSubsetTable = new D3DXATTRIBUTERANGE[this->dwNumMaterials];
0068:     pMeshOpt->GetAttributeTable(this->pSubsetTable, &this->dwNumMaterials);
0069: 
0070:     // FVF変換
0071:     hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDev, &pMesh);
0072:     if(FAILED(hr)) return E_FAIL;
0073:     RELEASE(pMeshOpt);
0074:     D3DXComputeNormals(pMesh,NULL);
0075: 
0076:     // Vertex Bufferにコピーする
0077:     D3DVERTEX* pSrc;
0078:     D3D_CUSTOMVERTEX* pDest;
0079:     LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0080:     WORD* pISrc;
0081:     WORD* pIDest;
0082: 
0083:     DWORD nMeshVertices = pMesh->GetNumVertices();
0084:     DWORD nMeshFaces = pMesh->GetNumFaces();
0085:     lpD3DDev->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),
0086:                             D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &this->pVB);
0087:     lpD3DDev->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&this->pIndex);
0088: 
0089:     pMesh->GetVertexBuffer(&pVB);
0090:     pVB->Lock(0,0,(BYTE**)&pSrc,0);
0091:     this->pVB->Lock(0,0,(BYTE**)&pDest,0);
0092:     for(i=0;i<nMeshVertices;i++){
0093:         pDest->position[0] = pSrc->x;
0094:         pDest->position[1] = pSrc->y;
0095:         pDest->position[2] = pSrc->z;
0096:         pDest->position[3] = 1.0f;
0097:         pDest->normal[0] = pSrc->nx;
0098:         pDest->normal[1] = pSrc->ny;
0099:         pDest->normal[2] = pSrc->nz;
0100:         pDest->normal[3] = 0.0f;
0101:         pDest->texcoord0[0] = pSrc->tu0;
0102:         pDest->texcoord0[1] = pSrc->tv0;
0103:         
0104:         pDest->weight[1] = pSrc->y;
0105:         pDest->weight[0] = 1.0f-pDest->weight[1];
0106: 
0107:         pSrc++;
0108:         pDest++;
0109:     }
0110:     pVB->Unlock();
0111:     pVB->Release();
0112:     this->pVB->Unlock();
0113: 
0114:     //インデックスのコピー
0115:     pMesh->GetIndexBuffer(&pSrcIndex);
0116:     pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0117:     this->pIndex->Lock(0,0,(BYTE**)&pIDest,0);
0118:     CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0119:     pSrcIndex->Unlock();
0120:     this->pIndex->Unlock();
0121:     pSrcIndex->Release();
0122: 
0123:     // pD3DXMtrlBuffer から、質感やテクスチャーの情報を読み取る
0124:     D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0125:     this->pTextures = new LPDIRECT3DTEXTURE8[this->dwNumMaterials];
0126:     this->pMaterials = new D3DMATERIAL8[this->dwNumMaterials];
0127: 
0128:     for(i = 0; i < this->dwNumMaterials; i++){
0129:         this->pMaterials[i] = d3dxMaterials[i].MatD3D;
0130:         this->pMaterials[i].Ambient = this->pMaterials[i].Diffuse;
0131:         hr = D3DXCreateTextureFromFile( lpD3DDev, 
0132:                                         d3dxMaterials[i].pTextureFilename, 
0133:                                         &this->pTextures[i] );
0134:         if(FAILED(hr)) this->pTextures[i] = NULL;
0135:     }
0136:     RELEASE(pD3DXMtrlBuffer);
0137:     
0138:     RELEASE(pMesh);
0139:     
0140:     this->bActive = true;       // 使えるようになりました
0141:     
0142:     return S_OK;
0143: }
0144: // ----------------------------------------------------------------------------
0145: void CMyMesh::Release()
0146: {
0147:     DWORD i;
0148: 
0149:     if(this->pVB == NULL) return;
0150: 
0151:     for(i=0; i<this->dwNumMaterials; i++){
0152:         RELEASE(this->pTextures[i]);
0153:     }
0154:     delete[] this->pTextures;
0155:     delete[] this->pMaterials;
0156:     delete[] this->pSubsetTable;
0157: 
0158:     RELEASE(this->pVB);
0159:     RELEASE(this->pIndex);
0160:     
0161:     this->bActive = false;
0162: }
0163: // ----------------------------------------------------------------------------
0164: // テクスチャー
0165: // ----------------------------------------------------------------------------
0166: HRESULT CTextureMgr::Load(LPDIRECT3DDEVICE8 lpD3DDev, const char *filename, LPDIRECT3DTEXTURE8 *ppTexture)
0167: {
0168:     D3DXCreateTextureFromFileEx(lpD3DDev, filename,0,0,0,0,D3DFMT_A8R8G8B8,
0169:                                 D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0170:                                 0, NULL, NULL, ppTexture);
0171:     
0172:     return S_OK;
0173: }
0174: // ----------------------------------------------------------------------------
0175: void CTextureMgr::Release(LPDIRECT3DTEXTURE8 pTexture)
0176: {
0177:     RELEASE(pTexture);
0178: }
0179: