sldbtree

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

进入DirectX 8后,微软移除了DirectDraw。对很多熟悉了“读取frame buffer(帧缓冲)句柄和内存跨度(pitch),然后对帧缓冲进行像素级操作”的程序员来说,很大的一个疑问是2D的图形该怎么做,因为即使在3D世界中,UI(人机界面)等很多元素还是需要通过2D来实现的。


在知道D3D的做法前,我们了解一下原理:对正常的3D的数据来说,无论是多大的一个几何体(geometric),最终都是有一系列的顶点(vertex)来构成,这些顶点用3D坐标,因此具备(x,y,z)三个分量来表示在空间中的位置。在3D渲染流程中,每个正常的顶点必然经过3个变换过程。第一个是转化到世界坐标(设置D3DTS_WORLD);第二个是转化到相机坐标(设置D3DTS_VIEW);第三个是转化到屏幕坐标(设置D3DTS_PROJECT). 注意到我前面讲到的是正常的顶点会进过这么几步转化。那么对于我们的2D图像来说,我们其实要做的是告诉D3D“请您不要对我的坐标进行转化,因为它们直接跟屏幕对应了”。也就是需要一些非正常的顶点。下面是相关的做法,


在上面讲的顶点转化到最后的时候,按我们的理解,其实最后的输出只有x、y坐标(事实上只要这两个坐标就可以)。但是D3D其实最后输出x,y,z,RHW(Reciprocal Homogeneous W)值。D3D要我们通过API做的手脚也就在这里,如果你需要绘2D,请把顶点的z,RHW设置为1.0f,这样通过3D API绘图的时候,D3D会得到信息,“用户这个顶点是要我不要对它进行转化了,直接跳到屏幕mapping去”。因此上面的三个转化就会被跳过,而实现跟DirectDraw一样的效果。


当然,上面说到z值和RHW值都需要设置为1是为了方便,事实上,只有RHW一定需要设置为1。z值的取值范围可以在0到1之间(不过1.0f这个值是表示无限远,用的话没有图像可以看到,用近似1.0的值就可以)。如果是0,意味着你画的所有2D在所有3D物体的前面,1则是让2D物体在最后面。举例,GUI (Graphics User Interface) HUD Heads-Up Display 的时候,我们取0.0f;如果是背景,我们就取近似1.0f。


 

好了,原理说到这里。离开前,大致说一下D3D的代码。在代码中,大致如此这般,


 

// vertex format declare

D3DVERTEXELEMENT9 decl[] {

0, 0,  D3DDECLTYPE_FLOAT4,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, },

0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    },

 

D3DDECL_END()

};


// create declaration

m_pDevice->CreateVertexDeclaration (decl, &vertexDecl);

 


 

// active this declaration

m_pDevice->SetVertexDeclaration(vertexDecl);


 

为防止你跟我一样在看其他人的示例代码的时候会快速扫描,请着重看一下红色部分,特别是D3DDECLUSAGE_POSITIOINT,看到最后一个字母的T没有(有木有!?)。


如果你对FVF的方式比较熟悉,那么是这样:


 

struct Vertex
{
   float     x, y, z, rhw;
   D3DCOLOR color;
}


#define VERTEX__FVF (D3DFVF_XYZRHW D3DFVF_DIFFUSE)


Note:

1、D3D内部统一都用3D的绘图方式,因此请注意你的QUAD其实也要遵循三角形的一切原则,如CCW顺序等。

2、用上述方法的时候,屏幕坐标跟DirectDraw一样,屏幕左上角是(0,0).

3、对那些hardcore coder,可以感谢COM技术,通过COM,DirectDraw还是可以用的。




参考书目:

1、Windows DirectX Graphics Documention(August 2009), 章节 Direct 3D Programming Guide Direct3D Resource Vertex Buffer Vertex Declaration Mapping FVF codes to Direct3D declaration



附录:

1、在D3D中绘制2D的示例代码

 

http://www.163disk.com/fileview_326826.html

注意:请用up/down键前后移动相机观察相机在z轴的位置变化会不会对Quad产生影响。

posted on 2011-06-28 15:09  sldbtree  阅读(812)  评论(0)    收藏  举报