【转】Directx11 HelloWorld之HLSL的Effect框架的使用
首先Effect最大好处的就是简单,使得编写Shader绘制的程序工作量大大下降。如果不用Effect框架,那么一个个Vertex Shader,Geometry Shader和Pixel Shader都要一遍遍的先用D3DX11CompileFromFile得到二进制代码,再分别调CreateVertexShader, CreateGeometryShader和CreatePixelShader等创建ID3D11VertexShader,ID3D11GeometryShader,ID3D11PixelShader等。
相比之下使用Effect框架的话,在用D3DX11CompileFromFile得到二进制代码后,只需要再调用D3DX11CreateEffectFromMemory得到ID3D11Effect接口便可。
第二个好处是Effect框架下,Directx中的变量和HLSL中的变量绑定逻辑比较清晰(也可以说简单)。之前的日志说过在不用Effect框架下,HLSL中的变量和Directx应用中的变量的绑定是根据变量的类型和顺序等来绑定的,这种隐式的绑定相当容易出错。而且还要考虑Global Variable,Constant Buffer等各种类型。Constant Buffer可能是不同的寄存器中,它也有着一套它自己的变量的更新规则等等。这些都相当的麻烦。而在Effect框架中,一切绑定通过GetVariableByName(),这使得逻辑非常的清晰简单。
当然还有可能有其他的好处坏处,留着在慢慢发掘。
下面记录下如何使用Directx的Effect框架。
在Dirext11中,Effect已经被单独划分出来了。要使用Effect框架,我们要引用相应的静态库。
首先要在Directx的SDk的安装目录下找到Samples/C++/Effect11,编译目录下的工程,在相应的Samples/C++/Effect11/Debug目录下找到Effects11这个静态库,拷贝这个静态库到自己工程的工作目录下,最后在自己项目中的Linker->Input->Additional Dependencies中输入Effects11.lib,表示要引用这个静态库。这就OK了。
然后再代码中加入#include <d3dx11effect.h>表示引用这个头文件。
下面从代码上说下如何在程序中使用Effect框架的几个基本的步骤,这里我们只是绘制几个简单的箱子。
先看HLSL代码:
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
cbuffer WorldConstantBuffer: register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul( Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Color = Color;
return output;
}
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( VS_OUTPUT input ) : SV_Target
{
return input.Color;
}
technique11 BasicTech
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0,VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader(ps_4_0,PS() ) );
}
}
基本和非Effect框架一样,只是多了个
technique11 BasicTech
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0,VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader(ps_4_0,PS() ) );
}
}
Technique把pass包装起来,pass把渲染管道里面所有需要用到的vertex,geometry,pixel包装起来。
看完HLSL代码,再来看看在Direct11中如何使用它们。第一步是在Direct11中先用D3DX11CompileFromFile()编译HLSL代码,再用D3DX11CreateEffectFromMemory生成Effect的接口。
HRESULT Box::BuildFX()
{
HRESULT hr=S_OK;
ID3DBlob *pBblob=NULL;
ID3DBlob *pErrorBlob=NULL;
DWORD shaderFlags=D3DCOMPILE_ENABLE_STRICTNESS;
hr=D3DX11CompileFromFile(L"Cube.fx",NULL,NULL,NULL,"fx_5_0",shaderFlags,0,NULL,&pBblob,&pErrorBlob,NULL);
if(FAILED(hr))
{
……
}
D3DX11CreateEffectFromMemory(pBblob->GetBufferPointer(),pBblob->GetBufferSize(),0,m_pDevice,&m_pFX);
……
return hr;
}
值得注意的是D3DX11CompileFromFile()中的"fx_5_0",在Directx11中一定要用"fx_5_0",这个是不向下兼容的,不能用"fx_4_0"及之前版本。
在得到Effect框架接口后,我们就要绑定HLSL和Directx中的相关变量
HRESULT Box::BuildFX()
{
HRESULT hr=S_OK;
ID3DBlob *pBblob=NULL;
ID3DBlob *pErrorBlob=NULL;
DWORD shaderFlags=D3DCOMPILE_ENABLE_STRICTNESS;
hr=D3DX11CompileFromFile(L"Cube.fx",NULL,NULL,NULL,"fx_5_0",shaderFlags,0,NULL,&pBblob,&pErrorBlob,NULL);
if(FAILED(hr))
{
if(pErrorBlob->GetBufferPointer())
{
char* errorMes=(char*)pErrorBlob->GetBufferPointer();
//printf(errorMes);
std::cout<<errorMes<<std::endl;
return E_FAIL;
}
}
IFR(D3DX11CreateEffectFromMemory(pBblob->GetBufferPointer(),pBblob->GetBufferSize(),0,m_pDevice,&m_pFX));
m_pTech=m_pFX->GetTechniqueByName("BasicTech");
m_pWorldMatVar=m_pFX->GetVariableByName("World")->AsMatrix();
m_pViewMatVar=m_pFX->GetVariableByName("View")->AsMatrix();
m_pProjMatVar=m_pFX->GetVariableByName("Projection")->AsMatrix();
return hr;
}
上面几个变量的类型分别是ID3DX11Effect *m_pFX;
ID3DX11EffectTechnique *m_pTech;
ID3DX11EffectMatrixVariable *m_pWorldMatVar;
ID3DX11EffectMatrixVariable *m_pViewMatVar;
ID3DX11EffectMatrixVariable *m_pProjMatVar;
最后我们要为顶点创建顶点的格式:ID3D11InputLayout。
HRESULT Box::BuildInputLayout()
{
HRESULT hr=S_OK;
// Define the input layout
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 );
// Create the input layout
D3DX11_PASS_DESC passDesc;
m_pTech->GetPassByIndex(0)->GetDesc(&passDesc);
IFR( m_pDevice->CreateInputLayout( layout,numElements,passDesc.pIAInputSignature,passDesc.IAInputSignatureSize, &m_pInputLayout ) );
// Set the input layout
m_pContext->IASetInputLayout( m_pInputLayout );
return hr;
}
初始化的工作完成后我们就可以渲染了。先是通过SetMatrix等函数设置HLSL中相应变量的值。然后再遍历technique中所有的pass,通过Apply调用相应pass的shader状态。
void Box::Render(const float *glMat,D3DXMATRIX* mView,D3DXMATRIX* mProj)
{
m_pWorldMatVar->SetMatrix(glMat);
m_pViewMatVar->SetMatrix( ((float*)mView) );
m_pProjMatVar->SetMatrix( ((float*)mProj) );
D3DX11_TECHNIQUE_DESC techDesc;
m_pTech->GetDesc(&techDesc);
for(int i=0;i<techDesc.Passes;i++)
{
ID3DX11EffectPass *pass=m_pTech->GetPassByIndex(i);
pass->Apply(0,m_pContext);
m_pContext->DrawIndexed( 36, 0, 0 ); // 36 vertices needed for 12 triangles in a triangle list
}
return;
}
这次主要总结下了Effect框架的相关使用问题和主要的步骤。由于Directx11的代码很长,就不一一贴出来了。
【转】Directx11 HelloWorld之HLSL的Effect框架的使用的更多相关文章
- Directx11学习笔记【十四】 使用最新的Effect框架和SDK
由于之前一直在看directx11龙书学习,因此sdk一直用的Microsoft DirectX SDK (June 2010) 版本,最近在stackoverflow上问dx11相关问题时,一直被大 ...
- Directx11学习笔记【十一】 画一个简单的三角形--effect框架的使用
这里不再介绍effect框架的具体使用,有关effect框架使用可参考http://www.cnblogs.com/zhangbaochong/p/5475961.html 实现的功能依然是画一个简单 ...
- 粒子系统与雨的效果 (DirectX11 with Windows SDK)
前言 最近在学粒子系统,看这之前的<<3D图形编程基础 基于DirectX 11 >>是基于Direct SDK的,而DXSDK微软已经很久没有更新过了并且我学的DX11是用W ...
- 【转】HLSL基础
原文地址http://blog.csdn.net/chpdirect1984/article/details/1911622 目录 前言 1.HLSL入门 1.1什么是着色器 1.2什么是HLSL 1 ...
- DirectX11笔记(十二)--Direct3D渲染8--EFFECTS
原文:DirectX11笔记(十二)--Direct3D渲染8--EFFECTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737 ...
- DirectX11笔记(五)--Direct3D渲染1--VERTICES AND INPUT LAYOUTS
原文:DirectX11笔记(五)--Direct3D渲染1--VERTICES AND INPUT LAYOUTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...
- 初学tornado之MVC版helloworld
作者:the5fire | 标签: MVC tornado | 发布:2012-08-06 2:41 p.m. 文接上篇,看我一个简单的helloworld,虽然觉得这个框架着实精小,但是实际开发 ...
- 跨平台渲染框架尝试 - constant buffer的管理
1. Preface Constant buffer是我们在编写shader的时候,打交道最多的一种buffer resource了.constant表明了constant buffer中的数据,在一 ...
- Jersey RESTful WebService框架学习(一)
介绍:RESTful (Representation State Transfer) 描述了一个架构样式的网络系统,比如 web 应用程序.它首次出现在 2000 年 Roy Fielding 的博士 ...
随机推荐
- MSF 离线攻击
MSF 离线攻击 MSF连环攻击在internet上实现是不太现实的,网络中的安全设备(防火墙.入侵检测.入侵防护系统). 实验拓扑如下: 实验说明:安全实验中的包过滤防火墙在测试中使用的是linux ...
- SWT中的多线程(Invalid thread access)
最近在学习swt的东西,遇到一个问题,特转录如下. SWT异常: org.eclipse.swt.SWTException: Invalid thread access 在创建SWT界面的线程之外的线 ...
- codeforces#256DIV2 D题Multiplication Table
题目地址:http://codeforces.com/contest/448/problem/D 当时是依照找规律做的,规律倒是找出来了,可是非常麻烦非常麻烦. . 看到前几名的红名爷们3分钟就过了, ...
- 利用Nginx构建负载均衡server
大家都知道.一个域名相应一个IP地址,而一个WebSite则相应一个IP地址上相应port服务的应用程序(或位置).而大型站点的并发訪问量很大,这些站点是怎样在一台Webserver上实现负载均衡的呢 ...
- 就这样CSDN账号被人盗了??
和往常一样,来到公司后的第一件事情就是看看自己博客.没想到今天一看,小伙伴惊呆了. 莫名其妙地多了这个多不是神马的博文,还好几篇. 这说明CSDN账号也不怎么安全哦,以后小伙伴们要注意了.
- 13、Cocos2dx 3.0三,找一个小游戏开发3.0中间Director :郝梦主,一统江湖
重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27706967 游戏中的基本元素 在曾经文章中,我们具 ...
- uva:10700 - Camel trading(贪婪)
题目:10700 - Camel trading 题目大意:给出一些表达式,表达式由数字和加号乘号组成,数字范围[1,20].这些表达式可能缺少了括号,问这种表达式加上括号后能得到的最大值和最小值. ...
- BZOJ 1269 文本编辑器 Splay
题目大意:维护一个文本编辑器,支持下列操作: 1.将光标移动到某一位置 2.在光标后插入一段字符串 3.删除光标后的一段字符 4.翻转光标后的一段字符 5.输出光标后的一个字符 6.光标-- 7.光标 ...
- 使用Xamarin在Visual Studio中开发Android应用
原文:使用Xamarin在Visual Studio中开发Android应用 本文使用的环境是Windows 8 Visual Studio 2012.2 1.下载Xamarin http://xam ...
- Windows Phone开发(18):变形金刚第九季——变换
原文:Windows Phone开发(18):变形金刚第九季--变换 变换不是一个好理解的概念,不是吓你,它涉及很多有关代数,几何,以及线性代数的知识.怎么?被我的话吓怕了?不用怕,尽管我们未必能够理 ...