//d3dwindow.h
#include "stdafx.h"
#include <d3d9.h>
#include <windows.h>
//-----------------------------------------------------------------------------
// Name: D3DUtil_InitLight()
// Desc: Initializes a D3DLIGHT structure, setting the light position. The
// diffuse color is set to white; specular and ambient are left as black.
//-----------------------------------------------------------------------------
VOID D3DUtil_InitLight( D3DLIGHT9& light, D3DLIGHTTYPE ltType,
FLOAT x, FLOAT y, FLOAT z )
{
D3DXVECTOR3 vecLightDirUnnormalized(x, y, z);
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type = ltType;
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecLightDirUnnormalized );
light.Position.x = x;
light.Position.y = y;
light.Position.z = z;
light.Range = 1000.0f;
}
/************************************************************************/
/* */
/************************************************************************/
HWND createWin32Window(WNDPROC MsgProc,HINSTANCE hInst,UINT windowWidth = 800,UINT windowHeight = 600)//MsgProc:应用函数回调函数 hInst:应用程序句柄
{
WNDCLASS wndClass = {0,MsgProc,0L,0L,hInst,
NULL,NULL,NULL,NULL,"D3D Sample"};
RegisterClass(&wndClass);
return CreateWindow("D3D Sample","D3D Sample",WS_OVERLAPPEDWINDOW,100,100,windowWidth,windowHeight,GetDesktopWindow(),NULL,wndClass.hInstance,NULL);
}
D3DPRESENT_PARAMETERS getWindowDisplayMode(LPDIRECT3DDEVICE9 &lpDirect3DDrive )
{
D3DPRESENT_PARAMETERS stPresentParam;
ZeroMemory(&stPresentParam,sizeof(stPresentParam));
stPresentParam.Windowed = true;
stPresentParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
stPresentParam.BackBufferFormat = D3DFMT_X8R8G8B8;
return stPresentParam;
}
D3DPRESENT_PARAMETERS getFullScreanDisplayMode(LPDIRECT3DDEVICE9 &lpDirect3DDrive ,UINT backBufferWidth,UINT backBufferHeight )
{
D3DPRESENT_PARAMETERS stPresentParam;
ZeroMemory(&stPresentParam,sizeof(stPresentParam));
stPresentParam.Windowed = FALSE;
stPresentParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
stPresentParam.BackBufferWidth = backBufferWidth;
stPresentParam.BackBufferHeight = backBufferHeight;
stPresentParam.BackBufferFormat = D3DFMT_X8R8G8B8;
return stPresentParam;
}
HRESULT InitD3D(LPDIRECT3D9 &lpDirect3D9, LPDIRECT3DDEVICE9 &lpDirect3DDrive ,D3DPRESENT_PARAMETERS &stPresentParam,HWND hWnd,bool fullScrean = FALSE,UINT backBufferWidth = 800,UINT backBufferHeight = 600 )
{
D3DDISPLAYMODE d3ddm;//d3d显示模式
if( NULL == (lpDirect3D9 = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
if (FAILED(lpDirect3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))
return E_FAIL;
ZeroMemory(&stPresentParam,sizeof(stPresentParam));
if(fullScrean)
{
stPresentParam.Windowed = FALSE;
stPresentParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
stPresentParam.BackBufferWidth = backBufferWidth;
stPresentParam.BackBufferHeight = backBufferHeight;
stPresentParam.BackBufferFormat = D3DFMT_X8R8G8B8;
}
else
{
stPresentParam.Windowed = true;
stPresentParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
stPresentParam.BackBufferFormat = d3ddm.Format;
}
if(FAILED(lpDirect3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&stPresentParam,&lpDirect3DDrive)))
{
MessageBox(hWnd,"CreateDevice error","",NULL);
return E_FAIL;
}
return S_OK;
}
// D3DSample01.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <d3d9.h>
#pragma comment(lib, "d3d9.lib") //d3dx9.lib
#include <d3dx9math.h>
#include <d3dx9mesh.h>
#pragma comment(lib, "d3dx9.lib")
//#pragma comment(lib, "d3dx9.lib")
//#pragma comment(lib, "dxerr9.lib")
#include <windows.h>
#include <conio.h>
#include "d3dwindow.h"
#define _DEBUG
#define SAFE_RELEASE(p) {if(p){p->Release();p=NULL;}}
#define SAFE_DELETE(p) {if(p){delete p;p=NULL;}}
#define SAFE_DELETE_ARRAY(p) {if(p){delete [](p);p=NULL;}}
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
/************************************************************************/
/* 这些多余的东西自己删掉吧 */
/************************************************************************/
struct CUSTOMVERTEX
{
FLOAT x,y,z,rhw; // 经过坐标转换的定点坐标
DWORD color; // 漫反射颜色值
};
ID3DXMesh * m_pD3DXMesh;//网格
D3DMATERIAL9 mtrl;//材质
/************************************************************************/
/* */
/************************************************************************/
LPDIRECT3D9 g_pD3D; // 一个Direct3D的COM实例的引用
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;//一个Direct3D Device的引用
D3DPRESENT_PARAMETERS g_stPresentParam ;
bool isFullScrean = FALSE;
/************************************************************************/
/* */
/************************************************************************/
LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);//消息函数
HRESULT changeMode(LPDIRECT3DDEVICE9 &lpDirect3DDrive,bool isFullScrean );//更改显示模式
void Render();//渲染函数
void RenderFrame();//渲染帧
HRESULT changeMode(LPDIRECT3DDEVICE9 &lpDirect3DDrive,bool isFullScrean );
HRESULT InitDeviceObjet();//这个函数在初始化D3D环境后将会被调用,且只调用一次。这里加载一些文件数据
HRESULT InvalidateDeviceObjects();//这个函数在显卡缓冲丢失后将被调用,用于删除显卡内存中已经无效的数据。
HRESULT RestoreDeviceObjects();//这个函数在窗体大小改变,显示模式改变,和内存页面丢失的时候会被调用,主要回复往显卡缓冲区里丢失的数据,比如显卡向量池中的数据。
HRESULT DeleteDeviceObject();//删除D3D文件数据
void setViewPointAndLight();
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
AllocConsole();
#ifdef _DEBUG
AllocConsole();
#endif
HWND hWnd = createWin32Window(MsgProc,hInstance);
if(NULL != hWnd )
{
if( SUCCEEDED(InitD3D(g_pD3D,g_pd3dDevice,g_stPresentParam,hWnd,isFullScrean)) )
{
InitDeviceObjet();
RestoreDeviceObjects();
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
#ifdef _DEBUG
//_cprintf("while");
#endif
RenderFrame();
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
else
{
MessageBox(NULL,"init windows false","init windows false",NULL);
}
return 0;
}
LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
break;
case WM_SIZE:
InvalidateDeviceObjects();
RestoreDeviceObjects();
break;
case WM_DESTROY:
DeleteDeviceObject();
PostQuitMessage(0);
#ifdef _DEBUG
if (!FreeConsole())
MessageBox(NULL,"Could not free the console!","",NULL);
#endif
return 0;
case WM_PAINT:
ValidateRect(hWnd,NULL);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_F5:
{
isFullScrean = !isFullScrean;
changeMode(g_pd3dDevice,isFullScrean);
}
break;
case VK_ESCAPE:
{
PostQuitMessage(0);
}
break;
}
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
HRESULT changeMode(LPDIRECT3DDEVICE9 &lpDirect3DDrive,bool isFullScrean )
{
if(NULL != g_pd3dDevice)
{
if(isFullScrean)
{
g_stPresentParam = getFullScreanDisplayMode(lpDirect3DDrive,800,600);
}
else
{
g_stPresentParam = getWindowDisplayMode(lpDirect3DDrive);
}
// 清除显存
InvalidateDeviceObjects();
//重设显示模式
if ( FAILED(g_pd3dDevice->Reset(&g_stPresentParam)) )
{
printf("设备重置失败 !!!!!/n");
return false;//设备重置适失鞍败
}
// 再次吧东东加载入显存
RestoreDeviceObjects();
}
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: 这个函数在窗体大小改变,显示模式改变,和内存页面丢失的时候会被调用,主要回复往显卡缓冲区里丢失的数据,比如显卡向量池中的数据。
//-----------------------------------------------------------------------------
HRESULT RestoreDeviceObjects()
{
#ifdef _DEBUG
_cprintf("RestoreDeviceObjects/n");
#endif
setViewPointAndLight();
return S_OK;
}
void setViewPointAndLight()
{
D3DXMATRIX matView;
D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -10.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &matView, &vFromPt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
D3DXMATRIX matProject;
D3DXMatrixOrthoLH(&matProject,20.0f,15.0f,1.0f,20.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProject);
D3DLIGHT9 light;
D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -1.0f, -1.0f, 2.0f );
g_pd3dDevice->SetLight( 0, &light );
g_pd3dDevice->LightEnable( 0, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
}
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: 这个函数在显卡缓冲丢失后将被调用,用于删除显卡内存中已经无效的数据。
//-----------------------------------------------------------------------------
HRESULT InvalidateDeviceObjects()
{
// Invalidate the texture object, mesh object, buffer etc.
return S_OK;
}
void checkD3DandRestore()
{
HRESULT hr = g_pd3dDevice->TestCooperativeLevel();
if( FAILED( hr ) )
{
// 页面已经丢失,无法回复
if( hr == D3DERR_DEVICELOST )
return;
// 页面已经丢失,但可以回复
if( hr == D3DERR_DEVICENOTRESET )
{
// 清除显存
InvalidateDeviceObjects();
//重设显示模式
hr = g_pd3dDevice->Reset( &g_stPresentParam );
if( FAILED(hr ) )
return;
// 再次吧东东加载入显存
RestoreDeviceObjects();
}
}
}
void RenderFrame()
{
if( NULL == g_pd3dDevice )
{
return;
}
checkD3DandRestore();
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
g_pd3dDevice->BeginScene();
Render();
g_pd3dDevice->EndScene();
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
void Render()
{
D3DXMATRIX matWorld;
D3DXMatrixTranslation(&matWorld,0.0f,0.0f,-0.5f);
g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);
g_pd3dDevice->SetMaterial(&mtrl);
m_pD3DXMesh->DrawSubset(0);
D3DXMATRIX cubeWorldMatrix1;
D3DXMatrixTranslation(&cubeWorldMatrix1,7.0f,0.0f,0.0f);
g_pd3dDevice->SetTransform(D3DTS_WORLD,&cubeWorldMatrix1);
m_pD3DXMesh->DrawSubset(0);
D3DXMATRIX cubeWorldMatrix;
D3DXMatrixTranslation(&cubeWorldMatrix,3.0f,0.0f,-2.0f);
g_pd3dDevice->SetTransform(D3DTS_WORLD,&cubeWorldMatrix1);
m_pD3DXMesh->DrawSubset(0);
}
HRESULT InitDeviceObjet()//这里加载一些D3D数据
{
//MessageBox(NULL,"Init","",NULL);
HRESULT hr;
// Init the font
// Create a teapot mesh using D3DX
// if( FAILED( hr = D3DXCreateBox( g_pd3dDevice,1.0f,1.0f,1.0f, &m_pD3DXMesh, NULL ) ) )
// return E_FAIL;
if( FAILED( hr = D3DXCreateTeapot( g_pd3dDevice, &m_pD3DXMesh, NULL ) ) )
return E_FAIL;
D3DCOLORVALUE red ;
red.r = 1.0f;
red.g = 0.0f;
red.b = 0.0f;
red.a = 1.0f;
D3DCOLORVALUE width ;
width.r = 1.0f;
width.g = 1.0f;
width.b = 1.0f;
width.a = 1.0f;
D3DCOLORVALUE black;
black.r = 0.0f;
black.g = 0.0f;
black.b = 0.0f;
black.g = 0.0f;
mtrl.Ambient = red;
mtrl.Diffuse = red;
mtrl.Specular = black;
mtrl.Emissive = black;
mtrl.Power = 5.0f;
return S_OK;
}
HRESULT DeleteDeviceObject()//删除D3D数据
{
//MessageBox(NULL,"Delete","",NULL);
SAFE_RELEASE( m_pD3DXMesh );
SAFE_RELEASE(g_pD3D);
SAFE_RELEASE(g_pd3dDevice);
return TRUE;
}