From 67fe5f8505c07807f485502d46b89bf864af4099 Mon Sep 17 00:00:00 2001 From: Squall-Leonhart Date: Thu, 29 Jun 2023 13:27:22 +1000 Subject: [PATCH] code so far WIP D3D9 --- CMakeLists.txt | 5 ++ CMakeSettings.json | 80 ++++++++++---------- cmake/FindDirectX.cmake | 87 +++++++++++----------- src/wx/CMakeLists.txt | 6 +- src/wx/drawing.h | 18 +++++ src/wx/panel.cpp | 161 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 271 insertions(+), 86 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2214f9ed..adf76550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,6 +431,11 @@ if(WIN32) set(SDL2_LIBRARY ${SDL2_LIBRARY} setupapi winmm) endif() +if(ENABLE_Direct3D) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") +find_package(DirectX REQUIRED) +endif() + # set the standard libraries all ports use set( VBAMCORE_LIBS diff --git a/CMakeSettings.json b/CMakeSettings.json index ce82bf68..40092157 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -4,92 +4,96 @@ "name": "x64-static-Debug", "generator": "Ninja", "configurationType": "Debug", - "inheritEnvironments": [ - "msvc_x64" - ], + "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x64-windows-static -DENABLE_SDL=TRUE" - }, { + }, + { "name": "x64-static-Release", "generator": "Ninja", "configurationType": "Release", - "inheritEnvironments": [ - "msvc_x64" - ], + "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x64-windows-static -DENABLE_SDL=TRUE" - }, { + "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x64-windows-static -DENABLE_SDL=TRUE", + "variables": [ + { + "name": "ENABLE_DIRECT3D", + "value": "True", + "type": "BOOL" + } + ] + }, + { "name": "x64-static-RelWithDebInfo", "generator": "Ninja", "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ - "msvc_x64" - ], + "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x64-windows-static -DENABLE_SDL=TRUE" - }, { + "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x64-windows-static -DENABLE_SDL=TRUE", + "variables": [ + { + "name": "ENABLE_DIRECT3D", + "value": "True", + "type": "BOOL" + } + ] + }, + { "name": "x86-static-Debug", "generator": "Ninja", "configurationType": "Debug", - "inheritEnvironments": [ - "msvc_x86" - ], + "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x86-windows-static -DENABLE_SDL=TRUE" - }, { + }, + { "name": "x86-static-Release", "generator": "Ninja", "configurationType": "Release", - "inheritEnvironments": [ - "msvc_x86" - ], + "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x86-windows-static -DENABLE_SDL=TRUE" - }, { + }, + { "name": "x86-static-RelWithDebInfo", "generator": "Ninja", "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ - "msvc_x86" - ], + "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=x86-windows-static -DENABLE_SDL=TRUE" - }, { + }, + { "name": "arm64-static-Debug", "generator": "Ninja", "configurationType": "Debug", - "inheritEnvironments": [ - "msvc_arm64" - ], + "inheritEnvironments": [ "msvc_arm64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=arm64-windows-static -DENABLE_SDL=TRUE" - }, { + }, + { "name": "arm64-static-Release", "generator": "Ninja", "configurationType": "Release", - "inheritEnvironments": [ - "msvc_arm64" - ], + "inheritEnvironments": [ "msvc_arm64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=arm64-windows-static -DENABLE_SDL=TRUE" - }, { + }, + { "name": "arm64-static-RelWithDebInfo", "generator": "Ninja", "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ - "msvc_arm64" - ], + "inheritEnvironments": [ "msvc_arm64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-DVCPKG_TARGET_TRIPLET=arm64-windows-static -DENABLE_SDL=TRUE" } ] -} +} \ No newline at end of file diff --git a/cmake/FindDirectX.cmake b/cmake/FindDirectX.cmake index 85aee211..4bdf84b2 100644 --- a/cmake/FindDirectX.cmake +++ b/cmake/FindDirectX.cmake @@ -1,48 +1,49 @@ -# -*- cmake -*- - -# mostly taken from emeraldviewer +# FindDirectX.cmake if (WIN32) - find_path(DIRECTX_INCLUDE_DIR dxdiag.h - "$ENV{DXSDK_DIR}/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2008)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (November 2007)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2007)/Include" - "C:/DX90SDK/Include" - "$ENV{PROGRAMFILES}/DX90SDK/Include" - ) - if (DIRECTX_INCLUDE_DIR) - include_directories(${DIRECTX_INCLUDE_DIR}) - if (DIRECTX_FIND_QUIETLY) - message(STATUS "Found DirectX include: ${DIRECTX_INCLUDE_DIR}") - endif (DIRECTX_FIND_QUIETLY) - else (DIRECTX_INCLUDE_DIR) - message(FATAL_ERROR "Could not find DirectX SDK Include") - endif (DIRECTX_INCLUDE_DIR) + # First, try to find the old DirectX SDK + find_path(DIRECTX_INCLUDE_DIR dxdiag.h + "$ENV{DXSDK_DIR}/Include" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Include" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2008)/Include" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (November 2007)/Include" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2007)/Include" + "C:/DX90SDK/Include" + "$ENV{PROGRAMFILES}/DX90SDK/Include" + ) + if (DIRECTX_INCLUDE_DIR) + include_directories(${DIRECTX_INCLUDE_DIR}) + else() + # If the old DirectX SDK is not found, use the Windows SDK + set(DIRECTX_INCLUDE_DIR "$ENV{WindowsSdkDir}/Include") + include_directories(${DIRECTX_INCLUDE_DIR}) + endif() - find_path(DIRECTX_LIBRARY_DIR dxguid.lib - "$ENV{DXSDK_DIR}/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2008)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (November 2007)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2007)/Lib/x86" - "C:/DX90SDK/Lib" - "$ENV{PROGRAMFILES}/DX90SDK/Lib" - ) - if (DIRECTX_LIBRARY_DIR) - if (DIRECTX_FIND_QUIETLY) - message(STATUS "Found DirectX include: ${DIRECTX_LIBRARY_DIR}") - endif (DIRECTX_FIND_QUIETLY) - else (DIRECTX_LIBRARY_DIR) - message(FATAL_ERROR "Could not find DirectX SDK Libraries") - endif (DIRECTX_LIBRARY_DIR) + find_path(DIRECTX_LIBRARY_DIR dxguid.lib + "$ENV{DXSDK_DIR}/Lib/x86" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Lib/x86" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2008)/Lib/x86" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (November 2007)/Lib/x86" + "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2007)/Lib/x86" + "C:/DX90SDK/Lib" + "$ENV{PROGRAMFILES}/DX90SDK/Lib" + ) -endif (WIN32) + if (NOT DIRECTX_LIBRARY_DIR) + # If the old DirectX SDK is not found, use the Windows SDK + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + # 64-bit build + set(DIRECTX_LIBRARY_DIR "$ENV{WindowsSdkDir}/Lib/x64") + else() + # 32-bit build + set(DIRECTX_LIBRARY_DIR "$ENV{WindowsSdkDir}/Lib/x86") + endif() + endif() +endif() -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(DirectX DEFAULT_MSG DIRECTX_LIBRARY_DIR DIRECTX_INCLUDE_DIR) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(DirectX DEFAULT_MSG DIRECTX_LIBRARY_DIR DIRECTX_INCLUDE_DIR) diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index a9f7f63a..065cf752 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -24,7 +24,7 @@ set(VBAM_LIBS ${VBAMCORE_LIBS}) if(WIN32) # not yet implemented - option(ENABLE_DIRECT3D "Enable Direct3D rendering for the wxWidgets port" OFF) + option(ENABLE_DIRECT3D "Enable Direct3D rendering for the wxWidgets port" ON) option(ENABLE_XAUDIO2 "Enable xaudio2 sound output for the wxWidgets port" ON) endif() @@ -896,6 +896,10 @@ set( list(APPEND ALL_SRC_WX openal.cpp) list(APPEND ALL_HDR_WX openal.h) +if(ENABLE_DIRECT3D) + list(APPEND VBAM_LIBS d3d9) +endif() + if(ENABLE_OPENAL) list(APPEND SRC_WX openal.cpp) list(APPEND HDR_WX openal.h) diff --git a/src/wx/drawing.h b/src/wx/drawing.h index 17b0ae07..5c2618a5 100644 --- a/src/wx/drawing.h +++ b/src/wx/drawing.h @@ -50,12 +50,30 @@ protected: #endif #if defined(__WXMSW__) && !defined(NO_D3D) +#include // main include file + +struct Vertex +{ + float x, y, z; + float u, v; +}; + class DXDrawingPanel : public DrawingPanel { public: DXDrawingPanel(wxWindow* parent, int _width, int _height); + virtual ~DXDrawingPanel(); protected: void DrawArea(wxWindowDC&); + void OnSize(wxSizeEvent& ev); + void DrawingPanelInit(); + + +private: + IDirect3D9* d3d; + IDirect3DDevice9* d3ddev; + IDirect3DTexture9* texture; + IDirect3DVertexBuffer9* vbuffer; }; #endif diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 09be1eeb..d0de8f89 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -2442,24 +2442,177 @@ void GLDrawingPanel::DrawArea(wxWindowDC& dc) #define DIRECT3D_VERSION 0x0900 #include // main include file //#include // required for font rendering -#include // contains debug functions DXDrawingPanel::DXDrawingPanel(wxWindow* parent, int _width, int _height) : DrawingPanel(parent, _width, _height) { - // FIXME: implement + // Create the Direct3D9 object + d3d = Direct3DCreate9(D3D_SDK_VERSION); + + // Set up the presentation parameters + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + + // Create the Direct3D9 device + d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetHWND(), + D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + + // Call the DrawingPanelInit method to initialize the rendering state and resources + DrawingPanelInit(); +} + +void DXDrawingPanel::DrawingPanelInit() +{ + // Set up the rendering state + bool bilinear = true; // Set the desired texture filtering mode here + d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, bilinear ? D3DTEXF_LINEAR : D3DTEXF_POINT); + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, bilinear ? D3DTEXF_LINEAR : D3DTEXF_POINT); + + // Define a matrix type + struct Matrix4x4 + { + float m[4][4]; + }; + + // Set up the projection matrix + Matrix4x4 matProj; + ZeroMemory(&matProj, sizeof(matProj)); + matProj.m[0][0] = 2.0f; + matProj.m[1][1] = -2.0f; + matProj.m[2][2] = 1.0f; + matProj.m[3][0] = -1.0f; + matProj.m[3][1] = 1.0f; + matProj.m[3][3] = 1.0f; + d3ddev->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&matProj); + + // Create the vertex buffer + Vertex vertices[] = { + { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, + { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } + }; + + d3ddev->CreateVertexBuffer(4 * sizeof(Vertex), D3DUSAGE_WRITEONLY, + D3DFVF_XYZ | D3DFVF_TEX1, + D3DPOOL_MANAGED, + &vbuffer, + NULL); + void* pVertices; + vbuffer->Lock(0, + sizeof(vertices), + (void**)&pVertices, + 0); + memcpy(pVertices, vertices, sizeof(vertices)); + vbuffer->Unlock(); + + // Create the texture + int texWidth = std::ceil(width * scale); + int texHeight = std::ceil(height * scale); + D3DFORMAT texFormat = out_16 ? D3DFMT_A1R5G5B5 : D3DFMT_A8R8G8B8; + HRESULT hr = d3ddev->CreateTexture(texWidth, + texHeight, + 1, + 0, + texFormat, + D3DPOOL_MANAGED, + &texture, + NULL); + if (FAILED(hr)) + { + // Handle error here + } +} + +DXDrawingPanel::~DXDrawingPanel() +{ + // Release any resources here + if (vbuffer) vbuffer->Release(); + if (texture) texture->Release(); + if (d3ddev) d3ddev->Release(); + if (d3d) d3d->Release(); } void DXDrawingPanel::DrawArea(wxWindowDC& dc) { - // FIXME: implement if (!did_init) { - DrawingPanelInit(); + DrawingPanelInit(); } if (todraw) { + // Update the texture data + D3DLOCKED_RECT rect; + texture->LockRect(0, &rect, NULL, 0); + + // Calculate the number of pixels in a row of the image data + int rowlen = std::ceil(width * scale) + (out_16 ? 2 : 1); + + // Copy the image data from the todraw variable to the locked rectangle of the texture + uint8_t* src = todraw + (int)std::ceil(rowlen * (out_16 ? 2 : 4) * scale); + uint8_t* dst = (uint8_t*)rect.pBits; + for (int y = 0; y < std::ceil(height * scale); y++) { + memcpy(dst, src, rowlen * (out_16 ? 2 : 4)); + src += rowlen * (out_16 ? 2 : 4); + dst += rect.Pitch; + } + + texture->UnlockRect(0); + + // Clear the back buffer + d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + + // Begin the scene + d3ddev->BeginScene(); + + // Set the texture and vertex buffer + d3ddev->SetTexture(0, texture); + d3ddev->SetStreamSource(0, vbuffer, 0, sizeof(Vertex)); + d3ddev->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1); + + // Draw the quad + d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + + // End the scene + d3ddev->EndScene(); + + // Present the back buffer to the screen + d3ddev->Present(NULL, NULL, NULL, NULL); } } + +void DXDrawingPanel::OnSize(wxSizeEvent& ev) +{ + // Reset the Direct3D device with updated presentation parameters + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Windowed = TRUE; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + d3dpp.BackBufferWidth = ev.GetSize().GetWidth(); + d3dpp.BackBufferHeight = ev.GetSize().GetHeight(); + d3ddev->Reset(&d3dpp); + + // Update the projection matrix + float width = (float)ev.GetSize().GetWidth(); + float height = (float)ev.GetSize().GetHeight(); + D3DMATRIX matProj = { + 2.0f / width, 0.0f, 0.0f, 0.0f, + 0.0f, -2.0f / height, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f + }; + d3ddev->SetTransform(D3DTS_PROJECTION, &matProj); + + // Call the base class handler + ev.Skip(); +} #endif #ifndef NO_FFMPEG