开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 20948|回复: 27
收起左侧

[源码分享] 游戏D3D透视制作教程从基础到源码

 关闭 [复制链接]
结帖率:57% (4/7)
发表于 2011-2-18 11:53:58 | 显示全部楼层 |阅读模式   四川省成都市
我整理了一下d3d的基本结构,简单的注释了一段源码,一起来了解一下direct3d的世界吧。
1:d3d的初始化
LPDIRECT3D9  g_pD3D=NULL;//d3d对象
LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;//d3d设备对象
LPDIRECT3DVERTEXBUFFER9 g_pVB=NULL;//顶点缓冲
//初始化D3D
HRESULT InitD3D(HWND hWnd)
{
//创建D3D
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
//填充D3DDevice结构
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
//创建D3DDevice
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pd3dDevice);
//初始化几何数据
HRESULT InitGeometry()
{
//初始化顶点数据
CUSTOMVERTEX g_Vertices[]= { {-1.0f,-1.0f,0.0f,0xffff0000,}, {1.0f,-1.0f,0.0f,0xff0000ff,}, {0.0f,1.0f,0.0f,0xffffffff,}, };
//创建顶点缓冲区
g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0,D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT,&g_pVB,NULL)
//填入顶点数据
VOID*pVertices;
g_pVB->Lock(0,sizeof(g_Vertices),(void**)&pVertices,0)
returnE_FAIL;
memcpy(pVertices,g_Vertices,sizeof(g_Vertices));
g_pVB->Unlock();
//渲染函数
VOID Render()
{
   pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
   pDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);//更改这两个渲染状态就可以实现透视功能
   //清空缓冲
  g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
g_pd3dDevice->BeginScene()
//在BeginScene后台缓存绘制图形
//开始绘制图形
g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX)); g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,1);
g_pd3dDevice->EndScene();
//在EndScene结束后台缓存渲染图形
//在这可以得到我们的颜色,画准心。
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);//将后台缓存绘制的图形提交到前台缓存显示
}

//清理资源
VOID Cleanup()
{
g_pVB->Release();//释放顶点缓存对象
g_pd3dDevice->Release();//释放设备对象
g_pD3D->Release();//释放d3d对象
}


下面是一篇网上的透视源码作简要注释



bool StartDll=1;
bool WallHack=1;//定义布尔变量用来判断是否开启透视功能
typedef HRESULT(WINAPI* DrawIndexedPrimitive_)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount);//从这开始是detours hook com接口需要的参数,后面有如何用detours hook com接口的方法,这里定义了一个类型
DrawIndexedPrimitive_ pDrawIndexedPrimitive;

HRESULT WINAPI nDrawIndexedPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex,UINT NumVertices, UINT StartIndex, UINT PrimitiveCount)//我们的hack函数。
{  

  IDirect3DVertexBuffer9* pStreamData = NULL;
  UINT iOffsetInBytes,iStride;  
  pDevice->GetStreamSource(0,&pStreamData,&iOffsetInBytes,&iStride); //用来获取stride,前面是定义这个函数的三个参数

  if (  iStride == 40 &&WallHack==1)//这里进行透视判断,当stride=40,WallHack=1时开启透视,如果我们不知道游戏人物的stride,可以增加一个变量把40替换掉,用自加来判断人物st
  {
      pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);//这里是更改渲染状态,禁用z轴,实现透视的方法,这应该都知道吧。
      pDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);
                //再给一种写法,两种效果是不一样,下面的人物自身不会透视,看不到自身的结构。
                pDevice->SetRenderState(D3DRS_ZENABLE,false);
      pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
                pDrawIndexedPrimitive(pDevice,Type,BaseVertexIndex, MinIndex, NumVertices, StartIndex,
      PrimitiveCount);
      pDevice->SetRenderState(D3DRS_ZENABLE,true);
                pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
  }
   
      
   return pDrawIndexedPrimitive(pDevice, Type, BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount);//返回值
                        
        
}

int StartHack ();



BOOL APIENTRY DllMain( HANDLE hModule,DWORD  ul_reason_for_call, LPVOID lpReserved )//这是默认的 DLL格式
{
    if (StartDll)
   {
      StartDll=0;
       CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)StartHack, NULL, NULL, NULL);               
   }
   return TRUE;
}

int StartHack ()//取tb,方法不止一种,我们也可以通过d3d对象来取tb数组,取hook函数位置,自己可以打开d3d头文件数数是在第几个~~
{
   char s[1000];
   DWORD offsetBase=0x4FE571A0;
   for(;; Sleep(500))
        {
               offsetBase=(DWORD)GetModuleHandle ("d3d9.dll");
            if (offsetBase)            
               break;            
        }

   DWORD a[2];
   a[0]=offsetBase+0x88840;
   sprintf (s,"[Noobshooter] Module d3d9 =%08X,Offset FuncHook =%08X",offsetBase,a[0]);
   OutputDebugString (s);
   pDrawIndexedPrimitive = (DrawIndexedPrimitive_)DetourFunction((PBYTE)a[0],(PBYTE)nDrawIndexedPrimitive);//进行绕到我们的函数,参数,地址,我们的函数

   for (;;Sleep (500))//按键的判断
   {
      if (GetAsyncKeyState (VK_F9)!=0)
      {
         Beep (2000,200);
         Wallhack=1;
      }
      if (GetAsyncKeyState (VK_F10)!=0)
      {
         Beep (3000,200);
         WallHack=0;
      }
   }
   return 1;

这是detours1.5用来hook com接口的格式
HRESULT STDCALL (*pfSeekTrampoline)(
   IStream * This,
   LARGE_INTEGER dlibMove,
   DWORD dwOrigin,
   ULARGE_INTEGER *plibNewPos);

HRESULT STDCALL SeekDetour(   
   IStream * This,
   LARGE_INTEGER dlibMove,
   DWORD dwOrigin,
   ULARGE_INTEGER *plibNewPos)
{
   return pfSeekTrampoline(This, dlibMove, dwOrgin, plibNewPos);
}

void detour_member_function(IStream *pi)
{
   (*(PBYTE*)pfSeekTrampoline) = DetourFunction(
      (PBYTE)pi->lpVtbl->Seek,
      (PBYTE)SeekDetour);
};

看完有什么收获没?~~其实很简单,有兴趣的来交流下吧

评分

参与人数 1好评 +1 精币 +10 收起 理由
紫旭 + 1 + 10 支持一下,学习

查看全部评分

结帖率:0% (0/1)
发表于 2011-2-18 12:45:20 | 显示全部楼层   贵州省六盘水市
无语,我看不懂!
回复 支持 反对

使用道具 举报

发表于 2011-2-18 12:56:45 | 显示全部楼层   广东省揭阳市
看不懂!!!!!!!!!!!!
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
发表于 2011-2-18 13:12:07 | 显示全部楼层   广西壮族自治区南宁市
这是什么语言啊?看了{:3_241:}
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)
发表于 2011-2-20 19:54:27 | 显示全部楼层   湖南省湘潭市
神马东西呀`?
回复 支持 反对

使用道具 举报

结帖率:80% (4/5)
发表于 2011-2-21 16:18:15 | 显示全部楼层   江苏省苏州市
完全看不懂 大哥。
回复 支持 反对

使用道具 举报

发表于 2011-7-28 21:26:54 | 显示全部楼层   四川省成都市
我也不懂,就 要学习
回复 支持 反对

使用道具 举报

发表于 2011-8-9 12:12:49 | 显示全部楼层   北京市北京市
VC++源码啊?看不懂啊啊!
回复 支持 反对

使用道具 举报

结帖率:50% (1/2)
发表于 2011-8-9 15:32:35 | 显示全部楼层   江苏省苏州市
一本无字天书就在眼前{:3_227:}
回复 支持 反对

使用道具 举报

结帖率:50% (1/2)

签到天数: 12 天

发表于 2011-8-11 16:00:23 | 显示全部楼层   吉林省长春市
还要好好干啊,学的不精啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表