最近尝试用了下Directx下的Effect框架,作为一初学者初学者,说下为什么我们要使用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框架的使用的更多相关文章

  1. Directx11学习笔记【十四】 使用最新的Effect框架和SDK

    由于之前一直在看directx11龙书学习,因此sdk一直用的Microsoft DirectX SDK (June 2010) 版本,最近在stackoverflow上问dx11相关问题时,一直被大 ...

  2. Directx11学习笔记【十一】 画一个简单的三角形--effect框架的使用

    这里不再介绍effect框架的具体使用,有关effect框架使用可参考http://www.cnblogs.com/zhangbaochong/p/5475961.html 实现的功能依然是画一个简单 ...

  3. 粒子系统与雨的效果 (DirectX11 with Windows SDK)

    前言 最近在学粒子系统,看这之前的<<3D图形编程基础 基于DirectX 11 >>是基于Direct SDK的,而DXSDK微软已经很久没有更新过了并且我学的DX11是用W ...

  4. 【转】HLSL基础

    原文地址http://blog.csdn.net/chpdirect1984/article/details/1911622 目录 前言 1.HLSL入门 1.1什么是着色器 1.2什么是HLSL 1 ...

  5. DirectX11笔记(十二)--Direct3D渲染8--EFFECTS

    原文:DirectX11笔记(十二)--Direct3D渲染8--EFFECTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737 ...

  6. DirectX11笔记(五)--Direct3D渲染1--VERTICES AND INPUT LAYOUTS

    原文:DirectX11笔记(五)--Direct3D渲染1--VERTICES AND INPUT LAYOUTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

  7. 初学tornado之MVC版helloworld

    作者:the5fire | 标签: MVC  tornado  | 发布:2012-08-06 2:41 p.m. 文接上篇,看我一个简单的helloworld,虽然觉得这个框架着实精小,但是实际开发 ...

  8. 跨平台渲染框架尝试 - constant buffer的管理

    1. Preface Constant buffer是我们在编写shader的时候,打交道最多的一种buffer resource了.constant表明了constant buffer中的数据,在一 ...

  9. Jersey RESTful WebService框架学习(一)

    介绍:RESTful (Representation State Transfer) 描述了一个架构样式的网络系统,比如 web 应用程序.它首次出现在 2000 年 Roy Fielding 的博士 ...

随机推荐

  1. Shell简易学习练习

    1.Linux Shell入门 Quiz 1 一个接受命令行参数的shell脚本 任务 编写一个shell脚本1.sh,这个脚本接受一个命令行参数,并把这个参数打印两次到标准输出. 如果输入没有参数输 ...

  2. Gnu Linux下文件的字符编码及转换工具

    /*********************************************************************  * Author  : Samson  * Date   ...

  3. HDU 3277 Marriage Match III(二分+最大流)

    HDU 3277 Marriage Match III 题目链接 题意:n个女孩n个男孩,每一个女孩能够和一些男孩配对,此外还能够和k个随意的男孩配对.然后有些女孩是朋友,满足这个朋友圈里面的人.假设 ...

  4. JavaScript模板引擎

    JavaScript模板引擎实例应用   在之前的一篇名为<移动端基于HTML模板和JSON数据的JavaScript交互>的文章中,我向大家说明了为什么要使用JavaScript模板以及 ...

  5. Egret是一套完整的HTML5游戏开发解决方案

    Egret是一套完整的HTML5游戏开发解决方案.Egret中包含多个工具以及项目.Egret Engine是一个基于TypeScript语言开发的HTML5游戏引擎,该项目在BSD许可证下发布.使用 ...

  6. logstash+ElasticSearch+Kibana VS Splunk

    logstash+ElasticSearch+Kibana VS Splunk 最近帮磊哥移植一套开源的日志管理软件,替代Splunk. Splunk是一个功能强大的日志管理工具,它不仅可以用多种方式 ...

  7. SVN常见问题及解决方案

    . 隐藏文件.svn目录删除了怎么办 Checkout后,工作空间下.svn目录下有大量隐藏文件,占用比较大的空间,他们是工作空间的管理文件,不能删除,如果不小心删除了也不要抓狂,不会影响服务器端的, ...

  8. windows phone 7,sliverlight 下载网页的解析,关于wp7 gb2312编码

    原文:windows phone 7,sliverlight 下载网页的解析,关于wp7 gb2312编码 关于silverlight和wp7(windows phone 7)是默认不支持gb2312 ...

  9. js中 正則表達式

    正則表達式使用具体解释 简单介绍 简单的说,正則表達式是一种能够用于模式匹配和替换的强有力的工具.其作用例如以下: 測试字符串的某个模式.比如,能够对一个输入字符串进行測试,看在该字符串是否存在一个电 ...

  10. WPF-21:WPF实现仿安卓的图案密码键盘(初级)

    希望大家有这方面好的代码给提供下,谢谢了! 想用C#做一个和手机上一样的图形密码键盘,貌似这方面资料比较少,虽然winphone手机上也有但是网上也没有这方面的代码.只好用常规的思维去实现一下,当然是 ...