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) }) };
然后重新编译,运行一下就可以了。
时间: 2024-10-05 13:53:19