编辑:抱歉,这是我第一次在这里发布。我现在添加了“ start_console”文件,以便您可以对其进行构建。抱歉,未指定问题。我的问题是我希望三角形在打开的窗口中呈现,但不是。
我已经尝试调试了一段时间,但找不到问题。非常感谢您的帮助:)除事件处理程序外,所有文件都发布在下面。我尝试启用D3D11_CREATE_DEVICE_DEBUG标志,并在每个HRESULT之后添加FAILED()函数,但没有发现任何错误。
main.cpp
//Headers
#define WIN32_LEAN_AND_MEAN
#include "windowCreation.h"
#include "vertex_buffer.h"
#include "shader.h"
#include <comdef.h>
#include "start_console.h"
//hInstance: Used to identify the .exe when it's loaded into memory.
//hPreviousInstance: Always 0.
//pCmdLine: Command-line arguments, convert to argv with CommandLineToArgvW().
//nCmdShow: Flag that says if it should be minimized, maximized or showed normally.
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine, _In_ int nCmdShow) {
RedirectIOToConsole();
HWND D3D_window = InitWindow(hInstance);
if (D3D_window == NULL) {
return 0;
}
assert(D3D_window);
D3D_create(D3D_window);
Create_Vertex_Buffer();
shader_compile_and_layout();
MSG msg = { };
ShowWindow(D3D_window, nCmdShow);
while (msg.message != WM_QUIT) {
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
FLOAT background_color[4] = { 1, 1, 1, 0 };
devcon->ClearRenderTargetView(pView, background_color);
devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devcon->IASetInputLayout(input_layout);
devcon->VSSetShader(vs, NULL, 0);
devcon->PSSetShader(ps, NULL, 0);
devcon->IASetVertexBuffers(0, 1, &Vertex_Buffer, &vertex_strides, &vertex_offset);
devcon->Draw(3, 0);
swapchain->Present(1, 0);
}
}
DestroyWindow(D3D_window);
CleanD3D();
return 0;
}
windowCreation.h
#ifndef WINDOWCREATION_H
#define WINDOWCREATION_H
#include <windows.h> //win32
#include <d3d11.h> //D3D 11
#include <dxgi.h> //Graphics devices and swap chain
#include <assert.h> //for assert()
#include <iostream>
//Libraries
#pragma comment( lib, "user32") //win32
#pragma comment( lib, "gdi32") //Graphics device interface
#pragma comment( lib, "d3d11") //Direct3D 11
#pragma comment( lib, "d3dcompiler.lib") //Shader Compiler
extern unsigned int width;
extern unsigned int height;
extern IDXGISwapChain *swapchain;
extern ID3D11Device *dev;
extern ID3D11DeviceContext *devcon;
extern ID3D11Texture2D* pSwapChainBuffer;
extern ID3D11RenderTargetView* pView;
//Event handler declaration
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND InitWindow(HINSTANCE);
void CleanD3D();
void D3D_create_device_and_swapchain(HWND D3D_window);
void D3D_create_rendertarget();
void D3D_create_rasterizer();
void D3D_create_depth_stencil_state();
void D3D_create_blendstate();
void D3D_create(HWND D3D_window);
#endif
windowCreation.cpp
#include "windowCreation.h"
IDXGISwapChain *swapchain;
ID3D11Device *dev;
ID3D11DeviceContext *devcon;
ID3D11Texture2D* pSwapChainBuffer = 0;
ID3D11RenderTargetView* pView = 0;
unsigned int width = 640;
unsigned int height = 480;
ID3D11RasterizerState *pRSState;
ID3D11DepthStencilState* pDepthStencilState;
ID3D11BlendState* pBlendState;
HWND InitWindow(HINSTANCE hInstance) {
//Declaring the windowclass.
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc; //Pointer to the windowproc-function that handles events.
wc.hInstance = hInstance; //Handle to the application instance.
wc.lpszClassName = L"BasicWindow"; //Identifies the window class
//Registers the window class with the opserating system
if (!RegisterClassEx(&wc)) {
return 0;
}
RECT rc = { 0, 0, width, height };
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
HWND D3D_window = CreateWindow(
L"BasicWindow",
L"BTH BasicWindow",
WS_OVERLAPPEDWINDOW,
//Size and position
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
nullptr, //Parent window
nullptr, //Menu
hInstance, //Instance handle
nullptr //Additional application data
);
return D3D_window;
}
void D3D_create_device_and_swapchain(HWND D3D_window) {
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = D3D_window;
scd.SampleDesc.Count = 1;
scd.Windowed = TRUE;
D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
D3D11_CREATE_DEVICE_DEBUG,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapchain,
&dev,
NULL,
&devcon
);
}
void D3D_create_rendertarget() {
HRESULT hr = swapchain->GetBuffer( 0,
__uuidof(ID3D11Texture2D),
(void**)&pSwapChainBuffer);
if (FAILED(hr)) {
std::cout << "fail";
}
hr = dev->CreateRenderTargetView( pSwapChainBuffer,
0,
&pView);
if (FAILED(hr)) {
std::cout << "fail";
}
devcon->OMSetRenderTargets(1, &pView, nullptr);
auto viewport = CD3D11_VIEWPORT(0.0f, 0.0f,
static_cast<float>(width), static_cast<float>(height)
);
devcon->RSSetViewports(1, &viewport);
}
void D3D_create_rasterizer() {
CD3D11_RASTERIZER_DESC desc = {};
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_NONE;
HRESULT hr = dev->CreateRasterizerState(&desc, &pRSState);
if (FAILED(hr)) {
std::cout << "fail";
}
devcon->RSGetState(&pRSState);
}
void D3D_create_depth_stencil_state() {
D3D11_DEPTH_STENCIL_DESC desc;
desc.DepthEnable = TRUE;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_LESS;
desc.StencilEnable = FALSE;
desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
HRESULT hr = dev->CreateDepthStencilState(&desc, &pDepthStencilState);
devcon->OMSetDepthStencilState(pDepthStencilState, 1);
}
void D3D_create_blendstate() {
D3D11_RENDER_TARGET_BLEND_DESC render_desc;
render_desc.BlendEnable = TRUE;
render_desc.SrcBlend = D3D11_BLEND_ONE;
render_desc.DestBlend = D3D11_BLEND_ZERO;
render_desc.BlendOp = D3D11_BLEND_OP_ADD;
render_desc.SrcBlendAlpha = D3D11_BLEND_ONE;
render_desc.DestBlendAlpha = D3D11_BLEND_ZERO;
render_desc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
render_desc.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
D3D11_BLEND_DESC desc;
desc.AlphaToCoverageEnable = FALSE;
desc.IndependentBlendEnable = FALSE;
desc.RenderTarget[0] = render_desc;
HRESULT hr = dev->CreateBlendState(&desc, &pBlendState);
if (FAILED(hr)) {
std::cout << "fail";
}
devcon->OMSetBlendState(pBlendState, NULL, NULL);
}
void D3D_create(HWND D3D_window) {
D3D_create_device_and_swapchain(D3D_window);
D3D_create_rendertarget();
D3D_create_rasterizer();
D3D_create_depth_stencil_state();
D3D_create_blendstate();
}
void CleanD3D() {
swapchain->Release();
dev->Release();
devcon->Release();
}
vertex_buffer.h
#pragma once
#ifndef VERTEX_BUFFER_H
#define VERTEX_BUFFER_H
#include <vector>
extern struct ID3D11Buffer* Vertex_Buffer;
extern unsigned int vertex_strides;
extern unsigned int vertex_offset;
void Create_Vertex_Buffer();
#endif
vertex_buffer.cpp
#include "vertex_buffer.h"
#include "windowCreation.h"
#include "directxmath.h"
using namespace DirectX;
struct VERTEX {
XMFLOAT3 pos;
XMFLOAT3 col;
};
ID3D11Buffer* Vertex_Buffer;
unsigned int vertex_strides = sizeof(VERTEX);
unsigned int vertex_offset = 0;
void Create_Vertex_Buffer() {
VERTEX vertex_array[] = {
{XMFLOAT3(10, 10, 100), XMFLOAT3(0.0f, 0.0f, 0.0f)},
{XMFLOAT3(100, 10, 100), XMFLOAT3(0.0f, 0.0f, 0.0f)},
{XMFLOAT3(55, 100, 100), XMFLOAT3(0.0f, 0.0f, 0.0f)}
};
D3D11_BUFFER_DESC buffer_struct;
buffer_struct.ByteWidth = sizeof(VERTEX) * 3;
buffer_struct.Usage = D3D11_USAGE_DEFAULT;
buffer_struct.BindFlags = D3D11_BIND_VERTEX_BUFFER;
buffer_struct.CPUAccessFlags = 0;
buffer_struct.MiscFlags = 0;
buffer_struct.StructureByteStride = sizeof(float);
D3D11_SUBRESOURCE_DATA resource_struct;
resource_struct.pSysMem = vertex_array;
resource_struct.SysMemPitch = 0;
resource_struct.SysMemSlicePitch = 0;
HRESULT hr = dev->CreateBuffer(&buffer_struct, &resource_struct, &Vertex_Buffer);
if (FAILED(hr)) {
std::cout << "fail";
}
}
vertex_pixel_shader.hlsl
struct VS_INPUT
{
float3 vColour : COLOR;
float3 vPosition : POSITION;
};
struct VS_OUTPUT
{
float3 vColour : COLOR;
float4 vPosition : SV_POSITION;
};
VS_OUTPUT VSMain(VS_INPUT input)
{
VS_OUTPUT output;
output.vPosition = float4(input.vPosition.xy, 0.0, 1.0);
output.vColour = input.vColour;
return output;
}
float4 PSMain(VS_OUTPUT input) : SV_TARGET
{
return float4(input.vColour, 1.0);
}
shader.h
#pragma once
#ifndef SHADER_H
#define SHADER_H
#include <d3dcompiler.h>
#include <string>
extern struct ID3D11VertexShader* vs;
extern struct ID3D11PixelShader* ps;
extern struct ID3D11InputLayout* input_layout;
void shader_compile_and_layout();
#endif
shader.cpp
#include "shader.h"
#include "windowCreation.h"
ID3DBlob* blob_vs = nullptr;
ID3DBlob* blob_error_vs = nullptr;
ID3DBlob* blob_ps = nullptr;
ID3DBlob* blob_error_ps = nullptr;
ID3D11VertexShader* vs;
ID3D11PixelShader* ps;
ID3D11InputLayout* input_layout;
void shader_compile_and_layout() {
HRESULT hr = D3DCompileFromFile(
L"vertex_pixel_shader.hlsl",
NULL,
NULL,
"VSMain",
"vs_5_0",
0,
0,
&blob_vs,
&blob_error_vs);
if (FAILED(hr)) {
std::cout << "fail";
}
hr = D3DCompileFromFile(
L"vertex_pixel_shader.hlsl",
NULL,
NULL,
"PSMain",
"ps_5_0",
0,
0,
&blob_ps,
&blob_error_ps);
if (FAILED(hr)) {
std::cout << "fail";
}
dev->CreateVertexShader(blob_vs->GetBufferPointer(), blob_vs->GetBufferSize(), NULL, &vs);
dev->CreatePixelShader(blob_ps->GetBufferPointer(), blob_ps->GetBufferSize(), NULL, &ps);
D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
hr = dev->CreateInputLayout(
input_element_desc, ARRAYSIZE(input_element_desc),
blob_vs->GetBufferPointer(),
blob_vs->GetBufferSize(),
&input_layout
);
if (FAILED(hr)) {
std::cout << "fail";
}
}
start_console.h
#pragma once
#ifndef VERTEX_BUFFER_H
#define VERTEX_BUFFER_H
#include <vector>
extern struct ID3D11Buffer* Vertex_Buffer;
extern unsigned int vertex_strides;
extern unsigned int vertex_offset;
void Create_Vertex_Buffer();
#endif
start_console.cpp
#include "start_console.h"
#include "windowCreation.h"
void RedirectIOToConsole()
{
AllocConsole();
HANDLE stdHandle;
int hConsole;
FILE* fp;
stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
hConsole = _open_osfhandle((long)stdHandle, _O_TEXT);
fp = _fdopen(hConsole, "w");
freopen_s(&fp, "CONOUT$", "w", stdout);
}
对于Direct3D,设置所有相关状态至关重要。
OMSetRenderTargets
通过您的渲染目标视图将交换链绑定到渲染上下文devcon->OMSetRenderTarget(1, &pView, nullptr);
RSSetViewports
的调用以设置正确的渲染像素矩形。auto viewport = CD3D11_VIEWPORT(0.0f, 0.0f,
static_cast<float>(backBufferWidth),
static_cast<float>(backBufferHeight)
);
devcon->RSSetViewports(1, &viewport);
RSSetState
设置渲染状态对象。如果您未将其默认设置,则将剔除模式设置为“后向剔除”,并且FrontCounterClockwise为FALSE。您的顶点数据可能使用了错误的缠绕,最终导致背面被剔除。一个好的开始是用“ Cull None”创建一个对象。ID3D11RasterizerState *pRSState;
auto desc = CD3D11_RASTERIZER_DESC
D3D11_RASTERIZER_DESC desc = {};
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_NONE;
hr = dev->CreateRasterizerState(&desc, &pRSState);
devcon->RSSetState(pRSState);
另一个重要状态是通过OMSetBlendState
的混合状态。默认为不透明设置。
您没有深度缓冲区,但是如果您确定要设置OMSetDepthStencilState
。
由于您仍在开始使用,您可能应该禁用MSAA,直到其他所有功能都可以使用。
scd.SampleDesc.Count = 1;
我可能要参考GitHub上的完整基本渲染循环和设备模板。
您也应该看一下DirectX Tool Kit。