D3D11 着色器编译成功,但出现白屏
D3D11 shaders compiles successfully, but I get a white screen
我正在设置 d3d11 来学习基础知识,但遇到了一些问题。我没有任何错误,一切都可以正常编译,但以白色 window 结尾。我在这里错过了什么吗? window 中应该有一个彩色四边形。对于提问中的任何错误,我们深表歉意。这是我第一次 post 来这里。
CPP 文件:
#include <Windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <iostream>
struct Vec3
{
float x, y, z;
};
struct Vertex
{
Vec3 position;
Vec3 color;
};
bool running = true;
HWND hwndApp;
LRESULT CALLBACK AppWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_DESTROY)
{
running = false;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int main()
{
WNDCLASSEX appWndClass = { };
appWndClass.lpfnWndProc = AppWndProc;
appWndClass.cbSize = sizeof(WNDCLASSEX);
appWndClass.cbClsExtra = NULL;
appWndClass.cbWndExtra = NULL;
appWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
appWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
appWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
appWndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
appWndClass.style = NULL;
appWndClass.hInstance = GetModuleHandle(NULL);
appWndClass.lpszClassName = "AppWndClass";
appWndClass.lpszMenuName = "";
RegisterClassEx(&appWndClass);
hwndApp = CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
appWndClass.lpszClassName,
"AppWndClass",
WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 1024, 768,
NULL,
NULL,
GetModuleHandle(NULL),
NULL
);
ShowWindow(hwndApp, SW_SHOW);
UpdateWindow(hwndApp);
ID3D11Device* d3dDevice = nullptr;
ID3D11DeviceContext* d3dDeviceContext = nullptr;
IDXGIDevice* dxgiDevice = nullptr;
IDXGIAdapter* dxgiAdapter = nullptr;
IDXGIFactory* dxgiFactory = nullptr;
IDXGISwapChain* dxgiSwapChain = nullptr;
ID3D11RenderTargetView* renderTargetView = nullptr;
D3D_FEATURE_LEVEL featureLevel;
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0
};
D3D11CreateDevice(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
0,
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&d3dDevice,
&featureLevel,
&d3dDeviceContext
);
if (d3dDevice == nullptr) return -1;
if (d3dDeviceContext == nullptr) return -1;
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)& dxgiDevice);
dxgiDevice->GetAdapter(&dxgiAdapter);
dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)& dxgiFactory);
RECT rc;
GetClientRect(hwndApp, &rc);
DXGI_SWAP_CHAIN_DESC swapChainDescription;
ZeroMemory(&swapChainDescription, sizeof(swapChainDescription));
swapChainDescription.BufferCount = 1;
swapChainDescription.BufferDesc.Width = rc.right - rc.left;
swapChainDescription.BufferDesc.Height = rc.bottom - rc.top;
swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDescription.BufferDesc.RefreshRate.Numerator = 60;
swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDescription.OutputWindow = hwndApp;
swapChainDescription.SampleDesc.Count = 1;
swapChainDescription.SampleDesc.Quality = 0;
swapChainDescription.Windowed = TRUE;
dxgiFactory->CreateSwapChain(d3dDevice, &swapChainDescription, &dxgiSwapChain);
ID3D11Texture2D* buffer = nullptr;
dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)& buffer);
if (buffer == nullptr) return -1;
d3dDevice->CreateRenderTargetView(buffer, nullptr, &renderTargetView);
buffer->Release();
if (renderTargetView == nullptr) return -1;
Vertex vertices[] =
{
{ -0.5f, -0.5f, 0.0f, 0, 0, 0 },
{ -0.5f, 0.5f, 0.0f, 1, 1, 0 },
{ 0.5f, -0.5f, 0.0f, 0, 0, 1 },
{ 0.5f, 0.5f, 0.0f, 1, 1, 1 }
};
UINT sizeVertices = ARRAYSIZE(vertices);
D3D11_INPUT_ELEMENT_DESC inputElementDescription[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA , 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
UINT sizeInputElementDescription = ARRAYSIZE(inputElementDescription);
D3D11_BUFFER_DESC bufferDescription = {};
bufferDescription.Usage = D3D11_USAGE_DEFAULT;
bufferDescription.ByteWidth = sizeof(Vertex) * sizeVertices;
bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDescription.CPUAccessFlags = 0;
bufferDescription.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA initialData = {};
initialData.pSysMem = vertices;
ID3D11Buffer* vertexBuffer;
d3dDevice->CreateBuffer(&bufferDescription, &initialData, &vertexBuffer);
void* shaderByteCode = nullptr;
size_t byteCodeLength = 0;
ID3DBlob* blobCode = nullptr;
ID3DBlob* blobErrorMsgs = nullptr;
//D3DCompileFromFile( L"VertexShader.hlsl", nullptr, nullptr, "vsmain", "vs_5_0", 0, 0, &blobCode, &blobErrorMsgs );
if (!SUCCEEDED(D3DCompileFromFile(L"VertexShader.hlsl", nullptr, nullptr, "vsmain", "vs_5_0", 0, 0, &blobCode, &blobErrorMsgs)))
{
if (blobErrorMsgs) blobErrorMsgs->Release();
std::cout << "ERROR COMPILING VERTEXSHADER" << std::endl;
return false;
}
shaderByteCode = blobCode->GetBufferPointer();
byteCodeLength = blobCode->GetBufferSize();
ID3D11VertexShader* vertexShader;
d3dDevice->CreateVertexShader(shaderByteCode, byteCodeLength, nullptr, &vertexShader);
vertexShader->Release();
ID3D11InputLayout* inputLayout;
d3dDevice->CreateInputLayout(inputElementDescription, sizeInputElementDescription, shaderByteCode, byteCodeLength, &inputLayout);
blobCode->Release();
void* shaderByteCode2 = nullptr;
size_t byteCodeLength2 = 0;
ID3DBlob* blobCode2 = nullptr;
ID3DBlob* blobErrorMsgs2 = nullptr;
//D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "psmain", "ps_5_0", 0, 0, &blobCode2, &blobErrorMsgs2);
if (!SUCCEEDED(D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "psmain", "ps_5_0", 0, 0, &blobCode2, &blobErrorMsgs2)))
{
if (blobErrorMsgs2) blobErrorMsgs2->Release();
std::cout << "ERROR COMPILING PIXELSHADER" << std::endl;
return false;
}
shaderByteCode2 = blobCode2->GetBufferPointer();
byteCodeLength2 = blobCode2->GetBufferSize();
ID3D11PixelShader* pixelShader;
d3dDevice->CreatePixelShader(shaderByteCode2, byteCodeLength2, nullptr, &pixelShader);
pixelShader->Release();
blobCode2->Release();
FLOAT clearColor[] = { 0.0, 0.0, 0.0, 1.0 };
while (running)
{
d3dDeviceContext->ClearRenderTargetView(renderTargetView, clearColor);
d3dDeviceContext->OMSetRenderTargets(1, &renderTargetView, NULL);
GetClientRect(hwndApp, &rc);
D3D11_VIEWPORT vp = {};
vp.Width = rc.right - rc.left;
vp.Height = rc.bottom - rc.top;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
d3dDeviceContext->RSSetViewports(1, &vp);
d3dDeviceContext->VSSetShader(vertexShader, nullptr, 0);
d3dDeviceContext->PSSetShader(pixelShader, nullptr, 0);
UINT stride = sizeof(Vertex);
UINT offset = 0;
d3dDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
d3dDeviceContext->IASetInputLayout(inputLayout);
d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
d3dDeviceContext->Draw(sizeVertices, 0);
dxgiSwapChain->Present(true, NULL);
MSG msg = { 0 };
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
renderTargetView->Release();
inputLayout->Release();
vertexBuffer->Release();
dxgiDevice->Release();
dxgiAdapter->Release();
dxgiFactory->Release();
d3dDeviceContext->Release();
d3dDevice->Release();
return 0;
}
顶点着色器
struct VS_INPUT
{
float4 position: POSITION;
float3 color: COLOR;
};
struct VS_OUTPUT
{
float4 position: SV_POSITION;
float3 color: COLOR;
};
VS_OUTPUT vsmain(VS_INPUT input)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.position = input.position;
output.color = input.color;
return output;
}
像素着色器
struct PS_INPUT
{
float4 position: SV_POSITION;
float3 color: COLOR;
};
float4 psmain(PS_INPUT input) : SV_TARGET
{
return float4(input.color,1.0f);
}
我希望 window 显示多色四边形,但 window 全是白色。
着色器已发布,随后在代码中使用。
vertexShader->Release();
pixelShader->Release();
将着色器的释放移动到程序的末尾解决了这个问题。
我正在设置 d3d11 来学习基础知识,但遇到了一些问题。我没有任何错误,一切都可以正常编译,但以白色 window 结尾。我在这里错过了什么吗? window 中应该有一个彩色四边形。对于提问中的任何错误,我们深表歉意。这是我第一次 post 来这里。
CPP 文件:
#include <Windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <iostream>
struct Vec3
{
float x, y, z;
};
struct Vertex
{
Vec3 position;
Vec3 color;
};
bool running = true;
HWND hwndApp;
LRESULT CALLBACK AppWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_DESTROY)
{
running = false;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int main()
{
WNDCLASSEX appWndClass = { };
appWndClass.lpfnWndProc = AppWndProc;
appWndClass.cbSize = sizeof(WNDCLASSEX);
appWndClass.cbClsExtra = NULL;
appWndClass.cbWndExtra = NULL;
appWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
appWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
appWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
appWndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
appWndClass.style = NULL;
appWndClass.hInstance = GetModuleHandle(NULL);
appWndClass.lpszClassName = "AppWndClass";
appWndClass.lpszMenuName = "";
RegisterClassEx(&appWndClass);
hwndApp = CreateWindowEx(
WS_EX_OVERLAPPEDWINDOW,
appWndClass.lpszClassName,
"AppWndClass",
WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 1024, 768,
NULL,
NULL,
GetModuleHandle(NULL),
NULL
);
ShowWindow(hwndApp, SW_SHOW);
UpdateWindow(hwndApp);
ID3D11Device* d3dDevice = nullptr;
ID3D11DeviceContext* d3dDeviceContext = nullptr;
IDXGIDevice* dxgiDevice = nullptr;
IDXGIAdapter* dxgiAdapter = nullptr;
IDXGIFactory* dxgiFactory = nullptr;
IDXGISwapChain* dxgiSwapChain = nullptr;
ID3D11RenderTargetView* renderTargetView = nullptr;
D3D_FEATURE_LEVEL featureLevel;
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0
};
D3D11CreateDevice(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
0,
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&d3dDevice,
&featureLevel,
&d3dDeviceContext
);
if (d3dDevice == nullptr) return -1;
if (d3dDeviceContext == nullptr) return -1;
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)& dxgiDevice);
dxgiDevice->GetAdapter(&dxgiAdapter);
dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)& dxgiFactory);
RECT rc;
GetClientRect(hwndApp, &rc);
DXGI_SWAP_CHAIN_DESC swapChainDescription;
ZeroMemory(&swapChainDescription, sizeof(swapChainDescription));
swapChainDescription.BufferCount = 1;
swapChainDescription.BufferDesc.Width = rc.right - rc.left;
swapChainDescription.BufferDesc.Height = rc.bottom - rc.top;
swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDescription.BufferDesc.RefreshRate.Numerator = 60;
swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDescription.OutputWindow = hwndApp;
swapChainDescription.SampleDesc.Count = 1;
swapChainDescription.SampleDesc.Quality = 0;
swapChainDescription.Windowed = TRUE;
dxgiFactory->CreateSwapChain(d3dDevice, &swapChainDescription, &dxgiSwapChain);
ID3D11Texture2D* buffer = nullptr;
dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)& buffer);
if (buffer == nullptr) return -1;
d3dDevice->CreateRenderTargetView(buffer, nullptr, &renderTargetView);
buffer->Release();
if (renderTargetView == nullptr) return -1;
Vertex vertices[] =
{
{ -0.5f, -0.5f, 0.0f, 0, 0, 0 },
{ -0.5f, 0.5f, 0.0f, 1, 1, 0 },
{ 0.5f, -0.5f, 0.0f, 0, 0, 1 },
{ 0.5f, 0.5f, 0.0f, 1, 1, 1 }
};
UINT sizeVertices = ARRAYSIZE(vertices);
D3D11_INPUT_ELEMENT_DESC inputElementDescription[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA , 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
UINT sizeInputElementDescription = ARRAYSIZE(inputElementDescription);
D3D11_BUFFER_DESC bufferDescription = {};
bufferDescription.Usage = D3D11_USAGE_DEFAULT;
bufferDescription.ByteWidth = sizeof(Vertex) * sizeVertices;
bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDescription.CPUAccessFlags = 0;
bufferDescription.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA initialData = {};
initialData.pSysMem = vertices;
ID3D11Buffer* vertexBuffer;
d3dDevice->CreateBuffer(&bufferDescription, &initialData, &vertexBuffer);
void* shaderByteCode = nullptr;
size_t byteCodeLength = 0;
ID3DBlob* blobCode = nullptr;
ID3DBlob* blobErrorMsgs = nullptr;
//D3DCompileFromFile( L"VertexShader.hlsl", nullptr, nullptr, "vsmain", "vs_5_0", 0, 0, &blobCode, &blobErrorMsgs );
if (!SUCCEEDED(D3DCompileFromFile(L"VertexShader.hlsl", nullptr, nullptr, "vsmain", "vs_5_0", 0, 0, &blobCode, &blobErrorMsgs)))
{
if (blobErrorMsgs) blobErrorMsgs->Release();
std::cout << "ERROR COMPILING VERTEXSHADER" << std::endl;
return false;
}
shaderByteCode = blobCode->GetBufferPointer();
byteCodeLength = blobCode->GetBufferSize();
ID3D11VertexShader* vertexShader;
d3dDevice->CreateVertexShader(shaderByteCode, byteCodeLength, nullptr, &vertexShader);
vertexShader->Release();
ID3D11InputLayout* inputLayout;
d3dDevice->CreateInputLayout(inputElementDescription, sizeInputElementDescription, shaderByteCode, byteCodeLength, &inputLayout);
blobCode->Release();
void* shaderByteCode2 = nullptr;
size_t byteCodeLength2 = 0;
ID3DBlob* blobCode2 = nullptr;
ID3DBlob* blobErrorMsgs2 = nullptr;
//D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "psmain", "ps_5_0", 0, 0, &blobCode2, &blobErrorMsgs2);
if (!SUCCEEDED(D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "psmain", "ps_5_0", 0, 0, &blobCode2, &blobErrorMsgs2)))
{
if (blobErrorMsgs2) blobErrorMsgs2->Release();
std::cout << "ERROR COMPILING PIXELSHADER" << std::endl;
return false;
}
shaderByteCode2 = blobCode2->GetBufferPointer();
byteCodeLength2 = blobCode2->GetBufferSize();
ID3D11PixelShader* pixelShader;
d3dDevice->CreatePixelShader(shaderByteCode2, byteCodeLength2, nullptr, &pixelShader);
pixelShader->Release();
blobCode2->Release();
FLOAT clearColor[] = { 0.0, 0.0, 0.0, 1.0 };
while (running)
{
d3dDeviceContext->ClearRenderTargetView(renderTargetView, clearColor);
d3dDeviceContext->OMSetRenderTargets(1, &renderTargetView, NULL);
GetClientRect(hwndApp, &rc);
D3D11_VIEWPORT vp = {};
vp.Width = rc.right - rc.left;
vp.Height = rc.bottom - rc.top;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
d3dDeviceContext->RSSetViewports(1, &vp);
d3dDeviceContext->VSSetShader(vertexShader, nullptr, 0);
d3dDeviceContext->PSSetShader(pixelShader, nullptr, 0);
UINT stride = sizeof(Vertex);
UINT offset = 0;
d3dDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
d3dDeviceContext->IASetInputLayout(inputLayout);
d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
d3dDeviceContext->Draw(sizeVertices, 0);
dxgiSwapChain->Present(true, NULL);
MSG msg = { 0 };
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
renderTargetView->Release();
inputLayout->Release();
vertexBuffer->Release();
dxgiDevice->Release();
dxgiAdapter->Release();
dxgiFactory->Release();
d3dDeviceContext->Release();
d3dDevice->Release();
return 0;
}
顶点着色器
struct VS_INPUT
{
float4 position: POSITION;
float3 color: COLOR;
};
struct VS_OUTPUT
{
float4 position: SV_POSITION;
float3 color: COLOR;
};
VS_OUTPUT vsmain(VS_INPUT input)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.position = input.position;
output.color = input.color;
return output;
}
像素着色器
struct PS_INPUT
{
float4 position: SV_POSITION;
float3 color: COLOR;
};
float4 psmain(PS_INPUT input) : SV_TARGET
{
return float4(input.color,1.0f);
}
我希望 window 显示多色四边形,但 window 全是白色。
着色器已发布,随后在代码中使用。
vertexShader->Release();
pixelShader->Release();
将着色器的释放移动到程序的末尾解决了这个问题。