I am learning DirectX 11 and trying to render a triangle, but nothing show up except the background color. There is no errors, no warnings. Here is my main file:
while (true)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (msg.message == WM_QUIT)
{
break;
}
// Rendering here
ID3D11Buffer* vertex_buffer;
const float color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
device_context->ClearRenderTargetView(render_target_view, color);
Vertex vertices[]{
{ 0.0f, -0.5f},
{ 0.5f, 0.5f},
{-0.5f, -0.5f}
};
D3D11_BUFFER_DESC vb_desc;
ZeroMemory(&vb_desc, sizeof(vb_desc));
vb_desc.ByteWidth = sizeof(vertices);
vb_desc.Usage = D3D11_USAGE_DEFAULT;
vb_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vb_desc.CPUAccessFlags = 0;
vb_desc.MiscFlags = 0;
vb_desc.StructureByteStride = sizeof(Vertex);
D3D11_SUBRESOURCE_DATA vb_data;
ZeroMemory(&vb_data, sizeof(vb_data));
vb_data.pSysMem = vertices;
device->CreateBuffer(&vb_desc, &vb_data, &vertex_buffer);
const UINT stride = sizeof(Vertex);
const UINT offset = 0;
device_context->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
ID3D11VertexShader *vertex_shader;
ID3D11PixelShader* pixel_shader;
ID3DBlob* result_blob;
ID3DBlob* error_blob;
D3DCompileFromFile(L"PixelShader.hlsl", NULL, NULL, "main", "ps_4_0", D3DCOMPILE_DEBUG, 0, &result_blob, &error_blob);
device->CreatePixelShader(result_blob->GetBufferPointer(), result_blob->GetBufferSize(), nullptr, &pixel_shader);
device_context->PSSetShader(pixel_shader, nullptr, 0);
D3DCompileFromFile(L"VertexShader.hlsl", NULL, NULL, "main", "vs_4_0", D3DCOMPILE_DEBUG, 0, &result_blob, &error_blob);
device->CreateVertexShader(result_blob->GetBufferPointer(), result_blob->GetBufferSize(), nullptr, &vertex_shader);
device_context->VSSetShader(vertex_shader, nullptr, 0);
ID3D11InputLayout *input_layout;
D3D11_INPUT_ELEMENT_DESC element_desc[] =
{
{"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
device->CreateInputLayout(element_desc, 1, result_blob->GetBufferPointer(), result_blob->GetBufferSize(), &input_layout);
device_context->IASetInputLayout(input_layout);
result_blob->Release();
if (error_blob != nullptr) error_blob->Release();
device_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
device_context->OMSetRenderTargets(1u, &render_target_view, nullptr);
D3D11_VIEWPORT vp;
vp.Width = 800;
vp.Height = 600;
vp.MinDepth = 0;
vp.MaxDepth = 1;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
device_context->RSSetViewports(1u, &vp);
device_context->Draw(3, 0);
vertex_buffer->Release();
vertex_shader->Release();
pixel_shader->Release();
input_layout->Release();
swap_chain->Present(1u, 0u);
}
////////////////////////////////////////////////////////////////////////////////
device->Release();
device_context->Release();
swap_chain->Release();
render_target_view->Release();
This is the vertex shader(named VertexShader.hlsl):
float4 main(float2 pos : Position) : SV_Position
{
return float4(pos.x, pos.y, 0.0f, 1.0f);
}
And here is the pixel shader(named PixelShader.hlsl):
float4 main() : SV_Target
{
return float4(0.0f, 1.0f, 0.0f, 1.0f);
}
I appreciate any hint to solve this. Thank you for helping.
EDIT Thanks @IWonderWhatThisAPIDoes for helping me with this problem. The solution is changing the coordinate of the vertices to
Vertex vertices[]{
{ 0.0f, 0.5f},
{ 0.5f,-0.5f},
{-0.5f, -0.5f}
};
As @IWonderWhatThisAPIDoes noted, the primary reason you see nothing is the 'winding order' of the triangles due to back-face culling . This is because you are using the 'default' DirectX 11 "Rasterizer State object" which is as follows from Microsoft Docs :
State | Default Value |
---|---|
FillMode | Solid |
CullMode | Back |
FrontCounterClockwise | FALSE |
DepthBias | 0 |
SlopeScaledDepthBias | 0.0f |
DepthBiasClamp | 0.0f |
DepthClipEnable | TRUE |
ScissorEnable | FALSE |
MultisampleEnable | FALSE |
AntialiasedLineEnable | FALSE |
You can make your triangle visible by:
Changing the vertices so they have a different winding-order
You can create and set a new RasterizerState object with a cull mode of D3D11_CULL_FRONT
or D3D11_CULL_NONE
instead of D3D11_CULL_BACK
.
You can create and set a new RasterizerState object with a FrontCounterClockwise of TRUE instead of FALSE.
Your loop currently creates and destroys the buffers, shaders objects, input layout every frame. You should reuse them each frame instead.
You should take a look at the DirectX Tool Kit as well as directx-vs-templates .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.