0

球体を描画しようとすると、3 つの問題があります。

  1. 球はいくつかの角度でグリッチしています: ここに画像の説明を入力
  2. 球に色を付ける方法がわからない
  3. 一度に 2 つの球体を描くことはできません - 1 つだけが表示されます。

コード。与える:

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);

d3dsphereD3DSphereクラスオブジェクトです。コンストラクターと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 パッケージを介してインストールしたヘッダーと互換性がありません。メソッドにはさまざまなコンストラクターとさまざまな引数があります。問題は、私が Visual Studio 15 を使用していることだと思いますが、Microsoft は少なくとも 17 を使用することを推奨しています (2 つの異なる DirectX12TK NuGet パッケージがあります - 1 つは VS15 用、もう 1 つは VS17 以降用です)。それは変だね。


レンダリングのコードを変更することで、3 番目の問題を解決しました。

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パッケージのバージョンは2019.12.17.1

4

1 に答える 1

1

VertexPositionColorここでは、使用していて頂点ごとの色が必要であることを Pipeline State Object に伝えました。

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);

GeometryPrimitive のファクトリ メソッドによって作成される実際の頂点の型は次のとおりです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 をサポートする DX12 用 DirectX ツール キットの最新リリースは、2019年 12 月のdirectxtk12_desktop_2015です。2019 年 12 月と 2020 年 4 月の間に機能や API の違いはほとんどないため、Wiki が古いと思われる理由がわかりません。どの NuGet パッケージとバージョンを使用していますか?

于 2020-04-23T18:08:43.213 に答える