博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Directx11学习笔记【十】 画一个简单的三角形
阅读量:7039 次
发布时间:2019-06-28

本文共 6614 字,大约阅读时间需要 22 分钟。

本篇笔记要实现的是在屏幕上渲染出一个三角形,重点要学习的是渲染一个几何体的流程方式。

为了渲染几何图形,需要一个顶点缓存和一个描述顶点布局的输入层,还有着色器(主要是顶点着色器和像素着色器),下面来看看具体Demo的实现。

新建一个Win32项目 ,新建一个类我们叫做TriangleDemo,继承自前面教程我们实现的基类Dx11DemoBase。

 

TriangleDemo.h头文件

#pragma once#include "Dx11DemoBase.h"class TriangleDemo : public Dx11DemoBase{public:    TriangleDemo();    ~TriangleDemo();    bool LoadContent() override;    void UnLoadContent() override;    void Update(float dt) override;    void Render() override;private:    ID3D11Buffer *m_pVertexBuffer;    ID3D11InputLayout *m_pInputLayout;    ID3D11VertexShader *m_pSolidColorVS;    ID3D11PixelShader *m_pSolidColorPS;};

在类中添加了四个成员变量,用来保存着色器、顶点缓存和顶点布局的指针。

定义顶点结构体

#include "TriangleDemo.h"#include 
struct VertexPos{ XMFLOAT3 pos;};TriangleDemo::TriangleDemo() : m_pInputLayout(0), m_pVertexBuffer(0), m_pSolidColorPS(0), m_pSolidColorVS(0){}TriangleDemo::~TriangleDemo(){}void TriangleDemo::UnLoadContent(){ if (m_pSolidColorPS) m_pSolidColorPS->Release(); if (m_pSolidColorVS) m_pSolidColorVS->Release(); if (m_pVertexBuffer) m_pVertexBuffer->Release(); if (m_pInputLayout) m_pInputLayout->Release(); m_pSolidColorVS = 0; m_pSolidColorPS = 0; m_pVertexBuffer = 0; m_pInputLayout = 0;}

着色器的加载

为了方便我们在基类中定义了一个CompileD3DShader函数实现加载着色器文本的功能,具体实现如下

bool Dx11DemoBase::CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer){    DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;#if defined _DEBUG || defined DEBUG    shaderFlags = D3DCOMPILE_DEBUG;#endif    ID3DBlob *errorBuffer = 0;    HRESULT result;    result = D3DX11CompileFromFile(filePath, 0, 0, entry, shaderModel, shaderFlags, 0, 0, buffer, &errorBuffer,0);    if (FAILED(result))    {        if (errorBuffer != 0)        {            OutputDebugString((char*)errorBuffer->GetBufferPointer());            errorBuffer->Release();        }        return false;    }    if (errorBuffer != 0)    {        return false;    }    return true;}

 

具体加载着色器的代码我们写在LoadContent函数中,下面是该函数的一部分代码

1 //载入顶点着色器 2     ID3DBlob *vsBuffer = 0; 3     bool compileResult = CompileD3DShader("SolidColor.fx", "VS_Main", "vs_4_0", &vsBuffer); 4     if (!compileResult) 5     { 6         MessageBox(0, "载入顶点着色器错误", "编译错误", MB_OK); 7         return false; 8     } 9 10     HRESULT result;11     result = m_pd3dDevice->CreateVertexShader(vsBuffer->GetBufferPointer(), vsBuffer->GetBufferSize(),12         0, &m_pSolidColorVS);13 14     if (FAILED(result))15     {16         if (vsBuffer)17         {18             vsBuffer->Release();19         }20         return false;21     }22 23     D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = 24     {25         {
"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}26 };27 28 UINT numLayoutElements = ARRAYSIZE(solidColorLayout);29 result = m_pd3dDevice->CreateInputLayout(solidColorLayout, numLayoutElements, vsBuffer->GetBufferPointer(),30 vsBuffer->GetBufferSize(), &m_pInputLayout);31 vsBuffer->Release();32 33 if (FAILED(result))34 {35 return false;36 }37 38 //载入像素着色器39 ID3DBlob *psBuffer = 0;40 compileResult = CompileD3DShader("SolidColor.fx", "PS_Main", "ps_4_0", &psBuffer);41 if (!compileResult)42 {43 MessageBox(0, "像素着色器加载失败", "编译错误", MB_OK);44 return false;45 }46 47 result = m_pd3dDevice->CreatePixelShader(psBuffer->GetBufferPointer(), psBuffer->GetBufferSize(),48 0, &m_pSolidColorPS);49 psBuffer->Release();50 if (FAILED(result))51 {52 return false;53 }

其中输入布局信息D3D11_INPUT_ELEMENT_DESC

(A description of a single element for the input-assembler stage.)

定义如下

typedef struct D3D11_INPUT_ELEMENT_DESC {  LPCSTR                     SemanticName;  UINT                       SemanticIndex;  DXGI_FORMAT                Format;  UINT                       InputSlot;  UINT                       AlignedByteOffset;  D3D11_INPUT_CLASSIFICATION InputSlotClass;  UINT                       InstanceDataStepRate;} D3D11_INPUT_ELEMENT_DESC;

 

顶点信息生成及处理

TriangleDemo::LoadContent() 的 上半部分完成了 inputlayout 和 shader, 剩下的就是 vertex 这些顶点的生成及处理了。

三角形的顶点列表 vertex list 存放处在 vertices数组里, 同时这个vertices 也作为 创建vertex buffer函数CreateBuffer()的参数之一:Subresource data。

下面是LoadContent()的另外一部分代码:

1 VertexPos vertices[]  = 2     { 3         XMFLOAT3(0.5f, 0.5f, 0.5f), 4         XMFLOAT3(0.5f, -0.5f, 0.5f), 5         XMFLOAT3(-0.5f,-0.5f,0.5f) 6     }; 7  8     D3D11_BUFFER_DESC vertexDesc; 9     ZeroMemory(&vertexDesc, sizeof(vertexDesc));10     vertexDesc.Usage = D3D11_USAGE_DEFAULT;11     vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;12     vertexDesc.ByteWidth = sizeof(VertexPos)* 3;13     14     D3D11_SUBRESOURCE_DATA resourceData;15     ZeroMemory(&resourceData, sizeof(resourceData));16     resourceData.pSysMem = vertices;17     18     result = m_pd3dDevice->CreateBuffer(&vertexDesc, &resourceData, &m_pVertexBuffer);19     if (FAILED(result))20     {21         return false;22     }23 24     return true;

其中D3D11_BUFFER_DESC定义如下:

typedef struct D3D11_BUFFER_DESC {  UINT        ByteWidth;  D3D11_USAGE Usage;  UINT        BindFlags;  UINT        CPUAccessFlags;  UINT        MiscFlags;  UINT        StructureByteStride;} D3D11_BUFFER_DESC;

D3D11_SUBRESOURCE_DATA定义如下:

typedef struct D3D11_SUBRESOURCE_DATA {  const void *pSysMem;  UINT       SysMemPitch;  UINT       SysMemSlicePitch;} D3D11_SUBRESOURCE_DATA;

 

渲染几何体

剩下代码是渲染几何体和 shaders 。我们在TriangleDemo::Render() 函数进行渲染几何体的工作

1 void TriangleDemo::Render() 2 { 3     if (m_pImmediateContext == 0) 4         return; 5     //清除渲染目标视图 6     float clearColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };//背景颜色 7     m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColor); 8  9     UINT stride = sizeof(VertexPos);10     UINT offset = 0;11     //设置数据信息格式控制信息12     m_pImmediateContext->IASetInputLayout(m_pInputLayout);13     //设置要绘制的几何体信息14     m_pImmediateContext->IASetVertexBuffers(0,1,&m_pVertexBuffer,&stride,&offset);15     //指明如何绘制三角形16     m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);17     m_pImmediateContext->VSSetShader(m_pSolidColorVS, 0, 0);18     m_pImmediateContext->PSSetShader(m_pSolidColorPS, 0, 0);19     m_pImmediateContext->Draw(3, 0);20     //马上输出21     m_pSwapChain->Present(0, 0);22 }

 

着色器.fx文件代码

float4 VS_Main( float4 pos : POSITION ) : SV_POSITION    {        return pos;    }    float4 PS_Main( float4 pos : SV_POSITION ) : SV_TARGET    {        return float4( 1.0f, 0.0f, 0.0f, 1.0f );    }

我们使用的vertex shader很简单的, 仅仅是传递输入的顶点坐标到输出设备;

pixel shader的工作也很简单, 仅仅是 为每个 像素pixel 配置一种固定的颜色( 红色)。 

 

最终效果图

转载地址:http://itxal.baihongyu.com/

你可能感兴趣的文章
引用类型参数,ref按引用传值
查看>>
基于Widnows Server 2003 SP2的系统需要新的系统准备工具
查看>>
C++ 制作 json 数据 并 传送给服务端(Server) 的 php
查看>>
如何从VS2003升级到VS2008
查看>>
Kernel内核的裁剪及移植(三)
查看>>
Oracle10g Bug 4612267 补丁安装备忘录
查看>>
我的Android开源项目:JNote
查看>>
跨线程操作UI
查看>>
关于Unity加载优化,你可能遇到这些问题
查看>>
在 Windows 7 和 Windows Server 2008 R2 上安装 Windows PowerShell 3.0
查看>>
专访IBM Power总经理 纵览Power 7新特性
查看>>
如何选购台式电脑和笔记本?购买时应注意什么
查看>>
Spring MVC基于注解来格式化数据
查看>>
mysql主从同步错误解决和Slave_IO_Running: NO
查看>>
编码问题之:java.io.UTFDataFormatException: Invalid byte 2 of 2-byte UTF-8 sequence.
查看>>
配置samba服务
查看>>
查找对话框实现
查看>>
Microsoft活动目录的作用以及优势
查看>>
小五思科技术学习笔记之单区域OSPF
查看>>
Hyper-V Server存储介绍
查看>>