我的 d3d11 渲染不会立即更新屏幕外的窗口部分

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

当我渲染三角形时 我把它移出屏幕 屏幕之外的部分不会立即更新

我不知道如何添加该行为,我不知道它是否是已知的事情,我不知道如何解决它,我不知道如何搜索它,所以我真的找不到任何东西。

我只是想知道如何解决这个问题,但我不知道如何解决。

我的代码:


 
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#include <d3d11_1.h>
#include <wrl/client.h>
#include <d3dcompiler.h>

#include "indoin.hpp"

#pragma comment(lib, "d3dcompiler")
#pragma comment(lib, "d3d11")
#pragma comment(lib, "dxgi")

#define check(x) Check(x, std::to_string(__LINE__), __FILE__)

#define VSFile L"shader.sh"
#define FSFile L"shader.sh"

#include <iostream>
struct position {
    float x, y;
};
struct color {
    float r, g, b;
};

struct vertex {

    position pos;
    color col;

};

const vertex vertices[] = {


    {-1.0f,  1.0f,  0.0f, 1.0f, 0.0f},
    { 1.0f, -1.0f,  0.0f, 0.0f, 1.0f},
    {-1.0f, -1.0f,  1.0f, 0.0f, 0.0f},

};

int other(HINSTANCE hInstance);

int main()
{

    window wnd(800, 500, L"window name", Y_sizable_Y_windowed);

    Microsoft::WRL::ComPtr<IDXGIFactory1> factory = nullptr; 
    Microsoft::WRL::ComPtr<ID3D11Device> device = nullptr; 
    Microsoft::WRL::ComPtr<ID3D11DeviceContext> context = nullptr; {

        check(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));
        Microsoft::WRL::ComPtr<IDXGIAdapter> adapter = nullptr;
        factory->EnumAdapters(0, adapter.GetAddressOf());
        check(D3D11CreateDevice(adapter.Get(), D3D_DRIVER_TYPE_UNKNOWN, 0, D3D11_CREATE_DEVICE_DEBUG, 0, 0, D3D11_SDK_VERSION, device.GetAddressOf(), 0, context.GetAddressOf()));
        DXGI_ADAPTER_DESC desc; HRESULT res = adapter->GetDesc(&desc);
        if(!FAILED(res))std::wcout << "using graphics adapter : (" << desc.Description << ")" << std::endl;
        else std::wcout << "no_graphics_adapter_found" << std::endl; check(res);
    }
    Microsoft::WRL::ComPtr<ID3D11Buffer> vertex_buffer = nullptr; {

        D3D11_BUFFER_DESC desc = {}; {
            desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
            desc.ByteWidth = sizeof(vertices);
            desc.MiscFlags = 0;
            desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
            desc.StructureByteStride = sizeof(vertex);
            desc.Usage = D3D11_USAGE_DYNAMIC;
        }
                                                            
        D3D11_SUBRESOURCE_DATA data = {}; {

            data.pSysMem = &vertices;

        }
        check(device->CreateBuffer(&desc, &data, &vertex_buffer));
    }
    Microsoft::WRL::ComPtr<ID3D11VertexShader> vertex_shader = nullptr;
    Microsoft::WRL::ComPtr<ID3DBlob> vs = nullptr; {

        check(D3DCompileFromFile(VSFile, NULL, NULL, "vs_main", "vs_5_0", 0, 0, vs.GetAddressOf(), NULL));
        check(device->CreateVertexShader(vs->GetBufferPointer(), vs->GetBufferSize(), NULL, vertex_shader.GetAddressOf()));

    }
    Microsoft::WRL::ComPtr<ID3D11PixelShader> pixel_shader = nullptr; {

        Microsoft::WRL::ComPtr<ID3DBlob> ps = nullptr;
        Microsoft::WRL::ComPtr<ID3DBlob> errorBlob = nullptr;
        check(D3DCompileFromFile(FSFile, NULL, NULL, "fs_main", "ps_5_0", 0, 0, ps.GetAddressOf(), errorBlob.GetAddressOf()));
        check(device->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), NULL, pixel_shader.GetAddressOf()));
    }

    Microsoft::WRL::ComPtr<IDXGISwapChain> swapchain = nullptr;{

        DXGI_SWAP_CHAIN_DESC desc = {}; {

            desc.Windowed = 1;
            desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
            desc.OutputWindow = wnd.wnd;
            desc.SampleDesc.Count = 1;
            desc.BufferCount = 2;
            desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
            desc.BufferDesc.RefreshRate = {120, 1};
            desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

        }
                                        
        check(factory->CreateSwapChain(device.Get(), &desc, swapchain.GetAddressOf()));

    }
    Microsoft::WRL::ComPtr <ID3D11RenderTargetView> RTV = nullptr; {

        D3D11_RENDER_TARGET_VIEW_DESC desc = {}; {

            desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
            desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
            desc.Texture2D.MipSlice = 0;
        }
        Microsoft::WRL::ComPtr<ID3D11Texture2D> back_buffer = nullptr; 
        check(swapchain->GetBuffer(0, IID_PPV_ARGS(back_buffer.GetAddressOf())));
        check(device->CreateRenderTargetView(back_buffer.Get(), &desc, &RTV));
        
    }
    Microsoft::WRL::ComPtr<ID3D11InputLayout> layout = nullptr; {

        const D3D11_INPUT_ELEMENT_DESC desc[] = {
        
            {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
            {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(position) , D3D11_INPUT_PER_VERTEX_DATA, 0}
        };
        check(device->CreateInputLayout(desc, ARRAYSIZE(desc), vs->GetBufferPointer(), vs->GetBufferSize(), layout.GetAddressOf()));
    }
    { UINT32 stride = sizeof(vertex); UINT offset = 0;
        context->IASetVertexBuffers(0, 1, vertex_buffer.GetAddressOf(), &stride, &offset);
        context->IASetInputLayout(layout.Get());
        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        context->VSSetShader(vertex_shader.Get(), NULL, 0);
        context->PSSetShader(pixel_shader.Get(), NULL, 0);
        
        context->OMSetRenderTargets(1, RTV.GetAddressOf(), nullptr);
    }

    ShowWindow(wnd.wnd, SW_SHOW);

    while (wnd.msg.message != WM_QUIT) {

        handle_msg(wnd);

        RECT winRect;
        GetClientRect(wnd.wnd, &winRect);
        D3D11_VIEWPORT port[] = { 
            {.TopLeftX = 0, .TopLeftY = 0, 
            .Width = (FLOAT)(winRect.right - winRect.left), 
            .Height = (FLOAT)(winRect.bottom - winRect.top), 
            .MinDepth = 0, .MaxDepth = 1 } 
        }; context->RSSetViewports(1, port);

        float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };

        context->ClearRenderTargetView(RTV.Get(), clearColor);
        context->Draw(3, 0);
        swapchain->Present(1, 0);

    }
    return 0;
}


窗口助手

indoin.hpp:


#pragma once
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <Windows.h>
#include <string>

#define handle_msg(a) { if(PeekMessage(&a.msg, 0, 0, 0, PM_REMOVE)) {  TranslateMessage(&a.msg); DispatchMessageW(&a.msg); } } 

static void Check(HRESULT hr, std::string str, std::string file);
#define check(x) Check(x, std::to_string(__LINE__), __FILE__)
enum window_type {
    N_sizable_Y_windowed,
    Y_sizable_N_windowed,
    Y_sizable_Y_windowed,
    N_sizable_N_windowed
};

enum window_controls {
    MINIMIZE,
    MAXIMIZE,
    RESTORE,
    HIDE,
    SHOW
};

class window
{
public:
    MSG msg = {};
    int height = 0;
    int width = 0;
    DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
    HWND wnd = nullptr;
    window(int width, int height, LPCWSTR title, window_type type):width(width),height(height){
        WNDCLASS default_class = {
            .style = CS_DBLCLKS,
            .lpfnWndProc = PROC,
            .cbClsExtra = 0,
            .cbWndExtra = 0,
            .hInstance = GetModuleHandle(nullptr),
            .hIcon = nullptr,
            .hCursor = nullptr,
            .hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0)),
            .lpszMenuName = nullptr,
            .lpszClassName = L"default_window_class_code98465665468"
        };
        if (!RegisterClass(&default_class)) {
            DWORD error = GetLastError(); HRESULT res = HRESULT_FROM_WIN32(error); if (res == 0x80070582) res = S_OK; check(res); }
        switch (type) {
        case N_sizable_Y_windowed: style = WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
            break;
        case Y_sizable_N_windowed: style = WS_BORDER | WS_POPUP | WS_SYSMENU;
            break;
        case Y_sizable_Y_windowed: style = WS_OVERLAPPEDWINDOW;
            break;
        case N_sizable_N_windowed: style = WS_POPUP | WS_SYSMENU;
            break;
        default: style = WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
        }
        RECT wndrect = {
            .left = 0, .top = 0,
            .right = this->width, .bottom = this->height
        };
        AdjustWindowRect(&wndrect, this->style, false);
        int w = wndrect.right - wndrect.left;
        int h = wndrect.bottom - wndrect.top;
        wnd = CreateWindow(default_class.lpszClassName, title, style, CW_USEDEFAULT, CW_USEDEFAULT, w, h, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
        if (!wnd) throw std::runtime_error("window creation failed!");
        UnregisterClass(default_class.lpszClassName, GetModuleHandle(nullptr));
    }
    static LRESULT CALLBACK PROC(HWND wnd, UINT msg, WPARAM wpr, LPARAM lpr) {
        switch (msg) {
        case WM_DESTROY: PostQuitMessage(0); break;
        default: return DefWindowProc(wnd, msg, wpr, lpr);
        }
        return 0;
    }
    void show(window_controls control) {
        switch (control) {
        case MINIMIZE: ShowWindow(wnd, SW_MINIMIZE); break;
        case MAXIMIZE: ShowWindow(wnd, SW_MAXIMIZE); break;
        case HIDE: ShowWindow(wnd, SW_HIDE); break;
        case RESTORE: case SHOW: default: ShowWindow(wnd, SW_SHOW); break;
        }
    }
};

static void Check(HRESULT hr, std::string str, std::string file) {
    if (FAILED(hr)) {
        LPVOID errorMsg;
        DWORD errorMessageID = FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL, hr, 0, reinterpret_cast<LPWSTR>(&errorMsg), 0, NULL
        );

        std::wcerr << "file(\"" << file.c_str() << "\") | " << "line(" << str.c_str() << ") : ";

        if (errorMessageID != 0) {
            std::wcerr << L"Error Code: 0x" << std::hex << hr << std::dec << std::endl;
            std::wcerr << L"Error Message: " << static_cast<LPCWSTR>(errorMsg) << std::endl;
            LocalFree(errorMsg);
        }
        else {
            std::wcerr << L"Unable to retrieve error message for HRESULT: 0x" << std::hex << hr << std::dec << std::endl;
        }
        exit(-1);
    }
    else {
        std::wcout << L"No failure | (HRESULT: 0x" << std::hex << hr << std::dec << ")" << std::endl;
    }
}

着色器代码:

// shader.sh

// Input structure representing a single vertex
struct VertexInput {
    float2 Position : POSITION;
    float3 Color : COLOR;
};

// Output structure to be passed to the pixel shader
struct VertexOutput {
    float4 Position : SV_POSITION;
    float3 Color : COLOR;
};

// The main vertex shader function
VertexOutput vs_main(VertexInput input) {
    VertexOutput output;

    // Transform the vertex position to clip space
    output.Position = float4(input.Position, 0.0f, 1.0f);

    // Pass the vertex color to the pixel shader
    output.Color = input.Color;

    return output;
}

float4 fs_main(VertexOutput input) : SV_TARGET
{

    return float4(input.Color, 1.0f);

}
c++ winapi graphics rendering direct3d
1个回答
0
投票

您可以参考绘制三角形示例,效果很好。比较之后我找不到线索。

© www.soinside.com 2019 - 2024. All rights reserved.