HRESULT CMesh3D::InitialMesh(LPCSTR Name, FILE *FileLog ) { m_pMesh = 0; m_pMeshMaterial = 0; m_pMeshTextura = 0; m_SizeFVF = 0; m_Alpha = 1.0f; ID3DXBuffer *pMaterialBuffer = 0; if ( FAILED( D3DXLoadMeshFromX( Name, D3DXMESH_SYSTEMMEM, g_pD3DDevice, 0, &pMaterialBuffer, 0, &m_TexturCount, &m_pMesh ) ) ) { if ( m_pMesh == 0 ) { if ( FileLog ) fprintf( FileLog, "error load x file '%s'\n", Name ); return E_FAIL; } } if ( m_pMesh->GetFVF() & D3DFVF_XYZ ) m_SizeFVF += sizeof(float)*3; if ( m_pMesh->GetFVF() & D3DFVF_NORMAL ) m_SizeFVF += sizeof(float)*3; if ( m_pMesh->GetFVF() & D3DFVF_TEX1 ) m_SizeFVF += sizeof(float)*2; m_pMesh->GetVertexBuffer( &m_VertexBuffer ); m_pMesh->GetIndexBuffer( &m_IndexBuffer ); // Извлекаем свойства материала и названия{имена} структуры D3DXMATERIAL *D3DXMeshMaterial = (D3DXMATERIAL *)pMaterialBuffer->GetBufferPointer(); m_pMeshMaterial = new D3DMATERIAL9[m_TexturCount]; m_pMeshTextura = new IDirect3DTexture9*[m_TexturCount]; for ( DWORD i = 0; i < m_TexturCount; i++ ) { // Копируем материал m_pMeshMaterial[i] = D3DXMeshMaterial[i].MatD3D; // Установить окружающего свет m_pMeshMaterial[i].Ambient = m_pMeshMaterial[i].Diffuse; // Загружаем текстуру string FileName = string( "model//" ) + string( D3DXMeshMaterial[i].pTextureFilename ); if ( FAILED( D3DXCreateTextureFromFile( g_pD3DDevice, FileName.c_str(), &m_pMeshTextura[i] ))) { fprintf( FileLog, "error load texture '%s'\n", D3DXMeshMaterial[i].pTextureFilename ); m_pMeshTextura[i] = 0; } } // Уничтожаем буфер материала pMaterialBuffer->Release(); return S_OK; }
HRESULT HelloShadowVolume::RestoreDeviceObjects() { HRESULT hr; IDirect3DDevice8* device; hr = m_spD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_dpps, &device); if (FAILED(hr)) { MessageBox(0, L"CreateDevice failed", 0, 0); return E_FAIL; } m_spDevice.reset(device, [](IDirect3DDevice8* device) { device->Release(); }); m_spDevice->SetRenderState(D3DRS_ZENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_LIGHTING, FALSE); m_spDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); D3DVIEWPORT8 viewport = { 0, 0, m_iWidth, m_iHeight }; m_spDevice->SetViewport(&viewport); D3DXVECTOR3 eye(0.0f, 0.0f, 30.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&m_mtView, &eye, &target, &up); D3DXMatrixPerspectiveFovLH(&m_mtProj, 0.2*D3DX_PI, (float)m_iWidth / (float)m_iHeight, 1.0f, 100.f); m_cPlaneTint = { 0.7f, 0.6f, 0.4f, 1.0f }; ID3DXMesh* plane; //D3DXCreatePolygon(m_spDevice.get(), 2.0f, 4, &plane, NULL); CreatePlane(m_spDevice.get(), 15.0f, 10, &plane); //D3DXCreateSphere(m_spDevice.get(), 1.0f,20,20, &plane, NULL); IDirect3DVertexBuffer8* vb; IDirect3DIndexBuffer8* ib; plane->GetVertexBuffer(&vb); plane->GetIndexBuffer(&ib); m_spPlaneVB.reset(vb, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spPlaneIB.reset(ib, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwPlaneNumVertices = plane->GetNumVertices(); m_dwPlaneNumFaces = plane->GetNumFaces(); plane->Release(); DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(0, D3DVSDT_FLOAT3), D3DVSD_REG(3, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"plane.vso", &m_dwPlaneVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"plane.pso", &m_dwPlanePSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } D3DXMATRIX Rx, Tz; D3DXMatrixRotationX(&Rx, D3DX_PI*0.5f); D3DXMatrixTranslation(&Tz, 0.0f, -3.0f, 0.0f); m_mtPlaneWorld = Rx * Tz; ID3DXMesh* occluder; CreateOccluder(m_spDevice.get(), &occluder); IDirect3DVertexBuffer8* vbOccluder; IDirect3DIndexBuffer8* ibOccluder; occluder->GetVertexBuffer(&vbOccluder); occluder->GetIndexBuffer(&ibOccluder); m_spOccluderVB.reset(vbOccluder, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spOccluderIB.reset(ibOccluder, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwOccluderNumVertices = occluder->GetNumVertices(); m_dwOccluderNumFaces = occluder->GetNumFaces(); occluder->Release(); hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"occluder.vso", &m_dwOccluderVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"occluder.pso", &m_dwOccluderPSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } m_cOccluderTint = { 0.3f, 0.0f, 0.8f, 1.0f }; D3DXMATRIX Rz, T; D3DXMatrixTranslation(&T, 5.1f * cosf(0.5), 0.0f, 5.1f * sinf(0.5)); D3DXMatrixIdentity(&m_mtVolumeWorld); D3DXMatrixRotationZ(&Rz, 0.5f); m_mtOccluderWorld = T * Rz; ID3DXMesh* volume; CreateVolume(m_spDevice.get(), &volume); IDirect3DVertexBuffer8* vbVolume; IDirect3DIndexBuffer8* ibVolume; volume->GetVertexBuffer(&vbVolume); volume->GetIndexBuffer(&ibVolume); m_spVolumeVB.reset(vbVolume, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spVolumeIB.reset(ibVolume, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwVolumeNumVertices = volume->GetNumVertices(); m_dwVolumeNumFaces = volume->GetNumFaces(); volume->Release(); hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"volume.vso", &m_dwVolumeVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"volume.pso", &m_dwVolumePSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } m_cVolumeTint = { 0.7f, 0.0f, 0.0f, 1.0f }; D3DXMATRIX Sx; D3DXMatrixIdentity(&m_mtVolumeWorld); D3DXMatrixScaling(&Sx, 6.0f, 1.0f, 1.0f); D3DXMatrixRotationZ(&Rz, 0.5f); m_mtVolumeWorld = Sx * Rz; return S_OK; }
void LODManager::Render(IDirect3DDevice9 *D3DDevice) { const char *meshpath = (lod == GRID_FARNEAR ? "landscape\\lod\\farnear\\" : (lod == GRID_FARFAR ? "landscape\\lod\\farfar\\" : "landscape\\lod\\farinf\\")); const char *textpath = (lod == GRID_FARNEAR ? "landscapelod\\generated\\farnear\\" : (lod == GRID_FARFAR ? "landscapelod\\generated\\farfar\\" : "landscapelod\\generated\\farinf\\")); int nativeminx = (GRID_SIZE * 32) + (Constants.Coordinates.x - GridDistantCount.Get()); int nativeminy = (GRID_SIZE * 32) + (Constants.Coordinates.y - GridDistantCount.Get()); int nativemaxx = (GRID_SIZE * 32) + (Constants.Coordinates.x + GridDistantCount.Get()); int nativemaxy = (GRID_SIZE * 32) + (Constants.Coordinates.y + GridDistantCount.Get()); /* y-axis has flipped rounding */ nativeminx = (nativeminx / 32) - GRID_SIZE; nativeminy = (nativeminy / 32) - GRID_SIZE + 0; nativemaxx = (nativemaxx / 32) - GRID_SIZE; nativemaxy = (nativemaxy / 32) - GRID_SIZE + 0; int gridx = Constants.Coordinates.x / 32; int gridy = Constants.Coordinates.y / 32; for (int x = (gridx - extend); x <= (gridx + extend); x++) for (int y = (gridy - extend); y <= (gridy + extend); y++) { /* TODO: try radius, seems it's not a box */ /* leave out Oblivion's native tiles */ if ((x >= nativeminx) && (x <= nativemaxx) && (y >= nativeminy) && (y <= nativemaxy)) continue; /* leave out other LOD's inner tiles */ if ((abs(gridx - x) <= inner) && (abs(gridy - y) <= inner)) continue; /* where are we? */ const float TileOffset[4] = {x * TILE_DIM, y * TILE_DIM, 0, 0}; /* filter outside-array coordinates */ if (((GRID_OFFSET + y) >= 0) && ((GRID_OFFSET + y) < GRID_SIZE) && ((GRID_OFFSET + x) >= 0) && ((GRID_OFFSET + x) < GRID_SIZE)) { /* never seen, never attempted */ if (MeshIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] < -1) { /* TODO: 32 means 32x32 cells, in theory that can be different as well */ char buf[256]; sprintf(buf, "%02d.%02d.%02d.32", WorldSpace, x * 32, y * 32); char pth[256]; strcpy(pth, meshpath); strcat(pth, buf); strcat(pth, ".x"); /* no textures without mesh, but we can render texture-free */ if ((MeshIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] = MeshManager::GetSingleton()->LoadPrivateMesh(pth, MR_REGULAR)) != -1) { if (ColrIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] < -1) { strcpy(pth, textpath); strcat(pth, buf); strcat(pth, ".dds"); ColrIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] = TextureManager::GetSingleton()->LoadPrivateTexture(pth, TR_PLANAR); } if (NormIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] < -1) { strcpy(pth, textpath); strcat(pth, buf); strcat(pth, "_fn.dds"); NormIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] = TextureManager::GetSingleton()->LoadPrivateTexture(pth, TR_PLANAR); } /* put the addresses */ ManagedMeshRecord *mesh = Meshes [lod][GRID_OFFSET + y][GRID_OFFSET + x] = MeshManager::GetSingleton()->GetMesh (MeshIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x]); ManagedTextureRecord *colr = Colors [lod][GRID_OFFSET + y][GRID_OFFSET + x] = TextureManager::GetSingleton()->GetTexture(ColrIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x]); ManagedTextureRecord *norm = Normals[lod][GRID_OFFSET + y][GRID_OFFSET + x] = TextureManager::GetSingleton()->GetTexture(NormIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x]); /* failure to load all resources */ if (!mesh || !colr || !norm) { if (mesh) mesh->Release(); if (colr) colr->Release(); if (norm) norm->Release(); MeshIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] = -1; ColrIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] = -1; NormIDs[lod][GRID_OFFSET + y][GRID_OFFSET + x] = -1; continue; } #if defined(OBGE_GAMMACORRECTION) /* remember DeGamma for this kind of texture */ static const bool PotDeGamma = true; colr->GetTexture()->SetPrivateData(GammaGUID, &PotDeGamma, sizeof(PotDeGamma), 0); #endif } } /* get the addresses */ ManagedMeshRecord *mesh = Meshes [lod][GRID_OFFSET + y][GRID_OFFSET + x]; ManagedTextureRecord *colr = Colors [lod][GRID_OFFSET + y][GRID_OFFSET + x]; ManagedTextureRecord *norm = Normals[lod][GRID_OFFSET + y][GRID_OFFSET + x]; ID3DXMesh *m; if (mesh && (m = (ID3DXMesh *)mesh->GetMesh())) { #if 0 DWORD FVF = m->GetFVF(); DWORD size = m->GetNumBytesPerVertex(); DWORD numf = m->GetNumFaces(); DWORD numv = m->GetNumVertices(); IDirect3DIndexBuffer9 *pIB; m->GetIndexBuffer(&pIB); IDirect3DVertexBuffer9 *pVB; m->GetVertexBuffer(&pVB); D3DDevice->SetStreamSource(0, pVB, 0, size); D3DDevice->SetFVF(FVF); D3DDevice->SetTexture(0, colr->GetTexture()); D3DDevice->SetTexture(1, norm->GetTexture()); D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numv, 0, numf); #endif D3DDevice->SetTexture(0, colr ? colr->GetTexture() : NULL); D3DDevice->SetTexture(1, norm ? norm->GetTexture() : NULL); D3DDevice->SetVertexShader(vShader[lod]); D3DDevice->SetPixelShader (pShader[lod]); D3DDevice->SetVertexShaderConstantF(32, TileOffset, 1); m->DrawSubset(0); } } /* water-planes */ D3DDevice->SetVertexShader(vShaderW); D3DDevice->SetPixelShader (pShaderW); D3DDevice->SetVertexShaderConstantF(32, TileOffset, 1); D3DDevice->SetStreamSource(0, WaterVertex, 0, sizeof(WaterTile)); D3DDevice->SetFVF(WATERTILEFORMAT); D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } const float TileOffset[4] = {0, 0, 0, 1}; /* infini-plane */ D3DDevice->SetVertexShader(vShaderW); D3DDevice->SetPixelShader (pShaderW); D3DDevice->SetVertexShaderConstantF(32, TileOffset, 1); D3DDevice->SetStreamSource(0, InfiniteVertex, 0, sizeof(WaterTile)); D3DDevice->SetFVF(WATERTILEFORMAT); D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); }
void Scene::LoadFromXFile(string file, IDirect3DDevice9 *device) { assert(device); ID3DXBuffer *material = nullptr; DWORD num_material = 0; ID3DXMesh *mesh = nullptr; HRESULT res = D3DXLoadMeshFromX(file.c_str(), // pFilename D3DXMESH_DYNAMIC, // Options device, // pD3DDevice nullptr, // ppAdjacency &material, // ppMaterials nullptr, // ppEffectInstances &num_material, // pNumMaterials &mesh); // ppMesh if (FAILED(res)) { Logger::GtLogError("load mesh from X file failed:%s", file.c_str()); return; } assert(num_material == 1); D3DXMATERIAL *mat = static_cast<D3DXMATERIAL *>(material->GetBufferPointer()); material_.ambient.r = mat->MatD3D.Ambient.r; material_.ambient.g = mat->MatD3D.Ambient.g; material_.ambient.b = mat->MatD3D.Ambient.b; material_.ambient.a = mat->MatD3D.Ambient.a; material_.diffuse.r = mat->MatD3D.Diffuse.r; material_.diffuse.g = mat->MatD3D.Diffuse.g; material_.diffuse.b = mat->MatD3D.Diffuse.b; material_.diffuse.a = mat->MatD3D.Diffuse.a; material_.specular.r = mat->MatD3D.Specular.r; material_.specular.g = mat->MatD3D.Specular.g; material_.specular.b = mat->MatD3D.Specular.b; material_.specular.a = mat->MatD3D.Specular.a; material_.emissive.r = mat->MatD3D.Emissive.r; material_.emissive.g = mat->MatD3D.Emissive.g; material_.emissive.b = mat->MatD3D.Emissive.b; material_.emissive.a = mat->MatD3D.Emissive.a; material_.power = mat->MatD3D.Power; bool ret = texture_.Load(mat->pTextureFilename, device); assert(ret); material->Release(); DWORD num_vertex = mesh->GetNumVertices(); IDirect3DVertexBuffer9 *vertex_buffer = nullptr; res = mesh->GetVertexBuffer(&vertex_buffer); assert(SUCCEEDED(res)); uint8 *vertex_data = nullptr; res = vertex_buffer->Lock(0, 0, reinterpret_cast<void **>(&vertex_data), D3DLOCK_READONLY); assert(SUCCEEDED(res)); D3DVERTEXELEMENT9 vertex_elements[MAX_FVF_DECL_SIZE] = {0}; res = mesh->GetDeclaration(vertex_elements); assert(SUCCEEDED(res)); int offset_pos = 0; int offset_nor = 0; int offset_tex = 0; int vertex_size = mesh->GetNumBytesPerVertex(); for (int i = 0; i < MAX_FVF_DECL_SIZE; ++i) { if (vertex_elements[i].Type == D3DDECLTYPE_UNUSED) break; if (vertex_elements[i].Usage == D3DDECLUSAGE_POSITION) { offset_pos = vertex_elements[i].Offset; } if (vertex_elements[i].Usage == D3DDECLUSAGE_NORMAL) { offset_nor = vertex_elements[i].Offset; } if (vertex_elements[i].Usage == D3DDECLUSAGE_TEXCOORD) { offset_tex = vertex_elements[i].Offset; } } Primitive verteies(num_vertex, nullptr, nullptr); for (int i = 0; i < num_vertex; ++i) { verteies.positions[i] = *reinterpret_cast<Vector3 *>(vertex_data + vertex_size * i + offset_pos); verteies.positions[i].Display(); verteies.normals[i] = *reinterpret_cast<Vector3 *>(vertex_data + vertex_size * i + offset_nor); verteies.normals[i].Display(); verteies.uvs[i] = *reinterpret_cast<Vector2 *>(vertex_data + vertex_size * i + offset_tex); verteies.uvs[i].Display(); } primitive_ = verteies; vertex_buffer->Unlock(); vertex_buffer->Release(); }