bool InitResourceDX9(void) { // 取得Direct3D 9裝置 LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9(); // 設定視角轉換矩陣 int w, h; GutGetWindowSize(w, h); float aspect = (float) h / (float) w; Matrix4x4 projection_matrix = GutMatrixPerspectiveRH_DirectX(g_fFovW, aspect, 0.1f, 100.0f); device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &projection_matrix); // 關閉打光 device->SetRenderState(D3DRS_LIGHTING, FALSE); // 畫出正向跟反向的三角形 device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // 載入貼圖 const char *texture_array[] = { "../../textures/uffizi_right.tga", "../../textures/uffizi_left.tga", "../../textures/uffizi_top.tga", "../../textures/uffizi_bottom.tga", "../../textures/uffizi_back.tga", // `右手座標系上 Z+ 為鏡頭後方.` "../../textures/uffizi_front.tga" // `右手座標系上 Z- 為鏡頭前方.` }; g_pTexture = GutLoadCubemapTexture_DX9(texture_array); if ( g_pTexture==NULL ) { // 有些舊硬體不支援 mipmapped cubemap , 改載入 dds 的版本. g_pTexture = GutLoadCubemapTexture_DX9("../../textures/uffizi_cubemap.dds"); if ( g_pTexture==NULL ) return false; } if ( !g_Model_DX9.ConvertToDX9Model(&g_Model) ) return false; return true; }
bool CGutModel_DX9::ConvertToDX9Model(CGutModel *pModel) { if ( pModel->m_iNumMeshes==0 ) return false; printf("Building model for Direct3D9\n"); LPDIRECT3DDEVICE9 pDevice = GutGetGraphicsDeviceDX9(); int i, j; m_iNumMaterials = pModel->m_iNumMaterials; char szTextureName[256]; if ( m_iNumMaterials ) { m_pMaterialArray = new sModelMaterial_DX9[m_iNumMaterials]; for ( i=0; i<m_iNumMaterials; i++ ) { sModelMaterial_DX9 *target = m_pMaterialArray + i; sModelMaterial *source = pModel->m_pMaterialArray + i; D3DMATERIAL9 *pMtl = &m_pMaterialArray[i].m_Material; pMtl->Ambient = *(D3DCOLORVALUE *) &source->m_Ambient; pMtl->Diffuse = *(D3DCOLORVALUE *) &source->m_Diffuse; pMtl->Specular = *(D3DCOLORVALUE *) &source->m_Specular; pMtl->Emissive = *(D3DCOLORVALUE *) &source->m_Emissive; pMtl->Power = source->m_fShininess; target->m_bCullFace = source->m_bCullFace; if ( !strcmp(source->m_szBlendMode, "replace") ) { target->m_bBlend = FALSE; } else { target->m_bBlend = TRUE; if ( !strcmp(source->m_szBlendMode, "blend") ) { target->m_SrcBlend = D3DBLEND_SRCALPHA; target->m_DestBlend = D3DBLEND_INVSRCALPHA; } else if ( !strcmp(source->m_szBlendMode, "add") ) { target->m_SrcBlend = D3DBLEND_ONE; target->m_DestBlend = D3DBLEND_ONE; } else { target->m_SrcBlend = D3DBLEND_ONE; target->m_DestBlend = D3DBLEND_ZERO; target->m_bBlend = FALSE; } } for ( j=0; j<MAX_NUM_TEXTURES; j++ ) { if ( source->m_szTexture[j][0] ) { sprintf(szTextureName, "%s%s", CGutModel::GetTexturePath(), source->m_szTexture[j]); if ( source->m_MapChannel[j]==MAP_CUBEMAP ) { target->m_pTextures[j] = GutLoadCubemapTexture_DX9(szTextureName); } else { target->m_pTextures[j] = GutLoadTexture_DX9(szTextureName); } } else { target->m_pTextures[j] = NULL; } target->m_MapChannel[j] = source->m_MapChannel[j]; } } } m_iNumMeshes = pModel->m_iNumMeshes; m_pMeshArray = new sModelMesh_DX9[m_iNumMeshes]; void *vbuffer_pointer, *ibuffer_pointer; for ( i=0; i<m_iNumMeshes; i++ ) { sModelMesh *pMeshSource = pModel->m_pMeshArray + i; sModelMesh_DX9 *pMesh = m_pMeshArray + i; pMesh->m_iNumVertexChunks = pMeshSource->m_iNumVertexChunks; pMesh->m_pVertexChunk = new sModelVertexChunk_DX9[pMesh->m_iNumVertexChunks]; for ( j=0; j<pMesh->m_iNumVertexChunks; j++ ) { sModelVertexChunk *pVertexChunkTarget = &pMeshSource->m_pVertexChunks[j]; sModelVertexChunk_DX9 *pVertexChunk = pMesh->m_pVertexChunk + j; sVertexDecl *pVertexDecl = &pVertexChunkTarget->m_VertexDecl; pVertexChunk->m_iVertexSize = pVertexChunkTarget->m_VertexDecl.m_iVertexSize; pVertexChunk->CreateFVF(pVertexDecl); pVertexChunk->m_iNumVertices = pVertexChunkTarget->m_iNumVertices; int vbuffer_size = pVertexChunk->m_iNumVertices * pVertexChunk->m_iVertexSize; // 配置一塊顯示卡記憶體 pDevice->CreateVertexBuffer(vbuffer_size, 0, 0, D3DPOOL_MANAGED, &pVertexChunk->m_pVertexBuffer, NULL); if ( D3D_OK==pVertexChunk->m_pVertexBuffer->Lock(0, vbuffer_size, &vbuffer_pointer, 0) ) { // 把頂點資料從主記憶體拷具到顯示卡上 pVertexChunkTarget->OutputVertexBuffer(vbuffer_pointer); pVertexChunk->m_pVertexBuffer->Unlock(); } else { return false; } pVertexChunk->m_iNumIndices = pVertexChunkTarget->m_iNumIndices; int ibuffer_size = pVertexChunk->m_iNumIndices * 2; // 配置一塊顯示卡記憶體 pDevice->CreateIndexBuffer(ibuffer_size, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pVertexChunk->m_pIndexBuffer, NULL); if ( D3D_OK==pVertexChunk->m_pIndexBuffer->Lock(0, ibuffer_size, &ibuffer_pointer, 0) ) { // 把索引資料從主記憶體拷具到顯示卡上 memcpy(ibuffer_pointer, pVertexChunkTarget->m_pIndexArray, ibuffer_size); pVertexChunk->m_pIndexBuffer->Unlock(); } else { return false; } // pVertexChunk->m_iNumBatches = pVertexChunkTarget->m_iNumBatches; if ( pVertexChunk->m_iNumBatches ) { pVertexChunk->m_pBatchArray = new sModelBatch[pVertexChunk->m_iNumBatches]; memcpy(pVertexChunk->m_pBatchArray, pVertexChunkTarget->m_pBatchArray, sizeof(sModelBatch) * pVertexChunk->m_iNumBatches); } } } return true; }