• Win10系列:VC++ Direct3D模板介绍2


    (3)CreateDeviceResources函数

    CreateDeviceResources函数默认添加在CubeRenderer.cpp源文件中,此函数用于创建着色器和立体图形顶点。接下来分别介绍CreateDeviceResources函数中用于创建着色器和立体图形顶点的具体实现代码,首先来看创建着色器的代码。

    在介绍CreateDeviceResources函数中用于创建着色器的实现代码之前,首先来了解在创建着色器的过程中将会用到的变量,这些变量声明在了CubeRenderer.h头文件中,代码如下所示:

    private:

        //声明成员变量m_vertexShader

        Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;

        //声明成员变量m_pixelShader

        Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;

        //声明成员变量m_inputLayout

        Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;

    在上面的代码中,使用private关键字声明三个私有的成员变量,分别为m_vertexShader、m_pixelShader和m_inputLayout,其中m_vertexShader为ID3D11VertexShader类型的指针,m_pixelShader为ID3D11PixelShader类型的指针,m_inputLayout为ID3D11InputLayout类型的指针。

    在CreateDeviceResources函数中用于创建着色器的代码如下所示:

    //读取顶点着色器解析文件

    auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso");

    //读取像素着色器解析文件

    auto loadPSTask = DX::ReadDataAsync("SimplePixelShader.cso");

    auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {

        //创建顶点着色器

        DX::ThrowIfFailed(

            m_d3dDevice->CreateVertexShader(

                fileData->Data,

                fileData->Length,

                nullptr,

                &m_vertexShader

            )

        );

        //描述了立体图形顶点的位置和颜色信息

        const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =

        {

            {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0, D3D11_INPUT_PER_VERTEX_DATA,0},

            { "COLOR",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12, D3D11_INPUT_PER_VERTEX_DATA,0},

        };

        //得到ID3D11InputLayout的对象

        DX::ThrowIfFailed(

            m_d3dDevice->CreateInputLayout(

                vertexDesc,

                ARRAYSIZE(vertexDesc),

                fileData->Data,

                fileData->Length,

                &m_inputLayout

            )

        );

    });

    auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {

        //创建像素着色器

        DX::ThrowIfFailed(

            m_d3dDevice->CreatePixelShader(

                fileData->Data,

                fileData->Length,

                nullptr,

                &m_pixelShader

            )

        );

        //得到储存ModelViewProjectionConstantBuffer结构体的缓存

        CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);

        DX::ThrowIfFailed(

            m_d3dDevice->CreateBuffer(

                &constantBufferDesc,

                nullptr,

                &m_constantBuffer

            )

        );

    });

    在上面的代码中,首先调用ReadDataAsync函数分别读取资源文件SimpleVertexShader.cso和SimplePixelShader.cso,这两个资源文件是编译项目中的SimplePixelShader.hlsl文件和SimpleVertexShader.hlsl文件所得到的文件。接着以读取SimpleVertexShader.cso资源文件所得到的数据和此数据的长度作为参数,调用CreateVertexShader函数得到一个ID3D11VertexShader类型的对象作为顶点着色器,并使用m_vertexShader指针指向这个对象。接着定义一个D3D11_INPUT_ELEMENT_DESC类型的数组vertexDesc,此数组用于描述立体图形顶点的位置和颜色信息,并以vertexDesc数组作为参数调用CreateInputLayout函数得到一个ID3D11InputLayout类型的对象,使用m_inputLayout指针指向这个对象。

    接下来以读取SimplePixelShader.cso资源文件将所得到的数据和此数据的长度作为参数,调用CreatePixelShader函数得到一个ID3D11PixelShader类型的对象作为像素着色器,并使用m_pixelShader指针指向这个对象。然后定义一个CD3D11_BUFFER_DESC结构体的变量constantBufferDesc,以constantBufferDesc结构体变量作为参数调用CreateBuffer函数来得到一个用于存储ModelViewProjectionConstantBuffer结构体的缓存,使用m_constantBuffer指针指向此缓存。

    讲解了创建着色器的代码以后,接着来介绍创建立体图形顶点的代码。在创建立体图形顶点的过程中会用到一个VertexPositionColor结构体,此结构体默认定义在CubeRenderer.h头文件中,代码如下所示:

    struct VertexPositionColor

    {

        DirectX::XMFLOAT3 pos;

        DirectX::XMFLOAT3 color;

    };

    在VertexPositionColor结构体中定义了两个XMFLOAT3结构体的变量pos和color,分别用于存储立体图形顶点的位置信息和颜色信息。

    CubeRenderer.cpp源文件的CreateDeviceResources函数用于实现创建立体图形顶点的代码如下所示:

    auto createCubeTask = (createPSTask && createVSTask).then([this] () {

        //定义数组cubeVertices

        VertexPositionColor cubeVertices[] =

        {

        {XMFLOAT3(-0.5f,-0.5f,-0.5f),XMFLOAT3(0.0f,0.0f,0.0f)},

        {XMFLOAT3(-0.5f,-0.5f,0.5f),XMFLOAT3(0.0f,0.0f,1.0f)},

        {XMFLOAT3(-0.5f,0.5f,-0.5f),XMFLOAT3(0.0f,1.0f,0.0f)},

        {XMFLOAT3(-0.5f,0.5f,0.5f),XMFLOAT3(0.0f,1.0f,1.0f)},

        {XMFLOAT3( 0.5f,-0.5f,-0.5f),XMFLOAT3(1.0f,0.0f,0.0f)},

        {XMFLOAT3( 0.5f,-0.5f,0.5f),XMFLOAT3(1.0f,0.0f,1.0f)},

        {XMFLOAT3( 0.5f,0.5f,-0.5f),XMFLOAT3(1.0f,1.0f,0.0f)},

        {XMFLOAT3( 0.5f,0.5f,0.5f),XMFLOAT3(1.0f,1.0f,1.0f)},

        };

        //创建cubeVertices缓存

        D3D11_SUBRESOURCE_DATA vertexBufferData = {0};

        vertexBufferData.pSysMem = cubeVertices;

        vertexBufferData.SysMemPitch = 0;

        vertexBufferData.SysMemSlicePitch = 0;

        CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);

        DX::ThrowIfFailed(

            m_d3dDevice->CreateBuffer(

                &vertexBufferDesc,

                &vertexBufferData,

                &m_vertexBuffer

            )

        );

        //定义数组cubeIndices

        unsigned short cubeIndices[] =

        {

            0,2,1,

            1,2,3,

            4,5,6,

            5,7,6,

            0,1,5,

            0,5,4,

            2,6,7,

            2,7,3,

            0,4,6,

            0,6,2,

            1,3,7,

            1,7,5,

        };

        //得到cubeIndices数组的大小

        m_indexCount = ARRAYSIZE(cubeIndices);

        //创建cubeIndices缓存

        D3D11_SUBRESOURCE_DATA indexBufferData = {0};

        indexBufferData.pSysMem = cubeIndices;

        indexBufferData.SysMemPitch = 0;

        indexBufferData.SysMemSlicePitch = 0;

        CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);

        DX::ThrowIfFailed(

            m_d3dDevice->CreateBuffer(

                &indexBufferDesc,

                &indexBufferData,

                &m_indexBuffer

            )

        );

    });

    在上面的代码中,首先定义一个VertexPositionColor类型的数组cubeVertices,用来存储立体图形的位置和颜色信息,其中位置信息指立体图形顶点的X轴、Y轴和Z轴的坐标,这里使用XMFLOAT3结构体来储存这三个坐标,而颜色信息则指顶点的RGB值,同样可以使用XMFLOAT3结构体来储存顶点的RGB值。

    接下来定义一个D3D11_SUBRESOURCE_DATA结构体的变量vertexBufferData,将cubeVertices数组赋值给vertexBufferData结构体变量的成员pSysMem,并将此结构体变量的成员SysMemPitch和SysMemSlicePitch都赋值为0。然后定义一个CD3D11_BUFFER_DESC结构体的变量vertexBufferDesc,以vertexBufferData结构体变量和vertexBufferDesc结构体变量作为参数调用CreateBuffer函数得到一个用于储存立体图形顶点信息的缓存,并使用m_vertexBuffer指针指向此缓存。

    然后定义一个unsigned short类型的数组cubeIndices,在此数组中储存了立体图形的36个顶点索引,其中每三个相邻的顶点索引用于绘制一个三角形。接着定义一个D3D11_SUBRESOURCE_DATA结构体的变量indexBufferData,将此结构体变量的成员pSysMem赋值为cubeIndices数组,并把成员SysMemPitch和SysMemSlicePitch都赋值为0。最后定义一个CD3D11_BUFFER_DESC结构体的变量indexBufferDesc,以indexBufferData结构体变量和indexBufferDesc结构体变量作为参数调用CreateBuffer函数得到一个用于储存立体图形顶点索引的缓存,并使用m_indexBuffer指针指向此缓存。

  • 相关阅读:
    .net开发微信(1)——微信订阅号的配置
    工作中EF遇到的问题
    .net Entity Framework初识1
    Razor视图
    jquery中利用队列依次执行动画
    .net找List1和List2的差集
    angularjs ng-if 中的ng-model 值作用域问题
    Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题
    springboot 启动排除某些bean 的注入
    angularjs 初始化方法执行两次以及url定义错误导致传值错误问题
  • 原文地址:https://www.cnblogs.com/finehappy/p/6645655.html
Copyright © 2020-2023  润新知