游戏开发基础(十七)

原创 2012年03月29日 12:39:15

第十七章

顶点着色器(vertex shader)是一段运行在图形卡GPU中的程序,可取代固定功能流水线中的变换和光照环节(当然,不是绝对的,在硬件部支持顶点着色器的情况下,Direct3D运行时就会用软件运算方式来模拟顶点着色器).

顶点着色器其实就是用HLSL语言编写的一段定制程序,这样在可实现的图形效果上就获得了很大的灵活性,例,借助顶点着色器,可使用任何可在顶点着色器中实现的光照算法

使用顶点数据结构也更加灵活,而且可编程流水线中的顶点结构可以包含比固定功能流水线更加丰富的数据

顶点着色器是一项比较新的特性,目前许多图形卡尚不支持该特性,尤其伴随DirectX 9.0发布的那些较新的顶点着色器版本,可通过检查D3DCAPS9结构的成员VertexShaderVersion并与宏D3DVS_VERSION进行比较,来检测图形卡是否支持某个顶点着色器版本

检测过程:

 //if the device's supported version is less than version 2.0
 if (caps.VertexShaderVersion < D3DVS_VERSION(2,0))//主次版本号
  // then vertex shader version 2.0 is not supported on this device
目前D3DXCompileShaderFromFile函数支持的顶点着色器版本为1.1,2.0和3.0

顶点声明:
在可编程流水线中,顶点结构甚至可以包含那些超出FVF描述能力的数据,因此,通常使用能力更强,功能更丰富的顶点声明(vertex declaration)

在可编程流水线中,如果顶点结构可用FVF来描述,仍可使用,但是,这是为了表示方便,实际上可编程流水线内部,FVF最终被转换为顶点声明。

顶点声明描述为一个D3DVERTEXELEMENT9类型的结构数组,该结构数组中的每个元素都描述了顶点结构的一个分量,所以,如果顶点结构具有3个分量(比如位置,法向量,颜色),则相应的顶点声明级可用一个维数为3的D3DVERTEXELEMENT9类型的结构数组来描述

typedef struct D3DVERTEXELEMENT9
{
 WORD Stream;//指定与顶点分量关联的数据流
 WORD Offset;//自顶点数据起始点到特定数据类型相关的数据的字节偏移量
 BYTE Type;//指定数据类型,该参数可取枚举类型D3DDECLTYPE的任何一个成员,D3DDECLTYPE_FLOAT1浮点类型标    //量,D3DDECLTYPE_FLOAT2浮点类型的2D向量,D3DDECLTYPE_FLOAT3浮点类型的3D向量,D3DDECLTYPE_FLOAT4浮点   //类型的4D向量,D3DDECLTYPE_D3DCOLOR一个被扩展为RGBA浮点类型颜色向量(r,g,b,a)的D3DCOLOR类型,其颜色  //向量的每个分量都被规范化至区间[0,1]内
 BYTE Method;//指定了网格化(tesselation)方法,该章默认使用D3DDECLMETHOD_DEFAULT来指定
 BYTE Usage;//指定了顶点分量的用途,例,即,某一个分量是作为位置向量,法向量还是纹理向量等,标识符取自枚举类    //型D3DDECLUSAHE;
 BYTE UsageIndex;//标识具有同用法的多个顶点分量,用法索引(usage index)是一个位于区间[0,15]内的整数,例,有3   //个顶点分量的用法都为D3DDECLUSAGE_NORMAL,则可按序将这3个顶点分量的用法索引分别指定为      //0,1,2,按照这种方式,可通过用法索引表示每个特定的法向量
}D3DVERTEXELEMENT9,*LPD3DVERTEXELEMENT9;

typedef enum D3DDECLUSAGE
{
 D3DDECLUSAGE_POSITION     = 0,//如果一个顶点声明中具有该标识,则表明该顶点已经经过了变换,并指示图形卡不要     //将该顶点输送到顶点处理环节中(变换和光照处理)
 D3DDECLUSAGE_BLENDWEIGHT  = 1,
 D3DDECLUSAGE_BLENDINDICES = 2,
 D3DDECLUSAGE_NORMAL       = 3,
 D3DDECLUSAGE_PSIZE        = 4,//用于指定顶点的点尺寸,该类型主要用于点精灵(point sprite),这样对每个尺寸进行     //控制
 D3DDECLUSAGE_TEXCOORD     = 5,

 D3DDECLUSAGE_TANGENT      = 6,
 D3DDECLUSAGE_BINORMAL     = 7,
 D3DDECLUSAGE_TESSFACTOR   = 8,
 D3DDECLUSAGE_POSITIONT    = 9,
 D3DDECLUSAGE_COLOR        = 10,
 D3DDECLUSAGE_FOG          = 11,
 D3DDECLUSAGE_DEPTH        = 12,
 D3DDECLUSAGE_SAMPLE       = 13
}D3DDECLUSAGE,*LPD3DECLUSAGE;

按照这种方式,就可通过用法索引表示每个特定的法向量

例:要描述的顶点格式包含了一个位置向量和3个法向量,则相应的顶点声明可指定为
 D3DVERTEXELEMENT9 decl{} =
 {
 {0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
 {0,12,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0},
 {0,24,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,1},
 {0,36,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,2},
 D3DDECL_END()//初始化D3DVERTEXELEMENT9数组中的最后一个顶点元素
 };


顶点声明的创建: 将顶点声明描述为一个D3DVERTEXELEMENT9类型的数组,就可用如下方法获得指向接口IDirect3DVertexDeclaration9指针:
HRESULT CreateVertexDeclaration(
    CONST D3DVERTEXELEMENT9* pVertexElements,//指向一个D3DVERTEXELEMENT9类型的结构数组          //描述了要创建的顶点声明
    IDirect3DVertexDeclaration9** ppDecl//返回指向所创建的IDirect3DVertexDeclaration9接        //口指针
    );

例 :
 IDirect3DVertexDeclaration9* _decl = 0 ;
 hr = _device->CreateVertexDeclaration(decl,&_decl);

灵活顶点格式是一项很有用的特性,在可编程流水线内部它将被转换为顶点声明,所以,直接使用顶点声明时,无需调用:
 Device->SetFVF(fvf);
而只是调用:
 Device->SetVertexDeclaration(_decl);//_decl是一个指向接口IDirect3DVertexDeclaration的指针

需要一种方式来定义从顶点声明中的元素到顶点着色器的输入结构的数据成员的映射,在输入结构中通过为每个数据成员指定一种语义(:usage -type[usage-index])来定义这种映射,该语义通过用法类型和用法索引来标识顶点声明中的每个元素,由数据成员的语义所标识的那个顶点元素就被映射到该数据成员的那个元素
例:与前面提到的那个顶点声明对用的输入结构为:
struct VS_INPUT
{
 vector position:POSITION;
 vector normal  :NORMAL0;
 vector facenormal1  :NORMAL1;
 vector facenormal2  :NORMAL2;
};

如果略去了用法索引,就意味着该索引为0,例,POSITION含义与POSITION0完全相同

顶点着色器支持的输入用法包括:
#POSITION[n]位置
#BLENDWEIGHTS[n]位置融合权值(blend weights)
#BLENDINDICES[n]融合索引(blend indices)
#NORMAL[n]法向量
#PSIZE[n]顶点的点尺寸
#DIFFUSE[n]漫反射颜色
#SPECULAR[n]高光颜色(specular color)
#TEXCOORD[n]纹理坐标
#TANGENT[n]切向量(tangent vector)
#BINORMAL[n]副法向量(binormal vector)
#TESSFACTOR[n]网格化因子(tessellation factor)
n为一个可选整数,但必须取自区间[0,15]内

对于输出结构,必须指定每个成员的用途,例如,该数据成员应看作位置向量,颜色向量,还是纹理坐标等,对于各数据成员的用途,图形卡无从知晓,需要显示指定,这种指定也是在语义层次实现,例:
 struct VS_OUTPUT
 {
  vector position :POSITION;
  vector diffuse :COLOR0;
  vector specular :COLOR1;
 };

顶点着色器支持的输出用法包括:
#POSITION[n]位置
#PSIZE[n]顶点的点尺寸
#FOG[n]雾融合值(fog blend value)
#COLOR[n]顶点颜色,注意可输出多个顶点颜色,这些颜色混合在一起生成最终颜色
#TEXCOORD[n]顶点纹理坐标,注意,可能输出多个顶点纹理坐标
n为一个可选整数,但必须取自区间[0,15]内


使用顶点着色器的步骤:
1 编写顶点着色器程序,并进行编译
2 创建一个IDirect3DVertexShader9接口的对象,以表示基于所编译的着色器代码的顶点着色器
3 用IDirect3DDevice9::SetVertexShader方法启用顶点着色器

当顶点着色器使用完毕后,必须进行销毁


该方法获取IDirect3DVertexShader9接口指针,该接口代表一个顶点着色器
HRESULT IDirect3DDevice9::CreateVertexShader(
         const DWORD *pFunction,//指向经过编译的代码指针,
         IDirect3DVertexShader9** ppShader//指向IDirect3DVertexShader接口的指针
         );

例;变量shader是一个指向ID3DXBuffer接口指针,则获取指向IDirect3DVertexShader9接口指针:
 IDirect3DVertexShader9* ToonShader = 0 ;
 hr = Device->CreateVertexShader(
     (DWORD*)Shader->GetBufferPointer(),
     &ToonShader);

D3DXCompileShaderFromFile函数能够返回经过编译的着色器代码(对应上面的shader)

该方法启用顶点着色器
HRESULT IDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9 * pShader);
该方法接收一个单个参数,可将一个指向希望被启用的顶点着色器的指针赋给该参数
例:
 Device->SetVertexShader(ToonShader);

IDirect3DVertexShader9在使用完毕后,必须调用其自身的Release来释放资源
例:
 d3d::Release<IDirect3DVertexShader9*>(ToonShader);

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

游戏开发笔记十七 游戏基础算法(一) 游戏随机系统初步

每一款游戏,或大或小,都是由一段段默默无闻的算法在支撑着他们的运作,我们不能只欣赏绚丽的游戏成品表现在我们面前的华丽与光鲜,还要看到那些支撑在华丽与光鲜背后的,鲜为人知的算法。 ...

【Visual C++】游戏开发笔记十七 游戏基础算法(一) 游戏随机系统初步

本系列文章由zhmxy555编写,转载请注明出处。http://blog.csdn.net/zhmxy555/article/details/7468011 作者:毛星云    邮箱: happ...
  • ybhjx
  • ybhjx
  • 2016-01-08 17:20
  • 182

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

【Visual C++】游戏开发笔记十七 游戏基础算法(一) 游戏随机系统初步

本系列文章由zhmxy555编写,转载请注明出处。http://blog.csdn.net/zhmxy555/article/details/7468011作者:毛星云    邮箱: happylif...

Android游戏开发之数据库SQLite 详细介绍(十七) .

雨松MOMO带你走进游戏开发的世界之数据库SQLite 详细介绍 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xy...

Android游戏开发之旅(十七) 图像渐变特效

在Android游戏开发中我们不免要涉及到一些图形特效处理,今天主要看下Android平台下实现渐变效果。在 android.graphics中我们可以找到有关Gradient字样的类,比如Linea...

【iOS-Cocos2d游戏开发之十七】灵活使用精灵可视区域(TextureRect)与锚点(anchorPoint),并结合可视区域与锚点制作进度条!

李华明Himi 原创,转载务必在明显处注明:转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/501.html      今天...

【iOS-Cocos2d游戏开发之十七】灵活使用精灵可视区域(TextureRect)与锚点(anchorPoint),并结合可视区域与锚点制作进度条!

Himi  原创, 欢迎转载,转载请在明显处注明! 谢谢。       原文地址:http://blog.csdn.net/xiaominghimi/...
  • Jerke
  • Jerke
  • 2012-02-21 15:51
  • 183

android游戏开发框架libgdx的使用(十七)—TiledMap中角色的行动路径

分享了一些素材,有兴趣的朋友可以看看:http://www.cnblogs.com/htynkn/archive/2012/01/19/game_resource.html 前些日子的文章介绍了ti...

Android游戏开发之数据库SQLite 详细介绍(十七)

带你走进游戏开发的世界之数据库SQLite 详细介绍 数据库SQLite介绍             数据库最经典的四个操作 添加、删除、修改、查找,在处理大量数据的时候使用数据库可以帮我...

unity3D游戏开发十七之NGUI四

接下来我们讲解下UIGrid,UIGrid是用来轻松的排列众多widget到固定大小格子的脚本。 编辑时和运行时都可以使用。如果想使用可变的格子单元大小,你可以使用UITable。
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)