Dx10和Dx9的一些区别

本文从程序员视角解析了DirectX 10 (DX10) 和 DirectX 9 (DX9) 在技术上的差异,包括全新的驱动模型、完全可编程管线、Shader Model 4.0等特性。并通过实例说明了DX10如何提高开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言: 
      DX10发布已经有一段时间了,网上可以查到很多关于Dx9与10的区别的文章。但是大多数都是从玩家角度考虑的。只是展示一下Dx9和Dx10分别渲染出的图片,并且Dx9所渲染的图片经常会缩水很多,目的就是为了展示出Dx10的强大。给大多数人的理解就是,DX10能做出比Dx9好很多的画面。我并不否认Dx10比Dx9优化了很多,但是随便展示出两张图片进行对比,其实意义也不是特别的大。因为我们不知道帧率的对比。而且虽然很多新的技术在Dx9 里面没有,但是还是有一部分可以用其他方法模拟出来的,只是效率上有所下降。

      本文简单介绍了DX10和DX9的一些技术上的区别。从程序员的角度看DX10比DX9优势的地方。适合对于Dx有一定了解的朋友。

正文: 
      在Windows 98的年代里,GDI和DirectX是完全独立的两个接口。GDI(Graphical Device Interface)是专门用于二维图形显示的接口,封装了一些基本的功能,效率相对DirectX来说要低一些。而DirectX是专门用于游戏开发领域的,它允许用户通过这个接口直接与硬件交互。但是这两个接口之间的交互是非常受限制的,主要原因就是由于底层的驱动架构:

新建位图图像

     我们看到,在这个驱动模型里面,底层的硬件驱动都是独立的两部分。直到Windows Vista的发布,微软更新了底层的驱动模型

新建位图图像 (2)

     在这个新的驱动架构下,所有的图形接口都是基于DirectX Runtime的。这就为GDI和DirectX交互提供了可能,这也是Vista能够提供更好的用户界面体验的一个重要原因。DirectX9为了向下兼容,所以不得不做一些妥协的工作。例如当VRAM的占用超出了一定界限的时候,Dx9会发出error,而这并不是因为驱动无法提供更多的VRAM。事实上,底层驱动完全可以提供几乎无限的VRAM,但是为了向下兼容其他比较旧的显卡,因为这些卡在这里面可能会出现问题,所以Dx9还会出现Error。由于这种向下兼容的被迫妥协,不免使得Dx9在Vista下的表现不能完全利用底层的优势。对于Dx熟悉的朋友可能会注意到,在Dx9与Dx10之间,有一版Dx 9Ex。这一个版本的Dx是不能在XP下运行的,因为它更多的利用了新的驱动模型的优势,需要新的驱动模型才可以支持。而XP下的驱动模型还是上面的模型。Dx10是完全建立在新的驱动模型下面的全新的接口,它在Vista下可以完全发挥底层设计的优势。但是也同样需要WDDM的支持,这就是DX10不能在XP下运行的最主要的原因了。

     简单从底层介绍了一下Dx9与Dx10的区别(希望了解更深入的朋友,可以查看DX SDK里面的Graphics APIs in Windows那篇文章)。那么下面我来介绍一下从编程接口角度看,DX10为我们带来了一些什么样的变化:

完全的可编程管线: 
     在DX10里面,是没有固定管线的。如果程序员想用这个接口渲染图形的话,就必须自己写Shader脚本来实现图元的现实。事实上,在大多数次时代的三维游戏中,几乎很少有单纯的固定管线渲染的图元了。因为Phong模型的表现力毕竟还很有限,只通过diffuse, specular等一些简单的属性描述出的东西很难让人信服。可能唯一大量需要固定管线的部分就是二维图形UI部分了。如果UI不是特别复杂,只是渲染二维图片的话,固定管线的功能也就很方便了。不过实现一个模拟固定管线的Shader脚本也并不是什么麻烦事情,所以即使Dx10没有固定管线,也对程序员来说,也不是什么损失了。

完全的HLSL脚本编写: 
     对于早期的可编程管线有了解的朋友,可能会想起来,在Dx8的时候是可以用类汇编语言来编写Shader脚本的。在Dx9可以用两者任意一个来编写Shader了。但是在DX10里面,是不可以用汇编来写shader脚本的。

Shader Model 4.0: 
     在Dx10里的Shader是基于Shader Model 4.0的。具体细节我不是很清楚,但是SM 4.0有更多的指令数。如果实现个多光源的效果,可能在SM2.0里面只能做到8个(当然不排除能做更多个),是因为指令数目是有限制的。那么在新的 SM4.0里面,肯定是可以实现更多的光源数目了。当然这只是一个例子而已,而且多光源技术也不是什么先进的东西,很多场景中都被延迟光照所取代了。

没有CAPS: 
     在Dx9里面,程序员经常会查询那些功能是被硬件所支持的,哪些是不能的。而在Dx10里面,CAPS的概念就被移除了。一块显卡或者支持DX10的所有特性,或者干脆就不是块DX10显卡。那么意味着程序员可以使用DX10的一切功能而不需要在这之前查询当前硬件是否支持这项功能。

Geometry Shader: 
     GS是DX10新推出的一个概念。它是在VS和PS之间的一个GPU Kernel类型,负责接收由VS处理后的顶点,然后可以生成新的顶点,重新做处理。举一个简单的例子,粒子系统,假设有1k个粒子。那么每帧实际需要从 CPU传输到GPU的数据是1K*4,因为每个粒子由四个顶点组成。而这些数据是要走PCIE总线的,这个总线的带宽的效率远远不及GPU On Chip Memory的。如果有了GS,我们完全可以只传输每个粒子的中心,然后GS由粒子中心信息生成新的顶点。那么这样以来,就可以省下四倍的传输。当然这只是一个简单的例子而已,而且即使在DX9上渲染粒子系统,粒子的更新如果用GPU来处理的话,完全可以不传输每个粒子的信息。

Shader脚本开始支持整型数据: 
     在DX9里面,实际上Shader中是没有整数的概念的。即使在VS或者PS里面声明一个int,其实硬件通过float的转换来处理的。在DX10里面,是有对于整数的支持的。可以对整数进行位运算等操作,这些都是在硬件上实现的。输入的纹理的数据类型也可以是整型的。

     贴两张网上对比Dx9和Dx10的效果图吧,^_^。

 20070309000355113   20070309000356678

 20070309000357224   20070309000357460

     左边的两张是Dx9的右边是Dx10的。

     DX10有了这些变化后,可以方便程序员进行开发。但不是说DX10可以做到的东西,DX9就完全做不到,只不过是DX10的效率更高一些。我们看上面的对比图,其实如果做一个fake的光照效果,左下角的图完全可以用DX9模拟出来(个人感觉只是右边加上了点后处理特效而已)。举另一个例子来说,用 DX10做阴影效果,Shadow Volumn可以在GPU端利用GS来生成,然后用Stream-out功能把生成的资源再利用,从而做出这个效果。但是我们也同样在DX9上看到了 Shadow Volumn的Demo。其实效果是差不多的,主要区别在于前者利用了GPU去生成Shadow Volumn,这个任务本身就是一个并行的过程,GPU处理要优于CPU处理。而且渲染是在GPU端进行的,如果利用CPU生成的数据,就必须把数据通过 PCIE传输到显卡上,这些也是很耗时的过程。当然,如果实在要用DX9在GPU端生成Shadow Volumn,还可以通过CUDA,OpenCL等一些通用计算接口来帮助处理。但是这样会给程序很大限制,因为AMD和Nvidia有各自不同的解决方案,如果你用了其中一家的,就很难在另一家的卡上Work(OpenCL除外)。

资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 在 Android 开发中,Fragment 是界面的一个模块化组件,可用于在 Activity 中灵活地添加、删除或替换。将 ListView 集成到 Fragment 中,能够实现数据的动态加载与列表形式展示,对于构建复杂且交互丰富的界面非常有帮助。本文将详细介绍如何在 Fragment 中使用 ListView。 首先,需要在 Fragment 的布局文件中添加 ListView 的 XML 定义。一个基本的 ListView 元素代码如下: 接着,创建适配器来填充 ListView 的数据。通常会使用 BaseAdapter 的子类,如 ArrayAdapter 或自定义适配器。例如,创建一个简单的 MyListAdapter,继承自 ArrayAdapter,并在构造函数中传入数据集: 在 Fragment 的 onCreateView 或 onActivityCreated 方法中,实例化 ListView 适配器,并将适配器设置到 ListView 上: 为了提升用户体验,可以为 ListView 设置点击事件监听器: 性能优化也是关键。设置 ListView 的 android:cacheColorHint 属性可提升滚动流畅度。在 getView 方法中复用 convertView,可减少视图创建,提升性能。对于复杂需求,如异步加载数据,可使用 LoaderManager CursorLoader,这能更好地管理数据加载,避免内存泄漏,支持数据变更时自动刷新。 总结来说,Fragment 中的 ListView 使用涉及布局设计、适配器创建与定制、数据绑定及事件监听。掌握这些步骤,可构建功能强大的应用。实际开发中,还需优化 ListView 性能,确保应用流畅运
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值