DX9绘图基础-------VB6编程学习DX9游戏编程DirectX9编程2D小游戏源码冷风引擎CoolWind2D游戏引擎(7)

**

绘图基础

**
一:清除后备缓冲区
在度娘搜索 “DX9绘图”或者“DirectX9绘图”,出来的东西不少,几乎找不到VB6的!还有会出来一个机器人,也叫DX9,不知道什么鬼!
上一篇搞定了DX9的初始化,出现一个800*600的窗口,今天,我们要在这个窗口中,画上一些图形,比如长方形,正方形,圆形,点,线这类的。
在DX9初始化结束后,我们要用IDirect3DDevice9::Clear函数来清除后备缓冲区。

IDirect3DDevice9::Clear 方法 (d3d9helper.h) 原型如下:C++

HRESULT Clear(
  [in] DWORD         Count,
  [in] const D3DRECT *pRects,
  [in] DWORD         Flags,
  [in] D3DCOLOR      Color,
  [in] float         Z,
  [in] DWORD         Stencil
);

参数如下:
Count :pRects 数组中的矩形数。 如果 pRect 为 NULL,则必须设置为 0。 如果 pRects 是有效的指针,则不能为 0。
pRects:指向描述要清除的矩形的 D3DRECT 结构的数组的指针。 将矩形设置为呈现目标的尺寸以清除整个图面。 每个矩形都使用对应于呈现目标上的点的屏幕坐标。 坐标被剪裁为视区矩形的边界。 若要指示要清除整个视区矩形,请将此参数设置为 NULL 并将 Count 设置为 0。
D3DRECT结构如下(作用:定义矩形的坐标。):

typedef struct D3DRECT {
  LONG x1; //矩形左上角的 x 坐标。
  LONG y1;//矩形左上角的 y 坐标。
  LONG x2;//矩形右下角的 x 坐标。
  LONG y2;//矩形右下角的 y 坐标。
} D3DRECT;

Flags:一个或多个 D3DCLEAR 标志的组合,这些标志指定要清除的图面 (s) 。
D3DCLEAR:这些标志标识调用 Clear 时要重置的图面。参数如下:
D3DCLEAR_STENCIL 清除模具缓冲区。
D3DCLEAR_TARGET 清除呈现目标或多个呈现目标中的所有目标。
D3DCLEAR_ZBUFFER 清除深度缓冲区。

Color:清除此 ARGB 颜色的呈现目标。这里我们为了方便调用,在模块里定义了一个常用颜色类型表,如下所示:
语言:VB6,放在BAS模块中。

'*********************常用颜色列表***************************
Enum CWColorConstants
    CWColorNone = &H0          '完全无色
    CWTransparent = &HFFFFFF    '透明有色(方便位运算截取颜色部分)
    
    CWBlack = &HFF000000        '黑色
    CWWhite = &HFFFFFFFF        '白色
    CWGrey = &HFF808080         '灰色
    CWRed = &HFFFF0000          '红色
    CWGreen = &HFF00FF00        '绿色
    CWBlue = &HFF0000FF         '蓝色
    CWYellow = &HFFFFFF00       '黄色
    CWPurple = &HFFFF00FF       '紫色
    CWCyan = &HFF00FFFF         '青色
    CWOrange = &HFFFF8000       '橙色
    CWkelly = &HFF80FF00        '黄绿色
    CWFuchsia = &HFFFF0080      '紫红色
    CWViolet = &HFF8000FF       '蓝紫色
    CWTurquoise = &HFF00FF80    '青绿色
    CWCyanine = &HFF0080FF      '青蓝色
    
    CWHA_Black = &H80000000     '半透明黑色
    CWHA_White = &H80FFFFFF     '半透明白色
    CWHA_Grey = &H80808080      '半透明灰色
    CWHA_Red = &H80FF0000       '半透明红色
    CWHA_Green = &H8000FF00     '半透明绿色
    CWHA_Blue = &H800000FF      '半透明蓝色
    CWHA_Yellow = &H80FFFF00    '半透明黄色
    CWHA_Purple = &H80FF00FF    '半透明紫色
    CWHA_Cyan = &H8000FFFF      '半透明青色
    CWHA_Orange = &H80FF8000    '橙色
    CWHA_kelly = &H8080FF00     '黄绿色
    CWHA_Fuchsia = &H80FF0080   '紫红色
    CWHA_Violet = &H808000FF    '蓝紫色
    CWHA_Turquoise = &H8000FF80 '青绿色
    CWHA_Cyanine = &H800080FF   '青蓝色
End Enum
'其他颜色请参考RGB颜色列表用CWColorARGB函数自行转换
'*********************常用颜色列表***************************

Z:清除深度缓冲区到此新的 z 值,范围为 0 到 1。 请参阅备注。
Stencil:清除模具缓冲区到此新值,范围为 0 到 2ⁿ-1 (n 是模具缓冲区) 的位深度。请参阅备注。

返回值:如果方法成功,则返回值D3D_OK。 如果方法失败,则返回值可以是:D3DERR_INVALIDCALL。

在VB6中如何使用呢?

    Public CWD3D9 As Direct3D9, CWD3DDevice9 As Direct3DDevice9,
    
    CWD3DDevice9.Clear 0, ByVal 0, D3DCLEAR_TARGET, BackColor, 0!, 0
    CWD3DDevice9.BeginScene

CWD3DDevice9.BeginScene表示开始场景渲染。更多的Direct3DDevice9接口方法可以参考巨硬官方站点的资料。

二:兄弟们,先给张三画上麻子脸!也就是在屏幕上绘制一个红点。俗话说的好,星星之火可以燎原,同样,在屏幕上画一个小点,也是值得期待的,这就相当于刚学VB的时候,敲出来“HELLO,世界!”一样。
在画点之前,我们先了解一下绘制流水线:在给定的3D场景指定观察方向的虚拟摄像机几何描述时,创建一幅2D图像。
怎么理解?
1,这老外讲话就是有档次啊,几何描述其实就是模型表示,在游戏中,任何物体都可以用三角形网格逼近表示。三角形网格是建立物体模型的基本单元。如下图所示,三角形越是密集,显示的图片效果越好,拟真度越高,但相应的占用的资源也越大。
三角形网格
所以一个模型包含以下部分:
①三角形单元:为了构建一个物体,需要创建一个描述物体形状和轮廓的三角形单元列表。这个列表包含了我们所希望绘制的每个独立三角形的数据。三角形各顶点的指定顺序非常重要,我们称其为绕序。

②顶点格式:
Direct3D允许自定义顶点格式。一般以结构体表示顶点格式。在创建好顶点格式之后,需要利用灵活顶点格式FVF(Flexible Vertex Format)标记的组合来描述顶点的组织结构。定义FVF时需要遵循的约定是:FVF标记的指定顺序必须与顶点结构中相应类型数据顺序保持一致。

③索引: 在利用三角形图元建立物体模型时,可能会有很多顶点是重合的。索引就是为了解决这个问题。

关于这部分内容有大量的数学理论和计算,我就不说了(其实我也不会),有兴趣的找一本计算机图形学方面的书看看。这里我们就简单的会用就行了,比如,先设置一个2D的顶点格式:

Public Type D2DVector   '2D顶点类
    X As Single
    Y As Single
    Z As Single
    Rhw As Single
    Color As CWColorConstants
'    Specular As Long
'    Tu As Single
'    Tv As Single
End Type

2.虚拟摄像机:摄像机指定了场景对观察者的可见部分,即我们依据那部分3D场景来创建2D图像。简单讲,就是在窗口绘图中,我们能看到的部分(看不到的地方比如树木背面,墙背面等就通过裁剪等方法舍去,涉及大量计算。)

3,场景绘制流程:在建立好3D场景的几何描述并设置好虚拟摄像机之后,下面就是在显示器中建立2D场景。下图为大致流程:
2D场景绘制流程
① 局部坐标系: 局部坐标系或者建模坐标系,用于定义物体的三角形单元列表的坐标系。采用局部坐标系的优点在于简化了建模过程。(下图是一个三个顶点定义的一个三角形)
三个顶点定义的一个三角形
②世界坐标系:构建物体模型时是使用局部坐标系,但要把这些物体组织在一起就需要世界坐标系。位于局部坐标系的物体通过一个世界变换(world transform)的运算变换到世界坐标系。世界变换用一个矩阵来表示,并由Direct3D呼叫IDirect3DDevice9::SetTransform方法加以利用。
世界坐标与局部坐标转换

Public Type CWMatrix   '2D矩阵
    m11 As Single: m12 As Single
    m21 As Single: m22 As Single
    mdx As Single: mdy As Single
End Type

③ 观察坐标系: 在世界空间中,几何体和摄像机都是相对世界坐标系定义的。但是,当摄像机的位置和朝向任意时,投影变换和其他类型的变换就略显困难或效率不高。为了简化运算,我们将摄像机变换至世界坐标系的原点,并将其旋转,使摄像机光轴和世界坐标的Z轴正方向一致。同时,世界坐标系的所有几何体随摄像机一同变换,使得其视场恒定。这种变换称为取景变换,变换后的几何体位于观察坐标系中。
④背面消隐:每个图形都正面和背面。背面要求是不可见的。即摄像机禁止进入内部实体空间。为了实现背面消隐,Direct3D需要知道哪些多边形是正面朝向的还是背面朝向的。默认状态下,Direct3D认为顶点排列顺序为顺时针的三角形单元是正面朝向的(在观察坐标系中)。
⑤光照:光源是在世界坐标系中定义的,但必须经过取景变换至观察坐标系方向方可使用。
⑥裁剪:把视域体之外的几何体剔除掉即为裁剪。一个三角形单元与视域体的位置关系有三种,分别为完全在内部、完全在外部和部分在内(部分在外)。
视域体用图形表示如下:
视域体
在3D图形学中,上述几何体称为“视域体”。采用视域体的主要原因是显示是矩形。那些视域体之外的部分是不可见的,因此需要丢弃,丢弃的过程称为裁剪(clipping)。投影窗口是一个2D区域,位于视域体的3D图形通过投影映射到该区域,便创建了2D图形。

⑦投影:观察坐标系中,我们的任务是获取3D场景的2D表示。从n维变换到n-1维的过程称为投影。我们这里讲透视投影(投影的一种)。透视投影会产生“透视缩短”的效果,即近大远小。这类投影可以使我们可以用2D图像表示3D场景。投影变换定义了视域体,并负责将视域体中的几何体投影到窗口中,因此投影矩阵比较复杂。如下函数是依据视域体的描述信息创建一个投影矩阵。
⑧ 视口变换:视口变换(viewport transform)的任务是将顶点坐标转换到屏幕的一个矩形区域中,该矩形区域被称为视口。在Direct3D中,视口用结构D3DVIEWPORT9描述。
⑨光栅化:顶点坐标变换为屏幕坐标后,我们就有一个2D三角形图元列表。光栅化的任务就是绘制每个三角形图元,如何计算构成三角形图元的每个像素的颜色值。光栅化的最终结果显示在屏幕上。

以上绘图原理了解即可,来个浑沦吞枣吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gosub60

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值