热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

1.4怎么用HLSL着色器

1.4怎么用HLSL着色器应用程序中对HLSL着色器的使用分为以下步骤:1.加载(称为编译更为妥当)着色器代码;2.创

1.4怎么用HLSL着色器

应用程序中对HLSL着色器的使用分为以下步骤:

1. 加载(称为编译更为妥当)着色器代码;

2. 创建(顶点/像素)着色器;

3. 对着色器中的变量进行赋值,完成应用程序和着色器之间的通信。

4. 把着色器设定到渲染管道中;

本例使用的着色器是一个顶点着色器,因此我们将通过顶点着色器的使用来讲解着色器的使用过程,像素着色器的使用过程与此大同小异,二者之间仅有些微差别。

1.4.1声明全局变量

IDirect3DVertexShader9* BasicShader = 0; //顶点着色器指针

ID3DXConstantTable* BasicConstTable = 0; //常量表指针

D3DXHANDLE WVPMatrixHandle = 0;

D3DXHANDLE ColorHandle = 0;

ID3DXMesh* Teapot = 0; //指向程序中D3D茶壶模型的指针

1.4.2编译着色器

通过D3DXCompileShaderFromFile函数从应用程序外部的文本文件BasicHLSL.txt中编译一个着色器:

//编译后的着色器代码将被放在一个buffer中,可以通过ID3DXBuffer接口对其进行访问,之后的着色器将从这里创建

ID3DXBuffer* shaderBuffer = 0;

//用于接受错误信息

ID3DXBuffer* errorBuffer = 0;

//编译着色器代码

D3DXCompileShaderFromFile("BasicHLSL.txt", //着色器代码文件名

0,

0,

"SetColor", //入口函数名称

"vs_1_1", //顶点着色器版本号

D3DXSHADER_DEBUG,// Debug模式编译

&shaderBuffer, //指向编译后的着色器代码的指针

&errorBuffer,

&BasicConstTable); //常量表指针

1.4.3创建着色器

应用程序通过CreateVertexShader创建一个顶点着色器,注意使用了上一步得到的shaderBuffer:

g_pd3dDevice->CreateVertexShader((DWORD*)shaderBuffer->GetBufferPointer(), &BasicShader);

1.4.3对着色器中的变量进行赋值

1.3.4节说到着色器的全局变量在应用程序中赋值而在着色器程序中使用,这是应用程序和着色器通信的关键所在,这里就具体说明赋值过程。

着色器中的全局变量在编译后都被放在一个叫常量表的结构中,我们可以使用ID3DXConstantTable接口对其进行访问,参照1.4.1中编译着色器函数D3DXCompileShaderFromFile的最后一个参数,该参数即返回了指向常量表的指针。

对一个着色器中变量进行赋值的步骤如下:

1. 通过变量名称得到指向着色器变量的句柄;

还记得在BasicHLSL.x着色器文件中我们声明的两个全局变量吗:

matrix WVPMatrix;

vector color;

我们在应用程序中相应的声明两个句柄:

D3DXHANDLE WVPMatrixHandle = 0;

D3DXHANDLE ColorHandle = 0;

然后通过变量名得到分别得到对应的两个句柄:

WVPMatrixHandle = BasicConstTable->GetConstantByName(0, "WVPMatrix");

ColorHandle = BasicConstTable->GetConstantByName(0, "color");

2. 通过句柄对着色器变量进行赋值;

我们可以先设置各变量为默认值:

BasicConstTable->SetDefaults(g_pd3dDevice);

之后,可以使用ID3DXConstantTable::SetXXX函数对各个变量进行赋值:

HRESULT SetXXX(

LPDIRECT3DDEVICE9 pDevice,

D3DXHANDLE hConstant,

XXX value

);

其中XXX代表变量类型,例如Matrix类型的变量就要使用SetMatrix函数赋值,而Vector类型的则要使用SetVector来赋值。

1.4.4把着色器设定到渲染管道中

这里我们使用SetVertexShader方法把顶点着色器设定到渲染管道中:

g_pd3dDevice->SetVertexShader(BasicShader);

1.4.5整个渲染过程如下

在渲染过程中,我们设定顶点的变换坐标和颜色值,渲染代码如下:

g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,

D3DCOLOR_XRGB(153,153,153), 1.0f, 0 );

//开始渲染

g_pd3dDevice->BeginScene();

//得到世界矩阵、观察矩阵和投影矩阵

D3DXMATRIX matWorld, matView, matProj;

g_pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld);

g_pd3dDevice->GetTransform(D3DTS_VIEW, &matView);

g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProj);

D3DXMATRIX matWVP = matWorld * matView * matProj;

//通过句柄对着色器中的WVPMatrix变量进行赋值

BasicConstTable->SetMatrix(g_pd3dDevice, WVPMatrixHandle, &matWVP);

D3DXVECTOR4 color(1.0f, 1.0f, 0.0f, 1.0f);

//通过句柄对着色器中的color变量进行赋值,这里我们赋值为黄色

BasicConstTable->SetVector(g_pd3dDevice, ColorHandle, &color);

//把顶点着色器设定到渲染管道中

g_pd3dDevice->SetVertexShader(BasicShader);

//绘制模型子集

Teapot->DrawSubset(0);

//渲染完毕

g_pd3dDevice->EndScene();

g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

编译运行程序,运行效果如图1.2所示,这里我们将顶点颜色设置为黄色,如果读者在渲染过程中不断变换对着色器变量color的赋值,你将会得到一个色彩不断变幻的D3D茶壶。

D3DXVECTOR4 color(1.0f, 1.0f, 0.0f, 1.0f); //读者可以尝试改变颜色值

BasicConstTable->SetVector(g_pd3dDevice, ColorHandle, &color);

1.2 着色器效果



推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
  • 本文介绍了在PostgreSQL中批量导入数据时的优化方法。包括使用unlogged表、删除重建索引、删除重建外键、禁用触发器、使用COPY方法、批量插入等。同时还提到了一些参数优化的注意事项,如设置effective_cache_size、shared_buffer等,并强调了在导入大量数据后使用analyze命令重新收集统计信息的重要性。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
author-avatar
夜的泪2502877077
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有