Windows 中的基本 D2D1 (directx 2d) 渲染器?

问题描述 投票:0回答:0

这个脚本应该呈现红色背景,但我的问题是,它只在单击或按住窗口顶部时呈现红色背景(我的意思是移动它的窗口顶部,如果那不是正确的名称)。 无论如何,有人知道如何解决这个问题吗?

globalVariable 只是静态变量

#include <Windows.h>
#include <d2d1.h>
#pragma comment(lib, "d2d1.lib")
#include <chrono>
#include "utils.cpp"

globalVariable bool GameIsrunning = true;
globalVariable bool Fullscreen = false;

// Settings
struct AppWindow {
    bool StartAsFullscreen;
};

globalVariable AppWindow appwindow;

struct RenderState {
    int height, width;
    void* memory;

    BITMAPINFO bitmapinfo;
};

globalVariable RenderState renderState;

#include "platform_common.cpp"

#define processButton(b, vk)\
case vk: {\
input.buttons[b].changed = isDown != input.buttons[b].isDown;\
input.buttons[b].isDown = isDown;\
} break;

LRESULT CALLBACK windowCallback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    LRESULT result = 0;
    switch (uMsg) {
    case WM_CLOSE:
    case WM_DESTROY: {
        GameIsrunning = false;
    } break;

    case WM_SIZE: {
        RECT rc;
        GetClientRect(hwnd, &rc);
        renderState.width = rc.right - rc.left;
        renderState.height = rc.bottom - rc.top;

        int size = renderState.width * renderState.height * sizeof(unsigned int);

        if (renderState.memory) VirtualFree(renderState.memory, 0, MEM_RELEASE);
        renderState.memory = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

        renderState.bitmapinfo.bmiHeader.biSize = sizeof(renderState.bitmapinfo.bmiHeader);
        renderState.bitmapinfo.bmiHeader.biWidth = renderState.width;
        renderState.bitmapinfo.bmiHeader.biHeight = renderState.height;
        renderState.bitmapinfo.bmiHeader.biPlanes = 1;
        renderState.bitmapinfo.bmiHeader.biBitCount = 32;
        renderState.bitmapinfo.bmiHeader.biCompression = BI_RGB;

    } break;

    default:
        result = DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return result;
}

void createConsoleWindow() {
    AllocConsole();
    FILE* consoleStream;
    freopen_s(&consoleStream, "CONOUT$", "w", stdout);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {

    //createConsoleWindow();

    // Create Window Class
    WNDCLASS windowClass = {};
    windowClass.style = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpszClassName = "Game Window Class";
    windowClass.lpfnWndProc = windowCallback;

    // Register Class
    RegisterClass(&windowClass);

    // Create Window
    HWND window = CreateWindow(
        windowClass.lpszClassName,
        "App",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        1280, 720, 0, 0,
        hInstance, 0
    );
    {
        //Fullscreen = true;
        //SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW);
        //MONITORINFO mi = { sizeof(mi) };
        //GetMonitorInfo(MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY), &mi);
        //SetWindowPos(window, HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
    }

    ID2D1Factory* factory;
    D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);

    ID2D1HwndRenderTarget* renderTarget;
    D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties = D2D1::RenderTargetProperties();
    renderTargetProperties.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);
    factory->CreateHwndRenderTarget(renderTargetProperties, D2D1::HwndRenderTargetProperties(window, D2D1::SizeU(renderState.width, renderState.height)), &renderTarget);

    HDC hdc = GetDC(window);

    Input input = {};

    std::chrono::system_clock::time_point m_previousTime;
    float m_totalTime = 0.0f;

    //computing delta time
    auto currentTime = std::chrono::system_clock::now();
    auto elapsedSeconds = std::chrono::duration<double>();

    if (m_previousTime.time_since_epoch().count())
        elapsedSeconds = currentTime - m_previousTime;

    m_previousTime = currentTime;

    auto deltaTime = (f32)elapsedSeconds.count();
    m_totalTime += deltaTime;

    LARGE_INTEGER frameBeginTime;
    QueryPerformanceCounter(&frameBeginTime);

    float performanceFrequency;
    {
        LARGE_INTEGER perf;
        QueryPerformanceFrequency(&perf);
        performanceFrequency = (float)perf.QuadPart;
    }

    while (GameIsrunning) {

        // Begin rendering
        renderTarget->BeginDraw();
        renderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black));

        // Render game objects
        ID2D1SolidColorBrush* brush;
        renderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &brush);
        D2D1_RECT_F rect = D2D1::RectF(0, 0, renderState.width, renderState.height);
        renderTarget->FillRectangle(&rect, brush);

        // End rendering
        renderTarget->EndDraw();


        // Input Handler
        {
            MSG message;

            for (int i = 0; i < BUTTON_COUNT; i++) {
                input.buttons[i].changed = false;
            }

            while (PeekMessage(&message, window, 0, 0, PM_REMOVE)) {
                switch (message.message) {
                case WM_KEYUP:
                case WM_KEYDOWN: {
                    u32 vkCode = (u32)message.wParam;
                    bool isDown = ((message.lParam & (1 << 31)) == 0);

                    switch (vkCode) {
                        // ALPHABET
                        processButton(BUTTON_A, 'A');
                        processButton(BUTTON_B, 'B');
                        processButton(BUTTON_C, 'C');
                        processButton(BUTTON_D, 'D');
                        processButton(BUTTON_E, 'E');
                        processButton(BUTTON_F, 'F');
                        processButton(BUTTON_G, 'G');
                        processButton(BUTTON_H, 'H');
                        processButton(BUTTON_I, 'I');
                        processButton(BUTTON_J, 'J');
                        processButton(BUTTON_K, 'K');
                        processButton(BUTTON_L, 'L');
                        processButton(BUTTON_M, 'M');
                        processButton(BUTTON_N, 'N');
                        processButton(BUTTON_O, 'O');
                        processButton(BUTTON_P, 'P');
                        processButton(BUTTON_Q, 'Q');
                        processButton(BUTTON_R, 'R');
                        processButton(BUTTON_S, 'S');
                        processButton(BUTTON_T, 'T');
                        processButton(BUTTON_U, 'U');
                        processButton(BUTTON_V, 'V');
                        processButton(BUTTON_W, 'W');
                        processButton(BUTTON_X, 'X');
                        processButton(BUTTON_Y, 'Y');
                        processButton(BUTTON_Z, 'Z');
                        
                        // NUMBERS
                        processButton(BUTTON_1, '1');
                        processButton(BUTTON_2, '2');
                        processButton(BUTTON_3, '3');
                        processButton(BUTTON_4, '4');
                        processButton(BUTTON_5, '5');
                        processButton(BUTTON_6, '6');
                        processButton(BUTTON_7, '7');
                        processButton(BUTTON_8, '8');
                        processButton(BUTTON_9, '9');
                        processButton(BUTTON_0, '0');

                        // Special Keys
                        processButton(BUTTON_UP, VK_UP);
                        processButton(BUTTON_DOWN, VK_DOWN);
                        processButton(BUTTON_LEFT, VK_LEFT);
                        processButton(BUTTON_RIGHT, VK_RIGHT);
                        processButton(BUTTON_SPACE, VK_SPACE);
                        processButton(BUTTON_ENTER, VK_RETURN);
                        processButton(BUTTON_ESCAPE, VK_ESCAPE);
                        processButton(BUTTON_F11, VK_F11);
                    }
                } break;
                default: {
                    TranslateMessage(&message);
                    DispatchMessage(&message);
                }
                }
            }
        }

        // Handle F11 key for Fullscreen
        if (input.buttons[BUTTON_F11].changed && input.buttons[BUTTON_F11].isDown) {
            if (GetWindowLong(window, GWL_STYLE) & WS_OVERLAPPEDWINDOW) {
                Fullscreen = true;

                // Switch to fullscreen mode
                SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW);
                SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) | WS_POPUP);

                // Resize window
                MONITORINFO mi = { sizeof(mi) };
                GetMonitorInfo(MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY), &mi);
                SetWindowPos(window, HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_NOOWNERZORDER | SWP_FRAMECHANGED);

                // Update render target size
                RECT rc;
                GetClientRect(window, &rc);
                renderState.width = rc.right - rc.left;
                renderState.height = rc.bottom - rc.top;

                ShowCursor(FALSE);
            }
            else {
                Fullscreen = false;

                // Switch to windowed mode
                SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_POPUP);
                SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) | WS_OVERLAPPEDWINDOW);

                // Resize window
                RECT rc = { 0, 0, 1280, 720 };
                AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
                SetWindowPos(window, HWND_TOP, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);

                // Update render target size
                RECT rcClient;
                GetClientRect(window, &rcClient);
                renderState.width = rcClient.right - rcClient.left;
                renderState.height = rcClient.bottom - rcClient.top;

                ShowCursor(TRUE);
            }
        }

        // Simulate Game
        //simulateGame(&input, deltaTime);

        // Render
        PatBlt(hdc, 0, 0, renderState.width, renderState.height, BLACKNESS);
        u32* row = (u32*)renderState.memory;
        for (int y = 0; y < renderState.height; y++) {
            for (int x = 0; x < renderState.width; x++) {
                u32 color = 0xFFFFFFFF;
                *row++ = color;
            }
        }
        StretchDIBits(hdc, 0, 0, renderState.width, renderState.height, 0, 0, renderState.width, renderState.height, renderState.memory, &renderState.bitmapinfo, DIB_RGB_COLORS, SRCCOPY);


        LARGE_INTEGER frameEndTime;
        QueryPerformanceCounter(&frameEndTime);
        deltaTime = (float)(frameEndTime.QuadPart - frameBeginTime.QuadPart) / performanceFrequency;
        frameBeginTime = frameEndTime;
    }
}
c++ winapi directx
© www.soinside.com 2019 - 2024. All rights reserved.