大家好,这篇帖子我在其他论坛发过,把这篇帖子发布到这里,也是希望和更多
有共同爱好的朋友一块交流。我是5月份来到广海的,终于做出了一些自己的东
西。最近一直在弄D3D游戏的透视,被他弄得焦头烂额,很多时间都花在了解决
代码错误的问题上。不过功夫不负有心人我取得了一些成果,在编写代码的过程
当中参阅了大量的DirectX编程方面的资料。同时也在国外N多论坛做了一个名
副其实的伸手党,了解和掌握了D3D程序实现透视的一些基础知识。在这里我把
我自己在研究过程中的心得体会和一些经验大体整理了一下,只是希望能够找到
对D3D感兴趣的朋友能够共同研究,话不多说了,下面开始咱们的教程。(说明
一下,下面的内容都是我一个字一个字敲出来的,没有复制粘贴)。  
 
在看这篇教程之前,你最好有一些基本的C++的知识,此外还需要一些基本的D
irectX编程的基础。我的教程呢分为两个部分,第一部分呢主要讲一些透视原
理。第二部分主要讲透视dll的制作过程。  
 
    首先来看第一部分,主要是讲解一些透视的原理,

在讲透视之前首先来说一下什么是Z轴缓冲 
     Z轴缓冲就是DirectX中的成像元素之一 ,他是一个深度缓冲,用来决定
渲染对象的遮蔽关系 ,在计算机图形学中, 有时候通过硬件完成,有时候通过
软件完成。 在观察被渲染对象的时候就出现这样一个问题, 如果一个对象在另
一个对象的后面,并且距离观察者的距离较远那么我们是看不到他的。 Z轴缓
冲也就是深度缓冲。 
上面说的可能有点抽象我就直白的说一下吧: Z轴缓冲就是要告诉摄像机,如
果他在一个对象的后面,就不用显示它了 ,如果他在这个对象前面,就得显示
他。  
现在根据上面所说的,你可能要说把Z轴缓冲禁用来实现透视就是了。但事实情
况并不是这样。你会注意到,你会看到所有的东西甚至还有场景之外的东西也就
是说你必须找到某一个对象,再选这个对象的时候来禁用Z轴缓冲。这就是:
Strides(数据流中每个顶点所占内存的大小), NumVertices(渲染的顶点索
引的跨度),和 PrimitiveCounts(渲染的图元个数)。  
上面这三个就决定了透视到墙(物体)后你想看到的东西,在大部分情况下就是
人物模型(也就是想弄人物透视) 
如果直接禁用Z轴缓冲的话,那就是全图透视了,玩过AVA
的都知道全图透视在冰冻工厂是可以使用的,不过在其他地图,或者可以说在其
他游戏里,全图透视效果是很差的,所以要实现人物透视就必须找到游戏中的人
物模型表示。例如,CF的人物模型表示为44和40,AVA(战地之王的人物模型
标识为32),所以我们说的人物透视是必须找到人物模

型的表示然后再禁用Z轴缓冲  
 
下面我们来禁用Z轴缓冲了。首先把人物模型标识来定义一下  
#define PlayerBody  ( Stride == 44 || Stride == 40 )// 注意这个 " ||
" 是“或”的意思。意思就是说"PlayerBody  等价于 44或者是40。  
//这里的Stride即为游戏中的人物模型标识,  
 
好了,上面的代码是对人物模型的标识进行了定义,下面就要开始D3D9中的Dr
awIndexedPrimitive函数来修改游戏中人物模型的渲染状态  
下面的的代码就是在hook the DrawIndexedPrimitive 这函数之中 
复制代码
1. 
LPDIRECT3DVERTEXBUFFER8 Stream_Data;  
  UINT Stride = 0;  
 
  if (m_pD3DDev->GetStreamSource(0, &Stream_Data, &Stride) == D3D_OK)
  
  Stream_Data->Release();  
 
if(Chams)//这里的chams是透视开关      if(Player)  
      {  
          {  
//一旦游戏中Stride的值等于所设定的值,就开始执行以下代码:    DrawIndexedPrim
itive(Device, Type, MinIndex,  NumVertices, StartIndex, PrimitiveCoun
t);  
//在墙后面就是绿色    Device->SetRenderState( D3DRS_ZENABLE,false );  
    Device->SetTexture( 0, texGreen );  
//禁用Z轴缓冲    DrawIndexedPrimitive(Device, Type, MinIndex, NumVerti
ces, StartIndex,  PrimitiveCount);  
//游戏模型在墙前面的话(就是可以看见)    Device->SetRenderState( D3DRS_ZEN
ABLE, true );  
//打开Z轴缓冲,并填充为蓝色    Device->SetTexture( 0, texBlue);  
    DrawIndexedPrimitive(Device, Type,  MinIndex,  NumVertices, Start
Index, PrimitiveCount);  
          }  
      }

我们继续: 
如果你想知道透视上色的代码是如何运行的,它是通过消息队列进行操作的。.  
下面就是他的工作流程: 
如果人物要被显示: 
给人物上色为红色. 
启用Z轴缓冲, 在物体前面的时候为红色。 
禁用Z轴缓冲 
在物体后面的时候就为黄色 
Disable stencil shaders.(这个我暂时还没搞懂)
然后这样不断重复。说到重复,有人就会问了,什么是重复。我简单地说一下吧。
游戏在渲染人物模型的时候,是一帧一帧的进行渲染的,放在显存中的中的每幅
图像从后备缓冲区到前台缓冲区并呈现到屏幕上。打个形象的比喻,好比放幻灯
片。速度慢了,可以看成是一张一张的,当速度很快时,就可以看成连续的画面。
所以上面的渲染过程至少每秒要执行24次,要不然画面就会很卡。

这是我在AVA中实现的透视效果图,当然了,最后着一张是《全球使命》的截图。
这里我是以AVA和全球使命为例子来讲解的,其他的FPS游戏都大同小异,游戏
的透视半透和全透只是一个函数的差别,就是遮盖剔除函数。加上遮盖剔除函数,
半透就可以变成全透  
 
    这就是透视的整个流程,其实上面只是写了最核心的人物透视,如果你还想
添加其他功能,比如说准星,透视上色、字幕显示,功能菜单等等都可往里面添
加函数,我会在教程的最后把D3D的透视模板发出来,大家想添加什么功能的话
只要往里面加入代码就可以了  
 
上面只是实现人物透视的最核心的部分,也是实现人物透视的实质内容。整个实
现透视的流程为:  
 
找到所需函数的地址 —> 修改函数地址(拦截API) -->写入你想修改的代码(比
如画准星,禁用Z轴缓冲,上色等操作)—> 返回正常值  
 
找到你想要HOOK的函数地址,由于DirectX是COM组件,普通的函数HOOK是找
不到这些函数的,我们必须用能HOOK  COM对象的函数,这就是Detour,利用D
etour我们就可以HOOK COM对象里的函数了。  
 
pEndScene =  (EndScene_)DetourFunction((PBYTE)VTable[ES],(PBYTE)pEndS
cene);  
 
上面就是一个detour的使用例子,其实很多功能都是在这个函数里面实现的,
例如画准星,菜单显示等等。那么第一个参数是怎么来的呢,这里我们就需要找
到EndScene这个函数的地址,怎么找呢,有两种方法:  
 
1、   修改PE导入地址表的函数地址,使游戏在调用函数的时候转到我们的函
数上来  
2、  直接找到EndScene函数的基址和偏移,然后把这个地址的函数改成我们自
己的函数  
举个例子我们可以在EndScene里面去设置开关,画准星以及渲染方框  
 
if(bTip)    //bTip初始化为true ,注入成功进入游戏后直接显示 
     { 
DrawFont( 600,50, D3DCOLOR_ARGB(255,0,255,255), "小键盘-> 0 文字提示,
 1 准星开关,人物透视");       
         DrawFont( 600,70, D3DCOLOR_ARGB(255,0,255,255), " Coded By
顶级小白QQ:812191628"); 
 
     } 
     if(crosshair)//画准星 
     { 
         D3DVIEWPORT9 viewP;                   //先定义一个接口指针 
        pDevice->GetViewport( &viewP );       //获得屏幕宽度和高度 
         DWORD ScreenCenterX = viewP.Width / 2;//屏幕中心X位置 
         DWORD ScreenCenterY = viewP.Height / 2; //屏幕中心Y位置 
         D3DRECT rec16 = {ScreenCenterX-15, ScreenCenterY, ScreenCenterX+ 15, Scree
nCenterY+1};//这个D3DRECT是一个结构体。就是指定了画的这条直线的范围,水平的那条线 
         D3DRECT rec17 = {ScreenCenterX, ScreenCenterY-15, ScreenCenterX+ 1,ScreenC
enterY+15};  //这个是垂直的那条线的上下两个点 
         pDevice->Clear( 1, &rec16, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ),
0,  0 );//clear方法可以指定使用某种颜色把后备缓冲区粉刷一遍(也可以是深度缓冲区,模
板缓冲区) 
         pDevice->Clear( 1, &rec17,D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ),
0,  0 );//要清空的矩形区域的数目(第一个参数)//要清空的举行的数组,和第一个参数决定了
要清除的矩形区域的组合(第二个参数) 
     } 
   //下面开始渲染方框 
    DrawBox (100,100,100,100,D3DCOLOR_ARGB(255, 255, 0, 255), D3DCOLOR_XRGB( 255, 0,
 0 ),pDevice); //红色准星 
     returnpEndScene(pDevice);//这里就是返回正常值  
 
voidFillRGB( intx, inty, intw, inth, D3DCOLOR color, IDirect3DDevice9* pDevice ) 

    if( w < 0 )w = 1; 
    if( h < 0 )h = 1; 
    if( x < 0 )x = 1; 
    if( y < 0 )y = 1; 
 
    D3DRECT rec = { x, y, x + w, y + h }; 
    pDevice->Clear( 1, &rec, D3DCLEAR_TARGET, color, 0, 0 ); 

voidDrawBorder( intx, inty, intw, inth, intpx, D3DCOLOR BorderColor, IDirect3DDevic
e9* pDevice ) 

    FillRGB( x, (y + h - px), w, px,    D3DCOLOR_XRGB( 255, 0, 0 ), pDevice ); //填
充颜色 
    FillRGB( x, y, px, h,                D3DCOLOR_XRGB( 255, 0, 0 ), pDevice ); 
    FillRGB( x, y, w, px,                D3DCOLOR_XRGB( 255, 0, 0 ), pDevice ); 
    FillRGB( (x + w - px), y, px, h,    D3DCOLOR_XRGB( 255, 0, 0 ), pDevice ); //红
色方框 

 
voidDrawBox( intx, inty, intw, inth, D3DCOLOR BoxColor, D3DCOLOR BorderColor, IDire
ct3DDevice9* pDevice ) //渲染一个方框 

     
    DrawBorder( x, y, w, h, 1,    BorderColor, pDevice );// 画方框边界 
}    
通过上面所说的就可以找到函数地址并进行HOOK..(这其中还有很多小细节需
要注意,但由于篇幅的原因,我只大概的介绍这些)  
 
好了,第一部分暂且讲到这里,如果你有不明白的地方建议你多去看看DirectX
编程方面的资料。  
 
下面开始第二部分来说一说透视dll的制作:  
 
Dll的制作我是翻译的国外论坛的几篇帖子  
 
先说明一下需要的工具:Microsoft Visual C++ 6.0  
 
VS 2008也可以(本人用的就是VS2008)然后还需要DX的SDKDirectX 9.0
SDK Update - (Summer 2009)  
D3D Starter Kit 3B  
这份代码我会打包放到附件里在你下载并安装了C++6.0以及D3D SDK之后你
就可以使用C++ 用SDK lib 文件了好,打开C++ 6  
打开“工具”

>选项>目录(Directories)在路径那里选择SDK的文件夹
添加Microsoft Directx 9.0 SDK include 文件夹如下图所示:(我机子上VC6.
0和9.0都安装了,第一个图这是我自己截的图)

(这是原文中的英文版的)做完这些之后, 开始添加“lib”文件了
在“目录”这里

然后选择Microsoft Directx 9.0 SDK lib文件夹(我机子上VC6.0和9.0都安
装了,原文截图已经丢失,这是我自己截的图)然后选择Microsoft Directx 9.
0 SDK lib文件夹(我机子上VC6.0和9.0都安装了,原文截图已经丢失,这是
我自己截的图

点击OK,这样工具就设置OK了现在我们可以启动starter kit这样我们就可以
用它了打开Starter kit 文件夹, 来到D3D9 文件夹如下图所示(我机子上VC6.
0和9.0都安装了,原文截图已经丢失,这是我自己截的图)

现在打开old_workspace 文件夹, 复制两个文件到D3D9 文件夹中(不知道是
哪两个文件。。。囧)然后打开VC6.0,点击“文件”----“打开工作空间”----
选择TatniumD3D.dsw  
 
 
做完这些之后你就可以去编译dll了。  
    希望各位朋友能够多多给力,不要让这篇帖子沉下去。大家可能注意到了,
这两张截图我都渲染了一个方框,但苦于找不到人物的坐标,所以在这里我也想
找几位对D3D透视感兴趣的朋友(熟悉C++和DirectX编程)一块研究方框透视
还有CF等其他射击游戏的透视,毕竟一个人的力量有限。

Direct3D透视教程,教你做出属于自己的透视相关推荐

  1. 【Java实战项目】两小时教你做出网上订餐系统

    今天主要给大家分享的是java毕业设计项目-网上订餐系统! 本套java项目视频主要针对于应届毕业生,毕业设计而制作,视频围绕毕业设计讲解网上订餐系统的制作全部流程.项目包括网站源码.项目原型.项目文 ...

  2. C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

    C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...

  3. php mvc教程 文档,PHP培训教程教你快速打造PHP MVC框架[PHP基础教程]

    PHP培训教程教你快速打造PHP MVC框架[PHP基础教程] 简介 MVC框架在现在的开发中相当流行,不论你使用的是JAVA,C#,PHP或者IOS,你肯定都会选择一款框架.虽然不能保证100%的开 ...

  4. 【Midjourney实操】逼真到颤抖!保姆级教程教生成效果炸裂的图片

    最近,许多由Midjourney V5创作的画作在网络上引起了热议,许多人惊呼:人类画师, 插画师, 设计师统统活不下去了! 比如下面这张中国情侣的画作: 因为前段时间这个很火, 我跟着同样的prom ...

  5. 智能车图像处理逆透视教程

    去畸变请参考:图像处理去畸变教程_LoseHu的博客-CSDN博客 去畸变+逆透视请参考:​​​​​​​​​​​​​​​​​​​​​智能车去畸变+逆透视教程_LoseHu的博客-CSDN博客 逆透视: ...

  6. 手把手教你玩转 Excel 数据透视表

    1.  什么是数据透视表 数据透视表是一种可以快速汇总.分析大量数据表格的交互式分析工具.使用数据透视表可以按照数据表格的不同字段从多个角度进行透视,并建立交叉表格,用以查看数据表格不同层面的汇总信息 ...

  7. 任天堂switch手柄怎么拆解图文教程 教你如何拆joycon

    任天堂switch手柄怎么拆解图文教程 教你如何拆joycon 2020-02-02 12:47:57 作者:电玩男/ 来源:未知/ 人气:5702 任天堂switch手柄JoyCon手柄的拆解相对于 ...

  8. 我的世界java村民繁殖条件,我的世界村民无限繁殖教程 教你村民怎么生孩子

    我的世界村民无限繁殖教程 教你村民怎么生孩子.那在我的世界中想要绿宝石就要有很多的村民才可以,那下面就给大家分享一下村民怎么无限繁殖吧!还有教你村民怎么生孩子哦~ 游戏园我的世界官方群:3250495 ...

  9. PS教程 教你制作古老的石头

    PS教程 教你制作古老的石头[@more@] 1.打开 Photoshop 新建一个文件,宽度:自定;高度: 自定; RGB模式;白色底色. 新建一个图层并命名为,然后用灰色填充整个图层,再将图层的不 ...

  10. 【小米红米手机】红米note4\note4x\联发科\调节音量分级教程 教你调节最小/最大音量

    一.红米note4\note4x\联发科\调节音量分级教程 教你调节最小/最大音量 二.小米红米手机 三.调一下       一.  此方法适用于搭载联发科CPU的安卓手机.无需root!完美解决外放 ...

最新文章

  1. 4种最常问的编码算法面试问题,你会吗?
  2. PySCF :基于Python的化学模拟框架
  3. php 继承内核中的基类,php – 从基类调用继承类的父方法
  4. C++Primer Plus (第六版)阅读笔记 + 源码分析【第四章:复合类型】
  5. 用户流失的事前预警与事后分析
  6. dom文档对象手册_HTML5学习之DOM编程
  7. (23)FPGA面试技能提升篇(SSC接口、V35接口)
  8. UVA 12299 RMQ with Shifts 线段树
  9. ubuntu snappy 记事
  10. mysql怎么创建表可视化_MYSQL系列1_MySQL的安装,可视化工具的使用,以及建库建表等...
  11. 国外统计学课程主页Statistical Books, Manuals and Journals
  12. U盘的量产一定要认定芯片及其型号
  13. adb 静默安装_apk 静默安装
  14. 当exe文件运行时,汉字出现乱码
  15. maya表情blendshape_带BlendShape表情的动作文件播放异常
  16. 判断一个数是否为四叶玫瑰数
  17. ArcGIS与插值(一): 统计与地统计
  18. 华为云数据灾备解决方案,你最佳的安全卫士
  19. 两台Sawyer机械臂在rviz中的运动规划
  20. 小心系统入侵之八——招吸星大法(转)

热门文章

  1. zemax设置 像方远心_ZEMAX:如何翻转整个光学系统
  2. 微信小程序:组件间的传值
  3. android eclipse三合一,创新巅峰之作全能型Orbitrap Eclipse三合一质谱仪
  4. RF(射频) - VSWR(电压驻波比)
  5. 数据解读 | 高考志愿慎重填,大学四年不留白
  6. SpringBoot集成editormd实现发表和查阅功能
  7. editorMd插件的使用总结(包括开启图片上传及拖拉粘贴上传图片)
  8. 20130419阿里电话面试记录
  9. WT6255 WIFI/BT调试文档
  10. 390计算机毕业设计