1.

{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXTURE", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXTURE", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 44, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_SINT, 0, 52, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
};

2.

先是一些准备性的东西,这样描述不太直觉,但是有利于你找到代码位置。

在BoxApp.cpp的前端,先把这个结构改了:

//struct Vertex
//{
// XMFLOAT3 Pos;
// XMFLOAT4 Color;
//}; //change end
struct VPosData
{
XMFLOAT3 Pos;
}; struct VColorData
{
XMFLOAT4 Color;
};

然后是 D3D12_INPUT_ELEMENT_DESC对象改为:

mInputLayout =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } //change end
};

在应用里有一个几何体类MeshGeometry

这个类是用来记录渲染集合体数据的,还有辅助创建buffer的数据和方法,这些都要修改:

//Microsoft::WRL::ComPtr<ID3DBlob> VertexBufferCPU = nullptr;
//change end
Microsoft::WRL::ComPtr<ID3DBlob> VertexPosBufferCPU = nullptr;
Microsoft::WRL::ComPtr<ID3DBlob> VertexColorBufferCPU = nullptr;
//Microsoft::WRL::ComPtr<ID3D12Resource> VertexBufferGPU = nullptr;
//change end
Microsoft::WRL::ComPtr<ID3D12Resource> VertexPosBufferGPU = nullptr;
Microsoft::WRL::ComPtr<ID3D12Resource> VertexColorBufferGPU = nullptr;
//Microsoft::WRL::ComPtr<ID3D12Resource> VertexBufferUploader = nullptr;
//change end
Microsoft::WRL::ComPtr<ID3D12Resource> VertexPosBufferUploader = nullptr;
Microsoft::WRL::ComPtr<ID3D12Resource> VertexColorBufferUploader = nullptr;
// Data about the buffers.
//UINT VertexByteStride = 0;
//UINT VertexBufferByteSize = 0;
//change end
UINT VertexPosByteStride = 0;
UINT VertexPosBufferByteSize = 0;
UINT VertexColorByteStride = 0;
UINT VertexColorBufferByteSize = 0;

//D3D12_VERTEX_BUFFER_VIEW VertexBufferView()const
//{
// D3D12_VERTEX_BUFFER_VIEW vbv;
// vbv.BufferLocation = VertexBufferGPU->GetGPUVirtualAddress();
// vbv.StrideInBytes = VertexByteStride;
// vbv.SizeInBytes = VertexBufferByteSize; // return vbv;
//}
//change end
D3D12_VERTEX_BUFFER_VIEW VertexPosBufferView()const
{
D3D12_VERTEX_BUFFER_VIEW vbv;
vbv.BufferLocation = VertexPosBufferGPU->GetGPUVirtualAddress();
vbv.StrideInBytes = VertexPosByteStride;
vbv.SizeInBytes = VertexPosBufferByteSize; return vbv;
} D3D12_VERTEX_BUFFER_VIEW VertexColorBufferView()const
{
D3D12_VERTEX_BUFFER_VIEW vbv;
vbv.BufferLocation = VertexColorBufferGPU->GetGPUVirtualAddress();
vbv.StrideInBytes = VertexColorByteStride;
vbv.SizeInBytes = VertexColorBufferByteSize; return vbv;
}
void DisposeUploaders()
{
//VertexBufferUploader = nullptr;
//change end
VertexPosBufferUploader = nullptr;
VertexColorBufferUploader = nullptr; IndexBufferUploader = nullptr;
}

这些描述输入数据的结构处理完以后就是渲染流程里的工作了,D3D12创建buffer的时候先是在主存里建一个数据段,用于将来做碰撞检测,拾取一类的功能,然后再在内存里建buffer,而且这个buffer还是很讲究的,它是一个不可以cpu随便修改的内存,那为了保持这个buffer和cpu的隔离,它还要建个中间内存叫做上传缓冲器。那下面就改这三个地方:

这段其实是准备一些基础数据的,给我们说的第二和第三个地方用

//const UINT vbByteSize = (UINT)vertices.size() * sizeof(Vertex);
//change end
const UINT vpbByteSize = (UINT)verticesPos.size() * sizeof(VPosData);
const UINT vcbByteSize = (UINT)verticesColor.size() * sizeof(VColorData);

下面一段就是主存的数据段,之所以叫CPUBlob是为了指明它是给CPU用的

//ThrowIfFailed(D3DCreateBlob(vbByteSize, &mBoxGeo->VertexBufferCPU));
//CopyMemory(mBoxGeo->VertexBufferCPU->GetBufferPointer(), vertices.data(), vbByteSize);
//change end
ThrowIfFailed(D3DCreateBlob(vpbByteSize, &mBoxGeo->VertexPosBufferCPU));
CopyMemory(mBoxGeo->VertexPosBufferCPU->GetBufferPointer(), verticesPos.data(), vpbByteSize);
ThrowIfFailed(D3DCreateBlob(vcbByteSize, &mBoxGeo->VertexColorBufferCPU));
CopyMemory(mBoxGeo->VertexColorBufferCPU->GetBufferPointer(), verticesColor.data(), vcbByteSize);

下面这段糅合了uploadbuffer和最终的vertexbuffer:

//mBoxGeo->VertexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
// mCommandList.Get(), vertices.data(), vbByteSize, mBoxGeo->VertexBufferUploader);
//change end
mBoxGeo->VertexPosBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
mCommandList.Get(), verticesPos.data(), vpbByteSize, mBoxGeo->VertexPosBufferUploader);
mBoxGeo->VertexColorBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
mCommandList.Get(), verticesColor.data(), vcbByteSize, mBoxGeo->VertexColorBufferUploader);

以上就是构建集合体及其数据的代码,如果你渲染多集合体多物体的话,你还要注意修改那些集合体顶点位置在整个内存中的位置下标:

//mBoxGeo->VertexByteStride = sizeof(Vertex);
//mBoxGeo->VertexBufferByteSize = vbByteSize;
//change end
mBoxGeo->VertexPosByteStride = sizeof(VPosData);
mBoxGeo->VertexPosBufferByteSize = vpbByteSize;
mBoxGeo->VertexColorByteStride = sizeof(VColorData);
mBoxGeo->VertexColorBufferByteSize = vcbByteSize;

然后就到了真正的Draw阶段,将buffer设置到渲染pipleline

//mCommandList->IASetVertexBuffers(0, 1, &mBoxGeo->VertexBufferView());
//change end
mCommandList->IASetVertexBuffers(0, 1, &mBoxGeo->VertexPosBufferView());
mCommandList->IASetVertexBuffers(1, 1, &mBoxGeo->VertexColorBufferView());

以上都准备好以后就输入你们的数据吧,我的数据是hardcore进代码的,非常ugly:

//  std::array<Vertex, 8> vertices =
// {
// Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
//Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
//Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
//Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
//Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
//Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
//Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
//Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) })
// };
//change end
std::array<VPosData,8> verticesPos =
{
VPosData({ XMFLOAT3(-1.0f, -1.0f, -1.0f) }),
VPosData({ XMFLOAT3(-1.0f, +1.0f, -1.0f) }),
VPosData({ XMFLOAT3(+1.0f, +1.0f, -1.0f) }),
VPosData({ XMFLOAT3(+1.0f, -1.0f, -1.0f) }),
VPosData({ XMFLOAT3(-1.0f, -1.0f, +1.0f) }),
VPosData({ XMFLOAT3(-1.0f, +1.0f, +1.0f) }),
VPosData({ XMFLOAT3(+1.0f, +1.0f, +1.0f) }),
VPosData({ XMFLOAT3(+1.0f, -1.0f, +1.0f) })
}; std::array<VColorData,8> verticesColor =
{
VColorData({ XMFLOAT4(Colors::White) }),
VColorData({ XMFLOAT4(Colors::Black) }),
VColorData({ XMFLOAT4(Colors::Red) }),
VColorData({ XMFLOAT4(Colors::Green) }),
VColorData({ XMFLOAT4(Colors::Blue) }),
VColorData({ XMFLOAT4(Colors::Yellow) }),
VColorData({ XMFLOAT4(Colors::Cyan) }),
VColorData({ XMFLOAT4(Colors::Magenta) })
};

然后重新编译,运行一下就可以了。

3.

这道题还用示例代码进行修改吧

原来的存储点位置和颜色的队列改成这样:

std::array<Vertex, 49> vertices =
{
Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) })
,//add end
//a point list
Vertex({ XMFLOAT3(-4.0f, -4.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(-3.0f, 0.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(-2.0f, -3.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3( 0.0f, 0.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3( 1.0f, -2.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3( 3.0f, 0.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3( 5.0f, -2.0f, 2.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3( 7.0f, 1.0f, 2.0f), XMFLOAT4(Colors::Red) }),
//a point strip
Vertex({ XMFLOAT3(-4.0f, -4.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(-3.0f, 0.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(-2.0f, -3.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(0.0f, 0.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(1.0f, -2.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(3.0f, 0.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(5.0f, -2.0f, 3.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(7.0f, 1.0f, 3.0f), XMFLOAT4(Colors::Green) }),
//a line list
Vertex({ XMFLOAT3(-4.0f, -4.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(-3.0f, 0.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(-2.0f, -3.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(0.0f, 0.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(1.0f, -2.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(3.0f, 0.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(5.0f, -2.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(7.0f, 1.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
//a triangle strip
Vertex({ XMFLOAT3(-4.0f, -4.0f, 5.0f), XMFLOAT4(Colors::White) }),
Vertex({ XMFLOAT3(-3.0f, 0.0f, 5.0f), XMFLOAT4(Colors::Black) }),
Vertex({ XMFLOAT3(-2.0f, -3.0f, 5.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(0.0f, 0.0f, 5.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(1.0f, -2.0f, 5.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(3.0f, 0.0f, 5.0f), XMFLOAT4(Colors::Yellow) }),
Vertex({ XMFLOAT3(5.0f, -2.0f, 5.0f), XMFLOAT4(Colors::Cyan) }),
Vertex({ XMFLOAT3(7.0f, 1.0f, 5.0f), XMFLOAT4(Colors::Magenta) }),
//a point list
Vertex({ XMFLOAT3(-4.0f, -4.0f, 6.0f), XMFLOAT4(Colors::White) }),
Vertex({ XMFLOAT3(-3.0f, 0.0f, 6.0f), XMFLOAT4(Colors::White) }),
Vertex({ XMFLOAT3(-2.0f, -3.0f, 6.0f), XMFLOAT4(Colors::White) }), Vertex({ XMFLOAT3(0.0f, 0.0f, 6.0f), XMFLOAT4(Colors::Yellow) }),
Vertex({ XMFLOAT3(3.0f, 0.0f, 6.0f), XMFLOAT4(Colors::Yellow) }),
Vertex({ XMFLOAT3(1.0f, -2.0f, 6.0f), XMFLOAT4(Colors::Yellow) }),
Vertex({ XMFLOAT3(5.0f, -2.0f, 6.0f), XMFLOAT4(Colors::Magenta) }),
Vertex({ XMFLOAT3(7.0f, 1.0f, 6.0f), XMFLOAT4(Colors::Magenta) }),
Vertex({ XMFLOAT3(8.0f, 0.0f, 6.0f), XMFLOAT4(Colors::Magenta) })
};

沿用它的机制,把子几何体存储起来

SubmeshGeometry submesh;
submesh.IndexCount = (UINT)indices.size();
submesh.StartIndexLocation = 0;
submesh.BaseVertexLocation = 0;
//add end
//a point list
SubmeshGeometry submesh1;
submesh1.VertexCount = 8;
//submesh.StartIndexLocation = 0;
submesh1.BaseVertexLocation = 8; //a line strip
SubmeshGeometry submesh2;
submesh2.VertexCount = 8;
//submesh.StartIndexLocation = 0;
submesh2.BaseVertexLocation = 16; //a line list
SubmeshGeometry submesh3;
submesh3.VertexCount = 8;
//submesh.StartIndexLocation = 0;
submesh3.BaseVertexLocation = 24; //a triangle strip
SubmeshGeometry submesh4;
submesh4.VertexCount = 8;
//submesh.StartIndexLocation = 0;
submesh4.BaseVertexLocation = 32; //a triangle list
SubmeshGeometry submesh5;
submesh5.VertexCount = 9;
//submesh.StartIndexLocation = 0;
submesh5.BaseVertexLocation = 40; mBoxGeo->DrawArgs["box"] = submesh;
//add end
mBoxGeo->DrawArgs["pointlist"] = submesh1;
mBoxGeo->DrawArgs["linestrip"] = submesh2;
mBoxGeo->DrawArgs["linelist"] = submesh3;
mBoxGeo->DrawArgs["trianglestrip"] = submesh4;
mBoxGeo->DrawArgs["trianglelist"] = submesh5;

添加集合体的时候要注意几何体类已经修改了,为了调用drawinstanced方便:

struct SubmeshGeometry
{
//add end
UINT VertexCount = 0;
UINT IndexCount = 0;
UINT StartIndexLocation = 0;
INT BaseVertexLocation = 0; // Bounding box of the geometry defined by this submesh.
// This is used in later chapters of the book.
DirectX::BoundingBox Bounds;
};

Draw函数里改用ID3D12GraphicsCommandList::DrawInstanced:

mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    mCommandList->SetGraphicsRootDescriptorTable(0, mCbvHeap->GetGPUDescriptorHandleForHeapStart());

    mCommandList->DrawIndexedInstanced(
mBoxGeo->DrawArgs["box"].IndexCount,
1, 0, 0, 0);
//add end
mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
mCommandList->DrawInstanced(
mBoxGeo->DrawArgs["pointlist"].VertexCount,
1, mBoxGeo->DrawArgs["pointlist"].BaseVertexLocation, 0); mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP);
mCommandList->DrawInstanced(
mBoxGeo->DrawArgs["linestrip"].VertexCount,
1, mBoxGeo->DrawArgs["linestrip"].BaseVertexLocation, 0); mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
mCommandList->DrawInstanced(
mBoxGeo->DrawArgs["linelist"].VertexCount,
1, mBoxGeo->DrawArgs["linelist"].BaseVertexLocation, 0); mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
mCommandList->DrawInstanced(
mBoxGeo->DrawArgs["trianglestrip"].VertexCount,
1, mBoxGeo->DrawArgs["trianglestrip"].BaseVertexLocation, 0); mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
mCommandList->DrawInstanced(
mBoxGeo->DrawArgs["trianglelist"].VertexCount,
1, mBoxGeo->DrawArgs["trianglelist"].BaseVertexLocation, 0);

4.

修改下几何体数据就行了

mCommandList->DrawIndexedInstanced(
mBoxGeo->DrawArgs["pyramid"].IndexCount,
1, 0, 0, 0);
std::array<Vertex, 5> vertices =
{
Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
//Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
//Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
//Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
//Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(0.0f, 0.412f, 0.0f), XMFLOAT4(Colors::Red) })
}; std::array<std::uint16_t, 18> indices =
{
// front face
0, 4, 1, // back face
3, 4, 2, // left face
2, 4, 0, // right face
1, 4, 3, // bottom face
0, 1, 2,
1, 3, 2
};
mBoxGeo->DrawArgs["pyramid"] = submesh;

5,

在光栅化三步走里最后一步就是顶点属性插值,我们像素点的值就取决于相邻两个定点的颜色,见196页。

6.

我选用了最简单的办法,只是修改了c++和hlsl的constant buffer结构体的格式。

cbuffer cbPerObject : register(b0)
{
float4x4 gWorldViewProj;
float gTime;
};

struct ObjectConstants
{
XMFLOAT4X4 WorldViewProj = MathHelper::Identity4x4();
float time;
};

然后你在调用update的时候别忘了给time赋值,代码里有现成的mTime可用:

objConstants.time = mTimer.TotalTime();

7.

它说要用world transformation让两个物体分开,这个我没写代码,还是hardcode进代码了,要改数据buffer,还要改辅助集合体类的数据,最后是多draw个实体:

std::array<Vertex, 13> vertices =
{
Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) }),
Vertex({ XMFLOAT3(1.1f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
//Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
//Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
Vertex({ XMFLOAT3(+3.1f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(1.1f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
//Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
//Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
Vertex({ XMFLOAT3(+3.1f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
Vertex({ XMFLOAT3(2.1f, 0.412f, 0.0f), XMFLOAT4(Colors::Red) })
}; std::array<std::uint16_t, 54> indices =
{
// front face
0, 1, 2,
0, 2, 3, // back face
4, 6, 5,
4, 7, 6, // left face
4, 5, 1,
4, 1, 0, // right face
3, 2, 6,
3, 6, 7, // top face
1, 5, 6,
1, 6, 2, // bottom face
4, 0, 3,
4, 3, 7, //pyramid
0, 4, 1, // back face
3, 4, 2, // left face
2, 4, 0, // right face
1, 4, 3, // bottom face
0, 1, 2,
1, 3, 2
};
SubmeshGeometry submesh;
submesh.IndexCount = 36;
submesh.StartIndexLocation = 0;
submesh.BaseVertexLocation = 0; //add end
SubmeshGeometry submesh1;
submesh1.IndexCount = 18;
submesh1.StartIndexLocation = 36;
submesh1.BaseVertexLocation = 8; mBoxGeo->DrawArgs["box"] = submesh;
//add end
mBoxGeo->DrawArgs["pyramid"] = submesh1;
mCommandList->DrawIndexedInstanced(
mBoxGeo->DrawArgs["pyramid"].IndexCount,
1, mBoxGeo->DrawArgs["pyramid"].StartIndexLocation, mBoxGeo->DrawArgs["pyramid"].BaseVertexLocation, 0); mCommandList->DrawIndexedInstanced(
mBoxGeo->DrawArgs["box"].IndexCount,
1, mBoxGeo->DrawArgs["box"].StartIndexLocation, mBoxGeo->DrawArgs["box"].BaseVertexLocation, 0);

8,9.

这两道题都是在设置光栅化的时候修改光栅话描述结构的属性,现在他们都被整合到PSO里了,所以要到bulidPso那个函数里,添加这么两行:

psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
//psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME;
psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_FRONT;

具体代码还要改成相应的标识符才能用,书上给的提示有错误,标识符是这个D3D12_CULL_MODE_FRONT和D3D12_CULL_MODE_NONE。

10.

书上把主要代码的改变都列出来了,颜色转换可以直接写:

Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMCOLOR(Colors::White) }),
Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMCOLOR(Colors::Black) }),
Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMCOLOR(Colors::Red) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMCOLOR(Colors::Green) }),
Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMCOLOR(Colors::Blue) }),
Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMCOLOR(Colors::Yellow) }),
Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMCOLOR(Colors::Cyan) }),
Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMCOLOR(Colors::Magenta) })

会自动调用XMCOLOR类里的loadfloat4函数

11.

a.在input layout description里面有一项叫做AlignByteOffset,是它标定了结构体内子项的顺序。但还有一项叫inputslot,如果想给这一项改不同的入口,就必须按着顺序来,这种设计挺反人类的。

b.更不受影响了,它是按着SemanticName和Semantic Index的组合来查找位置的。

12.

viewport的设定在第四章讲过,同时也要注意183也5.6.3.1关于投影窗口和backbuffer的长宽比不一致的时候,会出现拉伸。但现在的问题是我们只是用了一半backbuffer,所以投影窗口的宽高比要和这一半的backbuffer保持一致。

13.

实际上在DX12里ScissorEnable被取消了

D3D11_RASTERIZER_DESC structure:

typedef struct D3D11_RASTERIZER_DESC {
D3D11_FILL_MODE FillMode;
D3D11_CULL_MODE CullMode;
BOOL FrontCounterClockwise;
INT DepthBias;
FLOAT DepthBiasClamp;
FLOAT SlopeScaledDepthBias;
BOOL DepthClipEnable;
BOOL ScissorEnable;
BOOL MultisampleEnable;
BOOL AntialiasedLineEnable;
} D3D11_RASTERIZER_DESC;

D3D12_RASTERIZER_DESC structure:

typedef struct D3D12_RASTERIZER_DESC {
D3D12_FILL_MODE FillMode;
D3D12_CULL_MODE CullMode;
BOOL FrontCounterClockwise;
INT DepthBias;
FLOAT DepthBiasClamp;
FLOAT SlopeScaledDepthBias;
BOOL DepthClipEnable;
BOOL MultisampleEnable;
BOOL AntialiasedLineEnable;
UINT ForcedSampleCount;
D3D12_CONSERVATIVE_RASTERIZATION_MODE ConservativeRaster;
} D3D12_RASTERIZER_DESC;

默认情况下scissor test已经打开了。其实在龙书11上没有什么描写,因为 那时还是第一版DX11,后来又有写变动,出现了11.1,一般来说11.1、11.2应该只是指的一些新加的特性,不会在基础流程上做太多变化,奈何11.1其实重新设计了渲染主要的架构,只是尽量保持接口和之前保持一致,而DX12的时候就彻底放开了。然而这个变化的细节还是没有找到,继续关注吧。

14.

这个写法就多了,比如:

pin.Color = (pin.Color + cos(gTime));

15.

看附录B里有。

DX12龙书第6章习题的更多相关文章

  1. 正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——3 计算4个函数

    整个引擎代码在github上,地址为:https://github.com/sun2043430/RegularExpression_Engine.git nullable, firstpos, la ...

  2. 周志华-机器学习西瓜书-第三章习题3.5 LDA

    本文为周志华机器学习西瓜书第三章课后习题3.5答案,编程实现线性判别分析LDA,数据集为书本第89页的数据 首先介绍LDA算法流程: LDA的一个手工计算数学实例: 课后习题的代码: # coding ...

  3. DX12龙书 00 - 环境配置:通过 Visual Studio 2019 运行示例项目

    0x00 安装 Visual Studio 2019 安装 Visual Studio 2019 以及相关组件. 注:安装组件时带的 Windows 10 SDK 可以在 Individual com ...

  4. DX12龙书 01 - 向量在几何学和数学中的表示以及运算定义

    0x00 向量 向量 ( vector ) 是一种兼具大小 ( magnitude ) 和方向的量. 0x01 几何表示 几何方法中用一条有向线段来表示一个向量,其中,线段长度代表向量的模,箭头的指向 ...

  5. DX12龙书 02 - DirectXMath 库中与向量有关的类和函数

    0x00 需要用到的头文件 #include <DirectXMath> #include <DirectXPackedVector.h> using namespace Di ...

  6. 编译原理 #03# 龙书中缀转后缀JS实现版

    // 来自龙书第2章2.5小节-简单表达式的翻译器 笔记 既然是语法制导翻译(Syntax-directed translation),那么最重要的东西当然是描述该语言语法的文法,以下为中缀表达式文法 ...

  7. 统计学习导论:基于R应用——第三章习题

    第三章习题 部分证明题未给出答案 1. 表3.4中,零假设是指三种形式的广告对TV的销量没什么影响.而电视广告和收音机广告的P值小说明,原假设是错的,也就是电视广告和收音机广告均对TV的销量有影响:报 ...

  8. 统计学习导论:基于R应用——第四章习题

    第四章习题,部分题目未给出答案 1. 这个题比较简单,有高中生推导水平的应该不难. 2~3证明题,略 4. (a) 这个问题问我略困惑,答案怎么直接写出来了,难道不是10%么 (b) 这个答案是(0. ...

  9. 统计学习导论:基于R应用——第二章习题

    目前在看统计学习导论:基于R应用,觉得这本书非常适合入门,打算把课后习题全部做一遍,记录在此博客中. 第二章习题 1. (a) 当样本量n非常大,预测变量数p很小时,这样容易欠拟合,所以一个光滑度更高 ...

随机推荐

  1. ES6 箭头函数中的 this?你可能想多了(翻译)

    箭头函数=>无疑是ES6中最受关注的一个新特性了,通过它可以简写 function 函数表达式,你也可以在各种提及箭头函数的地方看到这样的观点——“=> 就是一个新的 function”. ...

  2. 自己写jquery插件之模版插件高级篇(一)

    需求场景 最近项目改版中,发现很多地方有这样一个操作(见下图gif动画演示),很多地方都有用到.这里不讨论它的用户体验怎么样. 仅仅是从复用的角度,如果每个页面都去写text和select元素,两个b ...

  3. Azure File Storage 基本用法 -- Azure Storage 之 File

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在<Azure Blob Storage 基 ...

  4. Liunx下配置DNS服务

    当Ping 主机名时可以映射出该主机的IP地址,反之亦然.配置并指定DNS服务器可以快速部署集群,不需要每台主机都去修改HOSTS文件即可实现IP与主机名的相互解析.而在Linux下的DNS是用bin ...

  5. jQuery系列:选择器

    jQuery选择器通过标签名.属性名或内容对DOM元素进行选择,而不用担心浏览器的兼容性. 1. 基本选择器 基本选择器是jQuery中使用最频繁的选择器,由元素ID.class.元素名.多个选择符组 ...

  6. 从零开始编写自己的C#框架(20)——框架异常处理及日志记录

    最近很忙,杂事也多,所以开发本框架也是断断续续的,终于在前两天将前面设定的功能都基本完成了,剩下一些小功能遗漏的以后发现再补上.接下来的章节主要都是讲解在本框架的基础上进行开发的小巧. 本框架主要有四 ...

  7. CSS3与页面布局学习总结(四)——页面布局大全

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  8. jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)

    文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎 ...

  9. 匹夫细说C#:从园友留言到动手实现C#虚函数机制

    前言 上一篇文章匹夫通过CIL代码简析了一下C#函数调用的话题.虽然点击进来的童鞋并不如匹夫预料的那么多,但也还是有一些挺有质量的来自园友的回复.这不,就有一个园友提出了这样一个代码,这段代码如果被编 ...

  10. Notepad++ 实用技巧

    Notepad++是一款开源的文本编辑器,功能强大.很适合用于编辑.注释代码.它支持绝大部分主流的编程语言. 本文主要列举了本人在实际使用中遇到的一些技巧. 快捷键 自定义快捷键 首先,需要知道的是: ...