//------------------------------------------------------------------------------ VOID Cleanup() { if ( g_pIndexBuff ) { g_pIndexBuff->Release(); g_pIndexBuff = NULL; } if ( g_pVertexBuff ) { g_pVertexBuff->Release(); g_pVertexBuff = NULL; } if ( g_pd3dDevice ) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } if ( g_pD3D ) { g_pD3D->Release(); g_pD3D = NULL; } }
/**----------------------------------------------------------------------------- * 초기화 객체들 소거 *------------------------------------------------------------------------------ */ VOID Cleanup() { if ( g_pTexNormal != NULL ) { g_pTexNormal->Release(); } if ( g_pTexHeight != NULL ) { g_pTexHeight->Release(); } if ( g_pTexDiffuse != NULL ) { g_pTexDiffuse->Release(); } if ( g_pIB != NULL ) { g_pIB->Release(); } if ( g_pVB != NULL ) { g_pVB->Release(); } if ( g_pd3dDevice != NULL ) { g_pd3dDevice->Release(); } if ( g_pD3D != NULL ) { g_pD3D->Release(); } }
/**----------------------------------------------------------------------------- * 초기화 객체들 소거 *------------------------------------------------------------------------------ */ VOID Cleanup() { if ( g_pTexHeight != NULL ) { g_pTexHeight->Release(); } if ( g_pTexDiffuse != NULL ) { g_pTexDiffuse->Release(); } if ( g_pIB != NULL ) { g_pIB->Release(); } if ( g_pVB != NULL ) { g_pVB->Release(); } if ( g_pd3dDevice != NULL ) { g_pd3dDevice->Release(); } if ( g_pD3D != NULL ) { g_pD3D->Release(); } delete[] g_pvHeightMap; }
VOID cleanup(){ if(g_pVB != NULL) g_pVB->Release(); if(g_pIB != NULL) g_pIB->Release(); if(g_pDevice != NULL) g_pDevice->Release(); if(g_pD3D != NULL) g_pD3D->Release(); }
void cSubDivSurf::Draw( matrix4& mat ) { LPDIRECT3DDEVICE9 lpDevice = Graphics()->GetDevice(); Graphics()->SetWorldMatrix( mat ); HRESULT hr; // The index buffer LPDIRECT3DINDEXBUFFER9 pIndexBuffer = 0; // Create the index buffer lpDevice->CreateIndexBuffer( m_nTris * 3 * sizeof( WORD ), // Size in bytes of buffer D3DUSAGE_WRITEONLY, // Will only be writing to the buffer D3DFMT_INDEX16, // 16 bit indices D3DPOOL_DEFAULT, // Default memory pooling &pIndexBuffer, // Address of the buffer pointer NULL ); // Reserved. set to NULL // Pointer to the index buffer data WORD* pData = 0; // Lock the index buffer pIndexBuffer->Lock( 0, 0, (void**)&pData, 0 ); // Copy the index data into the index buffer CopyMemory( pData, m_d3dTriList, m_nTris * 3 * sizeof( WORD ) ); // Unlock the index buffer pIndexBuffer->Unlock(); // Tell Direct3D to use the index buffer lpDevice->SetIndices( pIndexBuffer ); // Attach the vertex buffer to rendering stream 0 lpDevice->SetStreamSource( 0, m_pVertexBuffer, 0, sizeof( sVertex ) ); // Draw the primitive hr = lpDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_nVerts, 0, m_nTris ); if( FAILED( hr ) ) { DP0("[cSubDivSurf::Draw]: DrawIndexedPrimitive failed!\n"); } pIndexBuffer->Release(); }
//=============================================== //頂点情報のコンバート //=============================================== //[input] // pD3DX9:Direct3Dデバイス //[return] // HREULT値 //=============================================== bool CXMesh::ConvertVertex(LPDIRECT3DDEVICE9 pD3DX9) { LPD3DXBUFFER pD3DXMtrlBuffer = NULL; /*Vertex Bufferにコピーする*/ D3DVERTEX* pSrc; D3DVERTEX* pDest; LPDIRECT3DINDEXBUFFER9 pSrcIndex; WORD* pISrc; WORD* pIDest; /*VertexBuffer情報取得*/ LPDIRECT3DVERTEXBUFFER9 pVB; MeshData.pMesh->GetVertexBuffer(&pVB); D3DVERTEXBUFFER_DESC Desc; pVB->GetDesc( &Desc ); DWORD nMeshVertices = MeshData.pMesh->GetNumVertices(); DWORD nMeshFaces = MeshData.pMesh->GetNumFaces(); /*頂点バッファを作成*/ pD3DX9->CreateVertexBuffer( Desc.Size, 0, MeshData.pMesh->GetFVF(), D3DPOOL_MANAGED, &m_pMeshVB, NULL ); /*インデックスバッファを作成*/ pD3DX9->CreateIndexBuffer( nMeshFaces * 3 * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pMeshIndex, NULL ); /*頂点バッファをコピー*/ pVB->Lock(0,0,(void**)&pSrc,0); m_pMeshVB->Lock(0,0,(void**)&pDest,0); CopyMemory( pDest, pSrc, Desc.Size ); pVB->Unlock(); pVB->Release(); m_pMeshVB->Unlock(); /*インデックスのコピー*/ MeshData.pMesh->GetIndexBuffer( &pSrcIndex ); pSrcIndex->Lock( 0, 0, (void**)&pISrc, 0 ); m_pMeshIndex->Lock( 0, 0, (void**)&pIDest, 0 ); CopyMemory( pIDest, pISrc, nMeshFaces * 3 * sizeof( WORD ) ); pSrcIndex->Unlock(); m_pMeshIndex->Unlock(); pSrcIndex->Release(); return true; }
void ImGui_ImplDX9_InvalidateDeviceObjects() { if (!g_pd3dDevice) return; if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } // At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both. ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(g_FontTexture == io.Fonts->TexID); if (g_FontTexture) g_FontTexture->Release(); g_FontTexture = NULL; io.Fonts->TexID = NULL; }
~PMDDataDx9() { if(m_Material) delete[] m_Material; if(m_IndexBuffer) m_IndexBuffer->Release(); if(m_VertexBuffer) m_VertexBuffer->Release(); }
//----------------------------------------------------------------------------- //Desc: 生成蒙皮网格模型(含有每个顶点的混合权重、索引和一个骨骼组合表) //----------------------------------------------------------------------------- HRESULT DexAllocateHierarchy::GenerateGameSkinMesh(LPDIRECT3DDEVICE9 device, stDexMeshContainerEx *pMeshContainer) { getLog()->BeginLog(); HRESULT hr = S_OK; if (pMeshContainer->pSkinInfo == NULL) return hr; _SafeRelease( pMeshContainer->MeshData.pMesh ); _SafeRelease( pMeshContainer->pBoneCombinationBuf ); D3DCAPS9 d3dCaps; device->GetDeviceCaps( &d3dCaps ); UINT MaxMatrices = 26; pMeshContainer->NumPaletteEntries = min(MaxMatrices, pMeshContainer->pSkinInfo->GetNumBones()); DWORD Flags = D3DXMESHOPT_VERTEXCACHE; if (d3dCaps.VertexShaderVersion >= D3DVS_VERSION(1, 1)) { Flags |= D3DXMESH_MANAGED; } else { getLog()->Log(log_allert, ".X Animation file shader 錯誤!"); } //_SafeRelease(pMeshContainer->MeshData.pMesh); if(1) { DWORD NumMaxFaceInfl; DWORD Flags = D3DXMESHOPT_VERTEXCACHE; LPDIRECT3DINDEXBUFFER9 pIB; hr = pMeshContainer->pOrigMesh->GetIndexBuffer( &pIB ); if( FAILED( hr ) ) return hr; hr = pMeshContainer->pSkinInfo->GetMaxFaceInfluences( pIB, pMeshContainer->pOrigMesh->GetNumFaces(), &NumMaxFaceInfl ); pIB->Release(); if( FAILED( hr ) ) return hr; // 12 entry palette guarantees that any triangle (4 independent influences per vertex of a tri) // can be handled NumMaxFaceInfl = min( NumMaxFaceInfl, 12 ); if( d3dCaps.MaxVertexBlendMatrixIndex + 1 < NumMaxFaceInfl ) { // HW does not support indexed vertex blending. Use SW instead pMeshContainer->NumPaletteEntries = min( 256, pMeshContainer->pSkinInfo->GetNumBones() ); Flags |= D3DXMESH_SYSTEMMEM; } else { // using hardware - determine palette size from caps and number of bones // If normals are present in the vertex data that needs to be blended for lighting, then // the number of matrices is half the number specified by MaxVertexBlendMatrixIndex. pMeshContainer->NumPaletteEntries = min( ( d3dCaps.MaxVertexBlendMatrixIndex + 1 ) / 2, pMeshContainer->pSkinInfo->GetNumBones() ); Flags |= D3DXMESH_MANAGED; } hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh ( pMeshContainer->pOrigMesh, Flags, pMeshContainer->NumPaletteEntries, pMeshContainer->pAdjacency, NULL, NULL, NULL, &pMeshContainer->NumInfl, &pMeshContainer->NumAttributeGroups, &pMeshContainer->pBoneCombinationBuf, &pMeshContainer->MeshData.pMesh ); if( FAILED( hr ) ) return hr; return 1; } //生成蒙皮网格模型 hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh ( pMeshContainer->pOrigMesh, Flags, pMeshContainer->NumPaletteEntries, pMeshContainer->pAdjacency, NULL, NULL, NULL, &pMeshContainer->NumInfl, &pMeshContainer->NumAttributeGroups, &pMeshContainer->pBoneCombinationBuf, &pMeshContainer->MeshData.pMesh); if (FAILED(hr)) return hr; // FVF has to match our declarator. Vertex shaders are not as forgiving as FF pipeline DWORD NewFVF = (pMeshContainer->MeshData.pMesh->GetFVF() & D3DFVF_POSITION_MASK) | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_LASTBETA_UBYTE4; if (NewFVF != pMeshContainer->MeshData.pMesh->GetFVF()) { LPD3DXMESH pMesh; hr = pMeshContainer->MeshData.pMesh->CloneMeshFVF(pMeshContainer->MeshData.pMesh->GetOptions(), NewFVF, device, &pMesh); if (!FAILED(hr)) { pMeshContainer->MeshData.pMesh->Release(); pMeshContainer->MeshData.pMesh = pMesh; pMesh = NULL; } } D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE]; LPD3DVERTEXELEMENT9 pDeclCur; hr = pMeshContainer->MeshData.pMesh->GetDeclaration(pDecl); if (FAILED(hr)) return hr; // the vertex shader is expecting to interpret the UBYTE4 as a D3DCOLOR, so update the type // NOTE: this cannot be done with CloneMesh, that would convert the UBYTE4 data to float and then to D3DCOLOR // this is more of a "cast" operation pDeclCur = pDecl; while (pDeclCur->Stream != 0xff) { if ((pDeclCur->Usage == D3DDECLUSAGE_BLENDINDICES) && (pDeclCur->UsageIndex == 0)) pDeclCur->Type = D3DDECLTYPE_D3DCOLOR; pDeclCur++; } hr = pMeshContainer->MeshData.pMesh->UpdateSemantics(pDecl); if (FAILED(hr)) return hr; // allocate a buffer for bone matrices, but only if another mesh has not allocated one of the same size or larger if( m_NumBoneMatricesMax < pMeshContainer->pSkinInfo->GetNumBones() ) { m_NumBoneMatricesMax = pMeshContainer->pSkinInfo->GetNumBones(); // Allocate space for blend matrices delete[] m_pBoneMatrices; m_pBoneMatrices = new D3DXMATRIX[m_NumBoneMatricesMax]; if( m_pBoneMatrices == NULL ) { hr = E_OUTOFMEMORY; return hr; } } return hr; }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { wchar_t className[32] = L"Sample"; wchar_t windowName[32] = L"Sample"; //윈도우 클레스 정보 생성 //내가 이러한 윈도를 만들겠다 라는 정보 WNDCLASS WndClass; WndClass.cbClsExtra = 0; //윈도우에서 사용하는 여분의 메모리설정( 그냥 0 이다 신경쓰지말자 ) WndClass.cbWndExtra = 0; //윈도우에서 사용하는 여분의 메모리설정( 그냥 0 이다 신경쓰지말자 ) WndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); //윈도우 배경색상 WndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); //윈도우의 커서모양 결정 WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); //윈도우아이콘모양 결정 WndClass.hInstance = hInstance; //프로그램인스턴스핸들 WndClass.lpfnWndProc = (WNDPROC)WndProc; //윈도우 프로시져 함수 포인터 WndClass.lpszMenuName = NULL; //메뉴이름 없으면 NULL WndClass.lpszClassName = className; //지금 작성하고 있는 윈도우 클레스의 이름 WndClass.style = CS_HREDRAW | CS_VREDRAW; //윈도우 그리기 방식 설정 ( 사이즈가 변경될때 화면갱신 CS_HREDRAW | CS_VREDRAW ) //위에서 작성한 윈도우 클레스정보 등록 RegisterClass( &WndClass ); //윈도우 생성 //생성된 윈도우 핸들을 전역변수 g_hWnd 가 받는다. HWND hWnd = CreateWindow( className, //생성되는 윈도우의 클래스이름 windowName, //윈도우 타이틀바에 출력되는 이름 WS_OVERLAPPEDWINDOW, //윈도우 스타일 WS_OVERLAPPEDWINDOW WINPOS_X, //윈도우 시작 위치 X WINPOS_Y, //윈도우 시작 위치 Y WINSIZE_X, //윈도우 가로 크기 ( 작업영역의 크기가 아님 ) WINSIZE_Y, //윈도우 세로 크기 ( 작업영역의 크기가 아님 ) GetDesktopWindow(), //부모 윈도우 핸들 ( 프로그램에서 최상위 윈도우면 NULL 또는 GetDesktopWindow() ) NULL, //메뉴 ID ( 자신의 컨트롤 객체의 윈도우인경우 컨트롤 ID 가 된 hInstance, //이 윈도우가 물릴 프로그램 인스턴스 핸들 NULL //추가 정보 NULL ( 신경끄자 ) ); //윈도우를 정확한 작업영역 크기로 맞춘다 RECT rcClient = { 0, 0, WINSIZE_X, WINSIZE_Y }; AdjustWindowRect( &rcClient, WS_OVERLAPPEDWINDOW, FALSE ); //rcClient 크기를 작업 영영으로 할 윈도우 크기를 rcClient 에 대입되어 나온다. //윈도우 크기와 윈도우 위치를 바꾸어준다. SetWindowPos( hWnd, NULL, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_NOZORDER | SWP_NOMOVE ); if (!InitDirectX(hWnd)) { return 0; } InitVertexBuffer(); ShowWindow( hWnd, nCmdShow ); //메시지 구조체 MSG msg; ZeroMemory( &msg, sizeof( MSG ) ); int oldT = GetTickCount(); while (msg.message != WM_QUIT) { //PeekMessage 는 메시지 큐에 메시지가 없어도 프로그램이 멈추기 않고 진행이 된다. //이때 메시지큐에 메시지가 없으면 false 가 리턴되고 메시지가 있으면 true 가 리턴이된다. if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage( &msg ); //눌린 키보드 의 문자를 번역하여 WM_CHAR 메시지를 발생시킨다. DispatchMessage( &msg ); //받아온 메시지 정보로 윈도우 프로시져 함수를 실행시킨다. } else { const int curT = GetTickCount(); const int elapseT = curT - oldT; if (elapseT > 15) { oldT = curT; Render(elapseT); } } } if (g_pDevice) g_pDevice->Release(); if (g_pVB) g_pVB->Release(); if (g_pIB) g_pIB->Release(); if (g_pMesh) g_pMesh->Release(); return 0; }
MeshContainer* XFileLoader::CreateMeshContainer() { HRESULT hr; MeshContainer* meshContainer = NULL; Graphics* graphics = Graphics::GetInstance(); IDirect3DDevice9Ptr pD3DDevice = graphics->GetDirect3DDevice(); if( !(m_pD3DMesh->GetFVF() & D3DFVF_NORMAL) ) { LPD3DXMESH tmpMesh = NULL; // 柔軟な頂点フォーマット (FVF) コードを使ってメッシュのコピーを作成する hr = m_pD3DMesh->CloneMeshFVF( m_pD3DMesh->GetOptions(), m_pD3DMesh->GetFVF() | D3DFVF_NORMAL, pD3DDevice, &tmpMesh); // ←ここにコピー if(FAILED(hr)) { goto exit; } // メッシュに含まれる各頂点の法線を計算して、設定する //D3DXComputeNormals( tmpMesh, reinterpret_cast<DWORD*>(pAdjacencyBuf->GetBufferPointer()) ); D3DXComputeNormals( tmpMesh, NULL ); m_pD3DMesh->Release(); m_pD3DMesh = tmpMesh; } D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE]; hr = m_pD3DMesh->GetDeclaration(pDecl); if( FAILED(hr) ) { goto exit; } DWORD vertexNum = m_pD3DMesh->GetNumVertices(); DWORD faceNum = m_pD3DMesh->GetNumFaces(); DWORD attrNum = 0; m_pD3DMesh->GetAttributeTable(NULL, &attrNum); DWORD size = m_pD3DMesh->GetNumBytesPerVertex(); BYTE* pD3DVertice = NULL; m_pD3DMesh->LockVertexBuffer( 0,(LPVOID*)&pD3DVertice ); sVertex* vertices = new sVertex[vertexNum]; for( DWORD vertIdx = 0;vertIdx<vertexNum;vertIdx++ ) { sVertex* vertex = &vertices[vertIdx]; vertex->uv = D3DXVECTOR2(0.0f,0.0f); vertex->color = 0xFFFFFFFF; for( DWORD i=0;i<MAX_FVF_DECL_SIZE;i++ ) { D3DVERTEXELEMENT9& decl = pDecl[i]; if( decl.Stream==0xFF ) { break; } switch( decl.Usage ) { case D3DDECLUSAGE_POSITION: vertex->position = *(D3DXVECTOR3*)(pD3DVertice+vertIdx*size+decl.Offset); vertex->position = vertex->position * m_scale; break; case D3DDECLUSAGE_NORMAL: vertex->normal = *(D3DXVECTOR3*)(pD3DVertice+vertIdx*size+decl.Offset); break; case D3DDECLUSAGE_TEXCOORD: vertex->uv = *(D3DXVECTOR2*)(pD3DVertice+vertIdx*size+decl.Offset); break; case D3DDECLUSAGE_COLOR: vertex->color = *(DWORD*)(pD3DVertice+vertIdx*size+decl.Offset); break; } } } m_pD3DMesh->UnlockVertexBuffer(); LPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL; m_pD3DMesh->GetIndexBuffer( &pIndexBuffer ); D3DINDEXBUFFER_DESC desc; pIndexBuffer->GetDesc( &desc ); pIndexBuffer->Release(); DWORD* indices = new DWORD[faceNum*3]; if( desc.Format==D3DFMT_INDEX16 ) { WORD* pD3DIndices = NULL; m_pD3DMesh->LockIndexBuffer(0,(LPVOID*)&pD3DIndices ); for( DWORD i=0;i<faceNum*3;i++ ) { indices[i] = pD3DIndices[i]; } m_pD3DMesh->UnlockIndexBuffer(); } else { DWORD* pD3DIndices =NULL; m_pD3DMesh->LockIndexBuffer(0,(LPVOID*)&pD3DIndices ); memcpy( indices,pD3DIndices,sizeof(DWORD)*faceNum*3 ); m_pD3DMesh->UnlockIndexBuffer(); } D3DXATTRIBUTERANGE *attrList = new D3DXATTRIBUTERANGE[attrNum]; m_pD3DMesh->GetAttributeTable(attrList, &attrNum); meshContainer = new MeshContainer; meshContainer->pMesh = new Mesh; meshContainer->pMesh->Create( vertexNum,faceNum,attrNum ); meshContainer->pMesh->SetVertices( vertices ); meshContainer->pMesh->SetIndices( indices ); meshContainer->pMesh->SetAttributeRanges( attrList ); delete[] vertices; delete[] indices; delete[] attrList; meshContainer->materialNum = m_Materials; meshContainer->pMaterials = new sMaterial[m_Materials]; D3DXMATERIAL* pD3DMaterials = (D3DXMATERIAL*)m_pMaterialBuf->GetBufferPointer(); for( DWORD i=0;i<m_Materials;i++ ) { sMaterial* pMaterial = &meshContainer->pMaterials[i]; D3DXMATERIAL* pD3DMaterial = &pD3DMaterials[i]; pMaterial->colorDiffuse = pD3DMaterial->MatD3D.Diffuse; pMaterial->colorSpecular.r = pD3DMaterial->MatD3D.Specular.r; pMaterial->colorSpecular.g = pD3DMaterial->MatD3D.Specular.g; pMaterial->colorSpecular.b = pD3DMaterial->MatD3D.Specular.b; pMaterial->colorSpecular.a = 0.0f; pMaterial->colorAmbient.r = pD3DMaterial->MatD3D.Diffuse.r; pMaterial->colorAmbient.g = pD3DMaterial->MatD3D.Diffuse.g; pMaterial->colorAmbient.b = pD3DMaterial->MatD3D.Diffuse.b; pMaterial->colorAmbient.a = 0.0f; pMaterial->colorEmissive.r = pD3DMaterial->MatD3D.Emissive.r; pMaterial->colorEmissive.g = pD3DMaterial->MatD3D.Emissive.g; pMaterial->colorEmissive.b = pD3DMaterial->MatD3D.Emissive.b; pMaterial->colorEmissive.a = 0.0f; pMaterial->specularPower = pD3DMaterial->MatD3D.Power; TCHAR path[MAX_PATH]; _tcscpy_s( path,m_path.c_str() ); tstring texFileName; tstring sphereFileName; if( pD3DMaterial->pTextureFilename && strlen(pD3DMaterial->pTextureFilename)>0 ) { tstring filename = to_tstring(pD3DMaterial->pTextureFilename); tstring::size_type index = filename.find( _T("*") ); if( index != tstring::npos ) { sphereFileName = filename.substr( index+1 ); PathAppend( path,sphereFileName.c_str() ); sphereFileName = path; PathRemoveFileSpec( path ); texFileName = filename.erase( index ); PathAppend( path,texFileName.c_str() ); texFileName = path; PathRemoveFileSpec( path ); } else { texFileName = filename; PathAppend( path,texFileName.c_str() ); texFileName = path; PathRemoveFileSpec( path ); } tstring ext = PathFindExtension( texFileName.c_str() ); if( ext == _T(".sph" ) || ext == _T(".spa") ) { sphereFileName = texFileName; texFileName = _T(""); } } if( !texFileName.empty() ) { TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( texFileName ); if( !pTex ) { pTex = TexturePtr(new Texture); if( pTex->CreateFromFile( texFileName ) ) { ResourceManager::GetInstance().AddResource( texFileName,pTex ); } else { pTex.reset(); } } if( pTex ) { pMaterial->textureDiffuse = pTex; } } if( !sphereFileName.empty() ) { TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( sphereFileName ); if( !pTex ) { pTex = TexturePtr(new Texture); if( pTex->CreateFromFile( sphereFileName ) ) { ResourceManager::GetInstance().AddResource( sphereFileName,pTex ); } else { pTex.reset(); } } if( pTex ) { pMaterial->textureSphere = pTex; } tstring ext = PathFindExtension( sphereFileName.c_str() ); if( ext == _T(".sph" ) ) { pMaterial->spheremap = eSPHEREMAP_MUL; } else if( ext == _T(".spa") ) { pMaterial->spheremap = eSPHEREMAP_ADD; } } } exit: if( m_pMaterialBuf ) { m_pMaterialBuf->Release(); m_pMaterialBuf = NULL; } if( m_pEffectInstancesBuf ) { m_pEffectInstancesBuf->Release(); m_pEffectInstancesBuf = NULL; } if( m_pAdjacencyBuf ) { m_pAdjacencyBuf->Release(); m_pAdjacencyBuf = NULL; } if( m_pD3DMesh ) { m_pD3DMesh->Release(); m_pD3DMesh = NULL; } return meshContainer; }
void CSampleRigidParticlesAndTerrain::InititialisePhysics() { neV3 gravity; gravity.Set(0.0f, -8.0f, 0.0f); neSimulatorSizeInfo sizeInfo; sizeInfo.rigidParticleCount = NUMBER_OF_PARTICLES; sizeInfo.animatedBodiesCount = WALL_NUMBER; sizeInfo.geometriesCount = NUMBER_OF_PARTICLES * GEOMETRY_PER_BODY + WALL_NUMBER; { //dont need any of these sizeInfo.rigidBodiesCount = 0; sizeInfo.constraintsCount = 0; } s32 totalBody = NUMBER_OF_PARTICLES + WALL_NUMBER; sizeInfo.overlappedPairsCount = totalBody * (totalBody - 1) / 2; sim = neSimulator::CreateSimulator(sizeInfo, &all, &gravity); neV3 position; position.SetZero(); for (s32 j = 0; j < NUMBER_OF_PARTICLES; j++) { position.Set(0.0f, 2.0f * j + 20.0f, 0.0f); //position.Set(13.5f, 20.0f, 1.5f); MakeParticle(position, j); } //SetUpTerrain terrainRender.SetGraphicMesh(L"model\\landscape2.x"); terrainRender.SetDiffuseColor(D3DXCOLOR(0.1f,0.5f,0.1f,1.0f)); LPD3DXMESH lpterrainD3Dmesh = terrainRender.mMesh.GetMesh(); neTriangleMesh triMesh; triMesh.vertexCount = lpterrainD3Dmesh->GetNumVertices(); triMesh.triangleCount = lpterrainD3Dmesh->GetNumFaces(); neV3 * verts = new neV3[triMesh.vertexCount]; // DWORD dwFVF = lpterrainD3Dmesh->GetFVF(); DWORD dwOptions = lpterrainD3Dmesh->GetOptions(); DWORD dwNumFaces = lpterrainD3Dmesh->GetNumFaces(); DWORD dwNumVertices = lpterrainD3Dmesh->GetNumVertices(); DWORD dwBytes = lpterrainD3Dmesh->GetNumBytesPerVertex(); LPDIRECT3DVERTEXBUFFER9 pVB; lpterrainD3Dmesh->GetVertexBuffer(&pVB); byte* pBuffer; pVB->Lock(0, 0, (void**)&pBuffer, 0); byte* pPointer = pBuffer; for (int i = 0;i< triMesh.vertexCount;i++) { if (dwFVF & D3DFVF_XYZ) { D3DVECTOR *d3dvector; d3dvector = (D3DVECTOR*)pPointer; verts[i].Set(d3dvector->x,d3dvector->y,d3dvector->z); pPointer += sizeof(D3DVECTOR); } //if (dwFVF & D3DFVF_NORMAL) //{ // //don't care the NORMAL data // pPointer += sizeof(D3DVECTOR); //} //if (dwFVF & D3DFVF_TEX1) //{ // pPointer += 8; //} pPointer += dwBytes - sizeof(D3DVECTOR); } pVB->Unlock(); pVB->Release(); // triMesh.vertices = verts; neTriangle * tri = new neTriangle[triMesh.triangleCount]; s32 * triindex = new s32[triMesh.triangleCount * 3]; // LPDIRECT3DINDEXBUFFER9 pIB; lpterrainD3Dmesh->GetIndexBuffer(&pIB); D3DINDEXBUFFER_DESC kDesc; pIB->GetDesc(&kDesc); dwBytes = 0; if (kDesc.Format & D3DFMT_INDEX16) { dwBytes = 2 * sizeof(byte); } else if (kDesc.Format & D3DFMT_INDEX32) { dwBytes = 4 * sizeof(byte); } pIB->Lock(0, 0, (void**)&pBuffer, 0); pPointer = pBuffer; while ((pPointer - pBuffer) < kDesc.Size) { if (dwBytes == 2*sizeof(byte)) { //16bit triindex[(pPointer-pBuffer)/dwBytes] = *((s16*)pPointer); } else if (dwBytes == 4*sizeof(byte)) { //32bit triindex[(pPointer-pBuffer)/dwBytes] = *((s32*)pPointer); } pPointer += dwBytes; } pIB->Unlock(); pIB->Release(); // for (s32 i = 0; i < triMesh.triangleCount; i++) { tri[i].indices[0] = triindex[i * 3]; tri[i].indices[1] = triindex[i * 3 + 1]; tri[i].indices[2] = triindex[i * 3 + 2]; tri[i].materialID = 0; tri[i].flag = neTriangle::NE_TRI_TRIANGLE; //tri[i].flag = neTriangle::NE_TRI_HEIGHT_MAP; } triMesh.triangles = tri; sim->SetTerrainMesh(&triMesh); //SetUpRoom ground = sim->CreateAnimatedBody(); neGeometry * geom = ground->AddGeometry(); geom->SetBoxSize(gFloor.boxSize); ground->UpdateBoundingInfo(); ground->SetPos(gFloor.pos); groundRender.SetGraphicBox(gFloor.boxSize[0], gFloor.boxSize[1], gFloor.boxSize[2]); }
void Cleanup() { // release fonts if (gpFont) { gpFont->Release(); gpFont = NULL; } // release models if (gpTeapot) { gpTeapot->Release(); gpTeapot = NULL; } // release shaders if (gpEnvironmentMappingShader) { gpEnvironmentMappingShader->Release(); gpEnvironmentMappingShader = NULL; } if (gpNoEffect) { gpNoEffect->Release(); gpNoEffect = NULL; } if (gpGrayScale) { gpGrayScale->Release(); gpGrayScale = NULL; } if (gpSepia) { gpSepia->Release(); gpSepia = NULL; } // release textures if (gpStoneDM) { gpStoneDM->Release(); gpStoneDM = NULL; } if (gpStoneSM) { gpStoneSM->Release(); gpStoneSM = NULL; } if (gpStoneNM) { gpStoneNM->Release(); gpStoneNM = NULL; } if (gpSnowENV) { gpSnowENV->Release(); gpSnowENV = NULL; } // Release the fullscreen quad if (gpFullscreenQuadDecl) { gpFullscreenQuadDecl->Release(); gpFullscreenQuadDecl = NULL; } if (gpFullscreenQuadVB) { gpFullscreenQuadVB->Release(); gpFullscreenQuadVB = NULL; } if (gpFullscreenQuadIB) { gpFullscreenQuadIB->Release(); gpFullscreenQuadIB = NULL; } // release the render target if (gpSceneRenderTarget) { gpSceneRenderTarget->Release(); gpSceneRenderTarget = NULL; } // release D3D if (gpD3DDevice) { gpD3DDevice->Release(); gpD3DDevice = NULL; } if (gpD3D) { gpD3D->Release(); gpD3D = NULL; } }
//----------------------------------------------------------------------------- // Name: InitGeometry() // Desc: Load the mesh and build the material and texture arrays //----------------------------------------------------------------------------- HRESULT InitGeometry() { LPD3DXBUFFER pD3DXMtrlBuffer; LPDIRECT3DVERTEXBUFFER9 pMeshSourceVB; LPDIRECT3DINDEXBUFFER9 pMeshSourceIB; D3DVERTEX* pSrc; D3DVERTEX* pDst; // load the textures we are going to be using if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"cartoonpallet-white-to-black.bmp", &g_pTexture ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"cartoonpallet-black-to-white.bmp", &g_pTexture2 ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"marble.bmp", &marbleTexture ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"background.jpg", &backgroundTexture ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); // Load the mesh from the specified file if( FAILED( D3DXLoadMeshFromX( L"skull.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) g_pd3dDevice->SetFVF(D3DFVF_D3DVERTEX ); g_dwNumVertices = g_pMesh->GetNumVertices(); g_dwNumFaces = g_pMesh->GetNumFaces(); //Clone the mesh to set the FVF LPD3DXMESH pTempSysMemMesh = NULL; if( FAILED( g_pMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, D3DFVF_D3DVERTEX, g_pd3dDevice, &pTempSysMemMesh ) ) ) MessageBox(NULL,L"Mesh clone problem",NULL,NULL); g_pMesh->Release(); g_pMesh = pTempSysMemMesh; //Compute normals in case the meshes have them if( g_pMesh ) D3DXComputeNormals( g_pMesh, NULL ); //Meshes cloned if( FAILED(g_pd3dDevice->CreateVertexBuffer( g_dwNumVertices * sizeof(D3DVERTEX), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &g_pMeshVB, NULL ))) MessageBox(NULL,L"Vertex buffer create problem",NULL,NULL); if( FAILED(g_pd3dDevice->CreateIndexBuffer( g_dwNumFaces * 3 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pMeshIB, NULL ))) MessageBox(NULL,L"Index buffer create problem",NULL,NULL); g_pMesh->GetVertexBuffer(&pMeshSourceVB); g_pMeshVB->Lock( 0, 0, (void**)&pDst, 0 ); pMeshSourceVB->Lock( 0, 0, (void**)&pSrc, 0 ); memcpy( pDst, pSrc, g_dwNumVertices * sizeof(D3DVERTEX) ); g_pMeshVB->Unlock(); pMeshSourceVB->Unlock(); pMeshSourceVB->Release(); g_pMesh->GetIndexBuffer(&pMeshSourceIB); g_pMeshIB->Lock( 0, 0, (void**)&pDst, 0 ); pMeshSourceIB->Lock( 0, 0, (void**)&pSrc, 0 ); memcpy( pDst, pSrc, g_dwNumFaces * 3 * sizeof(WORD)); g_pMeshIB->Unlock(); pMeshSourceIB->Unlock(); pMeshSourceIB->Release(); //// Done with the material buffer pD3DXMtrlBuffer->Release(); return S_OK; }
//------------------------------------------------------------------------------------------------ // Name: XMesh // Desc: Constructs the subset geometry for a D3DXMesh //------------------------------------------------------------------------------------------------ bool XMesh::buildGeometryFromD3DXMesh(LPD3DXMESH d3dxMesh, SubsetGeometry* subsetGeometry, DWORD subsets) { // Check parameters if (APP_ERROR(!d3dxMesh || !subsetGeometry)("Invalid parameter to XMesh::buildGeometryFromD3DXMesh")) return false; // Add a reference to the mesh to counteract freeing it at the end d3dxMesh->AddRef(); // Get the device LPDIRECT3DDEVICE9 pd3dDevice = NULL; d3dxMesh->GetDevice(&pd3dDevice); // If this mesh isn't already in the correct format, have D3D do the grunt work of // converting it. bool generate_normals = false; // Whether or not normals need to be generated for this mesh if ((d3dxMesh->GetFVF() != D3DFVF_GEOMETRYVERTEX) || (D3DFMT_GEOMETRYINDEX == D3DFMT_INDEX32) && ((d3dxMesh->GetOptions() & D3DXMESH_32BIT) == 0)) { // Holds the mesh when its converted to the correct format LPD3DXMESH pTemd3dxMesh = NULL; // Duplicate the loaded mesh into the format if (APP_ERROR(d3dxMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM | ((D3DFMT_GEOMETRYINDEX == D3DFMT_INDEX32) ? D3DXMESH_32BIT : 0), D3DFVF_GEOMETRYVERTEX, pd3dDevice, &pTemd3dxMesh)) ("XMesh couldn't convert the source geometry format")) { d3dxMesh->Release(); pd3dDevice->Release(); return false; } // Generate normals if they didn't exist generate_normals = ((d3dxMesh->GetFVF()&D3DFVF_NORMAL)!=D3DFVF_NORMAL && (D3DFMT_GEOMETRYINDEX&D3DFVF_NORMAL)!=D3DFVF_NORMAL); // Use this mesh instead d3dxMesh->Release(); d3dxMesh = pTemd3dxMesh; } // The mesh must have its attributes sorted before it can be converted to single strips { // Allocate an adjacency buffer DWORD faces = d3dxMesh->GetNumFaces(); DWORD* pAdjacency = new DWORD[faces * 3]; bool failed = false; if (APP_ERROR(FAILED(d3dxMesh->GenerateAdjacency(ADJACENCY_EPSILON, pAdjacency)))("Unable to generate the mesh adjacency")) failed = true; { // Clean up "bowties" in the mesh that prevent lighting from being calculated correctly LPD3DXMESH cleaned_mesh = NULL; DWORD* cleaned_adjacency = new DWORD[faces * 3]; LPD3DXBUFFER errors_and_warnings = NULL; if (!failed && APP_ERROR(FAILED(D3DXCleanMesh(D3DXCLEAN_BOWTIES, d3dxMesh, pAdjacency, &cleaned_mesh, cleaned_adjacency, &errors_and_warnings))) ("Failed to clean mesh")) { failed = true; if (errors_and_warnings) { DEBUG_ERROR("Mesh cleaning error: %s", (const char*)errors_and_warnings->GetBufferPointer()); } } SAFE_RELEASE(errors_and_warnings); // If we successfully cleaned the mesh, use the new mesh and new set of // adjacencies. Otherwise, just delete anything that was allocated and // keep the original. if (failed) { SAFE_DELETE_ARRAY(cleaned_adjacency); SAFE_RELEASE(cleaned_mesh); } else { SAFE_DELETE_ARRAY(pAdjacency); SAFE_RELEASE(d3dxMesh) pAdjacency = cleaned_adjacency; d3dxMesh = cleaned_mesh; } } // Compute mesh normals, if necessary if (!failed && generate_normals && APP_ERROR(FAILED(D3DXComputeNormals(d3dxMesh, pAdjacency)))("Couldn't generate mesh normals")) { failed = true; } // Optimize the mesh if (!failed && APP_ERROR(FAILED(d3dxMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, pAdjacency, NULL, NULL, NULL))) ("Couldn't optimize mesh attributes")) { failed = true; } // Get rid of the temporary adjacency buffer SAFE_DELETE_ARRAY(pAdjacency); // Return if there was an error if (failed) { SAFE_RELEASE(d3dxMesh); SAFE_RELEASE(pd3dDevice); return false; } } // Lock the vertex buffer GeometryVertex* pXVertices = NULL; if (APP_ERROR(d3dxMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&pXVertices))("Couldn't lock source vertex buffer")) { // Erase this mesh d3dxMesh->Release(); pd3dDevice->Release(); // Failure return false; } // Iterate through all of the materials and copy vertex/index data, and assign material // information for the mesh. for (DWORD subset = 0; subset < subsets; subset++) { // Use D3DX to convert this subset into a nicely indexed form DWORD numStripIndices; LPDIRECT3DINDEXBUFFER9 pSubsetIB; if (APP_ERROR(D3DXConvertMeshSubsetToSingleStrip(d3dxMesh, subset, D3DXMESH_SYSTEMMEM, &pSubsetIB, &numStripIndices))("Couldn't convert mesh subset into indexable strip")) { // Erase any geometry we made DeallocateGeometry(subsetGeometry); // Get rid of the mesh d3dxMesh->UnlockVertexBuffer(); d3dxMesh->Release(); // Free our device pd3dDevice->Release(); // Return the error return false; } D3DINDEXBUFFER_DESC desc; GeometryIndex* pXIndices = NULL; // Check the format of the indices and lock the strip index buffer if (APP_ERROR(pSubsetIB->GetDesc(&desc))("Couldn't get .X mesh IB desc") || (desc.Format != D3DFMT_GEOMETRYINDEX) || APP_ERROR(pSubsetIB->Lock(0, 0, (VOID**)&pXIndices, D3DLOCK_READONLY))("Unable to lock the .X index buffer")) { // Erase any geometry we made DeallocateGeometry(subsetGeometry); // Get rid of the mesh pSubsetIB->Release(); d3dxMesh->UnlockVertexBuffer(); d3dxMesh->Release(); // Free our device pd3dDevice->Release(); // Error! return false; } // This table pairs an index from the .X file to an index in the buffer that // holds the vertices for this subset XIndicesTable xIndicesTable; // For each of the indices in the strip, puts its vertex ID into the indices // table. Use the counter to determine which vertex this is. { GeometryIndex vertexCounter = 0; for (DWORD e = 0; e < numStripIndices; ++e) { // Insert the entry [x-mesh index, subset index] into the table XIndicesTableInsertResult result = xIndicesTable.insert(XIndicesEntry(pXIndices[e], vertexCounter)); // If the result was successful (this isn't a duplicated X-mesh index) increment the vertex counter if (result.second) vertexCounter++; } } // Grab the number of vertices this geometry uses DWORD numVertices = (DWORD)xIndicesTable.size(); // This buffer holds all of the triangles in this subset TriangleList triangles; // This list keeps track of locations in the strip where the winding order changes. This is necessary // because this next part will remove degenerate triangles from the list. std::set<size_t> windingChanges; // Generate the list of triangles from the strip provided for (DWORD t = 0; t < numStripIndices - 2; ++t) { // Build the triangle that will be added to the buffer // CHANGED July 25, 2008: the winding order is wrong here //Triangle tri = { pXIndices[t + 0], pXIndices[t + 1], pXIndices[t + 2] }; Triangle tri = { pXIndices[t + 0], pXIndices[t + 2], pXIndices[t + 1] }; // Convert the triangle into subset-indices by using the lookup table // we generated before. tri.index[0] = xIndicesTable.find(tri.index[0])->second; tri.index[1] = xIndicesTable.find(tri.index[1])->second; tri.index[2] = xIndicesTable.find(tri.index[2])->second; // Check to make sure this triangle isn't degenerate. If it is, we can just skip // this triangle entirely to simplify the geometry. if (tri.index[0] == tri.index[1] || tri.index[1] == tri.index[2] || tri.index[0] == tri.index[2]) { // Try to find the winding in the list std::set<size_t>::iterator currentWinding = windingChanges.find(triangles.size()); // Add this to the winding change list, or remove the change if it's already there if (currentWinding != windingChanges.end()) windingChanges.erase(currentWinding); else windingChanges.insert(triangles.size()); // Don't insert a triangle here continue; } // Add this triangle to the list triangles.push_back(tri); } // Calculate the number of indices we need for the buffer DWORD numGeometryIndices = (DWORD)(triangles.size() * 3); // Allocate the destination geometry Geometry* pGeometry = NULL; if (APP_ERROR(AllocateGeometry(numVertices, numGeometryIndices, &pGeometry))("Couldn't allocate geometry")) { // Erase any geometry we made DeallocateGeometry(subsetGeometry); // Get rid of the mesh pSubsetIB->Unlock(); pSubsetIB->Release(); d3dxMesh->UnlockVertexBuffer(); d3dxMesh->Release(); // Free our device pd3dDevice->Release(); // Error! return false; } // Copy the vertices needed for this subset into the buffer GeometryVertex* pVertices = pGeometry->pVertices; for (XIndicesIterator i = xIndicesTable.begin(); i != xIndicesTable.end(); ++i) { GeometryVertex* pCurrentVertex = &pVertices[i->second]; *pCurrentVertex = pXVertices[i->first]; // Modify the vertex location to make this a unit mesh sitting on the X-Z plane pCurrentVertex->x = pCurrentVertex->x; pCurrentVertex->y = pCurrentVertex->y; pCurrentVertex->z = pCurrentVertex->z; //pVertices[i->second].color = D3DCOLOR_XRGB(255,255,255); // todo: enable color? } // Copy triangles into the indices buffer DWORD index = 0; GeometryIndex* pIndices = pGeometry->pIndices; DWORD windingOrder = 0; for (TriangleIterator t = triangles.begin(); t != triangles.end(); ++t) { // Find this index in the winding list if (windingChanges.find(index / 3) != windingChanges.end()) windingOrder = 1 - windingOrder; // Alternate the winding order so that everything shows up correctly if ((index / 3) % 2 == windingOrder) { pIndices[index + 0] = t->index[0]; pIndices[index + 1] = t->index[1]; pIndices[index + 2] = t->index[2]; } else { pIndices[index + 0] = t->index[1]; pIndices[index + 1] = t->index[0]; pIndices[index + 2] = t->index[2]; } // Increment the index counter index += 3; } // Unlock and delete strip index buffer pSubsetIB->Unlock(); pSubsetIB->Release(); // Store the buffers in the main array std::pair<SubsetGeometry::iterator,bool> result = subsetGeometry->insert(SubsetGeometry::value_type(subset, pGeometry)); if (APP_ERROR(!result.second)("Couldn't insert subset geometry into main array for .X mesh")) { // Get rid of this geometry DeallocateGeometry(pGeometry); DeallocateGeometry(subsetGeometry); // Erase the mesh d3dxMesh->UnlockVertexBuffer(); d3dxMesh->Release(); // Free our device pd3dDevice->Release(); // Return error return false; } //DEBUG_MSG("Subset %i has %i vertices %i indices (%i polygons)\n", subset, numVertices, numGeometryIndices, numGeometryIndices / 3); } // Done with the DirectX mesh. This will not erase the outside mesh. d3dxMesh->UnlockVertexBuffer(); d3dxMesh->Release(); // Free the device reference pd3dDevice->Release(); // Success return true; }
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // If text or lines are blurry when integrating ImGui in your engine: // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) { // Avoid rendering when minimized ImGuiIO& io = ImGui::GetIO(); if (io.DisplaySize.x <= 0.0f || io.DisplaySize.y <= 0.0f) return; // Create and grow buffers if needed if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) { if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } g_VertexBufferSize = draw_data->TotalVtxCount + 5000; if (g_pd3dDevice->CreateVertexBuffer(g_VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0) return; } if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) { if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } g_IndexBufferSize = draw_data->TotalIdxCount + 10000; if (g_pd3dDevice->CreateIndexBuffer(g_IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &g_pIB, NULL) < 0) return; } // Backup the DX9 state IDirect3DStateBlock9* d3d9_state_block = NULL; if (g_pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) return; // Copy and convert all vertices into a single contiguous buffer CUSTOMVERTEX* vtx_dst; ImDrawIdx* idx_dst; if (g_pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) return; if (g_pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) return; for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) { vtx_dst->pos[0] = vtx_src->pos.x; vtx_dst->pos[1] = vtx_src->pos.y; vtx_dst->pos[2] = 0.0f; //vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9 vtx_dst->col = vtx_src->col; vtx_dst->uv[0] = vtx_src->uv.x; vtx_dst->uv[1] = vtx_src->uv.y; vtx_dst++; vtx_src++; } memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); idx_dst += cmd_list->IdxBuffer.Size; } g_pVB->Unlock(); g_pIB->Unlock(); g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX)); g_pd3dDevice->SetIndices(g_pIB); g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); // Setup viewport D3DVIEWPORT9 vp; vp.X = vp.Y = 0; vp.Width = (DWORD)io.DisplaySize.x; vp.Height = (DWORD)io.DisplaySize.y; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; g_pd3dDevice->SetViewport(&vp); // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing g_pd3dDevice->SetPixelShader(NULL); g_pd3dDevice->SetVertexShader(NULL); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false); g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // Setup orthographic projection matrix // Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH() { const float L = 0.5f, R = io.DisplaySize.x+0.5f, T = 0.5f, B = io.DisplaySize.y+0.5f; D3DMATRIX mat_identity = { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } }; D3DMATRIX mat_projection = { 2.0f/(R-L), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f/(T-B), 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f, }; g_pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); g_pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); } // Render command lists int vtx_offset = 0; int idx_offset = 0; for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; if (pcmd->UserCallback) { pcmd->UserCallback(cmd_list, pcmd); } else { const RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; g_pd3dDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)pcmd->TextureId); g_pd3dDevice->SetScissorRect(&r); g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, idx_offset, pcmd->ElemCount/3); } idx_offset += pcmd->ElemCount; } vtx_offset += cmd_list->VtxBuffer.Size; } // Restore the DX9 state d3d9_state_block->Apply(); d3d9_state_block->Release(); }
HRESULT MoonSkinmesh::GenerateSkinmesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer) { HRESULT hr = S_OK; if (pMeshContainer->pSkinInfo == NULL) return hr; SAFE_RELEASE( pMeshContainer->MeshData.pMesh ); SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf ); //index ~~~~~~~~~ DWORD NumMaxFaceInfl; DWORD Flags = D3DXMESHOPT_VERTEXCACHE; LPDIRECT3DINDEXBUFFER9 pIB; hr = pMeshContainer->pOrigMesh->GetIndexBuffer(&pIB); if (FAILED(hr)) goto e_Exit; hr = pMeshContainer->pSkinInfo->GetMaxFaceInfluences(pIB, pMeshContainer->pOrigMesh->GetNumFaces(), &NumMaxFaceInfl); pIB->Release(); if (FAILED(hr)) goto e_Exit; // 12 entry palette guarantees that any triangle (4 independent influences per vertex of a tri) // can be handled NumMaxFaceInfl = min(NumMaxFaceInfl, 12); if (_d3dCaps->MaxVertexBlendMatrixIndex + 1 < NumMaxFaceInfl) { // HW does not support indexed vertex blending. Use SW instead pMeshContainer->NumPaletteEntries = min(256, pMeshContainer->pSkinInfo->GetNumBones()); pMeshContainer->UseSoftwareVP = true; Flags |= D3DXMESH_SYSTEMMEM; } else { // using hardware - determine palette size from caps and number of bones // If normals are present in the vertex data that needs to be blended for lighting, then // the number of matrices is half the number specified by MaxVertexBlendMatrixIndex. pMeshContainer->NumPaletteEntries = min( ( _d3dCaps->MaxVertexBlendMatrixIndex + 1 ) / 2, pMeshContainer->pSkinInfo->GetNumBones() ); pMeshContainer->UseSoftwareVP = false; Flags |= D3DXMESH_MANAGED; } hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh ( pMeshContainer->pOrigMesh, Flags, pMeshContainer->NumPaletteEntries, pMeshContainer->pAdjacency, NULL, NULL, NULL, &pMeshContainer->NumInfl, &pMeshContainer->NumAttributeGroups, &pMeshContainer->pBoneCombinationBuf, &pMeshContainer->MeshData.pMesh); if (FAILED(hr)) goto e_Exit; e_Exit: return hr; }