// this is the function that puts the 3D models into video RAM void init_graphics(void) { // create a vertex buffer interface called v_buffer d3ddev->CreateVertexBuffer(g_Sim.numPoints()*sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL); d3ddev->CreateVertexBuffer(5*sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, CUSTOMFVF, D3DPOOL_MANAGED, &v_bordbuffer, NULL); d3ddev->CreateIndexBuffer(g_Sim.numConstraints() * 2 * sizeof(short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &i_buffer, NULL); HRESULT hr = D3DXCreateFont(d3ddev, 17, 0, FW_NORMAL, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Courier New"), &font ); CUSTOMVERTEX* verts; v_bordbuffer->Lock(0, 0, (void**)&verts, 0); verts[0].X = MINX; verts[0].Y = MINY; verts[1].X = MINX; verts[1].Y = MAXY; verts[2].X = MAXX; verts[2].Y = MAXY; verts[3].X = MAXX; verts[3].Y = MINY; verts[4].X = MINX; verts[4].Y = MINY; verts[0].Z = verts[1].Z = verts[2].Z = verts[3].Z = verts[4].Z = 0.0f; verts[0].COLOR = verts[1].COLOR = verts[2].COLOR = verts[3].COLOR = verts[4].COLOR = D3DCOLOR_XRGB(127, 127, 127); v_bordbuffer->Unlock(); short* indices; i_buffer->Lock(0, 0, (void**)&indices, 0); for (unsigned i = 0; i < g_Sim.numConstraints(); i++) { const std::pair<unsigned, unsigned>& p = g_Sim.constraint(i); indices[2 * i] = p.first; indices[2 * i + 1] = p.second; } i_buffer->Unlock(); }
HRESULT CameraWorkBase::SetIB( LPDIRECT3DINDEXBUFFER9 _pIB, LPVOID _indices, INT _nIndex, INT _Size ) { LPVOID pIndices; if( FAILED( _pIB->Lock( 0, _nIndex * _Size, (VOID**)&pIndices, 0 ) ) ) { MessageBox( NULL, L"CameraWorkBase::m_pIB->Lock() failed.", NULL, MB_OK ); return E_FAIL; } memcpy( pIndices, _indices, _nIndex * _Size ); _pIB->Unlock(); return S_OK; }
//=============================================== //頂点情報のコンバート //=============================================== //[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 LoadMesh(const PMDLoader::DATA *_data) { LPDIRECT3DDEVICE9 device = DirectX9::Instance().Device; HRESULT hr; // 頂点バッファの作成 m_MaxVertex = _data->vert_count.u; hr = device->CreateVertexBuffer( sizeof(Vertex3D::VERTEX) * _data->vert_count.u, D3DUSAGE_WRITEONLY, // 頂点バッファの使用方法 Vertex3D::FVF, // 使用する頂点フォーマット D3DPOOL_MANAGED, // バッファを保持するメモリクエストを指定 &m_VertexBuffer, // 頂点のバッファの先頭アドレス NULL ); Vertex3D::VERTEX *vtx; hr = m_VertexBuffer->Lock(0,0,(void**)&vtx,0); for( unsigned int i = 0; i < _data->vert_count.u ; i++) { vtx[i].pos.x = _data->vertex[i].pos[0].f; vtx[i].pos.y = _data->vertex[i].pos[1].f; vtx[i].pos.z = -_data->vertex[i].pos[2].f; vtx[i].nor.x = _data->vertex[i].normal_vec[0].f; vtx[i].nor.y = _data->vertex[i].normal_vec[1].f; vtx[i].nor.z = -_data->vertex[i].normal_vec[2].f; vtx[i].tex.x = _data->vertex[i].uv[0].f; vtx[i].tex.y = _data->vertex[i].uv[1].f; } hr = m_VertexBuffer->Unlock(); // インデックスバッファの作成 m_MaxIndex = _data->face_vert_count.u; hr = device->CreateIndexBuffer( sizeof( WORD ) * m_MaxIndex, // バッファサイズ D3DUSAGE_WRITEONLY, // 頂点バッファの使用方法 D3DFMT_INDEX16, // 使用する頂点フォーマット D3DPOOL_MANAGED, // バッファを保持するメモリクエストを指定 &m_IndexBuffer, // 頂点インデックスのバッファの先頭アドレス NULL ); WORD *idx; hr = m_IndexBuffer->Lock(0,0,(void**)&idx,0); for( unsigned int i=0; i < _data->face_vert_count.u ; i++) { idx[i] = _data->face_vert_index[i].u; } hr = m_IndexBuffer->Unlock(); }
void D3DQuads_OnRecover (void) { if (!d3d_QuadBuffer) { D3DMain_CreateVertexBuffer (D3D_MAX_QUADS * 4 * sizeof (quadvert_t), D3DUSAGE_DYNAMIC, &d3d_QuadBuffer); d3d_NumQuads = 0; } if (!d3d_QuadIndexes) { unsigned short *ndx = NULL; D3DMain_CreateIndexBuffer16 (D3D_MAX_QUADS * 6, 0, &d3d_QuadIndexes); d3d_QuadIndexes->Lock (0, 0, (void **) &ndx, d3d_GlobalCaps.DefaultLock); // strips? go hang yer bollocks on them. with a 4-entry vertex cache this is just fine for (int i = 0, v = 0; i < D3D_MAX_QUADS; i++, v += 4, ndx += 6) { ndx[0] = v + 0; ndx[1] = v + 1; ndx[2] = v + 2; ndx[3] = v + 0; ndx[4] = v + 2; ndx[5] = v + 3; } d3d_QuadIndexes->Unlock (); d3d_RenderDef.numlock++; } if (!d3d_QuadDecl) { D3DVERTEXELEMENT9 d3d_quadlayout[] = { VDECL (0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0), VDECL (0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0), VDECL (0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0), D3DDECL_END () }; hr = d3d_Device->CreateVertexDeclaration (d3d_quadlayout, &d3d_QuadDecl); if (FAILED (hr)) Sys_Error ("D3DQuads_OnRecover: d3d_Device->CreateVertexDeclaration failed"); } }
void ChangeObject(void) { //顶点数据 CUSTOMVERTEX vertices[] = { { -20.0f, 20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { -20.0f, 20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, 20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, 20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { -20.0f, -20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { -20.0f, -20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, -20.0f, 20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) }, { 20.0f, -20.0f, -20.0f, D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256) } }; VOID * pVertics = 0; g_pVertexBuffer->Lock(0, sizeof(vertices), (void**)&pVertics, 0); memcpy(pVertics, vertices, sizeof(vertices)); g_pVertexBuffer->Unlock(); // 填充索引数据 WORD *pIndices = NULL; g_pIndexBuffer->Lock(0, 0, (void**)&pIndices, 0); // 顶面 pIndices[0] = 0, pIndices[1] = 1, pIndices[2] = 2; pIndices[3] = 0, pIndices[4] = 2, pIndices[5] = 3; // 正面 pIndices[6] = 0, pIndices[7] = 3, pIndices[8] = 7; pIndices[9] = 0, pIndices[10] = 7, pIndices[11] = 4; // 左侧面 pIndices[12] = 0, pIndices[13] = 4, pIndices[14] = 5; pIndices[15] = 0, pIndices[16] = 5, pIndices[17] = 1; // 右侧面 pIndices[18] = 2, pIndices[19] = 6, pIndices[20] = 7; pIndices[21] = 2, pIndices[22] = 7, pIndices[23] = 3; // 背面 pIndices[24] = 2, pIndices[25] = 5, pIndices[26] = 6; pIndices[27] = 2, pIndices[28] = 1, pIndices[29] = 5; // 底面 pIndices[30] = 4, pIndices[31] = 6, pIndices[32] = 5; pIndices[33] = 4, pIndices[34] = 7, pIndices[35] = 6; g_pIndexBuffer->Unlock(); }
void GdsNode::GenOctreeFaceIndex() { if ( !m_bUseOctree ) return; RENDER_OBJECT_CONTAINER::iterator it = m_list_RenderObject.begin(); for ( ; it != m_list_RenderObject.end() ; ++it ) { LPDWORD pIB; GdsRenderObject* rendertoken = it->first; LPDIRECT3DINDEXBUFFER9 pI = rendertoken->GetIndexBuffer(); if( SUCCEEDED( pI->Lock( 0 , 0 , (void**)&pIB , 0 ) ) ) { int iMaxCountIndex = genTriIndex( m_pOctreeRootNode , pIB , 0 ); rendertoken->SetIndexMaxCount( iMaxCountIndex ); } pI->Unlock(); } }
// // Creates a DirectX mesh void DirectX::Mesh::create( void* vertexBuffer, void* indexBuffer, unsigned long FVF, unsigned int nVertices, unsigned int nFaces, unsigned long options ) { // Calculate vertex stride int vertexStride = ((FVF|D3DFVF_XYZ) == FVF) * 12 + ((FVF|D3DFVF_XYZRHW) == FVF) * 12 + ((FVF|D3DFVF_XYZB1) == FVF) * 12 + ((FVF|D3DFVF_XYZB2) == FVF) * 12 + ((FVF|D3DFVF_XYZB3) == FVF) * 12 + ((FVF|D3DFVF_XYZB4) == FVF) * 12 + ((FVF|D3DFVF_XYZB5) == FVF) * 12 + ((FVF|D3DFVF_XYZW) == FVF) * 12 + ((FVF|D3DFVF_NORMAL) == FVF) * 12 + ((FVF|D3DFVF_DIFFUSE) == FVF) * 4 + ((FVF|D3DFVF_SPECULAR) == FVF) * 4 + ((FVF|D3DFVF_TEX1) == FVF) * 8 + ((FVF|D3DFVF_TEX2) == FVF) * 8 + ((FVF|D3DFVF_TEX3) == FVF) * 8 + ((FVF|D3DFVF_TEX4) == FVF) * 8 + ((FVF|D3DFVF_TEX5) == FVF) * 8 + ((FVF|D3DFVF_TEX6) == FVF) * 8 + ((FVF|D3DFVF_TEX7) == FVF) * 8 + ((FVF|D3DFVF_TEX8) == FVF) * 8; // Create mesh of sufficient size to store vertex/index buffer data HRESULT hr = D3DXCreateMeshFVF( nFaces, nVertices, options, FVF, DirectX::Manager::instance( )->getD3DDev( ), &m_mesh ); if( hr ) MessageBox( NULL, L"Call to D3DXCreateMeshFVF has failed.", L"DirectX Engine", NULL ); LPDIRECT3DVERTEXBUFFER9 vb; LPDIRECT3DINDEXBUFFER9 ib; m_mesh->GetVertexBuffer( &vb ); m_mesh->GetIndexBuffer( &ib ); // Lock the ibuffer and load the indices char* pVertices; vb->Lock( NULL, NULL, (void**)&pVertices, D3DLOCK_DISCARD ); memcpy( pVertices, vertexBuffer, nVertices*vertexStride ); vb->Unlock( ); // Lock the vbuffer and load the vertices char* pIndices; ib->Lock( NULL, NULL, (void**)&pIndices, D3DLOCK_DISCARD ); memcpy( pIndices, indexBuffer, nFaces*3*sizeof(short) ); ib->Unlock( ); // Register with the manager if( !(options&D3DXMESH_SYSTEMMEM) ) DirectX::Manager::instance( )->addResource( this ); }
///Create Vertex Buffer HRESULT initVB(){ CUSTOMVERTEX vertices[9]; vertices[0].x = 300; vertices[0].y = 250; vertices[0].z = 0.5f; vertices[0].rhw = 1.0f; vertices[0].color = 0xffff0000; for(int i=0; i<8; ++i){ vertices[i+1].x = (float)(200*sin(i*3.14159/4.0)) + 300; vertices[i+1].y = -(float)(200*cos(i*3.14159/4.0)) + 250; vertices[i+1].z = 0.5f; vertices[i+1].rhw = 1.0f; vertices[i+1].color = 0xff00ff00; } WORD indices[] = { 0,1,2, 0,2,3, 0,3,4, 0,4,5, 0,5,6, 0,6,7, 0,7,8, 0,8,1 }; //Vertex Buffer if(FAILED(g_pDevice->CreateVertexBuffer(9 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL))) return E_FAIL; VOID* pVertices; if(FAILED(g_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0))) return E_FAIL; memcpy(pVertices, vertices, sizeof(vertices)); g_pVB->Unlock(); ///Index Buffer if(FAILED(g_pDevice->CreateIndexBuffer(24* sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL))) return E_FAIL; VOID* pIndices; if(FAILED(g_pIB->Lock(0, sizeof(indices), (void**)&pIndices, 0))) return E_FAIL; memcpy(pIndices, indices, sizeof(indices)); g_pIB->Unlock(); return S_OK; }
HRESULT init_index_buffer() { CUSTOMINDEX indices[] = { { 0, 1, 2 }, { 0, 2, 3 }, /// 윗면 { 4, 6, 5 }, { 4, 7, 6 }, /// 아랫면 { 0, 3, 7 }, { 0, 7, 4 }, /// 왼면 { 1, 5, 6 }, { 1, 6, 2 }, /// 오른면 { 3, 2, 6 }, { 3, 6, 7 }, /// 앞면 { 0, 4, 5 }, { 0, 5, 1 } /// 뒷면 }; if (FAILED( g_pd3dDevice->CreateIndexBuffer( 12 * sizeof(CUSTOMINDEX), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIndexBuff, NULL ))) return E_FAIL; VOID* pIndices; if (FAILED( g_pIndexBuff->Lock( 0, sizeof(indices), (void**)&pIndices, 0 ))) return E_FAIL; memcpy( pIndices, indices, sizeof(indices) ); g_pIndexBuff->Unlock(); return S_OK; }
bool ReadModelFile( const string &fileName, LPDIRECT3DVERTEXBUFFER9 &vtxBuff, int &vtxSize, LPDIRECT3DINDEXBUFFER9 &idxBuff, int &faceSize ) { using namespace std; ifstream fin(fileName.c_str()); if (!fin.is_open()) return false; string vtx, vtx_eq; int numVertices; fin >> vtx >> vtx_eq >> numVertices; if (numVertices <= 0) return false; vtxSize = numVertices; // 버텍스 버퍼 생성. if (FAILED(g_pDevice->CreateVertexBuffer( numVertices * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &vtxBuff, NULL))) { return false; } // 버텍스 버퍼 초기화. Vertex* vertices; if (FAILED(vtxBuff->Lock( 0, sizeof(Vertex), (void**)&vertices, 0))) return false; float num1, num2, num3; for (int i = 0; i < numVertices; i++) { fin >> num1 >> num2 >> num3; vertices[i] = Vertex(num1, num2, num3); } vtxBuff->Unlock(); string idx, idx_eq; int numIndices; fin >> idx >> idx_eq >> numIndices; if (numIndices <= 0) return false; faceSize = numIndices; if (FAILED(g_pDevice->CreateIndexBuffer(numIndices*3*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &idxBuff, NULL))) { return false; } WORD *indices = NULL; idxBuff->Lock(0, 0, (void**)&indices, 0); int num4, num5, num6; for (int i = 0; i < numIndices*3; i+=3) { fin >> num4 >> num5 >> num6; indices[ i] = num4; indices[ i+1] = num5; indices[ i+2] = num6; } idxBuff->Unlock(); ComputeNormals(vtxBuff, vtxSize, idxBuff, faceSize); return true; }
void SetObject(void) { //顶点数据 CUSTOMVERTEX vertices[] = { // 正面顶点数据 { -10.0f, 10.0f, -10.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, -10.0f, 1.0f, 0.0f }, { 10.0f, -10.0f, -10.0f, 1.0f, 1.0f }, { -10.0f, -10.0f, -10.0f, 0.0f, 1.0f }, // 背面顶点数据 { 10.0f, 10.0f, 10.0f, 0.0f, 0.0f }, { -10.0f, 10.0f, 10.0f, 1.0f, 0.0f }, { -10.0f, -10.0f, 10.0f, 1.0f, 1.0f }, { 10.0f, -10.0f, 10.0f, 0.0f, 1.0f }, // 顶面顶点数据 { -10.0f, 10.0f, 10.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f, 1.0f, 0.0f }, { 10.0f, 10.0f, -10.0f, 1.0f, 1.0f }, { -10.0f, 10.0f, -10.0f, 0.0f, 1.0f }, // 底面顶点数据 { -10.0f, -10.0f, -10.0f, 0.0f, 0.0f }, { 10.0f, -10.0f, -10.0f, 1.0f, 0.0f }, { 10.0f, -10.0f, 10.0f, 1.0f, 1.0f }, { -10.0f, -10.0f, 10.0f, 0.0f, 1.0f }, // 左侧面顶点数据 { -10.0f, 10.0f, 10.0f, 0.0f, 0.0f }, { -10.0f, 10.0f, -10.0f, 1.0f, 0.0f }, { -10.0f, -10.0f, -10.0f, 1.0f, 1.0f }, { -10.0f, -10.0f, 10.0f, 0.0f, 1.0f }, // 右侧面顶点数据 { 10.0f, 10.0f, -10.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f, 1.0f, 0.0f }, { 10.0f, -10.0f, 10.0f, 1.0f, 1.0f }, { 10.0f, -10.0f, -10.0f, 0.0f, 1.0f }, }; VOID * pVertics = 0; g_pVertexBuffer->Lock(0, sizeof(vertices), (void**)&pVertics, 0); memcpy(pVertics, vertices, sizeof(vertices)); g_pVertexBuffer->Unlock(); // 填充索引数据 WORD *pIndices = NULL; g_pIndexBuffer->Lock(0, 0, (void**)&pIndices, 0); // 正面索引数据 pIndices[0] = 0; pIndices[1] = 1; pIndices[2] = 2; pIndices[3] = 0; pIndices[4] = 2; pIndices[5] = 3; // 背面索引数据 pIndices[6] = 4; pIndices[7] = 5; pIndices[8] = 6; pIndices[9] = 4; pIndices[10] = 6; pIndices[11] = 7; // 顶面索引数据 pIndices[12] = 8; pIndices[13] = 9; pIndices[14] = 10; pIndices[15] = 8; pIndices[16] = 10; pIndices[17] = 11; // 底面索引数据 pIndices[18] = 12; pIndices[19] = 13; pIndices[20] = 14; pIndices[21] = 12; pIndices[22] = 14; pIndices[23] = 15; // 左侧面索引数据 pIndices[24] = 16; pIndices[25] = 17; pIndices[26] = 18; pIndices[27] = 16; pIndices[28] = 18; pIndices[29] = 19; // 右侧面索引数据 pIndices[30] = 20; pIndices[31] = 21; pIndices[32] = 22; pIndices[33] = 20; pIndices[34] = 22; pIndices[35] = 23; g_pIndexBuffer->Unlock(); }
// 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(); }
//-------------------------------------- //NAME : CreateVertexBuffer() //DESC : 创建图形顶点缓存 //-------------------------------------- void CreateVertexBuffer() { //顶点缓存(Vertex Buffer)是Direct3D用来保存顶点数据的内存空间,可以位于系统内存和图形卡的显存中。 //当Direct3D绘制图形时,将根据这些顶点结构创建一个三角形列表来描述物体的形状和轮廓 /* 在Direct3D中,顶点缓存由IDirect3DVertexBuffer9接口对象表示。在使用顶点缓存之前,需要定义描述顶点的顶点结构,然后可以通过IDirect3DDevice9接口的CreateVertexBuffer方法创建顶点缓存 HRESULT IDirect3DDevice9::CreateVertexBuffer( UINT Length, DWORD Usage, //指定使用缓存的一些附加属性 DWORD FVF, //将要存储在顶点缓存中的灵活顶点格式 D3DPOOL Pool, //一个D3DPOOL枚举类型,用于指定存储顶点缓存或索引缓冲的内存位置,在默认情况下时位于显存中 IDirect3DVertexBuffer9** ppVertexBuffer, //IDirect3DVertexBuffer9接口类型的变量的指针,分别用于接收创建的顶点缓存和索引缓存的指针 HANDLE* pSharedHandle ); */ //创建顶点缓存 g_pd3dDevice->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVertexBuf,NULL); //填充顶点数据 CUSTOMVERTEX*pVertices=NULL; /* 在取得IDirect3DVertexBuffer9接口对象的指针后,就可以通过这该接口的Lock方法获取指向顶点缓存的存储区的指针,并通过该指针访问缓存中的数据 HRESULT IDirect3DVertexBuffer9::Lock( UINT OffsetToLock, //在存储区中加锁的起始位置 UINT SizeToLock, //以字节为单位的加锁的存储区大小,值为0表示整个缓存存储区 BYTE **ppbData, //用于接收被锁定的存储区起始位置的指针,该参数指向的存储区的读写方式由Flags参数指定 DWORD Flags ); */ //锁定缓存区 g_pVertexBuf->Lock(0,0,(void**)&pVertices,0); pVertices[0]=CUSTOMVERTEX(-5.0f,5.0f,-5.0f,D3DCOLOR_XRGB(255,0,0)); pVertices[1]=CUSTOMVERTEX(-5.0f,5.0f,5.0f,D3DCOLOR_XRGB(0,255,0)); pVertices[2]=CUSTOMVERTEX(5.0f,5.0f,5.0f,D3DCOLOR_XRGB(0,0,255)); pVertices[3]=CUSTOMVERTEX(5.0f,5.0f,-5.0f,D3DCOLOR_XRGB(255,255,0)); pVertices[4]=CUSTOMVERTEX(-5.0f,-5.0f,-5.0f,D3DCOLOR_XRGB(0,0,255)); pVertices[5]=CUSTOMVERTEX(-5.0f,-5.0f,5.0f,D3DCOLOR_XRGB(255,255,0)); pVertices[6]=CUSTOMVERTEX(5.0f,-5.0f,5.0f,D3DCOLOR_XRGB(255,0,0)); pVertices[7]=CUSTOMVERTEX(5.0f,-5.0f,-5.0f,D3DCOLOR_XRGB(0,255,0)); //当使用Lock方法对应缓存区进行加锁并完成数据的访问后,需要调用IDirect3DVertexBuffer9接口的Unlock方法对缓存进行解锁 g_pVertexBuf->Unlock(); //创建索引缓存 g_pd3dDevice->CreateIndexBuffer(36*sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_DEFAULT,&g_pIndexBuf,NULL); //填充索引数据 WORD*pIndices=NULL; g_pIndexBuf->Lock(0,0,(void**)&pIndices,0); //顶面由两个三角形组成 pIndices[0]=0,pIndices[1]=1,pIndices[2]=2; pIndices[3]=0,pIndices[4]=2,pIndices[5]=3; //正面 pIndices[6]=0,pIndices[7]=3,pIndices[8]=7; pIndices[9]=0,pIndices[10]=7,pIndices[11]=4; //左侧面 pIndices[12]=0,pIndices[13]=4,pIndices[14]=5; pIndices[15]=0,pIndices[16]=5,pIndices[17]=1; //右侧面 pIndices[18]=2,pIndices[19]=6,pIndices[20]=7; pIndices[21]=2,pIndices[22]=7,pIndices[23]=3; //背面 pIndices[24]=2,pIndices[25]=5,pIndices[26]=6; pIndices[27]=2,pIndices[28]=1,pIndices[29]=5; //底面 pIndices[30]=4,pIndices[31]=6,pIndices[32]=5; pIndices[33]=4,pIndices[34]=7,pIndices[35]=6; g_pIndexBuf->Unlock(); }
BOOL jcd3d::jcd3d_setup() { srand((UINT)time(NULL)); lpd3dd->CreateVertexBuffer( CORNOR_AMOUNT * (LAYER_AMOUNT + 1) * sizeof(JCD3D_Vertex_xyz_diffuse), D3DUSAGE_WRITEONLY, JCD3D_Vertex_xyz_diffuse::FVF, D3DPOOL_MANAGED, &lpvb, NULL ); // i5----i6----i7----i8 // | /| / | /| // | / | / | / | // | / | / | / | // |/ | / |/ | // i1----i2----i3----i4 JCD3D_Vertex_xyz_diffuse* vb; FLOAT degreeInc = D3DX_PI * 2 / CORNOR_AMOUNT; FLOAT radiusDegree = 0; FLOAT radiusDegreeInc = D3DX_PI * 2 / LAYER_AMOUNT; lpvb->Lock(0, 0, (VOID**)&vb, 0); for(INT layer = 0; layer < LAYER_AMOUNT + 1; layer++) { for(INT corner = 0; corner < CORNOR_AMOUNT; corner++) { vb[layer * CORNOR_AMOUNT + corner] = JCD3D_Vertex_xyz_diffuse( cosf(corner * degreeInc) * RADIUS_MAX * cosf(radiusDegree), layer * LAYER_HEIGHT, sinf(corner * degreeInc) * RADIUS_MAX * cosf(radiusDegree), rand() * 200 % 0xFFFFFF ); } radiusDegree += radiusDegreeInc; } lpvb->Unlock(); lpd3dd->CreateIndexBuffer( 6 * CORNOR_AMOUNT * LAYER_AMOUNT * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &lpib, NULL ); WORD* ib; INT ibIndex = 0; lpib->Lock(0, 0, (VOID**)&ib, 0); for (INT layer = 0; layer < LAYER_AMOUNT; layer++) { for(INT corner = 0; corner < CORNOR_AMOUNT; corner++) { // i1----i2 // | /| // | / | // | / | // |/ | // i3----i4 WORD index1 = layer * CORNOR_AMOUNT + corner; WORD index2 = corner == CORNOR_AMOUNT - 1 ? layer * CORNOR_AMOUNT + 0 : layer * CORNOR_AMOUNT + corner + 1; WORD index3 = (layer + 1) * CORNOR_AMOUNT + corner; WORD index4 = corner == CORNOR_AMOUNT - 1 ? (layer + 1) * CORNOR_AMOUNT + 0 : (layer + 1) * CORNOR_AMOUNT + corner + 1; ib[ibIndex++] = index1; ib[ibIndex++] = index2; ib[ibIndex++] = index3; ib[ibIndex++] = index2; ib[ibIndex++] = index4; ib[ibIndex++] = index3; } } lpib->Unlock(); D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (FLOAT)WIN_WIDTH / (FLOAT)WIN_HEIGHT, 1.0f, 1000.0f); lpd3dd->SetTransform(D3DTS_PROJECTION, &proj); if(!jcd3d_initRenderState(lpd3dd, D3DCULL_NONE, FALSE, TRUE, D3DSHADE_GOURAUD, D3DFILL_WIREFRAME, FALSE)) { return FALSE; } return TRUE; }
//----- Render() ------------------------------------------------------------ bool DirectXMeshCollision::Render(LPDIRECT3DDEVICE9 pd3dDevice, D3DXMATRIX& worldMatrix) { // early return on non rendering if ((_renderMode == DXRM_NONE) || _forceNoRender) return true; // create DX parameters if not existing if (_vecVBuffer.empty()) { for (unsigned int idxShape(0); idxShape < _vecVertices.size(); ++idxShape) { // vertices LPDIRECT3DVERTEXBUFFER9 pVBuffer (NULL); D3DCustomVertex* pVModel(NULL); D3DCustomVertex* pVertices (_vecVertices[idxShape]); unsigned int countVertices(_vecCountVertices[idxShape]); pd3dDevice->CreateVertexBuffer(countVertices*sizeof(D3DCustomVertex), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &pVBuffer, NULL); pVBuffer->Lock(0, 0, (void**)&pVModel, 0); for (unsigned int i(0); i < countVertices; ++i) { pVModel[i]._x = pVertices[i]._x; pVModel[i]._y = pVertices[i]._y; pVModel[i]._z = pVertices[i]._z; pVModel[i]._color = _wireframeColor; } pVBuffer->Unlock(); _vecVBuffer.push_back(pVBuffer); // indices if (_vecIBuffer.size() < _vecVBuffer.size()) { LPDIRECT3DINDEXBUFFER9 pIBuffer (NULL); unsigned short* pIModel(NULL); unsigned short* pIndices (_vecIndices[idxShape]); unsigned int countIndices(_vecCountIndices[idxShape]); pd3dDevice->CreateIndexBuffer(countIndices*sizeof(unsigned short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pIBuffer, NULL); pIBuffer->Lock(0, 0, (void**)&pIModel, 0); memcpy(pIModel, pIndices, countIndices*sizeof(unsigned short)); pIBuffer->Unlock(); _vecIBuffer.push_back(pIBuffer); } } // for (unsigned int idxShape(0); idxShape < _vesVertices.size(); ++idxShape) } // if (_vecVBuffer.empty()) // wireframe? if (_renderMode == DXRM_WIREFRAME) { pd3dDevice->SetTransform (D3DTS_WORLD, &worldMatrix); // set world transformation pd3dDevice->MultiplyTransform (D3DTS_WORLD, &_transform); // transform local object into world pd3dDevice->SetTexture (0, NULL); // no texture pd3dDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, false); // disable alpha blending pd3dDevice->SetRenderState (D3DRS_FILLMODE, D3DFILL_WIREFRAME); // forced wireframe pd3dDevice->SetRenderState (D3DRS_LIGHTING, false); // disable light pd3dDevice->SetFVF (D3DFVF_CUSTOMVERTEX_COLOR); // set vertex style for (unsigned int idxShape(0); idxShape < _vecVBuffer.size(); ++idxShape) { pd3dDevice->SetStreamSource (0, _vecVBuffer[idxShape], 0, sizeof(D3DCustomVertex)); // set vertices source pd3dDevice->SetIndices (_vecIBuffer[idxShape]); // set indices source unsigned int countIndices (_vecCountIndices[idxShape]); unsigned int countVertices(_vecCountVertices[idxShape]); switch (_vecPrimitiveType[idxShape]) { case D3DPT_TRIANGLELIST: { countIndices = countIndices/3; countVertices = countVertices; break; } case D3DPT_LINELIST: { countIndices = countIndices/2; countVertices = countVertices; break; } } pd3dDevice->DrawIndexedPrimitive(_vecPrimitiveType[idxShape], 0, 0, countVertices, 0, countIndices); // render } // for (unsigned int idxShape(0); idxShape < _vecVBuffer.size(); ++idxShape) } return true; }
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 InitFullScreenQuad() { // vertex declaration D3DVERTEXELEMENT9 vtxDesc[3]; int offset = 0; int i = 0; // position vtxDesc[i].Stream = 0; vtxDesc[i].Offset = offset; vtxDesc[i].Type = D3DDECLTYPE_FLOAT3; vtxDesc[i].Method = D3DDECLMETHOD_DEFAULT; vtxDesc[i].Usage = D3DDECLUSAGE_POSITION; vtxDesc[i].UsageIndex = 0; offset += sizeof(float)* 3; ++i; // UV coords 0 vtxDesc[i].Stream = 0; vtxDesc[i].Offset = offset; vtxDesc[i].Type = D3DDECLTYPE_FLOAT2; vtxDesc[i].Method = D3DDECLMETHOD_DEFAULT; vtxDesc[i].Usage = D3DDECLUSAGE_TEXCOORD; vtxDesc[i].UsageIndex = 0; offset += sizeof(float)* 2; ++i; // end of the vertex format (D3DDECL_END()) vtxDesc[i].Stream = 0xFF; vtxDesc[i].Offset = 0; vtxDesc[i].Type = D3DDECLTYPE_UNUSED; vtxDesc[i].Method = 0; vtxDesc[i].Usage = 0; vtxDesc[i].UsageIndex = 0; gpD3DDevice->CreateVertexDeclaration(vtxDesc, &gpFullscreenQuadDecl); // create a vertex buffer gpD3DDevice->CreateVertexBuffer(offset * 4, 0, 0, D3DPOOL_MANAGED, &gpFullscreenQuadVB, NULL); void * vertexData = NULL; gpFullscreenQuadVB->Lock(0, 0, &vertexData, 0); { float * data = (float*)vertexData; *data++ = -1.0f; *data++ = 1.0f; *data++ = 0.0f; *data++ = 0.0f; *data++ = 0.0f; *data++ = 1.0f; *data++ = 1.0f; *data++ = 0.0f; *data++ = 1.0f; *data++ = 0; *data++ = 1.0f; *data++ = -1.0f; *data++ = 0.0f; *data++ = 1.0f; *data++ = 1.0f; *data++ = -1.0f; *data++ = -1.0f; *data++ = 0.0f; *data++ = 0.0f; *data++ = 1.0f; } gpFullscreenQuadVB->Unlock(); // create an index buffer gpD3DDevice->CreateIndexBuffer(sizeof(short)* 6, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &gpFullscreenQuadIB, NULL); void * indexData = NULL; gpFullscreenQuadIB->Lock(0, 0, &indexData, 0); { unsigned short * data = (unsigned short*)indexData; *data++ = 0; *data++ = 1; *data++ = 3; *data++ = 3; *data++ = 1; *data++ = 2; } gpFullscreenQuadIB->Unlock(); }
HRESULT Objects_Init() { //创建字体 D3DXCreateFont(g_pd3dDevice, 36, 0, 0, 1000, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("Calibri"), &g_pTextFPS); D3DXCreateFont(g_pd3dDevice, 20, 0, 1000, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"华文中宋", &g_pTextAdaperName); D3DXCreateFont(g_pd3dDevice, 23, 0, 1000, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"微软雅黑", &g_pTextHelper); D3DXCreateFont(g_pd3dDevice, 26, 0, 1000, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, L"黑体", &g_pTextInfor); //-------------------------------------------------------------------------------------- // 创建顶点缓存和索引缓存 //-------------------------------------------------------------------------------------- //创建顶点缓存 if (FAILED(g_pd3dDevice->CreateVertexBuffer(24 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL))) { return E_FAIL; } // 创建索引缓存 if (FAILED(g_pd3dDevice->CreateIndexBuffer(36 * sizeof(WORD), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIndexBuffer, NULL))) { return E_FAIL; } //-------------------------------------------------------------------------------------- // 【纹理绘制四步曲之二】:顶点的访问 //-------------------------------------------------------------------------------------- //填充顶点缓存 CUSTOMVERTEX* pVertices; if (FAILED(g_pVertexBuffer->Lock(0, 24 * sizeof(CUSTOMVERTEX), (void**)&pVertices, 0))) return E_FAIL; // 正面顶点数据 pVertices[0] = CUSTOMVERTEX(-10.0f, 10.0f, -10.0f, 0.0f, 0.0f); pVertices[1] = CUSTOMVERTEX(10.0f, 10.0f, -10.0f, 1.0f, 0.0f); pVertices[2] = CUSTOMVERTEX(10.0f, -10.0f, -10.0f, 1.0f, 1.0f); pVertices[3] = CUSTOMVERTEX(-10.0f, -10.0f, -10.0f, 0.0f, 1.0f); // 背面顶点数据 pVertices[4] = CUSTOMVERTEX(10.0f, 10.0f, 10.0f, 0.0f, 0.0f); pVertices[5] = CUSTOMVERTEX(-10.0f, 10.0f, 10.0f, 1.0f, 0.0f); pVertices[6] = CUSTOMVERTEX(-10.0f, -10.0f, 10.0f, 1.0f, 1.0f); pVertices[7] = CUSTOMVERTEX(10.0f, -10.0f, 10.0f, 0.0f, 1.0f); // 顶面顶点数据 pVertices[8] = CUSTOMVERTEX(-10.0f, 10.0f, 10.0f, 0.0f, 0.0f); pVertices[9] = CUSTOMVERTEX(10.0f, 10.0f, 10.0f, 1.0f, 0.0f); pVertices[10] = CUSTOMVERTEX(10.0f, 10.0f, -10.0f, 1.0f, 1.0f); pVertices[11] = CUSTOMVERTEX(-10.0f, 10.0f, -10.0f, 0.0f, 1.0f); // 底面顶点数据 pVertices[12] = CUSTOMVERTEX(-10.0f, -10.0f, -10.0f, 0.0f, 0.0f); pVertices[13] = CUSTOMVERTEX(10.0f, -10.0f, -10.0f, 1.0f, 0.0f); pVertices[14] = CUSTOMVERTEX(10.0f, -10.0f, 10.0f, 1.0f, 1.0f); pVertices[15] = CUSTOMVERTEX(-10.0f, -10.0f, 10.0f, 0.0f, 1.0f); // 左侧面顶点数据 pVertices[16] = CUSTOMVERTEX(-10.0f, 10.0f, 10.0f, 0.0f, 0.0f); pVertices[17] = CUSTOMVERTEX(-10.0f, 10.0f, -10.0f, 1.0f, 0.0f); pVertices[18] = CUSTOMVERTEX(-10.0f, -10.0f, -10.0f, 1.0f, 1.0f); pVertices[19] = CUSTOMVERTEX(-10.0f, -10.0f, 10.0f, 0.0f, 1.0f); // 右侧面顶点数据 pVertices[20] = CUSTOMVERTEX(10.0f, 10.0f, -10.0f, 0.0f, 0.0f); pVertices[21] = CUSTOMVERTEX(10.0f, 10.0f, 10.0f, 1.0f, 0.0f); pVertices[22] = CUSTOMVERTEX(10.0f, -10.0f, 10.0f, 1.0f, 1.0f); pVertices[23] = CUSTOMVERTEX(10.0f, -10.0f, -10.0f, 0.0f, 1.0f); g_pVertexBuffer->Unlock(); // 填充索引数据 WORD *pIndices = NULL; g_pIndexBuffer->Lock(0, 0, (void**)&pIndices, 0); // 正面索引数据 pIndices[0] = 0; pIndices[1] = 1; pIndices[2] = 2; pIndices[3] = 0; pIndices[4] = 2; pIndices[5] = 3; // 背面索引数据 pIndices[6] = 4; pIndices[7] = 5; pIndices[8] = 6; pIndices[9] = 4; pIndices[10] = 6; pIndices[11] = 7; // 顶面索引数据 pIndices[12] = 8; pIndices[13] = 9; pIndices[14] = 10; pIndices[15] = 8; pIndices[16] = 10; pIndices[17] = 11; // 底面索引数据 pIndices[18] = 12; pIndices[19] = 13; pIndices[20] = 14; pIndices[21] = 12; pIndices[22] = 14; pIndices[23] = 15; // 左侧面索引数据 pIndices[24] = 16; pIndices[25] = 17; pIndices[26] = 18; pIndices[27] = 16; pIndices[28] = 18; pIndices[29] = 19; // 右侧面索引数据 pIndices[30] = 20; pIndices[31] = 21; pIndices[32] = 22; pIndices[33] = 20; pIndices[34] = 22; pIndices[35] = 23; g_pIndexBuffer->Unlock(); //-------------------------------------------------------------------------------------- // 【纹理绘制四步曲之三】:纹理的创建 //-------------------------------------------------------------------------------------- D3DXCreateTextureFromFile(g_pd3dDevice, L"pal5q.jpg", &g_pTexture); // 设置材质 D3DMATERIAL9 mtrl; ::ZeroMemory(&mtrl, sizeof(mtrl)); mtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); mtrl.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); mtrl.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); g_pd3dDevice->SetMaterial(&mtrl); D3DLIGHT9 light; ::ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); light.Specular = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); light.Direction = D3DXVECTOR3(1.0f, 1.0f, 0.0f); g_pd3dDevice->SetLight(0, &light); //设置光源 g_pd3dDevice->LightEnable(0, true);//启用光照 // 设置渲染状态 g_pd3dDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true); //初始化顶点法线 g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); //开启背面消隐 g_pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(36, 36, 36)); //设置一下环境光 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; }
bool ObjectInit(HWND hwnd) { srand(unsigned(time(nullptr))); PlaySound(_T("Kalafina - believe.wav"), nullptr, SND_ASYNC | SND_FILENAME | SND_LOOP); D3DXCreateFont(gPD3DDevice, 40, 0, 0, 0, 0, 0, 0, 0, 0, _T("楷体"), &gPFont); ////////////////////////////////////////////////////////////////////////// // some constant variables used to be modified to fit the screen ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// const float headRadius = 50.0f; const float neckWidth = 20.0f; const float neckHeight = 30.0f; const float bodyWidth = 200.0f; const float bodyHeight = 200.0f; const float armWidth = 100.0f; const float armHeight = 40.0f; const float legWidth = 40.0f; const float legHeight = 200.0f; const float handRadius = 30.0f; const float footRadius = 30.0f; ////////////////////////////////////////////////////////////////////////// // Set vertices ////////////////////////////////////////////////////////////////////////// enum ORGNIZM { HEAD, NECK, BODY, LEFT_ARM, RIGHT_ARM, LEFT_HAND, RIGHT_HAND, LEFT_LEG, RIGHT_LEG, LEFT_FOOT, RIGHT_FOOT, ORGAN_COUNT }; const int verticesNum[ORGAN_COUNT] = { 17, 4, 4, 4, 4, 9, 9, 4, 4, 4, 4 }; CUSTOM_VERTEX verticesHead[17]; CUSTOM_VERTEX verticesNeck[4] = { 0 }; CUSTOM_VERTEX verticesBody[4] = { 0 }; CUSTOM_VERTEX verticesLeftArm[4] = { 0 }; CUSTOM_VERTEX verticesRightArm[4] = { 0 }; CUSTOM_VERTEX verticesLeftHand[9] = { 0 }; CUSTOM_VERTEX verticesRightHand[9] = { 0 }; CUSTOM_VERTEX verticesLeftLeg[4] = { 0 }; CUSTOM_VERTEX verticesRightLeg[4] = { 0 }; CUSTOM_VERTEX verticesLeftFoot[4] = { 0 }; CUSTOM_VERTEX verticesRightFoot[4] = { 0 }; int verticesNumSum = 21; //for (int i = 0; i < ORGAN_COUNT; i++) //{ // verticesNumSum += verticesNum[i]; //} /** * Then fill in the custom vertices * */ verticesHead[0].x = 400.0f; verticesHead[0].y = 50.0f; verticesHead[0].z = 0.0f; verticesHead[0].rhw = 1.0f; verticesHead[0].color = D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256); for (int i = 0; i < verticesNum[HEAD]-1; i++) { verticesHead[i + 1].x = verticesHead[0].x + headRadius*cos(i*PI / 8); verticesHead[i + 1].y = verticesHead[0].y + headRadius*sin(i*PI / 8); verticesHead[i + 1].z = 0.0f; verticesHead[i + 1].rhw = 1.0f; verticesHead[i + 1].color = D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256); } verticesNeck[0].x = 400.0f - neckWidth/2; verticesNeck[1].x = verticesNeck[0].x; verticesNeck[2].x = verticesNeck[0].x + neckWidth; verticesNeck[3].x = verticesNeck[2].x; verticesNeck[0].y = headRadius * 2 - neckHeight / 3; verticesNeck[1].y = verticesNeck[0].y + neckHeight; verticesNeck[2].y = verticesNeck[0].y; verticesNeck[3].y = verticesNeck[1].y; for (int i = 0; i < 4; i++) { verticesNeck[i].z = 0.0f; verticesNeck[i].rhw = 1.0f; verticesHead[i + 1].color = D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256); } /** * Then copy to vertex buffer * */ gPD3DDevice->CreateVertexBuffer(verticesNumSum*sizeof(CUSTOM_VERTEX), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_DEFAULT, &gPVertexBuffer, nullptr); void* pVertices; gPVertexBuffer->Lock(0, verticesNumSum*sizeof(CUSTOM_VERTEX), (void**)(&pVertices), 0); memcpy(pVertices, verticesHead, verticesNumSum*sizeof(CUSTOM_VERTEX)); gPVertexBuffer->Unlock(); ////////////////////////////////////////////////////////////////////////// // Set indices ////////////////////////////////////////////////////////////////////////// //declare indices of different parts int indicesHead[48]{0}; int indicesNeck[6]{0}; int indicesNumSum = 54; int iIndicesNum = 0; //fill in the head indices for (int i = 0; i < 16; i++) { indicesHead[i * 3] = 0; indicesHead[i * 3 + 1] = i + 1; indicesHead[i * 3 + 2] = i + 2; iIndicesNum++; } indicesHead[47] = 1; //fill in the neck indices for (int i = 0; i < 2; i++) { indicesNeck[i*3] = iIndicesNum + i; indicesNeck[i*3 + 1] = 16 + 1; indicesNeck[i*3 + 2] = 16 + 2; iIndicesNum++; } indicesNeck[3] = 16 + 3; //create pIndices if (FAILED(gPD3DDevice->CreateIndexBuffer(indicesNumSum*sizeof(int), 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &gPIndexBuffer, nullptr))) { return false; } int* pIndices; gPIndexBuffer->Lock(0, 0, (void**)(&pIndices), 0); memcpy(pIndices, indicesHead, indicesNumSum*sizeof(int)); gPIndexBuffer->Unlock(); return true; }
HRESULT CreateCube() { // The vertex order in each face is in the following order when you // look at the face perpendicular against it's normal // bottom left -> bottom right -> top right -> top left // So you need to set the cull mode as D3DCULL_CW, since the default mode is D3DCULL_CCW Vertex vertices[] = { // Front face { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f }, // 0 { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }, // 1 { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f }, // 2 { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // 3 // Back face { 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, // Left face { 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // Right face { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // Top face { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // Bottom face { 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f }, } ; // Index buffer WORD indices[] = { // Front side 0, 1, 2, 0, 2, 3, // Back side 4, 5, 6, 4, 6, 7, // Top side 8, 9, 10, 8, 10, 11, // Bottom side 12, 13, 14, 12, 14, 15, // Left side 16, 17, 18, 16, 18, 19, // Right side 20, 21, 22, 20, 22, 23, } ; // Create vertex buffer if( FAILED( g_pd3dDevice->CreateVertexBuffer( sizeof(vertices) * sizeof(Vertex), D3DUSAGE_WRITEONLY, VERTEX_FVF, D3DPOOL_MANAGED, &g_pVB, NULL ) ) ) { return E_FAIL; } // Copy vertex data VOID* pVertices; if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, vertices, sizeof(vertices) ); g_pVB->Unlock(); // Create index buffer if( FAILED( g_pd3dDevice->CreateIndexBuffer( sizeof(indices) * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pIB, 0) ) ) { return E_FAIL ; } // Copy index data VOID *pIndices; if( FAILED( g_pIB->Lock( 0, sizeof(indices), (void **)&pIndices, 0) ) ) return E_FAIL; memcpy(pIndices, indices, sizeof(indices) ); g_pIB->Unlock() ; }
int SolidX::getSide(int index, float pU, float pV, D3DXVECTOR3* coor){ LPDIRECT3DVERTEXBUFFER9 pVB; LPDIRECT3DINDEXBUFFER9 pIB; mesh->GetVertexBuffer( &pVB ); mesh->GetIndexBuffer( &pIB ); WORD* pIndices; D3DVERTEX* pVertices; int subset = -1; for(int i=0; i<subsetNum; i++){ if(index >= attTable[i].FaceStart && index < attTable[i].FaceStart + attTable[i].FaceCount){ subset = i; break; } } int paintSize = paintSizes[subset]; D3DVERTEX tri[3]; pIB->Lock(0, 0, (void**)&pIndices, 0 ); pVB->Lock(0, 0, (void**)&pVertices, 0 ); tri[0] = pVertices[pIndices[index*3+0]]; tri[1] = pVertices[pIndices[index*3+1]]; tri[2] = pVertices[pIndices[index*3+2]]; pIB->Unlock(); pVB->Unlock(); D3DXVECTOR3 pos = tri[0].pos + (tri[1].pos-tri[0].pos)*pU + (tri[2].pos-tri[0].pos)*pV; D3DXVECTOR3 norm = Tools::Normalize(Tools::Cross(tri[1].pos-tri[0].pos,tri[2].pos-tri[0].pos)); *coor = pos; D3DXVECTOR2 uvMax = paintMaxUV[subset]; D3DXVECTOR2 uvMin = paintMinUV[subset]; D3DXVECTOR2 UV1 = tri[1].UV-tri[0].UV; D3DXVECTOR2 UV2 = tri[2].UV-tri[0].UV; float AreaABC = UV1.x*UV2.y - UV1.y*UV2.x; float u, v; u = tri[0].UV.x+ (tri[1].UV.x-tri[0].UV.x)*pU + (tri[2].UV.x-tri[0].UV.x)*pV; v = tri[0].UV.y+ (tri[1].UV.y-tri[0].UV.y)*pU + (tri[2].UV.y-tri[0].UV.y)*pV; u -= paintMinUV[subset].x; v -= paintMinUV[subset].y; u /= (paintMaxUV[subset]-paintMinUV[subset]).x; v /= (paintMaxUV[subset]-paintMinUV[subset]).y; u*=paintSize; v*=paintSize; D3DLOCKED_RECT temp; if(paints[subset]->LockRect(0, &temp, 0, 0) != D3D_OK) ALERT; unsigned int *a = (unsigned int*)temp.pBits; unsigned int c = a[(int)u+(int)v*paintSize]; if(paints[subset]->UnlockRect(0) != D3D_OK) ALERT; if(c>>24 < 10) return -1; if((c>>16)&255 > 10) return 0; if((c)&255 > 10) return 1; return -1; }
//----------------------------------------------------------------------------- // 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; }