www.pudn.com > SimpleD3D.rar > CreateDevice.cpp


#include  
#include  
#include  
 
#pragma comment(lib,"d3d8.lib") 
#pragma comment(lib,"d3dx8.lib") 
#pragma comment(lib,"winmm.lib") 
 
LPDIRECT3D8             g_pD3D       = NULL; // 用来创建D3D设备 
LPDIRECT3DDEVICE8       g_pd3dDevice = NULL; // D3D设备 
 
LPD3DXMESH              g_pMesh          = NULL; // 模型 
D3DMATERIAL8*           g_pMeshMaterials = NULL; // 模型的材质数组(一个模型可以有多个材质) 
LPDIRECT3DTEXTURE8*     g_pMeshTextures  = NULL; // 模型的纹理数组(一个模型可以有多个纹理) 
DWORD                   g_dwNumMaterials = 0L;   // 材质的数量(等于纹理数量) 
 
// 初始化D3D 
HRESULT InitD3D(HWND hWnd) 
{ 
	// 创建D3D对象 
	if(NULL == (g_pD3D = Direct3DCreate8(D3D_SDK_VERSION)))return E_FAIL; 
 
	// 获取当前的显示模式 
	D3DDISPLAYMODE d3ddm; 
	if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))return E_FAIL; 
 
	D3DPRESENT_PARAMETERS d3dpp;  
	ZeroMemory(&d3dpp, sizeof(d3dpp)); 
	d3dpp.Windowed = TRUE;						// 窗口模式 
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;	// 设置交换模式 
	d3dpp.BackBufferFormat = d3ddm.Format;		// 设置背景缓冲区格式为当前左面格式 
	d3dpp.EnableAutoDepthStencil = TRUE;		// 打开深度缓冲zbuffer 
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;	// 深度缓冲格式 
 
	// 创建D3D设备 
	// 第一个参数:使用默认的显卡适配器 
	// 第二个参数:请求使用硬件抽象层(HAL) 
	// 第三个参数:窗口句柄 
	// 第四个参数:使用软件处理顶点 
	// 第五个参数:创建的参数 
	// 第六个参数:创建的D3D设备指针 
	if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,  
									  D3DDEVTYPE_HAL,  
									  hWnd, 
									  D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
									  &d3dpp,  
									  &g_pd3dDevice))) 
	{ 
		return E_FAIL; 
	} 
 
	// 关闭culling,让我们能看到3角型的正反面 
	//g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 
 
	// 打开ZBUFFER 
	//g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 
 
	// Turn off D3D lighting 
    g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE); 
 
	return S_OK; 
} 
 
// 读取.x文件到模型,并生成对应的材质和纹理 
HRESULT InitGeometry() 
{ 
	// 材质缓冲 
    LPD3DXBUFFER pD3DXMtrlBuffer; 
 
    // 读入tiger.x到我们的模型 
    if(FAILED(D3DXLoadMeshFromX( 
		"Tiger.x",				// [输入].x文件名 
		D3DXMESH_SYSTEMMEM,		// [输入]使用系统内存 
		g_pd3dDevice,			// [输入]d3d设备指针 
		NULL,					// 不用管 
		&pD3DXMtrlBuffer,		// [输出]获取模型的材质缓冲 
		&g_dwNumMaterials,		// [输出]材质的数量 
		&g_pMesh)))			// [输出]模型对象指针 
    { 
        return E_FAIL; 
    } 
 
	// 获取材质指针 
	D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); 
	g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials]; 
	g_pMeshTextures  = new LPDIRECT3DTEXTURE8[g_dwNumMaterials]; 
 
	for(DWORD i=0; iRelease(); 
	 
	return S_OK; 
} 
 
// 释放D3D 
VOID Cleanup() 
{ 
	// 释放材质数祖 
    if(g_pMeshMaterials != NULL)  
        delete[] g_pMeshMaterials; 
 
	// 释放创建的纹理 
    if(g_pMeshTextures) 
    { 
        for(DWORD i = 0; i < g_dwNumMaterials; i++) 
        { 
            if(g_pMeshTextures[i]) 
                g_pMeshTextures[i]->Release(); 
        } 
        delete[] g_pMeshTextures; 
    } 
	 
	// 释放模型 
    if(g_pMesh != NULL) 
        g_pMesh->Release(); 
 
	// 释放D3D设备 
    if(g_pd3dDevice != NULL)  
        g_pd3dDevice->Release(); 
 
	// 释放D3D 
    if(g_pD3D != NULL) 
        g_pD3D->Release(); 
} 
 
// 设置世界矩阵和摄象机 
VOID SetupMatrices() 
{ 
    // 让世界矩阵绕Y轴旋转 
    D3DXMATRIX matWorld; 
    D3DXMatrixIdentity(&matWorld); 
    D3DXMatrixRotationY(&matWorld, timeGetTime()/2000.f); 
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld); 
 
	// 设置摄象机的位置 
    D3DXMATRIX matView; 
    D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 1.5f,-5.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); 
} 
 
// 渲染 
VOID Render() 
{ 
    if(NULL == g_pd3dDevice) 
        return; 
 
    // 清除背景为兰色 
    g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,255), 1.0f, 0); 
     
    // 开始绘制场景 
    g_pd3dDevice->BeginScene(); 
     
    // --渲染图形-- 
 
    // 设置摄象机位置 
    SetupMatrices(); 
 
	// 根据材质的数量我们的模型被切分了,每个材质对应一部分 
	// 所以渲染的时候也要分几个部分渲染 
	for(DWORD i=0; iSetMaterial(&g_pMeshMaterials[i]); 
		g_pd3dDevice->SetTexture(0, g_pMeshTextures[i]); 
     
		// 渲染这一部分 
		g_pMesh->DrawSubset(i); 
	} 
 
    // 结束场景绘制 
    g_pd3dDevice->EndScene(); 
     
    // 显示到屏幕上 
    g_pd3dDevice->Present(NULL, NULL, NULL, NULL); 
} 
 
// 消息处理 
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(msg) 
    { 
        case WM_DESTROY:	// 退出消息 
            PostQuitMessage(0); 
            return 0; 
    } 
 
    return DefWindowProc(hWnd, msg, wParam, lParam); 
} 
 
// WinMain程序入口 
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT) 
{ 
    // 注册窗口类 
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,  
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL, 
                      "D3D Tutorial", NULL }; 
    RegisterClassEx(&wc); 
 
    // 创建窗口 
    HWND hWnd = CreateWindow("D3D Tutorial", "3D游戏从头编",  
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, 
                              GetDesktopWindow(), NULL, wc.hInstance, NULL); 
 
    // 初始化D3D 
    if(SUCCEEDED(InitD3D(hWnd))) 
    {  
		if(SUCCEEDED(InitGeometry())) 
		{ 
			// 显示窗口 
			ShowWindow(hWnd, SW_SHOWDEFAULT); 
			UpdateWindow(hWnd); 
 
			// 消息循环 
            MSG msg; 
            ZeroMemory(&msg, sizeof(msg)); 
            while(msg.message!=WM_QUIT) 
            { 
                if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) 
                { 
                    TranslateMessage(&msg); 
                    DispatchMessage(&msg); 
                } 
                else 
                    Render(); 
            } 
		} 
    } 
 
    // 结束处理 
    Cleanup(); 
    UnregisterClass("D3D Tutorial", wc.hInstance); 
    return 0; 
}