博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DirectX11 创建和启用纹理
阅读量:4087 次
发布时间:2019-05-25

本文共 2585 字,大约阅读时间需要 8 分钟。

创建和启用纹理

1. 创建纹理步骤

纹理数据通常是存储在磁盘上的图像文件。我们需要将它读取出来,并载入到一个ID3D11Texture2D对象中(参见D3DX11CreateTextureFromFile)。不过,纹理资源是不能被直接绑定到渲染管线上的;我们需要为纹理创建一个着色器资源视图(ID3D11ShaderResourceView),然后将视图绑定到管线上。

这个过程可分为两步:

1.调用D3DX11CreateTextureFromFile,读取存储在磁盘上的图像文件,创建ID3D11Texture2D对象。

2.调用ID3D11Device::CreateShaderResourceView,为纹理创建对应的着色器资源视图。

这两步也可通过如下D3DX函数一次完成:

HRESULT D3DX11CreateShaderResourceViewFromFile(    ID3D11Device *pDevice,    LPCTSTR pSrcFile,    D3DX11_IMAGE_LOAD_INFO *pLoadInfo,    ID3DX11ThreadPump *pPump,    ID3D11ShaderResourceView **ppShaderResourceView,    HRESULT *pHResult);

1.pDevice:创建纹理时使用的Direct3D设备指针。

2.pSrcFile:所要载入的图像的文件名。

3.pLoadInfo:可选的图像信息;当设为空值时,该函数使用源图像文件信息。例如,我们在这里指定空值,那么源图像的尺寸就是纹理的尺寸;另外,该函数还会生成一个完整的多级渐近纹理链(8.4.2节)。这个默认值很好,因为它所执行的一系列行为通常都是我们想要的。

4.pPump:在一个新的线程中载入资源。如果要在当前的工作线程中载入资源,请将它设为空值。在本书中,这个参数总是设为空值。

5.ppShaderResourceView:返回纹理的着色器资源视图指针。

6.pHResult:当pPump设为空值时,该参数也应设为空值。

注意:有时,我们所说的“纹理”实际上是指“与它关联的着色器资源视图”。例如,我们会说:“将纹理绑定到管线上”,但实际上是指“将它的视图绑定到管线上”。

2. 纹理支持的格式

该函数可以载入以下格式的图像文件:BMP、JPG、PNG、DDS、TIFF、GIF、WMP(参见D3DX11_IMAGE_FILE_FORMAT)。

例如,要从图像文件WoodCrate01.dds创建一个纹理,我们可以编写如下代码:

ID3D11ShaderResourceView* mDiffuseMapSRV;HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,L"WoodCrate01.dds", 0, 0, &mDiffuseMapSRV, 0 ));

3. HLSL纹理定义

在纹理载入之后,我们需要把它指定给一个effect变量,使像素着色器中的代码可以访问到这个资源。在.fx文件中,2D纹理对象由Texture2D类型表示;例如,我们可以在effect文件中声明一个纹理变量:

// 非数值对象不能放在常量缓冲区中Texture2D gDiffuseMap;

如注释所述:“非数值对象不能放在常量缓冲区中”,纹理对象必须放在常量缓冲区之外。

4. 如何在程序中获取与更新HLSL纹理

我们可以在C++应用程序代码中获取这个Texture2D对象的指针(它是一个着色器资源变量):

ID3D11EffectShaderResourceVariable* mfxDiffuseMapVar;mfxDiffuseMapVar = mFX->GetVariableByName("gDiffuseMap")->AsShaderResource();

在我们获取Texture2D对象的指针之后,可以通过如下C++接口更新纹理对象:

// Set the C++ texture resource view to the effect texture variable.mfxDiffuseMapVar->SetResource(mDiffuseMapSRV);

与其他的effect效果变量相同,当我们在绘图调用之间更新效果变量时,一定要调用Apply方法:

// set crate texturemfxDiffuseMapVar->SetResource(mCrateMapSRV);pass->Apply(0, md3dImmediateContext);DrawCrate();// set grass texturemfxDiffuseMapVar->SetResource(mGrassMapSRV);pass->Apply(0, md3dImmediateContext);DrawGrass();// set brick texturemfxDiffuseMapVar->SetResource(mBrickMapSRV);pass->Apply(0, md3dImmediateContext);DrawBricks();

使用纹理贴图集可以在一次绘制调用中绘制更多的几何体,所以可以提高性能。例如,我们使用了如上一节图所示的包含条板、草地、砖墙纹理的贴图集,通过调整纹理坐标在每个对象上映射不同的子纹理,我们就可以在一次绘制调用中绘制整个几何体(假设每个对象都没有需要改变的其他参数):

//  set texture atlasmfxDiffuseMap ->SetResource(mAtlasSRV);pass ->Apply(0, md3dImmediateContext);DrawCrateGrassAndBricks();

调用绘制需要耗费资源,使用这个技术可以使绘制调用减到最少。

注意:纹理资源实际上可以由任何着色器(顶点、几何或像素)使用。但是目前我们只在像素着色器中使用纹理。如前所述,纹理本质上是一种特殊的数组,所以不难想象,这些数组数据也可以在顶点着色器和几何着色器中使用。

转载地址:http://fpyii.baihongyu.com/

你可能感兴趣的文章
这些网站有一些嵌入式面试题合集
查看>>
我觉得刷题是有必要的,不然小心实际被问的时候懵逼,我觉得你需要刷个50份面试题。跟考研数学疯狂刷卷子一样!
查看>>
我觉得嵌入式面试三要素:基础吃透+项目+大量刷题,缺一不可。不刷题是不行的。而且得是大量刷,刷出感觉套路,别人做题都做得是固定题型套路条件反射了,你还在那慢慢理解慢慢推是不行的,也是考研的教训。
查看>>
相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。
查看>>
现在来看,做个普罗米修斯的docker镜像对我而言并不难,对PX4仿真环境配置也熟悉了。
查看>>
删除docker容器和镜像的命令
查看>>
VINS-Fusion Intel® RealSense™ Depth Camera D435i
查看>>
使用Realsense D435i运行VINS-Fusion并建图
查看>>
gazebo似乎就是在装ROS的时候一起装了,装ROS的时候选择的是ros-melodic-desktop-full的话。
查看>>
React + TypeScript 实现泛型组件
查看>>
TypeScript 完全手册
查看>>
React Native之原理浅析
查看>>
Git操作清单
查看>>
基础算法
查看>>
前端面试
查看>>
React Hooks 异步操作踩坑记
查看>>
聊聊编码那些事,顺带实现base64
查看>>
TypeScript for React (Native) 进阶
查看>>
React 和 ReactNative 的渲染机制/ ReactNative 与原生之间的通信 / 如何自定义封装原生组件/RN中的多线程
查看>>
JavaScript实现DOM树的深度优先遍历和广度优先遍历
查看>>