DirectX图形处理(5)

在获得了指向IDirect3D7接口的指针之后,就可以通过调用IDirect3D7::CreateDevice方法来创建绘制设备。CreateDevice方法接受所需设备的全局惟一标识符(GUID),用于设备进行绘制的表面的IDirectDrawSurface7接口的地址,以及一个变量的地址(如果设备对象创建成功,则该方法会把IDirect3DDevice7接口指针设置到变量中)。虽然本例使用了硬编码的GUID值,实际的应用程序应当枚举设备来获得GUID。
   Triangle例子程序在创建设备之前检查显示模式。如果显示器设置为调色板模式,则程序就退出。为与调色板无联系的调色板表面创建设备会导致CreateDevice方法失败。这样做的目的是简化编程。实际的应用程序应当创建绘制目标表面并联系到一个调色板,或要求用户将显示模式设置为16位彩色或更高的模式。

   下列取自Triangle的代码检查了显示模式并创建了绘制设备:

    // 检查显示模式

    ddsd.dwSize = sizeof(DDSURFACEDESC2);

    g_pDD->GetDisplayMode( &ddsd );

    if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )

        return DDERR_INVALIDMODE;

 

    // 此处的GUID是硬编码的,在实际的应用程序中应通过枚举设备来获取

    hr = g_pD3D->CreateDevice( IID_IDirect3DHALDevice, g_pddsBackBuffer,

                            &g_pd3dDevice );

    if( FAILED( hr ) )

    {

        // 如果硬件GUID不能工作,尝试用软件设备

        hr = g_pD3D->CreateDevice( IID_IDirect3DRGBDevice, g_pddsBackBuffer,

                                 &g_pd3dDevice );

        if( FAILED( hr ) )

            return hr;

    }

   CreateDevice可能由于多种原因而失败。最可能的原因是主显示设备不支持3-D功能。另一个可能的原因是显示硬件不能在当前显示模式下绘制。在枚举设备期间应当检查这些可能性。为了保持代码的简短性,如果不能创建硬件设备,则Triangle企图创建一个软件绘制设备。

   注意:即使CreateDevice方法接受一个指向DirectDrawSurface对象的指针,绘制设备也不是表面。相反,它是一个离散的用表面来为绘制场景包含图形的COM对象。

(4)准备视口

   在创建了绘制设备之后,就可以创建视口并将其指派给该设备了。简而言之,视口决定了3-D场景中的几何图形怎样被剪裁,然后在显示屏幕的2-D空间中显示。

   设置视口是一个直接的过程,以在D3DVIEWPORT7结构中准备视口参数开始。Triangle 例子程序给绘制目标表面的尺寸设置视口参数,如下所示:

    // 创建视口

    DWORD dwRenderWidth = g_rcScreenRect.right - g_rcScreenRect.left;

    DWORD dwRenderHeight = g_rcScreenRect.bottom - g_rcScreenRect.top;

    D3DVIEWPORT7 vp = { 0, 0, dwRenderWidth, dwRenderHeight, 0.0f, 1.0f };

一旦准备好视口结构,Triangle应用程序就将它指派给绘制设备,如下所示:

    hr = g_pd3dDevice->SetViewport( &vp );

    if( FAILED( hr ) )

        return hr;

3. 初始化场景
   在创建了主Direct3D相关对象(一个DirectDraw对象、一个绘制设备和一个视口)后,就可以通过设置几何图形、准备材料和配置应用程序将使用的转换矩阵来初始化场景。Triangle例子程序使用一个应用程序定义的函数App_InitDeviceObjects来执行以下初始化场景的步骤。

(1)准备几何图形

   在用DirectDraw和Direct3D创建了主系统对象之后,就可以开始初始化场景。Triangle例子程序利用这个机会通过定义存储在一个D3DVERTEX结构数组中的顶点来初始化几何图形。从技术上来说,并不需要在这个时候初始化几何图形,可以在调用绘制方法之前的任何时候进行初始化。

HRESULT App_InitDeviceObjects( LPDIRECT3DDEVICE7 pd3dDevice )

{

    // 用于三角形几何图形的数据

    D3DVECTOR p1( 0.0f, 3.0f, 0.0f );

    D3DVECTOR p2( 3.0f,-3.0f, 0.0f );

    D3DVECTOR p3(-3.0f,-3.0f, 0.0f );

    D3DVECTOR vNormal( 0.0f, 0.0f, 1.0f );

   

    // 为三角形的前景初始化3个顶点

    g_pvTriangleVertices[0] = D3DVERTEX( p1, vNormal, 0, 0 );

    g_pvTriangleVertices[1] = D3DVERTEX( p2, vNormal, 0, 0 );

    g_pvTriangleVertices[2] = D3DVERTEX( p3, vNormal, 0, 0 );

   

    // 为三角形的背景初始化3个顶点

    g_pvTriangleVertices[3] = D3DVERTEX( p1, -vNormal, 0, 0 );

    g_pvTriangleVertices[4] = D3DVERTEX( p3, -vNormal, 0, 0 );

    g_pvTriangleVertices[5] = D3DVERTEX( p2, -vNormal, 0, 0 );

   上面的代码片段在3-D空间中定义了三个点,这三个点定义了一个位于z=0平面的三角形。

(2)设置材料和初始化光照状态

   在创建了基本3-D绘制对象(一个DirectDraw对象、一个绘制设备和一个视口)后,接下来创建并配置材料和设置一些初始光照状态。Triangle例子程序按下面所示的方法设置材料参数:

    D3DMATERIAL7 mtrl;

    ZeroMemory( &mtrl, sizeof(mtrl) );

    mtrl.ambient.r = 1.0f;

    mtrl.ambient.g = 1.0f;

    mtrl.ambient.b = 0.0f;

    pd3dDevice->SetMaterial( &mtrl );

   上面的代码准备了材料属性,用一个D3DMATERIAL7结构来表示。代码准备D3DMATERIAL7结构用于描述即将反映出环境光线的红色和绿色成分的材料,使其在场景上显示为黄色(本例只使用环境光线,因此只设置了一个环境反射系数属性。实际的应用程序应使用直接光线和环境光线,也应当设置漫射和镜面反射系数属性)。在准备了材料属性后,代码通过调用IDirect3DDevice7::SetMaterial方法将其应用于设备。

   注意:在使用纹理时,对象材料通常省略或着上白色。

   选择了当前的材料后,使用该材料来绘制所有的多边形,但在场景中的任何事物可见之前必须提供一些光线。Triangle应用程序中的代码通过调用IDirect3DDevice7:: SetRenderState方法来设置环境光线等级,如下所示:

    // 环境光照值是要设置的另一个状态,这里将环境光照值变为全白色

    pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT,OxFFFFFFFF);

(3)准备和设置转换矩阵

   设置简单场景的另一个步骤是设置世界矩阵、视图矩阵和投影矩阵。系统将这些矩阵用于把几何图形显示在场景中,调整照相机的位置和朝向,缩放顶点数据使远距离对象显得比近距离对象更小。

   Triangle例子程序通过用D3DMATRIX结构创建一个身份矩阵开始,然后操纵矩阵以产生所需要的转换。一旦准备好一个矩阵,代码就通过用D3DTRANSFORMSTATE _WORLD,D3DTRANSFORMSTATE_VIEW或D3DTRANSFORMSTATE_PROJECTION当做参数调用IDirect3DDevice7::SetTransform方法将该矩阵指派给设备。

    // 通过设置一个身份矩阵开始

    D3DMATRIX mat;

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

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

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

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

   

    // 世界矩阵在世界空间里控制多边形的位置和方向,在后面会用该矩阵来旋转

    // 三角形
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值