当我渲染三角形时 我把它移出屏幕 屏幕之外的部分不会立即更新
我不知道如何添加该行为,我不知道它是否是已知的事情,我不知道如何解决它,我不知道如何搜索它,所以我真的找不到任何东西。
我只是想知道如何解决这个问题,但我不知道如何解决。
我的代码:
#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);
}
您可以参考绘制三角形示例,效果很好。比较之后我找不到线索。