Здесь вы указали объекту состояния конвейера, что используете 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);
Последним выпуском набора инструментов DirectX для DX12 , который поддерживает Visual Studio 2015, является декабрь 2019 directxtk12_desktop_2015 . Между декабрем 2019 года и апрелем 2020 года очень мало функциональных или API-различий, поэтому я не уверен, почему вы считаете, что вики устарела. Какой пакет и версию NuGet вы используете?