• DirectX 3D C++ 圆柱体的渲染(源代码)


    作业内容 请勿抄袭

    代码功能:渲染一个绕中心轴自转的圆柱体。要求该圆柱体高度为3.0,半径为0.5。

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "resource.h"
    using namespace std;
    
    //自定义圆周率常量的近似值
    const float pi = 3.1415926536;
    
    //设置基本的参数(包括圆面的顶点数量 圆柱体高度和底面半径)
    float TotalHeight = 3.0;
    float radius = 0.5;
    const int RoundPointNum = 50;
    
    //通过结构体定义的方式来定义一个简单的顶点类型
    struct SimpleVertex
    {
        XMFLOAT3 Pos;    //通过一个三维向量表示顶点的三维坐标信息
        XMFLOAT4 Color;  //通过一个四维向量表示顶点的颜色信息(RGB和透明度)
    };
    
    //通过结构体的方式定义常量缓冲区的数据格式
    struct ConstantBuffer
    {
        XMMATRIX mWorld;       //存储世界矩阵,将顶点变换到世界空间
        XMMATRIX mView;        //存储观察矩阵,将顶点变换到观察空间
        XMMATRIX mProjection;  //存储投影矩阵,将顶点坐标变换到裁剪空间
    };
    
    //全局变量定义区
    HINSTANCE               g_hInst = NULL;                          //存储应用程序的实例句柄
    HWND                    g_hWnd = NULL;                           //存储应用程序的主窗口句柄
    D3D_DRIVER_TYPE         g_driverType = D3D_DRIVER_TYPE_NULL;     //存储Direct3D驱动类型
    D3D_FEATURE_LEVEL       g_featureLevel = D3D_FEATURE_LEVEL_11_0; //指定Direct3D特性级别
    ID3D11Device*           g_pd3dDevice = NULL;                     //指定Direct3D设备对象
    ID3D11DeviceContext*    g_pImmediateContext = NULL;
    IDXGISwapChain*         g_pSwapChain = NULL;
    ID3D11RenderTargetView* g_pRenderTargetView = NULL;
    ID3D11VertexShader*     g_pVertexShader = NULL;
    ID3D11PixelShader*      g_pPixelShader = NULL;
    ID3D11InputLayout*      g_pVertexLayout = NULL;
    ID3D11Buffer*           g_pVertexBuffer = NULL;
    ID3D11Buffer*           g_pIndexBuffer = NULL;
    ID3D11Buffer*           g_pConstantBuffer = NULL;
    XMMATRIX                g_World;
    XMMATRIX                g_View;
    XMMATRIX                g_Projection;
    
    //前向函数声明(用于后续的过程中)
    HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
    HRESULT InitDevice();
    void CleanupDevice();
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    void Render();
    
    
    //程序入口:进行了初始化并进入消息循环,在空闲时间内进行场景渲染
    int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
    {
        //消除未使用参数的编译警告
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
        //对窗口进行初始化
        if (FAILED(InitWindow(hInstance, nCmdShow)))
            return 0;
        //初始化Direct3D的设备和相关资源
        if (FAILED(InitDevice()))
        {
            CleanupDevice();
            return 0;
        }
        //处理窗口消息和渲染场景
        MSG msg = { 0 };
        //循环一直运行知道窗口关闭
        while (WM_QUIT != msg.message)
        {
            //判断消息队列中是否还有消息没有处理
            if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                //将未处理的消息转换为合适的形式发送给窗口过程
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            //空闲时间则进行渲染
            else
            {
                Render();
            }
        }
        //清理所占用的资源
        CleanupDevice();
        //消息循环的退出代码
        return (int)msg.wParam;
    }
    
    //初始化窗口并注册窗口类
    HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
    {
        //对窗口的相关属性进行设置
        WNDCLASSEX wcex;
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.hInstance = hInstance;
        wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszMenuName = NULL;
        wcex.lpszClassName = L"TutorialWindowClass";
        wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_TUTORIAL1);
        //对窗口进行创建
        if (!RegisterClassEx(&wcex))
            return E_FAIL;
        //完成创建窗口的过程
        g_hInst = hInstance;
        RECT rc = { 0, 0, 640, 480 };
        AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
        g_hWnd = CreateWindow(L"TutorialWindowClass", L"Direct3D 11 Tutorial 4: 3D Spaces", WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
            NULL);
        if (!g_hWnd)
            return E_FAIL;
        ShowWindow(g_hWnd, nCmdShow);
    
        return S_OK;
    }
    
    //用于编译着色器的辅助函数
    HRESULT CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
    {
        HRESULT hr = S_OK;
    
        DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
    #if defined( DEBUG ) || defined( _DEBUG )
        // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
        // Setting this flag improves the shader debugging experience, but still allows 
        // the shaders to be optimized and to run exactly the way they will run in 
        // the release configuration of this program.
        dwShaderFlags |= D3DCOMPILE_DEBUG;
    #endif
    
        ID3DBlob* pErrorBlob;
        hr = D3DX11CompileFromFile(szFileName, NULL, NULL, szEntryPoint, szShaderModel,
            dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL);
        if (FAILED(hr))
        {
            if (pErrorBlob != NULL)
                OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
            if (pErrorBlob) pErrorBlob->Release();
            return hr;
        }
        if (pErrorBlob) pErrorBlob->Release();
    
        return S_OK;
    }
    
    // 初始化和设置一些与图形渲染相关的对象和参数
    HRESULT InitDevice(void)
    {
        //定义了一个名为hr的变量,类型为HRESULT,并将其初始化为S_OK
        HRESULT hr = S_OK;
    
        //定义了一个名为rc的变量,类型为RECT,用于存储窗口的矩形区域
        RECT rc;
        //调用GetClientRect函数,将窗口g_hWnd的客户区域的矩形信息存储到rc变量中
        GetClientRect(g_hWnd, &rc);
        //计算窗口宽度
        UINT width = rc.right - rc.left;
        //计算窗口高度
        UINT height = rc.bottom - rc.top;
        //存储创建Direct3D设备时的标志
        UINT createDeviceFlags = 0;
        //如果定义了_DEBUG宏,则执行#ifdef _DEBUG和#endif之间的代码块
    #ifdef _DEBUG
        //如果处于调试模式,将D3D11_CREATE_DEVICE_DEBUG标志位按位或运算( |= )到createDeviceFlags变量上
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
        //定义了一个名为driverTypes的数组,包含了三种Direct3D驱动类型:硬件驱动、WARP驱动和参考驱动
        D3D_DRIVER_TYPE driverTypes[] =
        {
            D3D_DRIVER_TYPE_HARDWARE,
            D3D_DRIVER_TYPE_WARP,
            D3D_DRIVER_TYPE_REFERENCE,
        };
        //计算driverTypes数组中驱动类型的数量
        UINT numDriverTypes = ARRAYSIZE(driverTypes);
    
        //定义了一个名为featureLevels的数组,包含了三种Direct3D功能级别:11.0、10.1和10.0
        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
        };
        //计算featureLevels数组中功能级别的数量
        UINT numFeatureLevels = ARRAYSIZE(featureLevels);
    
        //设置交换链的描述信息
        //包括缓冲区数量、尺寸、像素格式、刷新率、使用方式、输出窗口、抗锯齿采样等
        DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;
    
        //使用一个循环来尝试不同的驱动类型,创建Direct3D设备和交换链
        for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
        {
            g_driverType = driverTypes[driverTypeIndex];
            hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
                D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext);
            if (SUCCEEDED(hr))
                break;
        }
        //如果设备和交换链创建失败则返回错误代码
        if (FAILED(hr))
            return hr;
    
        //创建渲染目标视图
        ID3D11Texture2D* pBackBuffer = NULL;
        hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
        if (FAILED(hr))
            return hr;
    
        hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
        pBackBuffer->Release();
        if (FAILED(hr))
            return hr;
    
        //将渲染目标视图设置为当前的渲染目标,以便将渲染的图像输出到该渲染目标
        g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);
    
        //设置视口,定义了渲染目标上的可见区域
        D3D11_VIEWPORT vp;
        vp.Width = (FLOAT)width;
        vp.Height = (FLOAT)height;
        vp.MinDepth = 0.0f;
        vp.MaxDepth = 1.0f;
        vp.TopLeftX = 0;
        vp.TopLeftY = 0;
        g_pImmediateContext->RSSetViewports(1, &vp);
    
        //编译顶点着色器
        ID3DBlob* pVSBlob = NULL;
        hr = CompileShaderFromFile(L"Cylinder Rendering.fx", "VS", "vs_4_0", &pVSBlob);
        if (FAILED(hr))
        {
            MessageBox(NULL,
                L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
            return hr;
        }
    
        //创建顶点着色器
        hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader);
        if (FAILED(hr))
        {
            pVSBlob->Release();
            return hr;
        }
    
        // 定义输入布局,指定顶点数据的格式
        D3D11_INPUT_ELEMENT_DESC layout[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        };
        UINT numElements = ARRAYSIZE(layout);
    
        //创建输入布局,将输入布局元素与顶点着色器关联起来
        hr = g_pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
            pVSBlob->GetBufferSize(), &g_pVertexLayout);
        pVSBlob->Release();
        if (FAILED(hr))
            return hr;
    
        //设置当前渲染管线中的输入布局
        g_pImmediateContext->IASetInputLayout(g_pVertexLayout);
    
        //编译像素着色器
        ID3DBlob* pPSBlob = NULL;
        hr = CompileShaderFromFile(L"Cylinder Rendering.fx", "PS", "ps_4_0", &pPSBlob);
        if (FAILED(hr))
        {
            MessageBox(NULL,
                L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
            return hr;
        }
    
        //创建像素着色器
        hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader);
        pPSBlob->Release();
        if (FAILED(hr))
            return hr;
        
        //设置构成圆面的顶点的个数
        const int PointNum = 2 * RoundPointNum + 2;
        float angleUnit = 360.0 / RoundPointNum;
        float halfHeight = TotalHeight / 2;
        SimpleVertex vertices[PointNum];
        random_device device;
        mt19937 engine(device());
        uniform_real_distribution<float> getRandom(0.0f, 1.0f);
        //逐一为每一个顶点设置空间坐标和颜色
        for (int i(0); i < RoundPointNum; ++i)
        {
            float x = radius * sin(i * angleUnit * pi / 180.0);
            float z = radius * cos(i * angleUnit * pi / 180.0);
            float R = getRandom(engine);
            float G = getRandom(engine);
            float B = getRandom(engine);
            vertices[i] = { XMFLOAT3(x,-halfHeight,z) ,XMFLOAT4(R,G,B,1.0f)};
            vertices[i + RoundPointNum] = { XMFLOAT3(x,halfHeight,z),XMFLOAT4(R,G,B,1.0f) };
        }
        float R1 = getRandom(engine);
        float G1 = getRandom(engine);
        float B1 = getRandom(engine);
        float R2 = getRandom(engine);
        float G2 = getRandom(engine);
        float B2 = getRandom(engine);
        vertices[2 * RoundPointNum] = { XMFLOAT3(0,halfHeight,0),XMFLOAT4(R1,G1,B1,1.0f) };
        vertices[2 * RoundPointNum + 1] = { XMFLOAT3(0,-halfHeight,0),XMFLOAT4(R2,G2,B2,1.0f) };
    
    
        D3D11_BUFFER_DESC bd;
        ZeroMemory(&bd, sizeof(bd));
        //设置缓冲区的使用方式为默认
        bd.Usage = D3D11_USAGE_DEFAULT;
        //设置缓冲区的字节宽度
        bd.ByteWidth = sizeof(SimpleVertex) * PointNum;
        //设置缓冲区的绑定标志为顶点缓冲区
        bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        //定义了一个D3D11_SUBRESOURCE_DATA结构体变量,并将其内存清零
        bd.CPUAccessFlags = 0;
        //将顶点数据数组的指针赋给InitData的pSysMem成员
        D3D11_SUBRESOURCE_DATA InitData;
        ZeroMemory(&InitData, sizeof(InitData));
        InitData.pSysMem = vertices;
        //创建顶点缓冲区
        hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pVertexBuffer);
        //检查创建顶点缓冲区是否失败
        if (FAILED(hr))
            return hr;
    
        //将顶点缓冲区绑定到输入装配阶段,使得图形渲染管线能够使用该顶点缓冲区中的数据进行渲染
        UINT stride = sizeof(SimpleVertex);
        UINT offset = 0;
        g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
    
        //创建一个索引数组
        WORD indices[12 * RoundPointNum];
        for (int i(0); i < RoundPointNum - 1; ++i)
        {
            //渲染下面的部分
            indices[i * 12] = 2 * RoundPointNum;
            indices[i * 12 + 1] = i;
            indices[i * 12 + 2] = i + 1;
            //渲染上面的部分
            indices[i * 12 + 3] = 2 * RoundPointNum + 1;
            indices[i * 12 + 4] = i + RoundPointNum;
            indices[i * 12 + 5] = i + RoundPointNum + 1;
            //渲染侧面的第一个三角形
            indices[i * 12 + 6] = i;
            indices[i * 12 + 7] = i + 1;
            indices[i * 12 + 8] = i + RoundPointNum;
            //渲染侧面的第二个三角形
            indices[i * 12 + 9] = i + 1;
            indices[i * 12 + 10] = i + RoundPointNum;
            indices[i * 12 + 11] = i + RoundPointNum - 1;
        }
        //渲染边界的情况
        int i(RoundPointNum - 1);
        //渲染下面的部分
        indices[i * 12] = 2 * RoundPointNum;
        indices[i * 12 + 1] = 0;
        indices[i * 12 + 2] = RoundPointNum - 1;
        //渲染上面的部分
        indices[i * 12 + 3] = 2 * RoundPointNum + 1;
        indices[i * 12 + 4] = RoundPointNum;
        indices[i * 12 + 5] = 2 * RoundPointNum - 1;
        //渲染侧面的第一个三角形
        indices[i * 12 + 6] = RoundPointNum - 1;
        indices[i * 12 + 7] = 0;
        indices[i * 12 + 8] = 2 * RoundPointNum - 1;
        //渲染侧面的第二个三角形
        indices[i * 12 + 9] = 0;
        indices[i * 12 + 10] = RoundPointNum;
        indices[i * 12 + 11] = 2 * RoundPointNum - 1;
    
        //设置缓冲区的使用方式为默认
        bd.Usage = D3D11_USAGE_DEFAULT;
        //设置缓冲区的字节宽度,这里是每个索引的字节大小乘以索引数量(36个索引)
        bd.ByteWidth = sizeof(WORD) * (12 * RoundPointNum);
        bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
        bd.CPUAccessFlags = 0;
        InitData.pSysMem = indices;
        hr = g_pd3dDevice->CreateBuffer(&bd, &InitData, &g_pIndexBuffer);
        if (FAILED(hr))
            return hr;
    
        //设置索引缓冲区
        g_pImmediateContext->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
    
        //设置图元拓扑,表示要绘制的图元拓扑类型为三角形列表
        g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
        //创建常量缓冲区
        bd.Usage = D3D11_USAGE_DEFAULT;
        bd.ByteWidth = sizeof(ConstantBuffer);
        bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
        bd.CPUAccessFlags = 0;
        hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pConstantBuffer);
        if (FAILED(hr))
            return hr;
    
        //初始化世界矩阵
        g_World = XMMatrixIdentity();
    
        //初始化视图矩阵
        XMVECTOR Eye = XMVectorSet(0.0f, 1.0f, -5.0f, 0.0f);
        XMVECTOR At = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
        XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
        g_View = XMMatrixLookAtLH(Eye, At, Up);
    
        //初始化投影矩阵
        g_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f);
    
        return S_OK;
    }
    
    //释放创建的对象的函数
    void CleanupDevice()
    {
        if (g_pImmediateContext) g_pImmediateContext->ClearState();
    
        if (g_pConstantBuffer) g_pConstantBuffer->Release();
        if (g_pVertexBuffer) g_pVertexBuffer->Release();
        if (g_pIndexBuffer) g_pIndexBuffer->Release();
        if (g_pVertexLayout) g_pVertexLayout->Release();
        if (g_pVertexShader) g_pVertexShader->Release();
        if (g_pPixelShader) g_pPixelShader->Release();
        if (g_pRenderTargetView) g_pRenderTargetView->Release();
        if (g_pSwapChain) g_pSwapChain->Release();
        if (g_pImmediateContext) g_pImmediateContext->Release();
        if (g_pd3dDevice) g_pd3dDevice->Release();
    }
    
    //窗口过程函数,用于处理程序接收到的消息
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        PAINTSTRUCT ps;
        HDC hdc;
    
        switch (message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;
    
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    
        return 0;
    }
    
    //用于渲染一帧的函数
    void Render(void)
    {
        //记录时间流逝的变量
        static float t = 0.0f;
        //检查当前的驱动类型是否为参考驱动类型
        if (g_driverType == D3D_DRIVER_TYPE_REFERENCE)
        {
            //如果使用参考驱动类型,将t增加一个固定的增量用于模拟动画效果。
            t += (float)XM_PI * 0.0125f;
        }
        //如果不是参考驱动类型,执行以下代码块
        else
        {
            //记录程序开始运行的时间
            static DWORD dwTimeStart = 0;
            //获取当前的系统时间
            DWORD dwTimeCur = GetTickCount();
            //如果dwTimeStart为0,表示是第一次执行Render函数,则将dwTimeStart设置为当前时间
            if (dwTimeStart == 0)
                dwTimeStart = dwTimeCur;
            //计算从程序开始运行到当前时间的经过的秒数
            t = (dwTimeCur - dwTimeStart) / 1000.0f;
        }
    
        //根据时间计算旋转矩阵用于物体的旋转变换
        g_World = XMMatrixRotationY(t);
    
        //定义一个清除元素数组(包含RGBA分量的值)
        float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };
        //使用清除颜色清除后备缓冲区,准备渲染新的帧
        g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, ClearColor);
    
        //定义一个名为cb的常量缓冲区结构
        ConstantBuffer cb;
        //将g_World矩阵转置后赋值给cb结构的mWorld成员
        cb.mWorld = XMMatrixTranspose(g_World);
        //将g_View矩阵转置后赋值给cb结构的mView成员
        cb.mView = XMMatrixTranspose(g_View);
        //将g_Projection矩阵转置后赋值给cb结构的mProjection成员
        cb.mProjection = XMMatrixTranspose(g_Projection);
        //将cb结构的数据更新到常量缓冲区g_pConstantBuffer中
        g_pImmediateContext->UpdateSubresource(g_pConstantBuffer, 0, NULL, &cb, 0, 0);
    
        //设置顶点着色器为g_pVertexShader
        g_pImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);
        //将常量缓冲区g_pConstantBuffer绑定到顶点着色器的指定槽位
        g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
        //设置像素着色器为g_pPixelShader
        g_pImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);
        //使用索引缓冲区进行绘制
        //绘制36个顶点,形成12个三角形。这是一个绘制立方体的操作
        g_pImmediateContext->DrawIndexed(12*RoundPointNum, 0, 0);
    
        //将后备缓冲区的内容呈现到屏幕上,显示渲染结果
        g_pSwapChain->Present(0, 0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
  • 相关阅读:
    RabbitMQ消息发送和接收(实例)
    汽车Type-C接口:特点与要求解析
    node笔记记录86router之2
    024-从零搭建微服务-系统服务(六)
    vue面试如何准备,这几道面试题助力你拿到理想offer
    智能钱包 AMA 第 8 期:探索进入市场的策略
    高等教育心理学:学习心理(重要)
    使用Fontcreator字体制作软件及字体设计学习
    MySQL数据库——第一节 — MySQL数据库基础
    实现游戏后处理6大常用模糊算法
  • 原文地址:https://blog.csdn.net/hanmo22357/article/details/133385024