DirectX9 例程

#include  < d3dx9.h >

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

D3DXVECTOR3 CubeLookAt[] 
=
{
    D3DXVECTOR3(
0.0f - 30.0f - 30.0f ),
    D3DXVECTOR3(
0.0f 0.0f 0.0f ),
    D3DXVECTOR3(
0.0f 1.0f 0.0f )
};

LPDIRECT3D9             g_pD3D           
=  NULL;  // Direct3D对象
LPDIRECT3DDEVICE9       g_pD3DDevice      =  NULL;  // Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer   =  NULL;  // Buffer to hold vertices

PDIRECT3DTEXTURE9       g_pTexture       
=  NULL;  // 纹理指针

LPD3DXMESH              g_pMesh          
=  NULL;  // 网格模型对象
D3DMATERIAL9 *            g_pMeshMaterials  =  NULL;  // 网格模型材质
LPDIRECT3DTEXTURE9 *      g_pMeshTextures   =  NULL;  // 网格模型纹理
DWORD                   g_dwNumMaterials  =   0L ;    // 网格模型材质数量

struct  CUSTOMVERTEX // 自定义的顶点格式
{
    FLOAT x, y, z; 
// 顶点坐标
    DWORD color;    // 顶点颜色
    FLOAT tu, tv;   // 纹理坐标
};

// Flexible Vertex Format (FVF) 灵活顶点格式
#define  D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

// 释放对象
#define  SafeRelease(pObject) if(pObject != NULL) {pObject->Release(); pObject=NULL;}

// 释放对象数组
#define  SafeDelete(pObjectArray) if(pObjectArray != NULL){delete[] pObjectArray;}

// 键盘控制
#define  KeyDown(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define  KeyUp(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

/* *************************************************************
 * Desc: 初始化 Direct3D
 *************************************************************
*/

HRESULT InitialiseD3D(HWND hWnd)
{
    
// First of all, create the main D3D object. If it is created successfully we 
    
// should get a pointer to an IDirect3D8 interface.
    g_pD3D  =  Direct3DCreate9(D3D_SDK_VERSION);
    
if (g_pD3D  ==  NULL)
    {
        
return  E_FAIL;
    }

    
// Get the current display mode
     /* D3DDISPLAYMODE d3ddm;
    if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
    {
        return E_FAIL;
    }
*/

    
// Create a structure to hold the settings for our device
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(
& d3dpp,  sizeof (d3dpp));

    
// Fill the structure. 
    
// We want our program to be windowed, and set the back buffer to a format
    
// that matches our current display mode
    d3dpp.Windowed  =  TRUE;
    d3dpp.SwapEffect 
=  D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat 
=  D3DFMT_UNKNOWN;

    
// 深度缓冲
    d3dpp.AutoDepthStencilFormat  =  D3DFMT_D16;
    d3dpp.EnableAutoDepthStencil 
=  TRUE; 

    
// Create a Direct3D device.
     if (FAILED(g_pD3D -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
& d3dpp,     
                                   
& g_pD3DDevice)))
    {
        
return  E_FAIL;
    }
    
    
// 开启背面拣选
    
// g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

    
// 去除灯光
    
// g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

    
// 激活深度缓冲
    
// g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

    
// 设置环境灯光
    g_pD3DDevice -> SetRenderState(D3DRS_AMBIENT,  0xFFFFFFFF );

    
return  S_OK;
}

/* *************************************************************
 * Desc: 初始化顶点缓冲(立方体)
 *************************************************************
*/

HRESULT InitVertexBuffer()
{
    VOID
*  pVertices;
    
    
// Store each point of the cube together with it's colour
    
// Make sure that the points of a polygon are specified in a clockwise direction,
    
// this is because anti-clockwise faces will be culled
    
// We will use a three triangle strips to render these polygons
    
// (Top, Sides, Bottom).
    CUSTOMVERTEX cvVertices[]  =
    { 
        
// Top Face
        { - 5.0f 5.0f - 5.0f , D3DCOLOR_XRGB( 0 0 255 ),  0.0f 1.0f },  // Vertex 0 - Blue 
        { - 5.0f 5.0f 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  0.0f 0.0f },  // Vertex 1 - Red 
        { 5.0f 5.0f - 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  1.0f 1.0f },  // Vertex 2 - Red 
        { 5.0f 5.0f 5.0f , D3DCOLOR_XRGB( 0 255 0 ),  1.0f 0.0f },  // Vertex 3 - Green 

        
// Face 1
        { - 5.0f - 5.0f - 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  0.0f 1.0f },  // Vertex 4 - Red 
        { - 5.0f 5.0f - 5.0f , D3DCOLOR_XRGB( 0 0 255 ),  0.0f 0.0f },  // Vertex 5 - Blue 
        { 5.0f - 5.0f - 5.0f , D3DCOLOR_XRGB( 0 255 0 ),  1.0f 1.0f },  // Vertex 6 - Green 
        { 5.0f 5.0f - 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  1.0f 0.0f },  // Vertex 7 - Red 

        
// Face 2
        { 5.0f - 5.0f 5.0f , D3DCOLOR_XRGB( 0 0 255 ),  0.0f 1.0f },  // Vertex 8 - Blue 
        { 5.0f 5.0f 5.0f , D3DCOLOR_XRGB( 0 255 0 ),  0.0f 0.0f },  // Vertex 9 - Green
        
        
// Face 3
        { - 5.0f - 5.0f 5.0f , D3DCOLOR_XRGB( 0 255 0 ),  1.0f 1.0f },  // Vertex 10 - Green 
        { - 5.0f 5.0f 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  1.0f 0.0f },  // Vertex 11 - Red 

        
// Face 4
        { - 5.0f - 5.0f - 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  0.0f 1.0f },  // Vertex 12 - Red 
        { - 5.0f 5.0f - 5.0f , D3DCOLOR_XRGB( 0 0 255 ),  0.0f 0.0f },  // Vertex 13 - Blue

        
// Bottom Face
        { 5.0f - 5.0f - 5.0f , D3DCOLOR_XRGB( 0 255 0 ),  0.0f 1.0f },  // Vertex 14 - Green 
        { 5.0f - 5.0f 5.0f , D3DCOLOR_XRGB( 0 0 255 ),  0.0f 0.0f },  // Vertex 15 - Blue 
        { - 5.0f - 5.0f - 5.0f , D3DCOLOR_XRGB( 255 0 0 ),  1.0f 1.0f },  // Vertex 16 - Red 
        { - 5.0f - 5.0f 5.0f , D3DCOLOR_XRGB( 0 255 0 ),  1.0f 0.0f },  // Vertex 17 - Green
    };

    
// Create the texture from file
     if (FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,  " 1.bmp " & g_pTexture)))
    {
        
return  E_FAIL;
    }

    
// Create the vertex buffer from our device.
     if (FAILED(g_pD3DDevice -> CreateVertexBuffer( 18   *   sizeof (CUSTOMVERTEX),
                                               
0 , D3DFVF_CUSTOMVERTEX,
                                               D3DPOOL_DEFAULT, 
& g_pVertexBuffer, NULL)))
    {
        
return  E_FAIL;
    }


    
// Get a pointer to the vertex buffer vertices and lock the vertex buffer
     if (FAILED(g_pVertexBuffer -> Lock( 0 sizeof (cvVertices), ( void ** ) & pVertices,  0 )))
    {
        
return  E_FAIL;
    }

    
// Copy our stored vertices values into the vertex buffer
    memcpy(pVertices, cvVertices,  sizeof (cvVertices));

    
// Unlock the vertex buffer
    g_pVertexBuffer -> Unlock();

    
return  S_OK;
}

/* *************************************************************
 * Desc: 响应键盘事件
 *************************************************************
*/

VOID ProcInput()
{
    
if (KeyDown(VK_DOWN))
    {
        CubeLookAt[
0 ].z  -=   0.2f ;
        CubeLookAt[
1 ].z  -=   0.2f ;
    }
    
if (KeyDown(VK_UP))
    {
        CubeLookAt[
0 ].z  +=   0.2f ;
        CubeLookAt[
1 ].z  +=   0.2f ;
    }
    
if (KeyDown(VK_RIGHT))
    {
        CubeLookAt[
1 ].x  +=   0.2f ;
    }
    
if (KeyDown(VK_LEFT))
    {
        CubeLookAt[
1 ].x  -=   0.2f ;
    }
}

/* *************************************************************
 * Desc: 初始化网格模型
 *************************************************************
*/

HRESULT InitMesh()
{
    LPD3DXBUFFER pMaterialsBuffer;
    
    
// 从磁盘文件加载网格模型
     if (FAILED(D3DXLoadMeshFromX( " SKULL.x " , D3DXMESH_MANAGED, g_pD3DDevice, NULL, 
                                
& pMaterialsBuffer, NULL,  & g_dwNumMaterials,  & g_pMesh)))
    {
        MessageBox(NULL, 
" Could not find corresponding mesh file " " Mesh " , MB_OK);
        
return  E_FAIL;
    }

    
// 从网格模型中提取材质属性和纹理文件名
    D3DXMATERIAL *  matMaterials  =  (D3DXMATERIAL * )pMaterialsBuffer -> GetBufferPointer();
    
    
// Create two arrays. One to hold the materials and other to hold the textures
    g_pMeshMaterials  =   new  D3DMATERIAL9[g_dwNumMaterials];
    g_pMeshTextures 
=   new  LPDIRECT3DTEXTURE9[g_dwNumMaterials];

    
// 逐块提取网格模型材质属性和纹理文件名
     for (DWORD i  =   0 ; i  <  g_dwNumMaterials; i ++ )
    {
        
// 材料属性
        g_pMeshMaterials[i]  =  matMaterials[i].MatD3D;

        
// 设置模型材料的环境光反射系数,因为模型材料本身没有设置
        g_pMeshMaterials[i].Ambient  =  g_pMeshMaterials[i].Diffuse;
        
        
// 创建纹理
         if (FAILED(D3DXCreateTextureFromFile(g_pD3DDevice,
                                            matMaterials[i].pTextureFilename,
                                            
& g_pMeshTextures[i])))
        {
            g_pMeshTextures[i] 
=  NULL;
        }

    }

    
// We've finished with the material buffer, so release it
    SafeRelease(pMaterialsBuffer);
    
    
return  S_OK;
}

/* *************************************************************
 * Desc: 渲染立方体
 *************************************************************
*/

void  RenderCube()
{
    ProcInput();

   
/* ***************************
    * Desc: 创建并设置世界矩阵 *
    ***************************
*/

    D3DXMATRIX matWorld, matWorldX, matWorldY, matWorldZ;

    
// Create the transformation matrices
    D3DXMatrixRotationX( & matWorldX, timeGetTime() / 400.0f );
    D3DXMatrixRotationY(
& matWorldY, timeGetTime() / 400.0f );
    D3DXMatrixRotationZ(
& matWorldZ, timeGetTime() / 400.0f );

    
/* 我们调用了D3DXMatrixRotationX、D3DXMatrixRotationY和D3DXMatrixRotationZ
    函数产生了3个矩阵而且分别将它们保存在了3个D3DXMATRIX结构中
    然后我们将它们相乘后形成了世界矩阵
*/
    D3DXMatrixMultiply(
& matWorld,  & matWorldX,  & matWorldY);
    D3DXMatrixMultiply(
& matWorld,  & matWorld,  & matWorldZ);

    
// 我们又调用了SetTransform函数为我们的顶点应用了此变换
    g_pD3DDevice -> SetTransform(D3DTS_WORLD,  & matWorld);

   
/* ***************************
    * Desc: 创建并设置观察矩阵 *
    ***************************
*/

    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(
& matView,  & CubeLookAt[ 0 ],   // Camera Position
                                  & CubeLookAt[ 1 ],   // Look At Position
                                  & CubeLookAt[ 2 ]);  // Up Direction
    g_pD3DDevice -> SetTransform(D3DTS_VIEW,  & matView);

   
/* ***************************
    * Desc: 创建并设置投影矩阵 *
    ***************************
*/

    D3DXMATRIX matProj;
    
/* 我们设置摄像机的镜头:我们确定了视界为PI/4(正常)而横纵比为1
    我们还确定了前、后裁剪平面分别为1和500,这意味着范围之外的三角形将会被裁剪掉
*/
    D3DXMatrixPerspectiveFovLH(
& matProj, D3DX_PI / 4 1.0f 1.0f 500.0f );
    g_pD3DDevice
-> SetTransform(D3DTS_PROJECTION,  & matProj);

    
// Set how the texture should be rendered.
     if (g_pTexture  !=  NULL)
    {
        
// A texture has been set. We don't want to blend our texture with
        
// the colours of our vertices, so use D3DTOP_SELECTARG1
        g_pD3DDevice -> SetTexture( 0 , g_pTexture);
        g_pD3DDevice
-> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    }
    
else
    {
        
// No texture has been set. So we will disable texture rendering.
        g_pD3DDevice -> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_DISABLE);
    }

    
// Rendering our objects
    g_pD3DDevice -> SetStreamSource( 0 , g_pVertexBuffer,  0 sizeof (CUSTOMVERTEX));
    g_pD3DDevice
-> SetFVF(D3DFVF_CUSTOMVERTEX);
    g_pD3DDevice
-> DrawPrimitive(D3DPT_TRIANGLESTRIP,  0 2 );  // Top
    g_pD3DDevice -> DrawPrimitive(D3DPT_TRIANGLESTRIP,  4 8 );  // Sides
    g_pD3DDevice -> DrawPrimitive(D3DPT_TRIANGLESTRIP,  14 2 );  // Bottom
}

/* *************************************************************
 * Desc: 渲染网格模型
 *************************************************************
*/

DWORD RenderMesh()
{
    
// 创建并设置世界坐标系
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY(
& matWorld, timeGetTime() / 1000.0f );
    g_pD3DDevice
-> SetTransform(D3DTS_WORLD,  & matWorld);

    
// 创建并设置观察矩阵
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(
& matView,  & D3DXVECTOR3( 0.0f 0.0f - 20.0f ),
                                 
& D3DXVECTOR3( 0.0f 0.0f 0.0f ),
                                 
& D3DXVECTOR3( 0.0f 1.0f 0.0f ));
    g_pD3DDevice
-> SetTransform(D3DTS_VIEW,  & matView);

    
// 创建并设置投影矩阵
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(
& matProj, D3DX_PI / 4 1.0f 1.0f 100.0f );
    g_pD3DDevice
-> SetTransform(D3DTS_PROJECTION,  & matProj);

    
// 逐块渲染网格模型
     if (g_pMesh  !=  NULL)
    {
        
for (DWORD i  =   0 ; i  <  g_dwNumMaterials; i ++ )
        {
            g_pD3DDevice
-> SetMaterial( & g_pMeshMaterials[i]);
            g_pD3DDevice
-> SetTexture( 0 , g_pMeshTextures[i]);
        
            g_pMesh
-> DrawSubset(i);
        }

        
return  g_pMesh -> GetNumFaces();
    }
    
else
    {
        MessageBox(NULL,
" Could not open mesh file " " Mesh " , MB_OK);
        
return   0 ;
    }
}

/* *************************************************************
 * Desc: 渲染主场景
 *************************************************************
*/

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

    
// 清空深度缓冲
    g_pD3DDevice -> Clear( 0 , NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0 0 0 ),  1.0f 0 );

    
// Begin the scene
    g_pD3DDevice -> BeginScene();

    
// RenderCube();
    RenderMesh();

    
// End the scene
    g_pD3DDevice -> EndScene();
    
    
// Filp the back and front buffers so that whatever has been rendered on the
    
// back buffer will now be visible on screen (front buffer).
    g_pD3DDevice -> Present(NULL, NULL, NULL, NULL);
}

/* *************************************************************
 * Desc: 释放对象
 *************************************************************
*/

void  CleanUp()
{
    SafeDelete(g_pMeshMaterials);

    
if (g_pMeshTextures  !=  NULL)
    {
        
for (DWORD i  =   0 ; i  <  g_dwNumMaterials; i ++ )
        {
            
if (g_pMeshTextures[i])
            {
                SafeRelease(g_pMeshTextures[i]);
            }
        }
    }

    SafeDelete(g_pMeshTextures);
    SafeRelease(g_pMesh);
    SafeRelease(g_pTexture);
    SafeRelease(g_pVertexBuffer);
    SafeRelease(g_pD3DDevice);
    SafeRelease(g_pD3D);
}

/* *************************************************************
 * Desc: 游戏循环
 *************************************************************
*/

void  GameLoop()
{
    
// Enter the game loop
    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)
        {
            
// Process message
            TranslateMessage( & msg); // 将虚拟键消息转换为字符消息
            DispatchMessage( & msg); // 将转换后的消息传送给windows
        }
        
else
        {
            
// No message to process, so render the current scene
            Render();
        }
    }
}

/* *************************************************************
 * Desc: 消息处理函数
 *************************************************************
*/

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:
                    
// User has pressed the escape key, so quit
                    DestroyWindow(hWnd);
                    
return   0 ;
                
break ;
            } 
        
break ;
    }

    
return  DefWindowProc(hWnd, msg, wParam, lParam); // 调用默认消息处理过程
}

/* *************************************************************
 * Desc: WIN32入口函数
 *************************************************************
*/

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
    
// Register the window class
     /* WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L,
                     GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                     "DX Project 3", NULL};
*/
    WNDCLASSEX wc;

    
// 指定了结构的大小
    wc.cbSize         =   sizeof (WNDCLASSEX);
    wc.style         
=  CS_CLASSDC;
    
// 指定窗口类别的消息处理函数
    wc.lpfnWndProc    =  WinProc;
    
// 指定窗口结构的额外空间
    wc.cbClsExtra     =   0L ;
    wc.cbWndExtra    
=   0L ;
    
// 代表程序的实例句柄
    wc.hInstance      =  GetModuleHandle(NULL);
    
// 图标
    wc.hIcon          =  LoadIcon(NULL,MAKEINTRESOURCE(IDI_ERROR));
    
// 鼠标指针
    wc.hCursor        =  LoadCursor(NULL,MAKEINTRESOURCE(IDC_CROSS));
    
// 背景
    wc.hbrBackground  =  NULL;
    
// 菜单
    wc.lpszMenuName   =  NULL;
    
// 窗口类的名称
    wc.lpszClassName  =   " DX Project 3 " ;
    
// 包含了窗口类的小图标句柄
    wc.hIconSm        =  NULL;

    RegisterClassEx(
& wc);

    
// 全屏模式
     /* HWND hWnd = CreateWindow("DX Project 3", "3D游戏", 
                              WS_POPUP, 0, 0, 
                              GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
                              GetDesktopWindow(), NULL, wc.hInstance, NULL);
*/
    
    
// 窗口模式
    HWND hWnd  =  CreateWindow( " DX Project 3 " " 3D游戏 "
                              WS_OVERLAPPEDWINDOW 
&   ~ WS_MAXIMIZEBOX  &   ~ WS_MINIMIZEBOX, 
                              
50 50 500 500 ,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL);

    
// Initialize Direct3D
     if (SUCCEEDED(InitialiseD3D(hWnd)))
    {
        
// Show our window
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        
// Initialize Vertex Buffer
         if (SUCCEEDED( /* InitVertexBuffer() */ InitMesh()))
        {
            
// Start game running: Enter the game loop
            GameLoop();
        }
    }

    CleanUp();

    UnregisterClass(
" DX Project 3 " , wc.hInstance);

    
return   0 ;
}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值