#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;
}
#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;
}
4732

被折叠的 条评论
为什么被折叠?



