LPD3DXMESH CWall::convertMesh(IDirect3DDevice9* pDevice, LPD3DXMESH& mesh){ D3DVERTEXELEMENT9 decl[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, sizeof(D3DXVECTOR3), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, sizeof(D3DXVECTOR3) * 2, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END()//will be declared on }; LPD3DXMESH newMesh = nullptr; VERTEX* pVerts; HRESULT result = mesh->CloneMesh(D3DXMESH_SYSTEMMEM, decl, pDevice, &newMesh); if (FAILED(result)) return nullptr; float u = 0; float v = 0; bool reverse = false; if (SUCCEEDED(newMesh->LockVertexBuffer(0, (LPVOID*)&pVerts))){ int numVerts = newMesh->GetNumVertices(); for (int i = 0; i < numVerts; i++){ pVerts->tu = u; pVerts->tv = v; if (u == 0 && v==0){ if (reverse) u++; else v++; } else if (v == 1 && u == 0){ u++; } else if (v == 0 && u == 1){ v++; } else{ if (reverse) reverse = false; else reverse = true; u = 0; v = 0; } pVerts++; } newMesh->UnlockVertexBuffer(); //temporary uv generator return newMesh; } else{ return nullptr; } }
bool CMesh::__GenerateDeclMesh(LPD3DXMESH& pMesh) { if (pMesh == NULL) return false; HRESULT hr; LPD3DXMESH pMeshSysMem = pMesh; LPD3DXMESH pMeshSysMem2 = NULL; hr = pMeshSysMem->CloneMesh(D3DXMESH_MANAGED, g_MESH_VERTEX_DESCRIPTION, &DEVICE, &pMeshSysMem2); if( FAILED(hr) ) { DEBUG_WARNING(hr); return false; } //确保顶点包含法线 hr = D3DXComputeNormals(pMeshSysMem2,NULL); if( FAILED(hr) ) { DEBUG_WARNING(hr); return false; } //计算切线 hr = D3DXComputeTangent( pMeshSysMem2, 0, 0, 0, true, NULL ); if( FAILED(hr) ) { DEBUG_WARNING(hr); return false; } /*D3DVERTEXELEMENT9 decl2[]= { {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0}, D3DDECL_END() };*/ hr = pMeshSysMem2->CloneMesh(D3DXMESH_MANAGED, g_MESH_VERTEX_DESCRIPTION, &DEVICE, &pMesh ); if( FAILED(hr) ) { DEBUG_WARNING(hr); return false; } //释放临时网格模型对象 DEBUG_RELEASE(pMeshSysMem); DEBUG_RELEASE(pMeshSysMem2); return true; }
HRESULT Mesh::AdjustMeshDecl() { HRESULT hr; LPD3DXMESH pInMesh = mMesh; LPD3DXMESH pOutMesh = NULL; D3DVERTEXELEMENT9 vertDecl[ MAX_FVF_DECL_SIZE ] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, // exact SH-coefficients {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0}, {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 1}, {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 2}, {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 3}, {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 4}, {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 5}, {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 6}, {0, 144, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 7}, {0, 160, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 8}, {0, 176, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2}, {0, 188, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 3}, D3DDECL_END() }; hr = pInMesh->CloneMesh( pInMesh->GetOptions(), vertDecl, mDevice, &pOutMesh ); PD( hr, L"clone mesh" ); if( FAILED(hr) ) return hr; if( !DoesMeshHaveUsage( D3DDECLUSAGE_NORMAL ) ) { hr = D3DXComputeNormals( pOutMesh, NULL ); PD( hr, L"compute normals" ); if( FAILED(hr) ) return hr; } ReleaseCOM( pInMesh ) mMesh = pOutMesh; return D3D_OK; }
//============================================================================= // メッシュのコンバート関数 //============================================================================ void CInheritanceHierarchy::ConvertMesh(LPD3DXMESH* pMesh) { LPDIRECT3DDEVICE9 *pDevice = CRenderer::GetDevice(); // クローン作製 D3DVERTEXELEMENT9 elements[] = { // 頂点ストリーム(パイプライン)番号, オフセット(頂点の型の先頭からのバイト数), データ型, DEFAULTでOK, 使用用途, 使用用途が同じものを複数使うときに仕分ける番号 { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 24, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 }, { 0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, D3DDECL_END() // 定義終了 絶対必要 }; HRESULT hr = 0; LPD3DXMESH pOldMesh = *pMesh; hr = pOldMesh->CloneMesh(D3DXMESH_MANAGED , elements , *pDevice , pMesh); pOldMesh->Release(); }
HRESULT InitScene() { HRESULT hr; LPD3DXBUFFER errors = NULL; SetWindowText(hwnd, TITLE); if( FAILED(hr = D3DXLoadMeshFromXA("../media/meshes/sphere.X", D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &mesh)) ) { MYERROR("Could not load sphere"); return hr; } // generate tangent frame LPD3DXMESH newmesh = NULL; D3DVERTEXELEMENT9 decl[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, { 0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 }, D3DDECL_END() }; if( FAILED(hr = mesh->CloneMesh(D3DXMESH_MANAGED, decl, device, &newmesh)) ) { MYERROR("Could not clone mesh"); return hr; } mesh->Release(); mesh = NULL; hr = D3DXComputeTangentFrameEx(newmesh, D3DDECLUSAGE_TEXCOORD, 0, D3DDECLUSAGE_TANGENT, 0, D3DDECLUSAGE_BINORMAL, 0, D3DDECLUSAGE_NORMAL, 0, 0, NULL, 0.01f, 0.25f, 0.01f, &mesh, NULL); newmesh->Release(); if( FAILED(hr) ) { MYERROR("Could not compute tangent frame"); return hr; } if( FAILED(hr = CreateChecker(device, 10, 10, 0xff7557a8, 0xffd8d8d8, &tex)) ) { MYERROR("Could not create texture"); return hr; } if( FAILED(hr = D3DXCreateTextureFromFileA(device, "../media/textures/brick_nh.dds", &normalmap)) ) { MYERROR("Could not load normalmap"); return hr; } hr = D3DXCreateEffectFromFileA(device, "../media/shaders/normal.fx", NULL, NULL, D3DXSHADER_DEBUG, NULL, &effect, &errors); if( FAILED(hr) ) { if( errors ) { char* str = (char*)errors->GetBufferPointer(); std::cout << str << "\n\n"; errors->Release(); } MYERROR("Could not create effect"); return hr; } D3DXVECTOR4 uv(3, 1, 0, 1); effect->SetVector("normuv", &uv); D3DXVECTOR3 eye(0, 0, -1.5f); D3DXVECTOR3 look(0, 0, 0); D3DXVECTOR3 up(0, 1, 0); D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 3, (float)screenwidth / (float)screenheight, 0.1f, 10); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixIdentity(&world); return S_OK; }