3D游戏编程(三)

前面三步已经实现了从普通Win32 SDK程序到D3D程序的转变, 并且对于设备的初始化和绘图框架也结合程序作了介绍. 接下来就要实现图形从静态到动态, 从平面到立体的变换.

第四步: 让图形动起来

在图形学中, 三维图形的绘制和运动是通过基本变换 (平移 (transition), 缩放 (Scaling), 旋转 (Rotation)) 的综合运用辅以时间控制实现. 前面我提到过, 几何变换在计算机中通过矩阵运算实现. 所以, 在这一步中, 矩阵是重头戏.

从几何学中的图形到进入人的视界的对象, 主要经过了三种变换: 世界变换 (World Transform), 摄像机变换 (Camera Transform), 投影变换 (Projection Transform), 在借助计算机实现时, 它们分别对象三种矩阵: World Metrix, View Metrix, Projection Metrix. 下面通过程序说明:

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"d3dx9.lib")

#include 
<MMSystem.h>    // 时间函数
#include <d3d9.h>               // 设备初始化及操作
#include <d3dx9.h>             //  矩阵操作

//

//    函数: InitInstance(HINSTANCE, int)
//

//    目的: 保存实例句柄并创建主窗口
//

//    注释:
//

//         在此函数中,我们在全局变量中保存实例句柄并
//
        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int
 nCmdShow)
{
    ......
    
if
 (SUCCEEDED(InitD3D(hWnd)))
    
{
        
if(SUCCEEDED(InitGeometry()))    // 使用InitGeometry函数

        {
            ShowWindow(hWnd, nCmdShow);
            UpdateWindow(hWnd);
        }

    }

    
return TRUE;
}


BOOL InitD3D(HWND hWnd)
{
    ......
    
// 卷起, 渲染三角形前面及后面

    g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    
// 顶点具有颜色值, 起到光源作用

    g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    
return
 S_OK;
}


HRESULT InitGeometry()
{
    
// 渲染三角形顶点

    CUSTOMVERTEX vertices[] = 
    
{
        
{-1.0f-1.0f0.0f0xffff0000},            // x, y, z, rhw

        {1.0f-1.0f0.0f0xff00ff00},
        
{0.0f1.0f0.0f0xff0000ff}

    }
;

    
// 创建顶点缓冲

    if(FAILED(g_pD3DDevice->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX),
            
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &
g_pVB, NULL)))
    
{
        
return
 E_FAIL;
    }


    
// 写入顶点缓冲
    VOID *pVertices;
    
if(FAILED(g_pVB->Lock(0sizeof(vertices), (void **)&pVertices, 0
)))
    
{
        
return
 E_FAIL;
    }

    memcpy(pVertices, vertices, 
sizeof(vertices));
    g_pVB
->
Unlock();

    
return
 S_OK;
}


void  SetupMatrices()
{
    
// 世界矩阵

    D3DXMATRIXA16 matWorld;

    UINT iTime 
= timeGetTime() % 1000
;
    FLOAT fAngle 
= iTime * (2.0f * D3DX_PI) / 1000.0f
;

    D3DXMatrixRotationY(
&matWorld, fAngle);     // 绕Y轴旋转

    g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

    
// 视图矩阵

    D3DXMATRIXA16 matView;
    D3DXVECTOR3 vEyePt(
0.0f3.0f-5.0f);        // 眼睛的位置

    D3DXVECTOR3 vLookatPt(0.0f0.0f0.0f);    // 眼睛观察的位置
    D3DXVECTOR3 vUpVec(0.0f1.0f0.0f);        // 表现顶点方向的上方向量

    D3DXMatrixLookAtLH(
&matView, &vEyePt, &vLookatPt, &vUpVec);
    g_pD3DDevice
->SetTransform(D3DTS_VIEW, &
matView);

    
// 投影矩阵

    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(
&matProj, D3DX_PI/41.0f1.0f100.0f
);
    g_pD3DDevice
->SetTransform(D3DTS_PROJECTION, &
matProj);
}


void  Render()
{
    
if(NULL ==
 g_pD3DDevice)
        
return
;

    
// 清除后置缓冲区, 同时设置为蓝色 (0, 0, 255)

    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(000), 1.0f0);

    
// 开始渲染

    if(SUCCEEDED(g_pD3DDevice->BeginScene()))
    
{
        
// 创建矩阵

        SetupMatrices();

        
//
 绘制顶点缓冲三角形
        
// 绑定设备数据流

        g_pD3DDevice->SetStreamSource(0, g_pVB, 0sizeof(CUSTOMVERTEX));

        
// 指定顶点着色信息(FVF)

        g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

        
// 输出三角形

        g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 01);

        
// 结束渲染

        g_pD3DDevice->EndScene();
    }


    
// 显示后置缓冲的画面
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

1)  由于涉及对象的旋转, 因此, 对三角形的前后都需要渲染;

2) 设定三种矩阵.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值