游戏艺术工厂

首页 » 游戏制作交流 » 游戏程序 » [转帖]DirectX9.0的初级教学
前腐后继 - 2006-12-13 10:57:00
 

编程环境VC++6。6
DirectX 9.0 SDK  没有可以去微软官方网站下载
进入C++6。0单击“文件”菜单,选“新建”,在“新建”对话框中选Win32 Application
输入文件名为Mygame1
以下选择空项目,完成既可。
这时新建文件,选择C++ SOURCE 文件。名为本Mygame1


#include <d3d9.h>

#pragma comment(lib,"d3d9.lib")          ///////////缺少这句编译不能通过

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;

HRESULT InitialiseD3D(HWND hWnd)
{
    //创建D3D对象,并获得D3D接口指针
 
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_pD3D == NULL)
    {
        return E_FAIL;
    }

    //获得当前的显示模式
    D3DDISPLAYMODE d3ddm;
    if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
    {
        return E_FAIL;
    }


    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    
    //创建窗口模式的D3D
    
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = d3ddm.Format;

    //创建D3D的设备对象,并获取接口IDirect3DDevice9的指针
    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,
                                   &g_pD3DDevice)))
    {
        return E_FAIL;
    }
    
    return S_OK;
}

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

    //用绿色清除后备缓存
    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
    
    //开始屏幕操作
    g_pD3DDevice->BeginScene();
    
    //我们将在中间完成所有的3D渲染
    
    //结束屏幕操作
    g_pD3DDevice->EndScene();
    
    
    //翻转后备为屏幕,使画面显示在屏幕上
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

void CleanUp()
{
    if(g_pD3DDevice != NULL)
    {
        g_pD3DDevice->Release();
        g_pD3DDevice = NULL;
    }

    if(g_pD3D != NULL)
    {
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}

void GameLoop()
{
    //进入游戏循环
    MSG msg; 
    BOOL fMessage;

    PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
    
    while(msg.message != WM_QUIT)
    {
        fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

        if(fMessage)
        {
            //处理消息
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
         //没有消息时,处理渲染图象
            Render();
        }

    }
}

//Windows消息处理机制,用来处理各种WINDOWS消息,包括常用的键盘消息
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        break;
        case WM_KEYUP: 
            switch (wParam)
            { 
                case VK_ESCAPE:
                    //按“ESC”键退出
                    DestroyWindow(hWnd);
                    return 0;
                break;
            } 
        break;

    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

//应用程序入口主函数,相当于C语言的main()函数
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
    //注册窗口类
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L, 
                     GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                     "DX9", NULL};
    RegisterClassEx(&wc);

    //创建应用程序窗口
    HWND hWnd = CreateWindow("DX9", "mygame1", 
                              WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL);

    //Initialize Direct3D
    if(SUCCEEDED(InitialiseD3D(hWnd)))
    { 
        //显示窗口
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        //开始游戏并循环
        GameLoop();
    }
    
    CleanUp();

    UnregisterClass("DX9", wc.hInstance);
    
    return 0;
}
前腐后继 - 2006-12-13 10:59:00
以前的教程都是画一个空间三角形,今天我们用D3D9来画多边行。
//-----------------------------X
多增加的代码在这两个标志的中间部分
//X-----------------------------
#include <d3d9.h>

#pragma comment(lib,"d3d9.lib")          ///////////缺少这句编译不能通过

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
//创建顶点缓存,D3D采用“可变形顶点格式(FVF)”的技术,
//除顶点坐标外,还包括顶点的法线、颜色、纹理坐标等数据
LPDIRECT3DVERTEXBUFFER9 g_pVB;//顶点缓存的接口指针
//定义FVF的顶点结构
//------------------------------------------------------X
struct CUSTOMVERTEX
{
float x,y,z,rhw;//顶点坐标
DWORD color;//顶点颜色
};
//定义FVF,用到坐标和颜色
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)

////X------------------------------------X
void InitGeometry()
{
//建立顶点坐标模型
CUSTOMVERTEX vertices[]=
    {  
{ 50.0f,  250.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0) },
{ 150.0f, 150.0f, -0.5f, 1.0f,D3DCOLOR_XRGB(0, 255, 0)},    
{  270.0f, 350.5f, 150.0f, 1.0f, D3DCOLOR_XRGB(0,0, 255) },
{  50.0f, 100.5f, 50.0f, 1.0f, D3DCOLOR_XRGB(0,255, 255) },
{ 150.0f,  250.0f, 70.5f, 1.0f, D3DCOLOR_XRGB(255, 255, 255) },
{ 50.0f,  250.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0) }
};     // x, y, z, rhw, color
   
//创建顶点缓存
g_pD3DDevice->CreateVertexBuffer(
sizeof(vertices),
0,D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,&g_pVB,NULL);
//把顶点数据输入缓存区
void* pVertices;
g_pVB->Lock(0,sizeof(vertices),(void**)&pVertices,0);
memcpy(pVertices,vertices,sizeof(vertices));
g_pVB->Unlock();




}
//X-----------------------------
HRESULT InitialiseD3D(HWND hWnd)
{
    //创建D3D对象,并获得D3D接口指针
 
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_pD3D == NULL)
    {
        return E_FAIL;
    }


    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    
    //创建窗口模式的D3D
    
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;//d3ddm.Format
    
    //创建D3D的设备对象,并获取接口IDirect3DDevice9的指针
    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,
                                   &g_pD3DDevice)))
    {
        return E_FAIL;
    }
    
    return S_OK;
}

void Render()
{
    if(g_pD3DDevice == NULL)
    {
        return;
    }
//InitGeometry();
    //用黑色清除后备缓存
    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    
    //开始屏幕操作  
g_pD3DDevice->BeginScene(); 
//我们将在中间完成所有的3D渲染
///-------------------------------------------------X
     //设置自定义的FVF
g_pD3DDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
      //绑定顶点缓存给设备数据源
g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
       //绘制图形,参数1为图形格式,参数3为所绘个数
g_pD3DDevice->DrawPrimitive(D3DPT_LINESTRIP ,0, 5);//空间画五条线
 
 //X--------------------------------------------   
   
    
    //结束屏幕操作
    g_pD3DDevice->EndScene();
    
    
    //翻转后备为屏幕,使画面显示在屏幕上
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

void CleanUp()////释放清除所有设备
{
if(g_pVB!=NULL)
{ g_pVB->Release();
g_pVB=NULL;
}
   
    if(g_pD3DDevice != NULL)
    {
        g_pD3DDevice->Release();
        g_pD3DDevice = NULL;
    }

    if(g_pD3D != NULL)
    {
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}

void GameLoop()
{
        InitGeometry();///载入数据
    //进入游戏循环
    MSG msg; 
    BOOL fMessage;

    PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
    
    while(msg.message != WM_QUIT)
    {
        fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

        if(fMessage)
        {
            //处理消息
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
         //没有消息时,处理渲染图象
            Render();
        }

    }
}

//Windows消息处理机制,用来处理各种WINDOWS消息,包括常用的键盘消息
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        break;
        case WM_KEYUP: 
            switch (wParam)
            { 
                case VK_ESCAPE:
                    //按“ESC”键退出
                    DestroyWindow(hWnd);
                    return 0;
                break;
            } 
        break;

    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

//应用程序入口主函数,相当于C语言的main()函数
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
    //注册窗口类
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L, 
                     GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                     "DX9", NULL};
    RegisterClassEx(&wc);

    //创建应用程序窗口
    HWND hWnd = CreateWindow("DX9", "mygame1", 
                              WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL);


    if(SUCCEEDED(InitialiseD3D(hWnd)))
    { 
        //显示窗口
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        //开始游戏并循环
        GameLoop();
    }
    
    CleanUp();

    UnregisterClass("DX9", wc.hInstance);
    
    return 0;
}
如果以上程序运行成功的话,会在窗口内画出5个边的图形!
初学者试着可以修改
g_pD3DDevice->DrawPrimitive(D3DPT_LINESTRIP ,0, 5);//空间画五条线
的参数,使其画出两个三角行表面。

前腐后继 - 2006-12-13 10:59:00
//该程序模拟彩色下雨特效。初学者如有疑问在下面跟帖。初学者可以自己修改颜色。

#include <Windows.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib,"d3d9.lib")          ///////////缺少这句编译不能通过
#pragma comment(lib,"d3dx9dt.lib")
#pragma comment(lib,"winmm.lib")
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
//创建顶点缓存,D3D采用“可变形顶点格式(FVF)”的技术,
//除顶点坐标外,还包括顶点的法线、颜色、纹理坐标等数据
LPDIRECT3DVERTEXBUFFER9 g_pVB=NULL;//顶点缓存的接口指针
//定义FVF的顶点结构

struct CUSTOMVERTEX
{
float x,y,z;//顶点坐标
DWORD color;//顶点颜色
}my_ex[150];////定义雨滴数组
//定义FVF,用到坐标和颜色
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)



void SetupMatrices()
{

D3DXVECTOR3 eye(0.0f,0.0f,-42.0f);///观察者视点位置
D3DXVECTOR3 lookat(0.0f,0.0f,0.0f);//观察者视线方向
D3DXVECTOR3 up(0.0f,1.0f,0.0f);//观察者头顶方向,也称上方向
D3DXMATRIXA16 matView;
///设置可视视角矩阵
D3DXMatrixLookAtLH(&matView,&eye,&lookat,&up);
///把视角矩阵设置到渲染环境
 g_pD3DDevice->SetTransform(D3DTS_VIEW,&matView);


D3DXMATRIXA16 matProj;
//设置透视投影矩阵
D3DXMatrixPerspectiveFovLH(&matProj,//结果矩阵
D3DX_PI/4,//可视弧度范围
1.0f,//屏幕高宽比
1.0f,//最近观测距离
100.0f);//最远观察距离

  ///把透视投影矩阵设置到渲染护环境
 g_pD3DDevice->SetTransform(D3DTS_PROJECTION,&matProj);

}
void InitGeometry()
{
int i;
for(i=0;i<150;i+=2)
{
my_ex.y --;
my_ex[i+1].y --;
    if(my_ex[i+1].y <-20)
{
           
        my_ex.x=my_ex[i+1].x =rand()%40-20;
    my_ex.y=10;
    my_ex.z =my_ex[i+1].z =rand()%40-20;
    my_ex.color =D3DCOLOR_XRGB(rand()%255, 255, 255);
    
    my_ex[i+1].y=13;
     my_ex[i+1].color =D3DCOLOR_XRGB(255, rand()%255, 255);

}
}

//创建顶点缓存
g_pD3DDevice->CreateVertexBuffer(
sizeof(my_ex),//
0,D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,&g_pVB,NULL);
//把顶点数据输入缓存区
void* pVertices;
g_pVB->Lock(0,sizeof(my_ex),(void**)&pVertices,0);
memcpy(pVertices,my_ex,sizeof(my_ex));
g_pVB->Unlock();




}

HRESULT InitialiseD3D(HWND hWnd)
{
    //创建D3D对象,并获得D3D接口指针
 
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    if(g_pD3D == NULL)
    {
        return E_FAIL;
    }


    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp));

    
    //创建窗口模式的D3D
    
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

    //创建D3D的设备对象,并获取接口IDirect3DDevice9的指针
    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,
                                   &g_pD3DDevice)))
    {
        return E_FAIL;
    }
     g_pD3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
      g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    return S_OK;
}

void Render()
{
 

    //用黑色清除后备缓存
    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);//
    
    //开始屏幕操作  
g_pD3DDevice->BeginScene(); 
//我们将在中间完成所有的3D渲染

      InitGeometry();
     SetupMatrices();///设置相关矩阵


g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
     //设置自定义的FVF
g_pD3DDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));
      //绑定顶点缓存给设备数据源


       //绘制图形,参数1为图形格式,参数3为所绘个数
g_pD3DDevice->DrawPrimitive(D3DPT_LINELIST ,0, 75);//D3DPT_LINESTRIP空间画五条线
 

   
    
    //结束屏幕操作
    g_pD3DDevice->EndScene();
    
    
    //翻转后备为屏幕,使画面显示在屏幕上
    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

void CleanUp()////释放清除所有设备
{
if(g_pVB!=NULL)
{ g_pVB->Release();
g_pVB=NULL;
}
   
    if(g_pD3DDevice != NULL)
    {
        g_pD3DDevice->Release();
        g_pD3DDevice = NULL;
    }

    if(g_pD3D != NULL)
    {
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}

void GameLoop()
{
       // InitGeometry();///载入数据
    //进入游戏循环
    MSG msg; 
    BOOL fMessage;

    PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
    
    while(msg.message != WM_QUIT)
    {
        fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);

        if(fMessage)
        {
            //处理消息
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
         //没有消息时,处理渲染图象
            Render();
        }

    }
}

//Windows消息处理机制,用来处理各种WINDOWS消息,包括常用的键盘消息
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        break;


        case WM_KEYUP: 
            switch (wParam)
            { 
                case VK_ESCAPE:
                    //按“ESC”键退出
                    DestroyWindow(hWnd);
                    return 0;
                break;
            } 
        break;

    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

//应用程序入口主函数,相当于C语言的main()函数
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
    //注册窗口类
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L, 
                     GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                     "DX9", NULL};
    RegisterClassEx(&wc);

    //创建应用程序窗口
    HWND hWnd = CreateWindow("DX9", "mygame1", 
                              WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL);

////////////////////////////////雨水坐标初始化
    for(int i=0;i<150;i++)
{
my_ex.x=my_ex[i+1].x =rand()%40-20;
my_ex.y=rand()%40-20;
my_ex.z =my_ex[i+1].z =rand()%40-20;
my_ex.color =D3DCOLOR_XRGB(rand()%255, 255, 255);
i++;

my_ex.y=my_ex[i-1].y-3;

my_ex.color =D3DCOLOR_XRGB(255, rand()%255, 255);
}

    if(SUCCEEDED(InitialiseD3D(hWnd)))
    { 
        //显示窗口
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        //开始游戏并循环
        GameLoop();
    }
    
    CleanUp();

    UnregisterClass("DX9", wc.hInstance);
    
    return 0;
}
lovemaxmax - 2007-5-5 6:26:00
[em04]支持~~
1