2

I am creating a application to make a menu appear for a game (32 bit) and im compiling this piece of code yet whenever i debug it nothing appears over the game or around it at all, wondering if anybody knows what is going on, i have not properly had the time to look into how directx11 works and how all of the other functions work yet.

I'm using a sample from the original imgui repository in examples im using the one for directx11 (win32), only thing i changed is the window handle from creating a new window to my own game window which currently exists (AssaultCube)

I know this i may get ahted on fore this but i also used AI to implement error checks as a lazy fail safe and i keep on getting "Failed to create D3D device and swap chain: 80070057".

#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_dx11.h"
#include <d3d11.h>
#include <tchar.h>
#include <cstdio>

// Data
static ID3D11Device* g_pd3dDevice = nullptr;
static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
static IDXGISwapChain* g_pSwapChain = nullptr;
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;

// Forward declarations of helper functions
bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
void CreateRenderTarget();
void CleanupRenderTarget();
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

// Main code
int main(int, char**) {
    // Find the AssaultCube window
    HWND hwnd = FindWindow(NULL, L"AssaultCube");
    if (hwnd == NULL) {
        printf("Error: Could not find window 'AssaultCube'. Error code: %lu\n", GetLastError());
        return 1; // Exit if window not found
    }

    // Initialize Direct3D with the existing window handle
    if (!CreateDeviceD3D(hwnd)) {
        CleanupDeviceD3D();
        return 1; // Exit if device creation fails
    }

    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGui_ImplWin32_Init(hwnd); // Initialize ImGui for Win32 with existing window handle
    ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
    ImGui::StyleColorsDark();

    // Main loop
    bool done = false;
    while (!done) {
        // Poll and handle messages
        MSG msg;
        while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
            if (msg.message == WM_QUIT)
                done = true;
        }

        // Start the Dear ImGui frame
        ImGui_ImplDX11_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();

        // Create a simple ImGui window
        {
            ImGui::Begin("Hello from ImGui!"); // Create a window called "Hello!"
            if (ImGui::Button("Click Me")) {
                printf("Button clicked!\n");
            }
            ImGui::End();
        }

        // Rendering
        ImGui::Render();
        const float clear_color[4] = { 0.45f, 0.55f, 0.60f, 1.00f };
        g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
        g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color);

        // Render ImGui data
        ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

        // Present the swap chain
        HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync
        if (FAILED(hr)) {
            printf("Failed to present swap chain: %08X\n", hr);
            break; // Exit on failure
        }
    }

    // Cleanup
    CleanupDeviceD3D();
    return 0;
}

// Definition of CreateDeviceD3D
bool CreateDeviceD3D(HWND hWnd) {
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory(&sd, sizeof(sd));
    sd.BufferCount = 1; // Change to 1 for a single back buffer
    sd.BufferDesc.Width = 0; // Use automatic sizing
    sd.BufferDesc.Height = 0; // Use automatic sizing
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = hWnd; // Use the existing window handle
    sd.Windowed = TRUE; // Set windowed mode

    UINT createDeviceFlags = 0;

    D3D_FEATURE_LEVEL featureLevel;
    const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0 };

    HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        createDeviceFlags,
        featureLevelArray,
        ARRAYSIZE(featureLevelArray),
        D3D11_SDK_VERSION,
        &sd,
        &g_pSwapChain,
        &g_pd3dDevice,
        &featureLevel,
        &g_pd3dDeviceContext);

    if (FAILED(res)) {
        printf("Failed to create D3D device and swap chain: %08X\n", res);
        return false; // Return false on failure
    }

    CreateRenderTarget(); // Ensure this function is defined elsewhere in your code.
    return true;
}

void CreateRenderTarget() {
    ID3D11Texture2D* pBackBuffer;

    HRESULT hr = g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));

    if (FAILED(hr)) {
        printf("Failed to get back buffer: %08X\n", hr);
        return; // Exit if getting buffer fails
    }

    hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);

    pBackBuffer->Release(); // Release back buffer regardless of success

    if (FAILED(hr)) {
        printf("Failed to create render target view: %08X\n", hr);
        return; // Exit if creation fails
    }
}

void CleanupRenderTarget() {
    if (g_mainRenderTargetView) {
        g_mainRenderTargetView->Release();
        g_mainRenderTargetView = nullptr;
    }
}

void CleanupDeviceD3D() {
    CleanupRenderTarget();

    if (g_pSwapChain) {
        g_pSwapChain->Release();
        g_pSwapChain = nullptr;
    }

    if (g_pd3dDeviceContext) {
        g_pd3dDeviceContext->Release();
        g_pd3dDeviceContext = nullptr;
    }

    if (g_pd3dDevice) {
        g_pd3dDevice->Release();
        g_pd3dDevice = nullptr;
    }
}

// Win32 message handler remains unchanged...
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
    case WM_SIZE:
        if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) {
            CleanupRenderTarget();
            CreateRenderTarget();
        }
        return 0;

    case WM_SYSCOMMAND:
        if ((wParam & 0xFFF0) == SC_KEYMENU) { // Disable ALT application menu
            return 0;
        }
        break;

    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;

    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_CHAR:
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
3
  • 1
    Are you trying to render into another application's window from a different process? Does Windows even support that? Usually people hack games by injecting a DLL into the process (and attaching to any existing render loop)... Commented Nov 8, 2024 at 10:49
  • 2
    This post has your problem (the swap chain part, not the imgui part), and a solution. I have no idea if it will work for you. Commented Nov 8, 2024 at 10:51
  • 1
    If you are going to get hated, I think it will be for not teaching yourself anything but instead copying sample code that you don't understand, not for using AI. Programming is hard, ultimately writing your own code is the only way to learn it. If I were you I'd find a good DirectX tutorial and work your way though it before you do anything else. Follow that with a good IMGui tutorial and only then come back to this program. But you want to run before you can walk, it's how it goes these days, Commented Nov 8, 2024 at 10:56

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.