[英]Drawing spheres via DirectX12 Tool Kit
嘗試繪制球體時遇到三個問題:
代碼。 使成為:
void Game::Render()
{
if (m_timer.GetFrameCount() == 0)
{
return;
}
m_deviceResources->Prepare();
Clear();
auto commandList = m_deviceResources->GetCommandList();
PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Render");
auto commandList2 = m_deviceResources->GetCommandList();
PIXBeginEvent(commandList2, PIX_COLOR_DEFAULT, L"Draw Sphere");
m_shapeEffect->Apply(m_deviceResources->GetCommandList());
for (int i(0); i < vsphere; i++)
{
m_shapeEffect->SetWorld(d3dsphere[i]->world);
d3dsphere[i]->Draw(commandList2);
}
PIXEndEvent(commandList2);
PIXEndEvent(commandList);
PIXBeginEvent(m_deviceResources->GetCommandQueue(), PIX_COLOR_DEFAULT, L"Present");
m_deviceResources->Present();
m_graphicsMemory->Commit(m_deviceResources->GetCommandQueue());
PIXEndEvent(m_deviceResources->GetCommandQueue());
}
我如何創建形狀效果
EffectPipelineStateDescription pd(
&VertexPositionColor::InputLayout,
CommonStates::Opaque,
CommonStates::DepthNone,
CommonStates::CullNone,
rtState,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::VertexColor, pd);
d3dsphere
是一個D3DSphere
class object; 構造函數和Draw
方法
D3DSphere(float x, float y, float z, float radius, float r, float g, float b, float a)
{
this->x = x;
this->y = y;
this->z = z;
this->radius = radius;
this->shape = GeometricPrimitive::CreateSphere(radius*2.0f);
this->world = Matrix::Identity;
this->world = XMMatrixMultiply(this->world, Matrix::CreateTranslation(x, y, z));
this->index = vsphere;
d3dsphere[vsphere] = this;
vsphere++;
}
void D3DSphere::Draw(ID3d12GraphicsCommandList* commandList)
{
this->shape->Draw(commandList);
}
如果我認為球體半徑(以及我場景中的所有內容)非常小(~10^-6),也許會很有用
由於我不知道的原因, Microsoft DirectX12 Tool Kit wiki 頁面中的示例代碼與我通過 NuGet 包安裝的頭文件不兼容 - 我有不同的構造函數,不同的 arguments 方法。 我認為問題在於我使用的是 Visual Studio 15,但微軟建議至少使用 17(有兩種不同的 DirectX12TK NuGet 包 - 一種用於 VS15,一種用於 VS17 及更高版本)。 真奇怪。
我通過更改渲染代碼解決了第三個問題:
for(int i(0);i<vsphere;i++)
{
m_shapeEffect->SetMatrices(d3dsphere->world, m_view, m_projection);
m_shapeEffect->Apply(m_deviceResources->GetCommandList());
d3dsphere[i]->Draw();
}
我使用的DirectX12TK NuGet package版本是2019.12.17.1
在這里,您告訴 Pipeline State Object 您正在使用VertexPositionColor
並希望每個頂點顏色:
EffectPipelineStateDescription pd(
&VertexPositionColor::InputLayout,
CommonStates::Opaque,
CommonStates::DepthNone,
CommonStates::CullNone,
rtState,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::VertexColor, pd);
GeometricPrimitive 的工廠方法創建的實際頂點類型是VertexPositionNormalTexture
( VertexType
類型別名是為了讓它更容易一些)。
因此,頂點數據包含
struct VertexPositionNormalTexture
{
XMFLOAT3 position;
XMFLOAT3 normal;
XMFLOAT2 textureCoordinate;
}
但是你告訴頂點着色器它是:
const D3D12_INPUT_ELEMENT_DESC VertexPositionColor::InputElements[] =
{
{ "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
};
將您的 BasicEffect 更改為:
EffectPipelineStateDescription pd(
&GeometricPrimitive::VertexType::InputLayout,
CommonStates::Opaque,
CommonStates::DepthNone,
CommonStates::CullNone,
rtState,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::None, pd);
沒有EffectFlags::Lighting
和m_shapeEffect->EnableDefaultLighting();
看起來會很無聊 ,但應該渲染。
如果要創建VertexPositionNormalTexture
以外的頂點格式,可以使用GeometricPrimitive
自定義幾何方法來生成形狀數據,但您需要在自己的代碼中實現 VB/IB 的創建和渲染(即GeometricPrimitive::CreateCustom
方法僅支持VertexPositionNormalTexture
)。
D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView;
D3D12_INDEX_BUFFER_VIEW m_indexBufferView;
UINT m_indexCount;
Microsoft::WRL::ComPtr<ID3D12Resource> m_vertexBuffer;
Microsoft::WRL::ComPtr<ID3D12Resource> m_indexBuffer;
// Create shape data
std::vector<VertexPositionNormalTexture> vertices;
std::vector<uint16_t> indices;
GeometricPrimitive::CreateSphere(vertices, indices);
std::vector<VertexPositionColor> newVerts;
newVerts.reserve(vertices.size());
for (auto it : vertices)
{
VertexPositionColor v;
v.position = it.position;
v.color = XMFLOAT4(it.normal.x, it.normal.y, it.normal.z, 1.f);
newVerts.emplace_back(v);
}
// Place data on upload heap
size_t vsize = newVerts.size() * sizeof(VertexPositionColor);
SharedGraphicsResource vb = GraphicsMemory::Get().Allocate(vsize);
memcpy(vb.Memory(), newVerts.data(), vsize);
size_t isize = indices.size() * sizeof(uint16_t);
SharedGraphicsResource ib = GraphicsMemory::Get().Allocate(isize);
memcpy(ib.Memory(), indices.data(), isize);
// You can render directly from the 'upload' heap or as shown here create static IB/VB resources
ResourceUploadBatch resourceUpload(device);
resourceUpload.Begin();
CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_DEFAULT);
auto vdesc = CD3DX12_RESOURCE_DESC::Buffer(vsize);
auto idesc = CD3DX12_RESOURCE_DESC::Buffer(isize);
DX::ThrowIfFailed(device->CreateCommittedResource(
&heapProperties, D3D12_HEAP_FLAG_NONE, &vdesc, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, IID_PPV_ARGS(m_vertexBuffer.GetAddressOf())));
DX::ThrowIfFailed(device->CreateCommittedResource(
&heapProperties, D3D12_HEAP_FLAG_NONE, &idesc, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, IID_PPV_ARGS(m_indexBuffer.GetAddressOf())));
resourceUpload.Upload(m_vertexBuffer.Get(), vb);
resourceUpload.Upload(m_indexBuffer.Get(), ib);
resourceUpload.Transition(m_vertexBuffer.Get(),
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
resourceUpload.Transition(m_indexBuffer.Get(),
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER);
auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
uploadResourcesFinished.wait();
// Create matching effect for new vertex layout
EffectPipelineStateDescription psd(
&VertexPositionColor::InputLayout,
CommonStates::Opaque,
CommonStates::DepthDefault,
CommonStates::CullNone,
rtState);
m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::VertexColor, psd);
// Set up buffer views
m_vertexBufferView = { m_vertexBuffer->GetGPUVirtualAddress(), UINT(vsize), sizeof(VertexPositionColor) };
m_indexBufferView = { m_indexBuffer->GetGPUVirtualAddress(), UINT(isize), DXGI_FORMAT_R16_UINT };
m_indexCount = UINT(indices.size());
m_shapeEffect->Apply(commandList);
commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
commandList->IASetIndexBuffer(&m_indexBufferView);
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->DrawIndexedInstanced(m_indexCount, 1, 0, 0, 0);
支持 Visual Studio 2015 的DirectX Tool Kit for DX12的最新版本是2019 年 12 月,即directxtk12_desktop_2015 。 2019 年 12 月和 2020 年 4 月之間幾乎沒有功能或 API 差異,所以我不確定您為什么認為 wiki 已過時。 您使用的是什么 NuGet package 和版本?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.