|
16 | 16 |
|
17 | 17 | #include "ddraw.h"
|
18 | 18 | #include <d3dhal.h>
|
| 19 | +#include <DirectXMath.h> |
19 | 20 |
|
20 | 21 | // Enable for testing only
|
21 |
| -//#define ENABLE_DEBUGOVERLAY |
| 22 | +#define ENABLE_DEBUGOVERLAY |
22 | 23 |
|
23 | 24 | #ifdef ENABLE_DEBUGOVERLAY
|
24 | 25 | #include "DebugOverlay.h"
|
@@ -338,15 +339,103 @@ HRESULT m_IDirect3DDeviceX::SetTransform(D3DTRANSFORMSTATETYPE dtstTransformStat
|
338 | 339 | break;
|
339 | 340 | }
|
340 | 341 |
|
341 |
| - HRESULT hr = (*d3d9Device)->SetTransform(dtstTransformStateType, lpD3DMatrix); |
342 |
| - |
343 |
| - if (SUCCEEDED(hr)) |
| 342 | + if(Config.DdrawConvertHomogeneousW) |
344 | 343 | {
|
345 | 344 | #ifdef ENABLE_DEBUGOVERLAY
|
| 345 | + // Set the original matrix |
346 | 346 | DOverlay.SetTransform(dtstTransformStateType, lpD3DMatrix);
|
347 | 347 | #endif
|
| 348 | + |
| 349 | + if(dtstTransformStateType == D3DTS_VIEW) |
| 350 | + { |
| 351 | + D3DVIEWPORT9 Viewport9; |
| 352 | + if(SUCCEEDED((*d3d9Device)->GetViewport(&Viewport9))) |
| 353 | + { |
| 354 | + const float width = (float)Viewport9.Width; |
| 355 | + const float height = (float)Viewport9.Height; |
| 356 | + const float ratio = width / height; |
| 357 | + |
| 358 | + // Replace the matrix with one that handles D3DFVF_XYZRHW geometry |
| 359 | + _D3DMATRIX view; |
| 360 | + ZeroMemory(&view, sizeof(_D3DMATRIX)); |
| 361 | + view._11 = 2.0f / width; |
| 362 | + view._22 = -2.0f / height; |
| 363 | + view._33 = 1.0f; |
| 364 | + view._41 = -1.0f; // translate X |
| 365 | + view._42 = 1.0f; // translate Y |
| 366 | + view._44 = 1.0f; |
| 367 | + |
| 368 | + if(!Config.DdrawConvertHomogeneousToWorld) |
| 369 | + { |
| 370 | + // Override the original matrix |
| 371 | + std::memcpy(lpD3DMatrix, &view, sizeof(_D3DMATRIX)); |
| 372 | + } |
| 373 | + else |
| 374 | + { |
| 375 | + // Override the original matrix |
| 376 | + std::memcpy(lpD3DMatrix, &view, sizeof(_D3DMATRIX)); |
| 377 | + |
| 378 | + // Store the original matrix so it can be restored |
| 379 | + std::memcpy(&RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixOriginal, &view, sizeof(_D3DMATRIX)); |
| 380 | + |
| 381 | + // The Black & White matrix is an ortho camera, so create a perspective one matching the game |
| 382 | + const float fov = Config.DdrawConvertHomogeneousToWorldFOV; |
| 383 | + const float nearplane = Config.DdrawConvertHomogeneousToWorldNearPlane; |
| 384 | + const float farplane = Config.DdrawConvertHomogeneousToWorldFarPlane; |
| 385 | + DirectX::XMMATRIX proj = DirectX::XMMatrixPerspectiveFovLH(fov * (3.14159265359f / 180.0f), ratio, nearplane, farplane); |
| 386 | + |
| 387 | + DirectX::XMStoreFloat4x4((DirectX::XMFLOAT4X4*)&RenderData.DdrawConvertHomogeneousToWorld_ProjectionMatrix, proj); |
| 388 | + |
| 389 | + DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); |
| 390 | + |
| 391 | + DirectX::XMMATRIX viewMatrix; |
| 392 | + if(Config.DdrawConvertHomogeneousToWorldUseGameCamera) |
| 393 | + { |
| 394 | + // To reconstruct the 3D world, we need to know where the camera is and where it is looking |
| 395 | + DirectX::XMVECTOR position = DirectX::XMVectorSet(lpD3DMatrix->_41, lpD3DMatrix->_42, lpD3DMatrix->_43, lpD3DMatrix->_44); |
| 396 | + DirectX::XMVECTOR direction = DirectX::XMVectorSet(lpD3DMatrix->_31, lpD3DMatrix->_32, lpD3DMatrix->_33, lpD3DMatrix->_34); |
| 397 | + |
| 398 | + viewMatrix = DirectX::XMMatrixLookToLH(position, direction, up); |
| 399 | + } |
| 400 | + else |
| 401 | + { |
| 402 | + const float cameradir = 1.0f; |
| 403 | + |
| 404 | + DirectX::XMVECTOR pos = DirectX::XMVectorSet(0.0f, 0.0f, -cameradir, 0.0f); |
| 405 | + DirectX::XMVECTOR direction = DirectX::XMVectorSet(0.0f, 0.0f, cameradir, 0.0f); |
| 406 | + |
| 407 | + viewMatrix = DirectX::XMMatrixLookToLH(pos, direction, up); |
| 408 | + } |
| 409 | + |
| 410 | + // Store the 3D view matrix so it can be set later |
| 411 | + DirectX::XMStoreFloat4x4((DirectX::XMFLOAT4X4*)&RenderData.DdrawConvertHomogeneousToWorld_ViewMatrix, viewMatrix); |
| 412 | + |
| 413 | + // Store the view inverse matrix of the game, so we can transform the geometry with it |
| 414 | + DirectX::XMMATRIX toViewSpace = DirectX::XMLoadFloat4x4((DirectX::XMFLOAT4X4*)lpD3DMatrix); |
| 415 | + DirectX::XMMATRIX vp = DirectX::XMMatrixMultiply(viewMatrix, proj); |
| 416 | + DirectX::XMMATRIX vpinv = DirectX::XMMatrixInverse(nullptr, vp); |
| 417 | + |
| 418 | + DirectX::XMMATRIX depthoffset = DirectX::XMMatrixTranslation(0.0f, 0.0f, Config.DdrawConvertHomogeneousToWorldDepthOffset); |
| 419 | + |
| 420 | + RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixInverse = DirectX::XMMatrixMultiply(depthoffset, DirectX::XMMatrixMultiply(toViewSpace, vpinv)); |
| 421 | + } |
| 422 | + } |
| 423 | + } |
| 424 | + else |
| 425 | + { |
| 426 | + return D3D_OK; |
| 427 | + } |
348 | 428 | }
|
349 | 429 |
|
| 430 | + HRESULT hr = (*d3d9Device)->SetTransform(dtstTransformStateType, lpD3DMatrix); |
| 431 | + |
| 432 | +#ifdef ENABLE_DEBUGOVERLAY |
| 433 | + if (SUCCEEDED(hr) && !Config.DdrawConvertHomogeneousW) |
| 434 | + { |
| 435 | + DOverlay.SetTransform(dtstTransformStateType, lpD3DMatrix); |
| 436 | + } |
| 437 | +#endif |
| 438 | + |
350 | 439 | return hr;
|
351 | 440 | }
|
352 | 441 |
|
@@ -1617,7 +1706,7 @@ HRESULT m_IDirect3DDeviceX::EndScene()
|
1617 | 1706 | }
|
1618 | 1707 |
|
1619 | 1708 | #ifdef ENABLE_DEBUGOVERLAY
|
1620 |
| - DOverlay.EndScene(); |
| 1709 | + DOverlay.EndScene(RenderData); |
1621 | 1710 | #endif
|
1622 | 1711 |
|
1623 | 1712 | // The IDirect3DDevice7::EndScene method ends a scene that was begun by calling the IDirect3DDevice7::BeginScene method.
|
@@ -2453,11 +2542,98 @@ HRESULT m_IDirect3DDeviceX::DrawIndexedPrimitive(D3DPRIMITIVETYPE dptPrimitiveTy
|
2453 | 2542 | }
|
2454 | 2543 | else
|
2455 | 2544 | {
|
| 2545 | + const UINT stride = GetVertexStride(dwVertexTypeDesc); |
| 2546 | + |
| 2547 | + // Handle PositionT |
| 2548 | + if((dwVertexTypeDesc & D3DFVF_XYZRHW) != 0 && Config.DdrawConvertHomogeneousW) |
| 2549 | + { |
| 2550 | + if(!Config.DdrawConvertHomogeneousToWorld) |
| 2551 | + { |
| 2552 | + UINT8 *vertex = (UINT8*)lpVertices; |
| 2553 | + |
| 2554 | + for (UINT x = 0; x < dwVertexCount; x++) |
| 2555 | + { |
| 2556 | + float *pos = (float*) vertex; |
| 2557 | + |
| 2558 | + pos[3] = 1.0f; |
| 2559 | + |
| 2560 | + vertex += stride; |
| 2561 | + } |
| 2562 | + |
| 2563 | + // Update the FVF |
| 2564 | + dwVertexTypeDesc = (dwVertexTypeDesc & ~D3DFVF_XYZRHW) | D3DFVF_XYZW; |
| 2565 | + } |
| 2566 | + else |
| 2567 | + { |
| 2568 | + const UINT newstride = stride - sizeof(float); |
| 2569 | + const UINT restSize = stride - sizeof(float) * 4; |
| 2570 | + |
| 2571 | + RenderData.DdrawConvertHomogeneousToWorld_IntermediateGeometry.resize(newstride * dwVertexCount); |
| 2572 | + |
| 2573 | + UINT8 *sourceVertex = (UINT8*)lpVertices; |
| 2574 | + UINT8 *targetVertex = (UINT8*)RenderData.DdrawConvertHomogeneousToWorld_IntermediateGeometry.data(); |
| 2575 | + |
| 2576 | + lpVertices = targetVertex; |
| 2577 | + |
| 2578 | + for (UINT x = 0; x < dwVertexCount; x++) |
| 2579 | + { |
| 2580 | + // Transform the vertices into world space |
| 2581 | + float *srcpos = (float*) sourceVertex; |
| 2582 | + float *trgtpos = (float*) targetVertex; |
| 2583 | + |
| 2584 | + DirectX::XMVECTOR xpos = DirectX::XMVectorSet(srcpos[0], srcpos[1], srcpos[2], srcpos[3]); |
| 2585 | + |
| 2586 | + DirectX::XMVECTOR xpos_global = DirectX::XMVector3TransformCoord(xpos, RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixInverse); |
| 2587 | + |
| 2588 | + xpos_global = DirectX::XMVectorDivide(xpos_global, DirectX::XMVectorSplatW(xpos_global)); |
| 2589 | + |
| 2590 | + trgtpos[0] = DirectX::XMVectorGetX(xpos_global); |
| 2591 | + trgtpos[1] = DirectX::XMVectorGetY(xpos_global); |
| 2592 | + trgtpos[2] = DirectX::XMVectorGetZ(xpos_global); |
| 2593 | + |
| 2594 | + // Copy the rest |
| 2595 | + std::memcpy(targetVertex + sizeof(float) * 3, sourceVertex + sizeof(float) * 4, restSize); |
| 2596 | + |
| 2597 | + // Move to next vertex |
| 2598 | + sourceVertex += stride; |
| 2599 | + targetVertex += newstride; |
| 2600 | + } |
| 2601 | + |
| 2602 | + // Set transform |
| 2603 | + (*d3d9Device)->SetTransform(D3DTS_VIEW, &RenderData.DdrawConvertHomogeneousToWorld_ViewMatrix); |
| 2604 | + (*d3d9Device)->SetTransform(D3DTS_PROJECTION, &RenderData.DdrawConvertHomogeneousToWorld_ProjectionMatrix); |
| 2605 | + |
| 2606 | + // Update the FVF |
| 2607 | + const DWORD newVertexTypeDesc = (dwVertexTypeDesc & ~D3DFVF_XYZRHW) | D3DFVF_XYZ; |
| 2608 | + |
| 2609 | + // Set fixed function vertex type |
| 2610 | + (*d3d9Device)->SetFVF(newVertexTypeDesc); |
| 2611 | + |
| 2612 | + // Draw indexed primitive UP |
| 2613 | + hr = (*d3d9Device)->DrawIndexedPrimitiveUP(dptPrimitiveType, 0, dwVertexCount, GetNumberOfPrimitives(dptPrimitiveType, dwIndexCount), lpIndices, D3DFMT_INDEX16, lpVertices, newstride); |
| 2614 | + |
| 2615 | + // Restore transform |
| 2616 | + _D3DMATRIX identityMatrix; |
| 2617 | + ZeroMemory(&identityMatrix, sizeof(_D3DMATRIX)); |
| 2618 | + identityMatrix._11 = 1.0f; |
| 2619 | + identityMatrix._22 = 1.0f; |
| 2620 | + identityMatrix._33 = 1.0f; |
| 2621 | + |
| 2622 | + (*d3d9Device)->SetTransform(D3DTS_VIEW, &RenderData.DdrawConvertHomogeneousToWorld_ViewMatrixOriginal); |
| 2623 | + (*d3d9Device)->SetTransform(D3DTS_PROJECTION, &identityMatrix); |
| 2624 | + |
| 2625 | + // Handle dwFlags |
| 2626 | + UnSetDrawFlags(rsClipping, rsLighting, rsExtents, newVertexTypeDesc, dwFlags, DirectXVersion); |
| 2627 | + |
| 2628 | + return hr; |
| 2629 | + } |
| 2630 | + } |
| 2631 | + |
2456 | 2632 | // Set fixed function vertex type
|
2457 | 2633 | (*d3d9Device)->SetFVF(dwVertexTypeDesc);
|
2458 | 2634 |
|
2459 | 2635 | // Draw indexed primitive UP
|
2460 |
| - hr = (*d3d9Device)->DrawIndexedPrimitiveUP(dptPrimitiveType, 0, dwVertexCount, GetNumberOfPrimitives(dptPrimitiveType, dwIndexCount), lpIndices, D3DFMT_INDEX16, lpVertices, GetVertexStride(dwVertexTypeDesc)); |
| 2636 | + hr = (*d3d9Device)->DrawIndexedPrimitiveUP(dptPrimitiveType, 0, dwVertexCount, GetNumberOfPrimitives(dptPrimitiveType, dwIndexCount), lpIndices, D3DFMT_INDEX16, lpVertices, stride); |
2461 | 2637 | }
|
2462 | 2638 |
|
2463 | 2639 | // Handle dwFlags
|
|
0 commit comments