vertex shader(2)
一次只有一个vertex shader是活跃的。你可以有多个vertex shader,如果一个物体特殊的变换或者灯光,你可以选择合适的vertex shader来完成这个任务。
你可能想使用vertex shaders在每个物体或每个网格上,例如,十个网格,你可以使用十个不同的vertex shader,但那样可能会harm你的游戏的运行。
每个vertex shader-driven程序必须通过下面的步骤运行:
1。检查你的设备是否支持vertex shader。 (在direct X9以后已经不需要了)
2。用D3DVSD_* 宏声明vertex shader,用于将顶点缓冲(vertex buffer streams)映射(map)到输入寄存器(input register)。
3。用SetVertexShaderConstant()设置顶点着色器的常量寄存器。
4。用D3DXAssembleShader*()编译事先写的顶点着色器。
5。用CreateVertexShader()创建一个顶点着色器句柄。
6。用SetVertexShader()为一个要特效化的物体设置顶点着色器。
7。用DeleteVertexShader()删除顶点着色器。
由于第一步在directX 9以后就不需要了,所以这里省略它。
以下实现均对应于上述步骤。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
2。声明顶点着色器。
在使用一个顶点着色器之前必须声明它。这个声明可以被称作一个静态的外部接口。
float c[] = {0.0f,0.5f,1.0f,2.0f};
DWORD dwDesc10[] = {
D3DVSD_STREAM(),
D3DVSD_REG(,D3DVSDT_FLOAT3), //input register v0
D3DVSD_REG(,D3DVSDT_D3DCOLOR), //input register v5
// set a few constants
D3DVSD_CONST(,),
*(DWORD*)&c[],
*(DWORD*)&c[],
*(DWORD*)&c[],
*(DWORD*)&c[],
D3DVSD_END()
};
这个顶点着色器声明用D3DVSD_STREAM(0)设置数据流0。之后,通过使用这个声明,SetStreamSource()绑定一个顶点缓冲区到设备数据流。
你必须声明哪一个输入顶点属性或输入顶点数据被映射到哪一个输入寄存器。D3DVSD_REG从顶点流中绑定一个单个的顶点寄存器到一个顶点元素。在我们这个声明的例子中,D3DVSD_FLOAT3值应该被放在第一个输入寄存器,而D3DVSD_D3DCOLOR颜色值应该被放在第六个输入寄存器。例如,位置数据可以被输入寄存器0(v0)用D3DVSD_REG(0,D3DVSDT_FLOAT3)处理,法线数据可以被输入寄存器3(v3)用D3DVSD_REG(3,D3DVSDT_FLOAT3)处理。
注意,除非你想使用N-Patches,这需要位置数据在v0,法线数据在v3,否则,开发者可以自由定义顶点数据输入到的寄存器的映射。
相比之下,在固定管线中,顶点数据输入到特定寄存器的映射是固定的。
D3DVSD_CONST将常量值载入到顶点着色器的常量寄存器。第一个参数是常量数组开始填充数据的开始位置,可能的值范围是0-95(in the case of the RADEON 8500, from 0-191.)我们在0处开始。第二个参数是要载入的常量向量的数目,如果你要载入一个4x4矩阵(也就是4个向量),可以如下载入:
float c[] = (0.0f, 0.5f, 1.0f, 2.0f,
0.0f, 0.5f, 1.0f, 2.0f,
0.0f, 0.5f, 1.0f, 2.0f,
0.0f, 0.5f, 1.0f, 2.0f);
D3DVSD_CONST(, ), *(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],
*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],
*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],
*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],*(DWORD*)&c[],
D3DVSD_END生成一个END,标志顶点着色器的结束。
D3DVSD_END()
3。SetVertexShaderConstant() 设置顶点着色器常量寄存器
你可以用SetVertexShaderConstant()填充顶点着色器常量寄存器,用GetVertexShaderConstant()得到这些寄存器中的值。
SetVertexShaderConstant()的声明如下:
HRESULT SetVertexShaderConstant(
DWORD Register,
CONST void* pConstantData,
DWORD ConstantCount);
设置顶点着色器常量:
m_pd3dDevice->SetVertexShaderConstant( , &vZero, );
m_pd3dDevice->SetVertexShaderConstant( , &vOne, );
m_pd3dDevice->SetVertexShaderConstant( , &vWeight, );
m_pd3dDevice->SetVertexShaderConstant( , &matTranspose, );
m_pd3dDevice->SetVertexShaderConstant( , &matCameraTranspose, );
m_pd3dDevice->SetVertexShaderConstant( , &matViewTranspose, );
m_pd3dDevice->SetVertexShaderConstant( , &fLight, );
m_pd3dDevice->SetVertexShaderConstant( , &fDiffuse, );
m_pd3dDevice->SetVertexShaderConstant( , &fAmbient, );
m_pd3dDevice->SetVertexShaderConstant( , &fFog, );
m_pd3dDevice->SetVertexShaderConstant( , &fCaustics, );
m_pd3dDevice->SetVertexShaderConstant( , &matProjTranspose, );
如之前所述,至少有96个常量寄存器可以被填充。SetVertexShaderConstant()第一个参数为寄存器的索引,最后一个参数为常量的数目。比如,matViewTranspose将被载入到
寄存器12,载入数目为4个,寄存器16-19未被使用,fLight被载入到寄存器20,载入数目为1. 那么 ,用在着色器声明中的D3DVSD_CONST和SetVertexShaderConstant()有什么不同呢?
D3DVSD_CONST只能是用仅仅一次,而SetVertexShaderConstant()可以在每次DrawPrimitive*()之前调用。
待续.....
vertex shader(2)的更多相关文章
- vertex shader(4)
Swizzling and Masking 如果你使用输入.常量.临时寄存器作为源寄存器,你可以彼此独立地swizzle .x,.y,.z,.w值.如果你使用输出.临时寄存器作为目标寄存器,你可以把. ...
- vertex shader(3)
之前我们学习了如何声明顶点着色器.如何设置常量寄存器中的常量.接下来我们学习如何写和编译一个顶点着色器程序. 在我们编译一个顶点着色器之前,首先需要写一个. 有17种不同的指令(instruction ...
- vertex shader(1)
Vertex shader Architecture: 所有在vertex shader中的数据都用128-bit的quad-floats表示(4x32-bit). vertex shader线性地执 ...
- 【Unity Shader实战】卡通风格的Shader(二)
写在前面 本系列其他文章: 卡通风格的Shader(一) 好久没写博客了,一定是因为课程作业比较多,一定不是因为我懒,恩恩. 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface ...
- 【Unity Shader实战】卡通风格的Shader(一)
写在前面 本系列其他文章: 卡通风格的Shader(二) 呜,其实很早就看到了这类Shader,实现方法很多,效果也有些许不一样.从这篇开始,陆续学习一下接触到的卡通类型Shader的编写. 本篇的最 ...
- 学习笔记:GLSL Core Tutorial – Vertex Shader(内置变量说明)
1.每个Vertex Shader都有用户定义的输入属性,例如:位置,法线向量和纹理坐标等.Vertex Shaders也接收一致变量(uniform variables). uniform vari ...
- 基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)
在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数.在本文中,我将演示一下如何编写自己的shader,同时, ...
- Unity Shader (三)Surface Shader机制
转自:http://blog.csdn.net/candycat1992/article/details/39994049 写在前面 一直以来,Unity Surface Shader背后的机制一直是 ...
- Unity Shader (一)ShaderLab 语法
一.什么是Shader Shader(着色器):是可以在GPU上运行的一段程序,通过Shader可以进行一些渲染相关的设置. 二.什么是ShaderLab 目前面向GPU的编程有三种高级图像语言:HL ...
随机推荐
- C的动态链表建立
运用到的函数为: 动态内存分配函数malloc() 比如:char *name=(char *)malloc(20); 相当与c++的new关键字 动态内存释放函数free ...
- {Reship}{Meanshift}Mean Shift Tracking: 2000-2012回顾
Mean Shift跟踪从 2000年被提出至今已经经历了十余个年头,从被大量灌水到如今不屑被拿来作为比较算法,经历了辉煌高潮的 Mean-Shift based Tracking正在慢慢淡出主流tr ...
- direct2D图片处理
转自:http://blog.csdn.net/augusdi/article/details/9040177 Using Bitmap Brushes Direct2D 中的图片处理增加了很多的灵 ...
- 关于浏览器和IIS基础的简单理解
浏览器 输入域名或者IP地址,按回车访问后:发生了什么??IIS是如何工作的?为什么能这么工作?? 1 浏览器和IIS 分别是两个应用程序:浏览器访问网址实际就是 两个应用程序的数据交互往来: ...
- 关于angular.extend的用法
ng中的ng-function中会有些方法,便于我们进行js代码的编写 关于angular.extend(dst, src);通过从src对象复制所有属性到dst来扩展目标对象dst.你可以指定多个s ...
- 框架(yii和thinkphp)中实例化php内置或者扩展中的对象问题
将php原生语句实例化SphinxClient对象移植到yii2框架中报错 原生语句中这样写: $s = new SphinxClient(); 框架中应该加入反斜杠,这样写: $s = new \S ...
- 常见企业IT支撑【2、samba共享文件夹】
samba共享文件夹,较Window自带的比较:开源,安全 建议安装samba4,兼容性好 1.安装samba #yum -y install samba4 samba4-client 2.备份sam ...
- GOF23设计模式之状态模式(state)
一.状态模式概述 用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题. 结构: (1)Context 环境类 环境类中维护一个 State 对象,它定义了当前的状态. (2)State ...
- FU-A 分包
FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法 [原创] RFC3984是H.264的baseline码流在RTP方式下传输的规范,这里只讨论FU-A分包方式,以及从RTP包 ...
- Java-Runoob-高级课程:Java 8 新特性
ylbtech-Java-Runoob-高级课程:Java 8 新特性 1.返回顶部 1. Java 8 新特性 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本. Or ...