DirectX图形处理(6)

D3DMATRIX matWorld = mat;

    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );

 

    // 视图矩阵定义了照相机的位置和方向,这里只是将其沿z轴向后移动了10

    // 个单位

    D3DMATRIX matView = mat;

    matView._43 = 10.0f;

    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );

 

    // 投影矩阵定义了怎样将3-D场景投影到2-D绘制目标表面上

 

    // 设置一个非常简单的投影,x和y的单位为2,用 -1.0来翻译z

    D3DMATRIX matProj = mat;

    matProj._11 =  2.0f;

    matProj._22 =  2.0f;

    matProj._34 =  1.0f;

    matProj._43 = -1.0f;

    matProj._44 =  0.0f;

    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );

   当设置了转换之后,Triangle就完成了设置场景的任务。应用程序定义的App_InitDeviceObjects函数向调用者返回S_OK。然后,Initialize3DEnvironment函数向WinMain返回该值,WinMain继续处理系统消息。

4. 监视系统消息
   在创建了应用程序窗口以后创建了DirectX对象,然后初始化了场景,接着就可以绘制场景了。在大多数情况下,Windows应用程序在其消息循环中监视系统消息,并在消息队列为空时绘制帧。Triangle例子程序没有不同,它在其消息循环中使用了下列代码:

    BOOL bGotMsg;

    MSG  msg;

    PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

    g_bReady = TRUE;

 

    while( WM_QUIT != msg.message  )

    {

        // 在应用程序处于活动状态时使用函数Use PeekMessage(),因此可以使用

        // 空闲时间来绘制场景。另外,用函数GetMessage()来避免消耗CPU时间

        if( g_bActive )

            bGotMsg = PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE );

        else

            bGotMsg = GetMessage( &msg, NULL, 0U, 0U );

 

        if( bGotMsg )

        {

                TranslateMessage( &msg );

                DispatchMessage( &msg );

        }

        else

        {

            // 在空闲时间内绘制一帧(没有消息在等待)

            if( g_bActive && g_bReady )

                Render3DEnvironment();

        }

    }

   上面的代码使用了一个全局标志变量g_bActive来跟踪应用程序是否处于活动状态,另一个变量g_bReady用于表明所有的系统对象是否准备好绘制场景。应用程序在窗口不可见时将g_bActive设置为 FALSE,在需要重建用于绘制场景的对象时将g_bReady变量设置为FALSE。

   如果应用程序处于活动状态,就会检查消息队列是否存在未决消息。如果在该队列中有消息,代码就像任何其他Windows应用程序那样将它们分发出去。否则,就调用应用程序定义的Render3DEnvironment函数来绘制一帧场景。

5. 绘制与显示场景
   在应用程序没有处理系统消息时,可以绘制一幅场景的框架。当消息队列为空时,Triangle例子程序在WinMain中调用应用程序定义的Render3DEnvironment函数来绘制场景。Render3DEnvironment函数将绘制任务分为三个子步骤。

(1)更新场景

   Triangle例子程序中在调用Render3DEnvironment函数后,立即调用App_ FrameMove(另一个应用程序定义的函数)。App_FrameMove函数简单地更新Direct3D用于几何图形的世界矩阵,以便反映沿y轴方向的基于一个内部计数值的旋转,该计数值以fTimeKey参数的形式传递给函数。因为旋转对每一帧都要执行一次,最终结果看起来好像模型被实地旋转一样。代码如下:

HRESULT App_FrameMove( LPDIRECT3DDEVICE7 pd3dDevice, FLOAT fTimeKey )

{

    // 在这个例子中沿y轴方向旋转三角形。设置一个4×4矩阵来定义旋转并将它

    // 设置为新的世界转换

    D3DMATRIX matSpin;

    matSpin._11 = matSpin._22 = matSpin._33 = matSpin._44 = 1.0f;

    matSpin._12 = matSpin._13 = matSpin._14 = matSpin._41 = 0.0f;

    matSpin._21 = matSpin._23 = matSpin._24 = matSpin._42 = 0.0f;

    matSpin._31 = matSpin._32 = matSpin._34 = matSpin._43 = 0.0f;

   

    matSpin._11 = (FLOAT)cos( fTimeKey );

    matSpin._33 = (FLOAT)cos( fTimeKey );

    matSpin._13 = -(FLOAT)sin( fTimeKey );

    matSpin._31 = (FLOAT)sin( fTimeKey );

 

    pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matSpin );

 

    return S_OK;

}

   当然,在现实世界中,应用程序将执行比对一个三角形实施一次简单的旋转更多的任务。

(2)绘制场景

   一旦几何图形更新后反映出所需要的动画,就可以绘制场景了。Triangle例子程序采用了一种典型的方法。在例子程序的Render3DEnvironment函数中调用的应用程序定义的App_Render函数通过清除视口开始:

HRESULT App_Render(LPDIRECT3DDEVICE7 pd3dDevice, D3DRECT* prcViewRect )

{

    // 将视口清除为蓝色

    pd3dDevice->Clear( 1UL, prcViewRect, D3DCLEAR_TARGET, Ox000000FF,

                       0L, 0L );

   上面的代码调用IDirect3DDevice7::Clear方法来清除视口。Clear方法接收的前两个参数为:一个用于描述绘制目标表面上要清除的区域的矩形数组的地址;另一个用于通知该方法应当清除多少个来自数组的矩形的值。在大多数情况下会使用一个覆盖了整个绘制目标的矩形。第三个参数决定了该方法的行为。可以清除一个绘制目标表面、一个相关深度缓冲区、模板缓冲区,或者这三者的任意组合。这个例子没有使用深度缓冲区,D3DCLEAR _TARGET是所使用的惟一标志。最后三个参数用于为绘制目标、深度缓冲区和模板缓冲区反映清除值。Triangle例子程序将绘制目标表面的清除颜色设置为蓝色。因为剩下的参数在例子程序中没有使用,代码将它们设置为零。Clear方法在相应的标志没有出现时会忽略它们。

   在清除了视口之后,Triangle例子程序通知Direct3D绘制将要开始,然后绘制场景,最后发出信号表明绘制已经完成,如下所示:

    // 开始场景

    if( FAILED( pd3dDevice->BeginScene() ) )

        return E_FAIL;

 

    // 调用函数DrawPrimitive()来绘制三角形,接着例子程序将进入更多的调用各

    // 种绘制多边形的函数的细节

    pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX,

                             g_pvTriangleVertices, 6, NULL );

 

    // 结束场景

    pd3dDevice->EndScene();

 

    return S_OK;

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi是一种高级的编程语言,基于Object Pascal。它广泛用于开发Windows应用程序,包括图形和游戏方面的开发。DirectX则是一套由微软开发的多媒体API,用于在Windows平台上进行高效的图形和游戏开发。 使用Delphi可以结合DirectX库来创建各种图形和游戏应用程序。DirectX提供了强大的图形渲染和音频处理功能,而Delphi则提供了易于使用的开发工具和语法。通过结合使用这两个工具,可以轻松地创建出令人惊叹的图形效果和吸引人的游戏体验。 Delphi提供了一系列的组件和类库,方便开发人员使用DirectX进行开发。例如,它提供了TDirectX 图形控件,可以用于显示图像、视频和动画。此外,Delphi还提供了TDirectXInput组件,用于处理游戏中的用户输入,例如键盘和鼠标操作。还有一些其他的组件,用于处理声音、网络和多媒体等方面的功能。 在使用Delphi与DirectX进行游戏开发时,可以通过使用DirectX提供的渲染功能来创建各种2D和3D图形效果。Delphi提供了丰富的绘图函数和工具,可以轻松地绘制各种形状和效果。此外,可以使用Delphi的事件和处理机制来处理游戏中的用户输入和游戏逻辑。通过使用这些功能,开发人员可以创造出各种各样的游戏:从简单的益智游戏到复杂的角色扮演游戏,都可以轻松实现。 总而言之,Delphi与DirectX的结合使得图形和游戏开发变得更容易和高效。借助Delphi的简洁语法和丰富功能,以及DirectX的强大渲染和音频处理能力,开发人员可以创造出令人惊叹的图形效果和吸引人的游戏体验。无论是初学者还是有经验的开发人员,都可以通过使用这两个工具来实现他们的游戏开发梦想。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值