很多D3D的初学者最感到困惑的问题是如何用D3D来实现2D的效果,因为DirectDraw已经不存在了(当然你还是可以用以前的版本的,但是可能不法利用一些最近的硬件加速)在这里我给大家介绍几种方法可以实现用D3D编写2D游戏

方法一:
使用D3DX的接口ID3DXSprite,

void DrawSprite_2D( 
        int dx,//窗口中的X座标
        int dy,//窗口中的Y座标
        int sx,//tex纹理中的X座标
        int sy,//tex纹理中的Y座标
        int sw,//tex纹理中的子区域宽度
        int sh,//tex纹理中的子区域高度
        IDirect3DDevice9* device,
        ID3DXSprite* sprite,
        IDirect3DTexture9* tex,//已生成的纹理
        bool trans )
{
D3DXCOLOR c = D3DCOLOR_XRGB(255,255,255);
D3DXMATRIX identity;
D3DXMatrixIdentity( &identity );

RECT r;
r.left = sx;
r.top = sy;
r.right = sx+sw;
r.bottom = sy+sh;

device->SetTransform( D3DTS_WORLD,&identity );
device->SetTransform( D3DTS_VIEW,&identity );

if( trans )
{
sprite->Begin( D3DXSPRITE_ALPHABLEND );
}
else
{
sprite->Begin( 0 );
}

//把纹理中的子区域画在指定的屏幕坐标上
sprite->Draw( tex,&r,0,&D3DXVECTOR3(dx,dy,0),c );
sprite->End();
}

是不是很简单呢?但是要有一些要注意的地方,因为D3D对纹理的大小有一些限制,必须是2的N次幂,因此,如果你想通过一个任意大小的图片来生成纹理,那么在生成的过程中D3D会自动把它变成2的N次幂的纹理,在些过程中会产生一些拉申或收宿的效果,这样就很难显示一些图片的原始效果,这里的解决办法是,在用PHOTOSHOP等软件画图时,最好是把图片的长与宽都指定成256X256等型式,这样在用ID3DXSprite接口画图片时就不会产生走样了

方法二:
使用平行投影相机OrthoCamera

这里的程序示例以在窗口中画一个四边型为例,画图片是相同的道理

struct VERTEX_T
{
VERTEX_T()
{
v = D3DXVECTOR3( 0,0,0 );
c = D3DCOLOR_ARGB( 0,0,0,0 );
}
VERTEX_T( float x,float y,float z )
{
v = D3DXVECTOR3(  x,y,z );
c = D3DCOLOR_ARGB( 125,0,0,0 );
}

VERTEX_T( float x,float y,float z,D3DCOLOR dif )
{
v = D3DXVECTOR3(  x,y,z );
c = dif;
}

D3DXVECTOR3 v;
D3DCOLOR c;

static const DWORD FVF;
};

const DWORD VERTEX_T::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

void DrawRect_2D( 
int x,
int y,
int w,
int h,
D3DXCOLOR c0,
D3DXCOLOR c1,
D3DXCOLOR c2,
D3DXCOLOR c3,
IDirect3DDevice9* device,
bool trans,
float alpha )
{
VERTEX_T v[4];
D3DXMATRIX proj,identity;

D3DXMatrixIdentity( &identity );
D3DXMatrixOrthoOffCenterLH(&proj,0.0f,(float)Width,-(float)
         Height,0.0f,-100.0f,100.0f);

device->SetTransform(D3DTS_WORLD,&identity);
device->SetTransform(D3DTS_VIEW,&identity);
device->SetTransform(D3DTS_PROJECTION,&proj);
device->SetRenderState(D3DRS_ZENABLE,false);

if( trans )
{
device->SetRenderState( D3DRS_ALPHABLENDENABLE,true );
device->SetRenderState( D3DRS_SRCBLEND,D3DBLEND_SRCALPHA );
device->SetRenderState( D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA );
c0.a = alpha;
c1.a = alpha;
c2.a = alpha;
c3.a = alpha;
}

v[0] = VERTEX_T( x,-y,0,c0 );
v[1] = VERTEX_T( x + w,-y,0,c1 );
v[2] = VERTEX_T( x,-( y + h ),0,c2 );
v[3] = VERTEX_T( x + w,-( y + h ),0,c3 );

device->SetFVF( VERTEX_T::FVF );
device->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP,2,v,sizeof( VERTEX_T ) );

device->SetRenderState( D3DRS_ZENABLE,true );
device->SetRenderState( D3DRS_ALPHABLENDENABLE,false );
}

由于代码很少,在此就不作详细说明了代码中的Width和Height变量是窗口的客户区宽与高

方法三:
可以使用顶点的RHW,在顶点的格式中或上D3DFVF_XYZRHW
RHW它是指该顶点包含已经进行光照、坐标转换后的数据,而该数据就是屏幕座标,因些可以直接在顶点的数据结构中写上屏幕座标即可。我很少用这种方法,只是用它作过实验,因些代码暂不列出

方法四:
就是在3D空间中与相机方向垂直的指定平面上画图,因些就要有两个函数一个是获取相机的原点到屏幕上一点的射线,另一个就是射线与平面的交点,
有了这个交点就可以在3D空间中画四边型了,从而显示出2D图像,
而关键是第一个函数,射线与平面的交点可用数学知识直接求出

下面的函数为计算出鼠标点击窗口的客户区后所产生的相机原点与该点相连的射线

RAY_T CPerspectiveCamera::GetRay( int x,int y )
{
int w = m_W;//D3D绘图区的宽
int h = m_H;//D3D绘图区的高

D3DXMATRIX matProj;
matProj = GetProjMatrix();//得到投影矩阵

POINT ptCursor;
ptCursor.x = x;
ptCursor.y = y;

D3DXVECTOR3 v;
v.x =  ( ( ( 2.0f * ptCursor.x ) / w  ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * ptCursor.y ) / h ) - 1 ) / matProj._22;
v.z =  1.0f;

D3DXMATRIX matView,m;
matView = GetViewMatrix();
D3DXMatrixInverse( &m,NULL,&matView );

RAY_T _ray;

_ray.dir.x  = v.x*m._11 + v.y*m._21 + v.z*m._31;
_ray.dir.y  = v.x*m._12 + v.y*m._22 + v.z*m._32;
_ray.dir.z  = v.x*m._13 + v.y*m._23 + v.z*m._33;
_ray.org.x = m._41;
_ray.org.y = m._42;
_ray.org.z = m._43;

return _ray;
}

由于这个函数是我编写的程序中的一部分,因此有一些函数在这里没有给出原程序,但不影响对这个程序的阅读,请朋友们见谅

以上是我所知道的在D3D中画2D图形的方法,如果大家还有好的方法,请指教
如果以上有错误,请指正,以免给大家造成误导
谢谢

D3D来实现2D的效果 的方法相关推荐

  1. java enum 2d array,Java-打印2D数组的最佳方法?

    Java-打印2D数组的最佳方法? 我想知道打印2D阵列的最佳方法是什么. 这是我的一些代码,我只是想知道这是否是一种好习惯. 如果发现任何其他错误,请更正我在此代码中犯的任何其他错误. 谢谢! in ...

  2. 使用css绘制弹幕,实现弹幕效果的方法总结(css和canvas)

    这篇文章主要介绍了关于实现弹幕效果的方法总结(css和canvas) ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 之前在一个移动端的抽奖页面中,在抽奖结果的展示窗口需要弹幕轮播显示 ...

  3. flash图片如何镜像翻转_在canvas上实现元素图片镜像翻转动画效果的方法

    这篇文章主要介绍了在canvas上实现元素图片镜像翻转动画效果的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧! 一.Canvas图片水平镜像翻转效果预览 ...

  4. 使用Unity实现动态2D水效果

    http://forum.china.unity3d.com/thread-16044-1-1.html 在这片教程里面我们将会用简单的物理效果来模拟动态的2D水效果.我们将会使用Line Rende ...

  5. 使用Unity创造动态的2D水体效果

    者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染器,触发器以及粒子的混合体来创造这一水体效果,最终得到可运用于你下款游戏的水纹和 ...

  6. android怎么模拟返回,Android中障蔽返回键,HOME键以及模拟HOME键返回效果的方法...

    Android中屏蔽返回键,HOME键以及模拟HOME键返回效果的方法 在Android开发中,有时需要屏蔽一些实体的按键,如HOME键,返回键等实体的按键,实现的方法如下. 1. 屏蔽实体按键 屏蔽 ...

  7. java css隔行变色_JS+CSS实现Li列表隔行换色效果的方法

    本文实例讲述了JS+CSS实现Li列表隔行换色效果的方法.分享给大家供大家参考.具体实现方法如下: CSS+Js实现Li列表隔行换色效果 .mytable {border-collapse:colla ...

  8. jQuery 效果 - animate() 方法

    实例 改变 "div" 元素的高度: $(".btn1").click(function(){ $("#box").animate({hei ...

  9. 制作一个状态栏中跑马灯效果_snapseed制作“照片中的照片”画中画效果的方法...

    用摄影修图软件做出"我拿着我的照片给你看"的效果,用snapseed在手机上修图就可以实现,用"双重曝光"+"图层蒙版"的方式,非常容易做到 ...

最新文章

  1. 力扣(LeetCode)刷题,简单题(第7期)
  2. matlab内存管理
  3. spring cloud微服务分布式云架构--hystrix的使用
  4. 微信小程序 wx.request异步网络请求
  5. [骨科手术导航]2D/3D医学图像配准研究_罗博博_南方科技大学
  6. SLF4J: Failed to load class org.slf4j.impl.StaticLoggerBinder
  7. 郑州大学计算机科学复试分数线,2021郑州大学考研复试线发布,计算机大涨,部分热门专业达406分...
  8. docker 4 section
  9. python安装在d盘环境变量配置_python安装与环境变量配置
  10. JavaScript 之 JS重载
  11. 使用代码更新 UIVersion 属性
  12. 定理在数学中的简写形式_初中数学常用的定理大全
  13. 小学生数据分析《西游记》发现大BUG
  14. 懒癌发作,福利直接发,不抢白不抢!
  15. 读遍装修书,我们帮你选出了最有用的10本
  16. 中科院半导体所裴为华研究团队及其合作者在脑电电极领域取得重要研究进展...
  17. java三角形边长_利用java解决三角形角度问题
  18. 成人肛门镜的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  19. 对于2022年美联储将要加息、缩表的见解
  20. 服务器显示EE00,安装完成后,打开前台报错,后台显示不出验证码

热门文章

  1. 中国存储“军团”补位美光,存储芯片的垄断格局要崩了
  2. 【论文阅读】LUPerson-NL
  3. 能测量位移的差动电容式传感器仿真(转)
  4. (10) 朴素贝叶斯
  5. c mysql 批量插入_c#之mysql四种带事务批量插入
  6. Linux 设置开机启动项的几种方法
  7. C#WinForm实现串口通讯
  8. python游戏编程入门源代码_python游戏编程入门源代码
  9. 推荐一款免费的AI代码提示工具Codeium
  10. MySQL批量更新数据总结