DX12龙书第6章习题

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

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

龙书11_chapter_4 二:习题中的Adapter

如何计算设备的Adapter数? 主要参考MSDN:  EnumAdapters 在d3dApp.cpp文件InitDirect3D()接口中: HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); //begin 检测本设备有几个图形卡 UINT myAdapterNums = 0; IDXGIAdapter *pAdapter; std::vector<IDXGIAdapter* > vAdap

龙书学习笔记(二)

补线代之余抽空把第四章上色学了,之所以说之余,是因为这一章内容确实不怎么多,不过为了巩固知识,便结合刚学的上色又做了一个小程序. 首先进行回顾,这一章学到的一共有四点: 一.Direct3D中颜色用RGB(Red.Green.Blue)三元组表示,用两种结构来保存 D3DCOLOR,即unsigned long,共32位,分成4个8位项,分别保存Alpha(这玩意的作用会在第七章学到).红.绿.蓝,均在0x00~0xff之间取值(就是0~255) 通过结构体来保存(D3DXCOLOR和D3DCO

编译原理 龙书 第二章 一个简单的算术式(+,-)翻译器实现

昨天晚上决定正面硬刚神课<编译原理>.硬上龙书. 下面是 一个简单的算术式中缀变后缀的翻译器. 这个也是 龙书中 一个C实现源码 .部分用c++改写. #include <iostream> #include <ctype.h> #include <stdlib.h> #include <stdio.h> using namespace std; int lookahead; void error()//错误处理 { cout<<&q

DirectX 9.0c游戏开发手记之“龙书”第二版学习笔记之8: Chap10: Lighting

这一章讲的是光照.光照(lighting)是Direct3D中非常重要的概念,而与之相对应的是材质(material)的概念.如果没有材质的话,那么光照的作用也无法体现. 在较早一些的关于DirectX 9的编程入门书籍里,一般是使用D3DLIGHT9结构体来建立一个光源,而用D3DMATERIAL9结构体来定义物体的材质.我们要做的就是一些很琐碎的家务活,基本上就是创建这些结构体对象.设定其中的参数.启用光照之类的,至于具体实现的细节就非吾等所需(和所能)操心的了. 不过在我们的"龙书&quo

紫书第4章 函数和递归

1  序 系统的整理下第四章的学习笔记.同上次一样,尽量在不依赖书本的情况下自己先把例题做出来.这次有许多道题代码量都比较大,在例题中我都用纯C语言编写,但由于习题的挑战性和复杂度,我最终还是决定在第五章开始前,就用C++来完成习题.不过所有的代码都是能在C++提交下AC的. 在习题中,我都习惯性的构造一个类来求解问题,从我个人角度讲,这会让我的思路清晰不少,希望自己的一些代码风格不会影响读者对解题思路的理解. 其实在第四章前,我就顾虑着是不是真的打算把题目全做了,这些题目代码量这么大,要耗费很

龙书学习笔记(三)

在将第五章每个示例代码过了一遍之后,大致明白了光照这一章的内容,主要分为四点: 一.光照的类型分为三种,并且均通过结构D3DCOLORVALUE或D3DXCOLOR来表示光线的颜色 环境光(Ambient Light)经其它表面反射到达物体表面,并照亮整个场景,通常用做较低代价的粗略模拟. 漫射光(Diffuse Light)沿着特定的方向传播,到达某个表面后将沿着各个方向均匀反射,因此从各个方向观察物体表面亮度均相同. 镜面光(Specular Light)沿着特定的方向传播,到达一表面后将沿

紫书第三章 数组和字符串

1  序 系统的整理下第三章的学习笔记.例题代码是在未看书本方法前自己尝试并AC的代码,不一定比书上的标程好:习题除了3-8百度了求解方法,其它均独立完成后,会适当查阅网上资料进行整理总结.希望本博文方便自己日后复习的同时,也能给他人带来点有益的帮助(建议配合紫书--<算法竞赛入门经典(第2版)>阅读本博客).有不足或错误之处,欢迎读者指出. 2  例题 2.1  UVa272--Tex Quotes #include <stdio.h> int main() { bool log

龙书11_chapter_4 一: GameTime解读

看龙书DX11,首先是第四章,本文对GameTime类进行解释 问:此类主要实现了什么功能? 答:Returns the total time elapsed since Reset() was called, NOT counting any time when the clock is stopped. 从渲染窗口Reset开始记时,记录总共的时间.不包括此间的pause时间. 问:关键时间接口? 答: 1. //获取频率(取决于主板 OS相关,不是CPU的主频)参考:http://www.

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

第四章习题,部分题目未给出答案 1. 这个题比较简单,有高中生推导水平的应该不难. 2~3证明题,略 4. (a) 这个问题问我略困惑,答案怎么直接写出来了,难道不是10%么 (b) 这个答案是(0.1*0.1)/(1*1),所以答案是1% (c) 其实就是个空间所占比例,所以这题是(0.1**100)*100 = 0.1**98% (d) 这题答案显而易见啊,而且是指数级别下降 (e) 答案是0.1**(1).0.1**(1/2).0.1**(1/3)...0.1**(1/100) 5. 这题