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.0f0.0f0.0f),
    D3DXVECTOR3(
0.0f1.0f0.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.0f5.0f-5.0f, D3DCOLOR_XRGB(00255), 0.0f1.0f}, //Vertex 0 - Blue 
        {-5.0f5.0f5.0f, D3DCOLOR_XRGB(25500), 0.0f0.0f}, //Vertex 1 - Red 
        {5.0f5.0f-5.0f, D3DCOLOR_XRGB(25500), 1.0f1.0f}, //Vertex 2 - Red 
        {5.0f5.0f5.0f, D3DCOLOR_XRGB(02550), 1.0f0.0f}, //Vertex 3 - Green 

        
//Face 1
        {-5.0f-5.0f-5.0f, D3DCOLOR_XRGB(25500), 0.0f1.0f}, //Vertex 4 - Red 
        {-5.0f5.0f-5.0f, D3DCOLOR_XRGB(00255), 0.0f0.0f}, //Vertex 5 - Blue 
        {5.0f-5.0f-5.0f, D3DCOLOR_XRGB(02550), 1.0f1.0f}, //Vertex 6 - Green 
        {5.0f5.0f-5.0f, D3DCOLOR_XRGB(25500), 1.0f0.0f}, //Vertex 7 - Red 

        
//Face 2
        {5.0f-5.0f5.0f, D3DCOLOR_XRGB(00255), 0.0f1.0f}, //Vertex 8 - Blue 
        {5.0f5.0f5.0f, D3DCOLOR_XRGB(02550), 0.0f0.0f}, //Vertex 9 - Green
        
        
//Face 3
        {-5.0f-5.0f5.0f, D3DCOLOR_XRGB(02550), 1.0f1.0f}, //Vertex 10 - Green 
        {-5.0f5.0f5.0f, D3DCOLOR_XRGB(25500), 1.0f0.0f}, //Vertex 11 - Red 

        
//Face 4
        {-5.0f-5.0f-5.0f, D3DCOLOR_XRGB(25500), 0.0f1.0f}, //Vertex 12 - Red 
        {-5.0f5.0f-5.0f, D3DCOLOR_XRGB(00255), 0.0f0.0f}, //Vertex 13 - Blue

        
//Bottom Face
        {5.0f-5.0f-5.0f, D3DCOLOR_XRGB(02550), 0.0f1.0f}, //Vertex 14 - Green 
        {5.0f-5.0f5.0f, D3DCOLOR_XRGB(00255), 0.0f0.0f}, //Vertex 15 - Blue 
        {-5.0f-5.0f-5.0f, D3DCOLOR_XRGB(25500), 1.0f1.0f}, //Vertex 16 - Red 
        {-5.0f-5.0f5.0f, D3DCOLOR_XRGB(02550), 1.0f0.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(0sizeof(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/41.0f1.0f500.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, 0sizeof(CUSTOMVERTEX));
    g_pD3DDevice
->SetFVF(D3DFVF_CUSTOMVERTEX);
    g_pD3DDevice
->DrawPrimitive(D3DPT_TRIANGLESTRIP, 02); //Top
    g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 48); //Sides
    g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 142); //Bottom
}

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

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

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

    
//创建并设置投影矩阵
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(
&matProj, D3DX_PI/41.0f1.0f100.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(000), 1.0f0);

    
//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, 0U0U, PM_NOREMOVE);
    
    
while(msg.message != WM_QUIT)
    {
        fMessage 
= PeekMessage(&msg, NULL, 0U0U, 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, 
                              
5050500500,
                              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;
}
 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值