Direct3D纹理映射

news2024/11/16 17:32:40

借助纹理映射技术,我们可将图像数据映射到三角形单元中,这种功能可以显著地增加所绘制场景的细节和真实感,例如创建一个立方体然后为其每个面映射一个板条纹理,从而将该立方体变为一个板条箱,在Direct3D中纹理用接口IDirect3DTexture9来表示,纹理是类似于表面的一个像素矩阵,与表面不同的是它可被映射到三角形单元中。

纹理坐标

Direct3D锁使用的纹理坐标系由沿水平方向的u轴和沿垂直方向的v轴构成,用坐标对(u,v)标识的纹理元素称为纹理元,注意v轴的正方向是竖直向下的

为了能够处理不同尺度的纹理,Direct3D将纹理坐标做了规范化处理,使之限定在区间[0,1]内,对于每个3D三角形单元,我们都可以在纹理中定义一个相应的三角形区域,然后将该三角形区域内的纹理映射到该3D三角形单元中,为了实现该映射,需要再次修改顶点结构,为之添加一个纹理坐标对以标识纹理中的顶点

struct TextureVertex
{
	TextureVertex(){}
	TextureVertex()
	{

	}
	float _x, _y, _z;
	float _nx, _ny, _nz;
	float _u, _v;			//纹理坐标
	static const DWORD FVF;
};
const DWORD TextureVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; //D3DFVF_TEX1表示顶点结构中包含了一对纹理坐标

现在由3个顶点对象构成的每个三角形都在该纹理坐标系中定义了一个相应的纹理三角形,虽然指定了,但直到光栅化时,即该3D三角形已被变换至屏幕坐标系时,纹理映射才会进行

创建并启用纹理

纹理数据通常从磁盘中的图像文件读入,然后再加载到IDirect3DTexture9对象中,可使用D3DXCreateTextureFromFile函数来实现,该函数可以加载下列格式的图像:BMP、DDS、DIB、JPG、PNG和TGA

HRESULT D3DXCreateTextureFromFile(
	LPDIRECT3DDEVICE9         pDevice,
	LPCSTR                    pSrcFile,
	LPDIRECT3DTEXTURE9*       ppTexture
);
IDirect3DTexture9* _stonewall;
D3DXCreateTextureFromFile(Device, "stonewall.bmp", &_stonewall);

HRESULT IDirect3DDevice9::SetTexture(
	DWORD Stage,	//纹理层
	IDirect3DBaseTexture9* pTexture
);

//禁用某一纹理层,可将pTexture参数设为0,绘制物体时若不想使用纹理可以这样做
Device->SetTexture(0, 0);
renderObjectWithoutTexture();

//如果场景中的各个三角形所使用的纹理均不相同
Device->SetTexture(0, tex0);
drawTrisUsingTex0();

Device->SetTexture(0, tex1);
drawTrisUsingTex1();

在Direct3D中,最多可设置8层纹理,可以对这些纹理进行组合以创建一幅更细致的图像,这称为多重纹理

纹理过滤器

通常纹理三角形与屏幕三角形的的大小并不一致,当纹理三角形与屏幕三角形大小不一致时,为适应后者,纹理三角形需要被放大或者缩小,这俩种情况都有畸变发生,为了从某种程度克服这类畸变,Direct采用了一项称为纹理过滤的技术。

Direct3D提供了3种类型的纹理过滤器,过滤器的质量越高,运算开销越大,处理速度越慢。纹理过滤方式可用方法SetSamplerState来设置。

最近点采样:Direct3D默认使用的过滤方式,该方式的处理速度最快,但效果最差,下面代码分别表示将最近点采样方式设置为放大过滤器和缩小过滤器

线性纹理过滤器:该类型的过滤方式可以产生相当好的结果,而且以目前的硬件配置水平也可获得较快的处理速度

各向异性纹理过滤:该类型的过滤方式可以产生最好的结果,但是处理速度也是最慢的,使用该过滤时,必须对D3DSAMP_MAXANISOTROPIC水平值进行设定,该值决定了各向异性过滤的质量水平。该值越大图像效果越好,请调用IDirect3DDevice::GetDeviceCaps函数检查返回的D3DCAPS9结构参数,以获得硬件支持的值的合法取值范围。

//设置最近点采样纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

//设置线性纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

//设置各向异性纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);

//将各向异性过滤的质量水平设置为4
Device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);

多级渐进纹理

屏幕上的三角形通常与纹理三角形大小不一致,为了尽量消除由二者尺寸差异带来的影响,我们可为纹理创建一个多级渐进纹理链,方法是由某一个纹理创建一系列分辨率逐渐减小的纹理图像并且每种分辨率下的纹理所采用的过滤房还是进行定制,以便保留那些较重要的细节,在Direct3D中使用多级渐进纹理十分容易,如果硬件支持多级渐进纹理D3DXCreateTextureFromFile函数将创建一个多级渐进纹理链,此外Direct3D还将自动从纹理链中选择与屏幕三角形最匹配的那个一级纹理,所以由于可被Direct3D自动设置,而且处理时的时间和空间代价都比较低,多级渐进纹理得到了广泛应用。

多级渐进纹理过滤器

多级渐进纹理过滤器主要用于控制Direct3D使用多级渐进纹理的方式,可这样对多级渐进纹理过滤器进行如下设置

Device->SetSamplerState(0, D3DSAMP_MIPFILTER, Filter);

Filter可取以下值

D3DTEXF_NONE:禁用多级渐进纹理过滤器
D3DTEXF_POINT:通过使用该过滤器,Direct3D将选择尺寸与屏幕三角形最接近的那一级纹理,一旦选择了某一级纹理,Direct3D就会用指定的放大过滤器和缩小过滤器对该级纹理进行过滤
D3DTEXF_LINEAR:通过使用该过滤器,Direct3D将取与屏幕三角形尺寸最接近的俩个纹理级,用指定的放大过滤器和缩小过滤器对每级纹理进行过滤,然后再将这俩级纹理进行线性组合,从而形成最终的颜色值。

寻址模式

前面部分中,我们说过纹理坐标必须限制在区间[0,1]内,从技术角度讲是有问题的,因为有时坐标可能超出该范围,Direct3D定义了4种用来处理纹理坐标值超出[0,1]区间的纹理映射模式。分别是重复寻址模式(wrap)、边界颜色寻址模式(border color)、箝位寻址模式(clamp)、镜像寻址模式(mirror)。

//set wrap address mode
if (::GetAsyncKeyState('W') & 0x8000f)
{
	//表示对纹理的u方向或v方向设置纹理寻址模式
	Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
	Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); 
	//D3DTADDRESS_CLAMP、D3DTADDRESS_MIRROR
}

//set border color address mode
if (::GetAsyncKeyState('B') & 0x8000f)
{
	//表示对纹理的u方向或v方向设置纹理寻址模式
	Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
	Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
	Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff);
}

纹理四边形例程

1.构造组成物体的顶点,并为其指定纹理坐标
2.用函数D3DXCreateTextureFromFile为IDirect3DTexture9接口加载一种纹理
3.设置缩小/放大过滤器、和多级渐进纹理过滤器
4.绘制物体前,用函数IDirect3DDevice9::SetTexture来设定与该物体关联的纹理

bool SetUpTextureQuad()
{
	Device->CreateVertexBuffer(6 * sizeof(TextureVertex), D3DUSAGE_WRITEONLY, TextureVertex::FVF, D3DPOOL_MANAGED, &Quad, 0);
	TextureVertex* v;
	Quad->Lock(0, 0, (void**)&v, 0);
	v[0] = TextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
	v[1] = TextureVertex(-1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	v[2] = TextureVertex(1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);

	v[3] = TextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
	v[4] = TextureVertex(1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);
	v[5] = TextureVertex(1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 3.0f);
	Quad->Unlock();
	
	D3DXCreateTextureFromFile(Device, "dx5_logo.bmp", &Tex);
	//启用纹理
	Device->SetTexture(0, Tex);
	//设置放大/缩小过滤器
	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	//设置渐进纹理过滤器
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

	//不使用光照
	Device->SetRenderState(D3DRS_LIGHTING, false);

	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)Width / (float)Height, 1.0f, 1000.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);
	return true;
}

bool DisplayTextureQuad(float timeDelta)
{
	if (Device)
	{
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
		Device->BeginScene();
		Device->SetStreamSource(0, Quad, 0, sizeof(TextureVertex));
		Device->SetFVF(TextureVertex::FVF);
		Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
		Device->EndScene();
		Device->Present(0, 0, 0, 0);
	}
	return true;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1012388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

武汉凯迪正大—高压信号发生器

一、产品介绍 本产品是我公司在长期从事电缆故障测试研究方面新开发的创新型换代产品,采用大屏幕彩色液晶显示器、指示高压侧真实电压值、具有过压、过流保护。该产品满足《中华人民共和国电力行业标准,高压试验装置通用技术条件》,主要用于对…

数学建模——差分方程结论介绍

适用对象:事物发展具有明显阶段性 一、差分方程介绍 差分方程是一种描述离散系统演化的数学工具。与微分方程不同,差分方程使用差分代替微分来描述变量之间的关系。 差分方程通常由递归关系定义。假设有一个序列 {y₀, y₁, y₂, y₃, ...},…

两个单链表相交的问题

两链表相交及其第一个节点 判断有环无环 判断有无环,如果有环返回第一个入环节点,如果无环返回null 使用额外空间:Set结构 沿着指针将a、b、c、d、e、c放入set结构中,每次放入前查看在set集合中是否存在; 若遍历到…

供应商整合对企业有哪些好处?

企业采购总是希望降低成本,赢得更多的利润。实现这目标的其中一种方法就是供应商整合。 究竟什么是供应商整合?整合供应商有哪些好处?本文为你详细解答。 什么是供应商整合? 供应商整合是减少特定产品或服务的供应商数量的过程。…

JTS:06 九交模型讲解

版本 org.locationtech.jts:jts-core:1.19.0 链接: github 九交模型讲解:Dimensionally Extended 9 Intersection Matrix 九交模型 九交模型,是通过矩阵来判断俩个物体的关系的,请看上面九交模型讲解 九交模型测试 测试环境 www.geogebra…

Unity中 UI Shader的基本功能

文章目录 前言一、实现思路1、暴露一个 2D 类型的属性来接受UI的纹理2、设置shader的层级为TransParent半透明渲染层级,一般UI都是在这个渲染层级3、更改混合模式,是 UI 使用的纹理,该透明的地方透明 二、代码实现 前言 Unity中 UI Shader的…

SpringBoot-线程池ThreadPoolExecutor异步处理(包含拆分集合工具类)

ThreadPoolExecutor VS ThreadPoolTaskExecutor ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。 配置文件application.yml # 异步线程配置 自定义使用参数 async:executor:thread:core_pool_size: 10max_pool_size: 100 # 配置最大线程数queue_capacity: …

gif动态图片如何做?两个方法教你在线制作gif

制作gif动画的方法有哪些?gif动图作为当下流行的一种图片格式,是由一帧一帧的图像,循环播放而产生的动画效果。那么,制作gif动画的方法有哪些呢?给大家分享一款专业的gif动画制作(https://www.gif.cn/&…

【JVM】Java的内存模型(JMM)!

一、运行时数据区域划分 JVM虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。 JDK 1.8之前分为:线程共享(Heap堆区、Method Area方法区)、线程私有(虚拟机栈、本地方法栈、程序计数器) …

“一种三元前驱体废水螯合树脂回收钴的装置”实用新型专利

“一种三元前驱体废水螯合树脂回收钴的装置”实用新型专利 (证书号:第19681862号;专利号:ZL 2022 2 1042752.0) 三元前驱体通常由三元液(硫酸镍、钴、锰的混合溶液)、液碱与氨水在一定条件下液相合成,再经陈化、固液分离、流水洗涤、干燥、过…

PMP考试注意事项有哪些?

1. PMI明确规定:不允许考生使用自带文具,包括自带的笔、削笔刀、橡皮、笔袋、计算器和草稿纸等。 2. 本次考试考场内为每位考生配备2B铅笔、橡皮、计算器(若有需要)和草稿纸。如文具有缺损或考试过程中如需更换铅芯等,请向监考老师举手示意。…

【实战】H5 页面同时适配 PC 移动端 —— 旋转横屏

文章目录 一、场景二、方案三、书单推荐01 《深入实践Kotlin元编程》02 《Spring Boot学习指南》03 《Kotlin编程实战》 一、场景 一个做数据监控的单页面,页面主要内容是一个整体必须是宽屏才能正常展示,这时就不能用传统的适配方案了,需要…

DC电源模块单路、双路输出的不同应用场景

BOSHIDA DC电源模块单路、双路输出的不同应用场景 DC电源模块是一种常见的供电设备,通常用于将市电转换为稳定的直流电源,以供电给各种电子设备。DC电源模块的输出方式分为单路和双路两种,下面将分别介绍它们的不同应用场景。 一、单路输出…

wx.getPrivacySetting 小程序隐私保护指引的使用(复制粘贴即用)

创建privacyPopup 组件 privacyPopup.js Component({properties: {},data: {wxPrivacyName: ,showAgreement: false},lifetimes: {attached() {this.init();}},methods: {async init() {if (isLogin()) {const userPrivacy await this.getPrivacy();this.setData({wxPrivacy…

vue项目生产环境隐藏暴露的代码_源码

// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 productionSourceMap: false,

思维导图,掌握思维的艺术!免费的Mindomo Desktop for Mac等你来体验

您是否曾为了整理复杂的思绪而苦恼?或许您需要一款强大而直观的思维导图软件来帮助您理清思路。Mindomo Desktop for Mac是一款免费的思维导图软件,它将为您带来高效的思考和组织工具。 Mindomo Desktop for Mac的界面简洁直观,操作简单易上…

留资机器人助你有效提高营销成功率

我们都知道,当客户产生留资行为,就要抓住机会,让工作人员及时地对客户进行回访,然后将留资线索跟踪、维系。而如何准确有效地提高客户保留率和转化率是营销成功的关键。所以对于企业来说,留资机器人正是引导客户留资&a…

自动化测试工程师简历(吐血整理)附模板

张三(软件测试) 联系电话:175XXXXXXXXX 电子邮件:XXXqq.com 学 历:本 科 专 业:计算机科学与技术 毕业院校:XXXXXX …

Redis缓存高可用集群

1、Redis集群方案比较 哨兵模式 在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可…

Postman应用——接口请求(Get和Post请求)

文章目录 新增请求接口请求Get接口请求Post 这里只讲用的比较多的Get和Post请求方式,也可以遵循restful api接口规范,使用其他请求方式。 GET(SELECT):从服务器取出资源(一项或多项)POST&#…