用DirectX 11绘制一个Cube
之前一篇文章讲了如何初始化DirectX 11,现在在此基础上绘制一个Cube,总体可概括为以下几个步骤:
- 定义Cube顶点数据结构
- 创建Vertex Buffer和Index Buffer
- 编写应用于Cube的effect file
- 读取effect,编译创建
- 根据顶点数据结构,创建input layout,将顶点与effect中VS的input signature关联
- 开始绘制,clear掉render target view和depth stencil view
- 设置若干IA参数,input layout,primitive toplogy,vertex buffer,index buffer
- 将一些必要参数设置给effect的cbuffer中,如worldViewProjMatrix
- 将effect的每个pass依次apply到context中,进行绘制
- 绘制提交,结束绘制
定义Cube顶点数据结构
当前只需要顶点的position和color属性,position是三维向量,color是四维向量,定义如下:
struct Vertex
{
XMFLOAT3 position;
XMFLOAT4 color;
};
这里用的是DirectXmath.h
中的XMFLOAT3
和XMFLOAT4
,也可以用自定义的向量类。
创建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
可以被当作是两者关联的桥梁,现在顶点只有position
和color
两个属性,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的更多相关文章
- 用DirectX12绘制一个Cube
之前一篇文章讲了DirectX12的初始化流程,现在来看看在此基础上如何绘制一个Cube. 首先,我们要为这个Cube准备一个shader,来告诉GPU绘制的具体流程,DirectX中的shader使 ...
- Unity3d修炼之路:用Mesh绘制一个Cube
#pragma strict function Awake(){ var pMeshFilter : MeshFilter = gameObject.AddComponent(typeof(MeshF ...
- DX11 Without DirectX SDK--03 渲染一个立方体
回到 DirectX11--使用Windows SDK来进行开发 一个立方体有8个顶点,然而绘制一个立方体需要画12个三角形,如果按照前面的方法绘制的话,则需要提供36个顶点,而且这里面的顶点数据会重 ...
- {转自MC}NVIDIA DirectX 11演示DEMO详解
http://tieba.baidu.com/p/1960826986 图形技术无论如何发展,最终都要落到实际的应用中才有效果.在个人电脑上,图形技术最大的用户除了显示UI和操作界面外,就是呈现美轮美 ...
- DirectX 文本绘制
在Direct中进行文本绘制,可以通过Win32程序框架实现,也可以通过DXUT进行绘制. 基于第一篇的Win32框架入门实现非常简单,只需要添加数行代码即可.主要说需要修改的地方. #pragma ...
- Introduction to 3D Game Programming with DirectX 11 翻译--开篇
Direct3D 11简介 Direct3D 11是一个渲染库,用于在Windows平台上使用现代图形硬件编写高性能3D图形应用程序.Direct3D是一个windows底层库,因为它的应用程序编程接 ...
- CAD绘制一个单行文字(com接口VB语言)
主要用到函数说明: _DMxDrawX::DrawText 绘制一个单行文字.详细说明如下: 参数 说明 DOUBLE dPosX >文字的位置的X坐标 DOUBLE dPosY 文字的位置的Y ...
- CAD绘制一个对齐标注(com接口VB语言)
主要用到函数说明: _DMxDrawX::DrawDimAligned 绘制一个对齐标注.详细说明如下: 参数 说明 DOUBLE dExtLine1PointX 第一条界线开始点X值 DOUBLE ...
- CAD绘制一个角度标注(com接口VB语言)
主要用到函数说明: _DMxDrawX::DrawDimAngular 绘制一个角度标注.详细说明如下: 参数 说明 DOUBLE dAngleVertexX 角度标注的顶点的X值 DOUBLE dA ...
随机推荐
- 轻松将CAD文件转为加密的PDF文件
对于从事设计相关工作的朋友来说,CAD肯定再熟悉不过了.一些有特殊要求的CAD文件,需要将其转换成为PDF文件以方便保存.传输.打印,同时还得保证设计图稿的安全性,所以将CAD文件直接转为加密的PDF ...
- 用大白话讲大数据HBase,老刘真的很用心(1)
老刘今天复习HBase知识发现很多资料都没有把概念说清楚,有很多专业名词一笔带过没有解释.比如这个框架高性能.高可用,那什么是高性能高可用?怎么实现的高性能高可用?没说! 如果面试官听了你说的,会有什 ...
- CCF-CSP认证 C++题解目录
持续更新中,记录刷题过程并分享一下小小的心得总结. 试题编号 试题名称 标签 202006-1 线性分类器 | 题解 线性规划 202006-2 稀疏向量| 题解 归并排序思想 202006-3 化学 ...
- MySQL的两种日志类型,redo log,binlog
文章内容学习:极客时间-林晓彬老师-MySQL实战45讲 整理而得 我们知道MySQL数据库在发生意外宕机的情况下,可以将数据恢复到历史的某个时间点,能实现这个功能依靠的是日志,MySQL提供两种类型 ...
- 企业安全03Django GIS SQL注入漏洞CVE-2020-9402
Django GIS SQL注入漏洞CVE-2020-9402 一.漏洞描述 Django是Django基金会的一套基于Python语言的开源Web应用框架.该框架包括面向对象的映射器.视图系统.模板 ...
- Steps 组件的设计与实现
NutUI 组件源码揭秘 前言 本文的主题是 Steps 组件的设计与实现.Steps 组件是 Steps 步骤和 Timeline 组件结合的组件,在此之前他们是两个不同的组件,在 NutUI 最近 ...
- C++-codeblocks安装
2020-02-15 "Test_leetcode - Debug": The compiler's setup (GNU GCC Compiler) is invalid, so ...
- Kubernetes K8S之固定节点nodeName和nodeSelector调度详解
Kubernetes K8S之固定节点nodeName和nodeSelector调度详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-mas ...
- 喝完可乐桶后程序员回归本源,开源Spring基础内容
周六了,又是摸鱼的一天,今天还有点不在状态,脑瓜子迷迷糊糊的,昨晚出去喝可乐桶喝的脑子到现在都不是很正常(奉劝各位可以自己小酌:450ml威士忌+1L多一点可乐刚刚好,可能是我酒量不好),正好没啥事就 ...
- 第7.3节 Python特色的面向对象设计:协议、多态及鸭子类型
Python是一种多态语言,其表现特征是:对象方法的调用方只管方法是否可调用,不管对象是什么类型,从而屏蔽不同类型对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化. 一. P ...