之前一篇文章讲了如何初始化DirectX 11,现在在此基础上绘制一个Cube,总体可概括为以下几个步骤:

  1. 定义Cube顶点数据结构
  2. 创建Vertex Buffer和Index Buffer
  3. 编写应用于Cube的effect file
  4. 读取effect,编译创建
  5. 根据顶点数据结构,创建input layout,将顶点与effect中VS的input signature关联
  6. 开始绘制,clear掉render target view和depth stencil view
  7. 设置若干IA参数,input layout,primitive toplogy,vertex buffer,index buffer
  8. 将一些必要参数设置给effect的cbuffer中,如worldViewProjMatrix
  9. 将effect的每个pass依次apply到context中,进行绘制
  10. 绘制提交,结束绘制

定义Cube顶点数据结构

当前只需要顶点的position和color属性,position是三维向量,color是四维向量,定义如下:

	struct Vertex
{
XMFLOAT3 position;
XMFLOAT4 color;
};

这里用的是DirectXmath.h中的XMFLOAT3XMFLOAT4,也可以用自定义的向量类。

创建Vertex Buffer和Index Buffer

HRESULT CreateBuffer(
const D3D11_BUFFER_DESC *pDesc,
const D3D11_SUBRESOURCE_DATA *pInitialData,
ID3D11Buffer **ppBuffer
);

主要用到的是ID3D11Device::CreateBuffer这一函数。其中,pDesc主要设置要创建的buffer大小,用途,是否cpu可访问等等,D3D11_BIND_VERTEX_BUFFER用于创建vertex buffer,D3D11_BIND_INDEX_BUFFER用于创建index buffer;pInitialData存放的是初始化数据。

编写应用于Cube的effect file

这个effect效果很简单,就是将Cube变换到正确的屏幕空间位置,设置为插值后的颜色。大致包括的内容如下:

cbuffer cbPerObject
{
float4x4 gWorldViewProj;
}; struct VertexIn
{
float3 posL : POSITION;
float4 color : COLOR;
}; struct VertexOut
{
float4 posH : SV_POSITION;
float4 color : COLOR;
}; VertexOut VS(VertexIn vIn)
{
VertexOut vOut;
vOut.posH = mul(float4(vIn.posL, 1.0f), gWorldViewProj);
vOut.color = vIn.color; return vOut;
} float4 PS(VertexOut pIn) : SV_TARGET
{
return pIn.color;
} technique11 ColorTech
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetPixelShader(CompileShader(ps_5_0, PS()));
}
}

cBuffer存放的是要从外部读取的数据,这里就是个MVP矩阵了。

读取effect,编译创建

HRESULT D3DX11CompileFromFile(
_In_ LPCTSTR pSrcFile,
_In_ const D3D10_SHADER_MACRO *pDefines,
_In_ LPD3D10INCLUDE pInclude,
_In_ LPCSTR pFunctionName,
_In_ LPCSTR pProfile,
_In_ UINT Flags1,
_In_ UINT Flags2,
_In_ ID3DX11ThreadPump *pPump,
_Out_ ID3D10Blob **ppShader,
_Out_ ID3D10Blob **ppErrorMsgs,
_Out_ HRESULT *pHResult
);

这里,我们要编译整个effect而不是某个shader,因而将pFunctionName设置为nullptr。得到编译后的effect后:

HRESULT D3DX11CreateEffectFromMemory(
void *pData,
SIZE_T DataLength,
UINT FXFlags,
ID3D11Device *pDevice,
ID3DX11Effect **ppEffect
);

effect创建完成。

创建input layout

input layout将定义的顶点结构与effect中VS的input结构关联,为VS中的input指定输入来源。

HRESULT CreateInputLayout(
const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
UINT NumElements,
const void *pShaderBytecodeWithInputSignature,
SIZE_T BytecodeLength,
ID3D11InputLayout **ppInputLayout
);

pInputElementDescs可以被当作是两者关联的桥梁,现在顶点只有positioncolor两个属性,pInputElementDescs定义如下:

D3D11_INPUT_ELEMENT_DESC VertexDesc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0},
};

D3D11_APPEND_ALIGNED_ELEMENT这个宏省去了自己计算每个分量偏移的麻烦。

绘制

首先,清空back buffer和depth/stencil buffer;

void ClearRenderTargetView(
ID3D11RenderTargetView *pRenderTargetView,
const FLOAT [4] ColorRGBA
);
void ClearDepthStencilView(
ID3D11DepthStencilView *pDepthStencilView,
UINT ClearFlags,
FLOAT Depth,
UINT8 Stencil
);

接下来,设置若干IA参数,这里我们需要的就是input layout关联,绘制基本primitive的类型,还有设置vertex buffer和index buffer。

void IASetInputLayout(
ID3D11InputLayout *pInputLayout
);
void IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY Topology
);
void IASetVertexBuffers(
UINT StartSlot,
UINT NumBuffers,
ID3D11Buffer * const *ppVertexBuffers,
const UINT *pStrides,
const UINT *pOffsets
);
void IASetIndexBuffer(
ID3D11Buffer *pIndexBuffer,
DXGI_FORMAT Format,
UINT Offset
);

值得一提的是,vertex buffer可以存在多个,index buffer只能存在一个。不同的vertex buffer会分配到不同的input slots中去,这里只用到了一个vertex buffer,暂时不考虑多个input slots的情况。

在effect渲染之前,往往存在需要设置一些参数给effect的情况,比如我们这个例子,就需要把MVP矩阵传给effect:

		XMMATRIX worldViewProj = world * view * proj;
shaderMVP->SetMatrix(reinterpret_cast<float*>(&worldViewProj));

然后就到了正式的绘制阶段,将effect的每个pass依次apply到context中,进行绘制:

		D3DX11_TECHNIQUE_DESC techDesc;
shaderTech->GetDesc(&techDesc);
for (UINT i = 0; i < techDesc.Passes; ++i)
{
shaderTech->GetPassByIndex(i)->Apply(0, mD3dImmediateContext);
mD3dImmediateContext->DrawIndexed(36, 0, 0);
}

一个Cube有6个面,描述一个面需要6个index,所以总共是36个index。

最后不要忘记将绘制内容提交:

mSwapChain->Present(0, 0);

运行效果如图:

用DirectX 11绘制一个Cube的更多相关文章

  1. 用DirectX12绘制一个Cube

    之前一篇文章讲了DirectX12的初始化流程,现在来看看在此基础上如何绘制一个Cube. 首先,我们要为这个Cube准备一个shader,来告诉GPU绘制的具体流程,DirectX中的shader使 ...

  2. Unity3d修炼之路:用Mesh绘制一个Cube

    #pragma strict function Awake(){ var pMeshFilter : MeshFilter = gameObject.AddComponent(typeof(MeshF ...

  3. DX11 Without DirectX SDK--03 渲染一个立方体

    回到 DirectX11--使用Windows SDK来进行开发 一个立方体有8个顶点,然而绘制一个立方体需要画12个三角形,如果按照前面的方法绘制的话,则需要提供36个顶点,而且这里面的顶点数据会重 ...

  4. {转自MC}NVIDIA DirectX 11演示DEMO详解

    http://tieba.baidu.com/p/1960826986 图形技术无论如何发展,最终都要落到实际的应用中才有效果.在个人电脑上,图形技术最大的用户除了显示UI和操作界面外,就是呈现美轮美 ...

  5. DirectX 文本绘制

    在Direct中进行文本绘制,可以通过Win32程序框架实现,也可以通过DXUT进行绘制. 基于第一篇的Win32框架入门实现非常简单,只需要添加数行代码即可.主要说需要修改的地方. #pragma  ...

  6. Introduction to 3D Game Programming with DirectX 11 翻译--开篇

    Direct3D 11简介 Direct3D 11是一个渲染库,用于在Windows平台上使用现代图形硬件编写高性能3D图形应用程序.Direct3D是一个windows底层库,因为它的应用程序编程接 ...

  7. CAD绘制一个单行文字(com接口VB语言)

    主要用到函数说明: _DMxDrawX::DrawText 绘制一个单行文字.详细说明如下: 参数 说明 DOUBLE dPosX >文字的位置的X坐标 DOUBLE dPosY 文字的位置的Y ...

  8. CAD绘制一个对齐标注(com接口VB语言)

    主要用到函数说明: _DMxDrawX::DrawDimAligned 绘制一个对齐标注.详细说明如下: 参数 说明 DOUBLE dExtLine1PointX 第一条界线开始点X值 DOUBLE ...

  9. CAD绘制一个角度标注(com接口VB语言)

    主要用到函数说明: _DMxDrawX::DrawDimAngular 绘制一个角度标注.详细说明如下: 参数 说明 DOUBLE dAngleVertexX 角度标注的顶点的X值 DOUBLE dA ...

随机推荐

  1. 轻松将CAD文件转为加密的PDF文件

    对于从事设计相关工作的朋友来说,CAD肯定再熟悉不过了.一些有特殊要求的CAD文件,需要将其转换成为PDF文件以方便保存.传输.打印,同时还得保证设计图稿的安全性,所以将CAD文件直接转为加密的PDF ...

  2. 用大白话讲大数据HBase,老刘真的很用心(1)

    老刘今天复习HBase知识发现很多资料都没有把概念说清楚,有很多专业名词一笔带过没有解释.比如这个框架高性能.高可用,那什么是高性能高可用?怎么实现的高性能高可用?没说! 如果面试官听了你说的,会有什 ...

  3. CCF-CSP认证 C++题解目录

    持续更新中,记录刷题过程并分享一下小小的心得总结. 试题编号 试题名称 标签 202006-1 线性分类器 | 题解 线性规划 202006-2 稀疏向量| 题解 归并排序思想 202006-3 化学 ...

  4. MySQL的两种日志类型,redo log,binlog

    文章内容学习:极客时间-林晓彬老师-MySQL实战45讲 整理而得 我们知道MySQL数据库在发生意外宕机的情况下,可以将数据恢复到历史的某个时间点,能实现这个功能依靠的是日志,MySQL提供两种类型 ...

  5. 企业安全03Django GIS SQL注入漏洞CVE-2020-9402

    Django GIS SQL注入漏洞CVE-2020-9402 一.漏洞描述 Django是Django基金会的一套基于Python语言的开源Web应用框架.该框架包括面向对象的映射器.视图系统.模板 ...

  6. Steps 组件的设计与实现

    NutUI 组件源码揭秘 前言 本文的主题是 Steps 组件的设计与实现.Steps 组件是 Steps 步骤和 Timeline 组件结合的组件,在此之前他们是两个不同的组件,在 NutUI 最近 ...

  7. C++-codeblocks安装

    2020-02-15 "Test_leetcode - Debug": The compiler's setup (GNU GCC Compiler) is invalid, so ...

  8. Kubernetes K8S之固定节点nodeName和nodeSelector调度详解

    Kubernetes K8S之固定节点nodeName和nodeSelector调度详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...

  9. 喝完可乐桶后程序员回归本源,开源Spring基础内容

    周六了,又是摸鱼的一天,今天还有点不在状态,脑瓜子迷迷糊糊的,昨晚出去喝可乐桶喝的脑子到现在都不是很正常(奉劝各位可以自己小酌:450ml威士忌+1L多一点可乐刚刚好,可能是我酒量不好),正好没啥事就 ...

  10. 第7.3节 Python特色的面向对象设计:协议、多态及鸭子类型

    Python是一种多态语言,其表现特征是:对象方法的调用方只管方法是否可调用,不管对象是什么类型,从而屏蔽不同类型对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化. 一.    P ...