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_NORMAL, D3DVSDT_FLOAT3 ), //D3DVSDE_NORMAL, 3
0030: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ), //D3DVSDE_TEXCOORD0, 7
0031: // D3DVSD_REG(D3DVSDE_TEXCOORD1,D3DVSDT_FLOAT2 ), //D3DVSDE_TEXCOORD1, 8
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),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&this->pVB);
0086: lpD3DDev->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&this->pIndex);
0087:
0088: // LPDIRECT3DVERTEXBUFFER8 pVB;
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->x = pSrc->x;
0094: pDest->y = pSrc->y;
0095: pDest->z = pSrc->z;
0096: pDest->nx = pSrc->nx;
0097: pDest->ny = pSrc->ny;
0098: pDest->nz = pSrc->nz;
0099: pDest->tu0 = pSrc->tu0;
0100: pDest->tv0 = pSrc->tv0;
0101: // pDest->tu1 = pSrc->tu0;
0102: // pDest->tv1 = pSrc->tv0;
0103: pSrc += 1;
0104: pDest += 1;
0105: }
0106: pVB->Unlock();
0107: pVB->Release();
0108: this->pVB->Unlock();
0109:
0110: //インデックスのコピー
0111: pMesh->GetIndexBuffer(&pSrcIndex);
0112: pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0113: this->pIndex->Lock(0,0,(BYTE**)&pIDest,0);
0114: CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0115: pSrcIndex->Unlock();
0116: this->pIndex->Unlock();
0117: pSrcIndex->Release();
0118:
0119: // pD3DXMtrlBuffer から、質感やテクスチャーの情報を読み取る
0120: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0121: this->pTextures = new LPDIRECT3DTEXTURE8[this->dwNumMaterials];
0122: this->pMaterials = new D3DMATERIAL8[this->dwNumMaterials];
0123:
0124: for(i = 0; i < this->dwNumMaterials; i++){
0125: this->pMaterials[i] = d3dxMaterials[i].MatD3D;
0126: this->pMaterials[i].Ambient = this->pMaterials[i].Diffuse;
0127: hr = D3DXCreateTextureFromFile( lpD3DDev,
0128: d3dxMaterials[i].pTextureFilename,
0129: &this->pTextures[i] );
0130: if(FAILED(hr)) this->pTextures[i] = NULL;
0131: }
0132: RELEASE(pD3DXMtrlBuffer);
0133:
0134: RELEASE(pMesh);
0135:
0136: this->bActive = true; // 使えるようになりました
0137:
0138: return S_OK;
0139: }
0140: // ----------------------------------------------------------------------------
0141: void CMyMesh::Release()
0142: {
0143: DWORD i;
0144:
0145: if(this->pVB == NULL) return;
0146:
0147: for(i=0; i<this->dwNumMaterials; i++){
0148: RELEASE(this->pTextures[i]);
0149: }
0150: delete[] this->pTextures;
0151: delete[] this->pMaterials;
0152: delete[] this->pSubsetTable;
0153:
0154: RELEASE(this->pVB);
0155: RELEASE(this->pIndex);
0156:
0157: this->bActive = false; // 準備できるようになるまで、待つ
0158: }
0159: // ----------------------------------------------------------------------------
0160: // テクスチャー
0161: // ----------------------------------------------------------------------------
0162: HRESULT CTextureMgr::Load(LPDIRECT3DDEVICE8 lpD3DDev, const char *filename, LPDIRECT3DTEXTURE8 *ppTexture)
0163: {
0164: // HRESULT hr;
0165: D3DXCreateTextureFromFileEx(lpD3DDev, filename,0,0,0,0,D3DFMT_A8R8G8B8,
0166: D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0167: 0, NULL, NULL, ppTexture);
0168:
0169: return S_OK;
0170: }
0171: // ----------------------------------------------------------------------------
0172: void CTextureMgr::Release(LPDIRECT3DTEXTURE8 pTexture)
0173: {
0174: RELEASE(pTexture);
0175: }
0176: // ----------------------------------------------------------------------------
0177: // 頂点シェーダー
0178: // ----------------------------------------------------------------------------
0179: HRESULT CVertexShaderMgr::Load(LPDIRECT3DDEVICE8 lpD3DDev, const char *filename, DWORD *phVertexShader, const DWORD dwDecl[])
0180: {
0181: HRESULT hr;
0182: LPD3DXBUFFER pshader;
0183:
0184: hr = D3DXAssembleShaderFromFile(filename, 0,NULL, &pshader, NULL);
0185: if ( FAILED(hr) ) return hr;
0186:
0187: hr = lpD3DDev->CreateVertexShader( dwDecl, (DWORD*)pshader->GetBufferPointer(), phVertexShader, 0 );
0188: RELEASE(pshader);
0189: if ( FAILED(hr) ) return hr;
0190:
0191: return S_OK;
0192: }
0193: // ----------------------------------------------------------------------------
0194: void CVertexShaderMgr::Release(LPDIRECT3DDEVICE8 lpD3DDev, DWORD *phVertexShader)
0195: {
0196: if ( *phVertexShader != ~0 ){
0197: lpD3DDev->DeleteVertexShader( *phVertexShader );
0198: *phVertexShader = ~0;
0199: }
0200: }
0201: // ----------------------------------------------------------------------------
0202: // ピクセルシェーダー
0203: // ----------------------------------------------------------------------------
0204: HRESULT CPixelShaderMgr::Load(LPDIRECT3DDEVICE8 lpD3DDev, const char *filename, DWORD *phPixelShader)
0205: {
0206: HRESULT hr;
0207: LPD3DXBUFFER pshader;
0208:
0209: *phPixelShader = NULL;
0210: hr = D3DXAssembleShaderFromFile(filename, 0,NULL, &pshader, NULL);
0211: if ( FAILED(hr) ) return hr;
0212:
0213: hr = lpD3DDev->CreatePixelShader( (DWORD*)pshader->GetBufferPointer(), phPixelShader);
0214: RELEASE(pshader);
0215: if ( FAILED(hr) ) return hr;
0216:
0217: return S_OK;
0218: }
0219: // ----------------------------------------------------------------------------
0220: void CPixelShaderMgr::Release(LPDIRECT3DDEVICE8 lpD3DDev, DWORD *phPixelShader)
0221: {
0222: if ( *phPixelShader != ~0 ){
0223: lpD3DDev->DeleteVertexShader( *phPixelShader );
0224: *phPixelShader = ~0;
0225: }
0226: }
0227: