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); }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) MainWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "xtocmod"; if (RegisterClass(&wc) == 0) { MessageBox(NULL, "Failed to register the window class.", "Fatal Error", MB_OK | MB_ICONERROR); return NULL; } DWORD windowStyle = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); g_mainWindow = CreateWindow("xtocmod", "xtocmod", windowStyle, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInstance, NULL); if (g_mainWindow == NULL) { MessageBox(NULL, "Error creating application window.", "Fatal Error", MB_OK | MB_ICONERROR); } //ShowWindow(g_mainWindow, SW_SHOW); SetForegroundWindow(g_mainWindow); SetFocus(g_mainWindow); // Initialize D3D g_d3d = Direct3DCreate9(D3D_SDK_VERSION); if (g_d3d == NULL) { ShowD3DErrorMessage("Initializing D3D", 0); return 1; } D3DPRESENT_PARAMETERS presentParams; ZeroMemory(&presentParams, sizeof(presentParams)); presentParams.Windowed = TRUE; presentParams.SwapEffect = D3DSWAPEFFECT_COPY; #if 0 presentParams.BackBufferWidth = 300; presentParams.BackBufferHeight = 300; presentParams.BackBufferCount = 1; presentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; presentParams.Windowed = TRUE; #endif HRESULT hr = g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_mainWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presentParams, &g_d3dDev); if (FAILED(hr)) { ShowD3DErrorMessage("Creating D3D device", hr); //return 1; } string inputFilename(lpCmdLine); string outputFilename(inputFilename, 0, inputFilename.rfind('.')); outputFilename += ".cmod"; ID3DXMesh* mesh = NULL; ID3DXBuffer* adjacency = NULL; ID3DXBuffer* materialBuf = NULL; ID3DXBuffer* effects = NULL; DWORD numMaterials; hr = D3DXLoadMeshFromX(inputFilename.c_str(), 0, g_d3dDev, &adjacency, &materialBuf, &effects, &numMaterials, &mesh); if (FAILED(hr)) { ShowD3DErrorMessage("Loading mesh from X file", hr); return 1; } DWORD numVertices = mesh->GetNumVertices(); DWORD numFaces = mesh->GetNumFaces(); cout << "vertices: " << numVertices << '\n'; cout << "faces: " << numFaces << '\n'; cout << "adjacency buffer size: " << adjacency->GetBufferSize() << '\n'; ofstream meshfile(outputFilename.c_str()); // Output the header meshfile << "#celmodel__ascii\n\n"; cout << "numMaterials=" << numMaterials << '\n'; D3DXMATERIAL* materials = reinterpret_cast<D3DXMATERIAL*>(materialBuf->GetBufferPointer()); for (DWORD mat = 0; mat < numMaterials; mat++) { meshfile << "material\n"; meshfile << "diffuse " << materials[mat].MatD3D.Diffuse << '\n'; //meshfile << "emissive " << materials[mat].MatD3D.Emissive << '\n'; meshfile << "specular " << materials[mat].MatD3D.Specular << '\n'; meshfile << "specpower " << materials[mat].MatD3D.Power << '\n'; meshfile << "opacity " << materials[mat].MatD3D.Diffuse.a << '\n'; meshfile << "end_material\n\n"; } // Vertex format D3DVERTEXELEMENT9 declElements[MAX_FVF_DECL_SIZE]; hr = mesh->GetDeclaration(declElements); if (FAILED(hr)) { ShowD3DErrorMessage("Checking vertex declaration", hr); return 1; } DWORD stride = D3DXGetDeclVertexSize(declElements, 0); VertexAttribute vertexMap[VertexAttribute::MaxAttribute]; CreateVertexAttributeMap(declElements, vertexMap); meshfile << "mesh\n\n"; DumpVertexDescription(vertexMap, meshfile); ID3DXMesh* optMesh = NULL; ID3DXBuffer* vertexRemap = NULL; DWORD* faceRemap = new DWORD[numFaces]; DWORD* optAdjacency = new DWORD[numFaces * 3]; hr = mesh->Optimize(D3DXMESHOPT_COMPACT | D3DXMESHOPT_STRIPREORDER, //D3DXMESHOPT_VERTEXCACHE | reinterpret_cast<DWORD*>(adjacency->GetBufferPointer()), optAdjacency, faceRemap, &vertexRemap, &optMesh); if (FAILED(hr)) { ShowD3DErrorMessage("Optimize failed: ", hr); return 1; } // Attribute table DWORD attribTableSize = 0; hr = optMesh->GetAttributeTable(NULL, &attribTableSize); if (FAILED(hr)) { ShowD3DErrorMessage("Querying attribute table size", hr); return 1; } D3DXATTRIBUTERANGE* attribTable = NULL; if (attribTableSize > 0) { attribTable = new D3DXATTRIBUTERANGE[attribTableSize]; hr = optMesh->GetAttributeTable(attribTable, &attribTableSize); if (FAILED(hr)) { ShowD3DErrorMessage("Getting attribute table", hr); return 1; } } cout << "Attribute table size: " << attribTableSize << '\n'; if (attribTableSize == 1) { cout << "Attribute id: " << attribTable[0].AttribId << '\n'; } if (!DumpMeshVertices(optMesh, vertexMap, stride, meshfile)) return 1; // output the indices for (DWORD attr = 0; attr < attribTableSize; attr++) { StripifyMeshSubset(optMesh, attr, meshfile); } meshfile << "\nend_mesh\n"; #if 0 IDirect3DIndexBuffer9* indices = NULL; hr = mesh->GetIndexBuffer(&indices); #endif #if 0 // No message loop required for this app MSG msg; GetMessage(&msg, NULL, 0u, 0u); while (msg.message != WM_QUIT) { GetMessage(&msg, NULL, 0u, 0u); TranslateMessage(&msg); DispatchMessage(&msg); } #endif return 0; }