代码还有点问题,等我调试好了,我再写详细点,不过注释是非常详细了,我觉得不用再说明了。
//**************************************************************************** //说明: // 开发环境:.NET 7.1.3091 // 操作系统:WindowsXP SP2 // S D K:Microsoft DirectX 9.0 SDK // computer: // CPU::Inter 2.6C // 内存:1G DDR400 // 显卡:FX5900 128MB // 硬盘:120G*2 8MB 7200 // 主板:Inter865PE //**************************************************************************** #pragma comment(lib,"d3d9.lib") #pragma comment(lib,"d3dx9.lib") #pragma comment(lib,"dinput8.lib") #pragma comment(lib,"dxguid.lib")
#include<windows.h> #include<d3d9.h> #include<d3dx9.h> #include<dinput.h>
#define SAFE_RELEASE(p){if(p){(p)->Release();(p)=NULL;}}
#define _FullScreen//设定是窗口模式还是全屏模式
//函数申明 int InitGraph(HWND hwnd); void InitInput(); void RefreshGraph(); void CloseGraph(); int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow); static BOOL InitWindow(HINSTANCE hInstance,int nCmdShow); LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
//变量说明 HWND hWnd; WNDCLASS WC; LPD3DXMESH Mesh;//模型 DWORD nMater;//材质数 D3DMATERIAL9 * Mater;//材质 LPDIRECT3DTEXTURE9 * Tex;//纹理 LPDIRECT3D9 pD3D;//D3D对象 LPDIRECT3DDEVICE9 pDev;//D3D设备 D3DDISPLAYMODE d3ddm;//D3D显示模式 D3DPRESENT_PARAMETERS d3dpp;//D3D图像显示方法 LPDIRECTINPUT8 pInput;//DInput对象 LPDIRECTINPUTDEVICE8 pInputDev;//DInput设备 int mousex=-200,mousey=25; //初始化鼠标位置 float x=0,y=0,z=0; //主角位置 float eyex=0,eyey=0,eyez=0; //眼睛所看位置 float height=4; //主角身高
int InitGraph(HWND hwnd) { if(NULL==(pD3D=Direct3DCreate9(D3D_SDK_VERSION))) return -1;//创建D3D对象 if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm))) return -1;//得到当前的显示模式
ZeroMemory(& d3dpp,sizeof(d3dpp));
#if defined(_Windowed)//如果需要程序在窗口模式运行 d3dpp.Windowed=TRUE; d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD; #endif
#if defined(_FullScreen)//如果需要程序在全屏幕模式运行 d3dpp.Windowed=FALSE; d3dpp.hDeviceWindow=hwnd; d3dpp.SwapEffect=D3DSWAPEFFECT_FLIP; d3dpp.BackBufferCount=1; //有一个后台缓存 d3dpp.BackBufferWidth;//屏幕宽度为800像素 d3dpp.BackBufferHeight=600;//屏幕长度为600像素 //立即显示刷新后的图像 d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; #endif
d3dpp.BackBufferFormat=d3ddm.Format;//色彩深度为桌面的色彩深度(如果显示不对 D3DFMT_A8R8G8B8 OR D3DFMT_X8R8G8B8
//开启自动深度缓冲 d3dpp.EnableAutoDepthStencil=TRUE; d3dpp.AutoDepthStencilFormat=D3DFMT_D16;//16位自动深度缓存
//创建D3D设备 //***************************************出现问题*************出现问题******************************************************************** if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pDev)))//要创建的D3D设备 return 1; //**************************************************************************************************************************************** //------------------------------------------------------------------------------------------------------------- pDev->SetRenderState(D3DRS_LIGHTING,FALSE); pDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); pDev->SetRenderState(D3DRS_ZENABLE,TRUE);
D3DXMATRIX matWorld;//定义world矩阵 D3DXMatrixIdentity(& matWorld);////定义其为单位矩阵,既不改变场景 pDev->SetTransform(D3DTS_WORLD,& matWorld);//设置矩阵 D3DXMATRIX matProj; //定义Projection 矩阵 D3DXMatrixPerspectiveFovLH(& matProj, D3DX_PI/2,//视角大小,这里设为90度 800.0f/600.0f, 0.01f, //眼睛可以看多近 500.0f);//眼睛可以看多远 pDev->SetTransform(D3DTS_PROJECTION,& matProj);//设置矩阵 //------------------------------------------------------------------------------------------------------------- LPD3DXBUFFER pBuffer;//临时缓存 D3DXMATERIAL* tMater;//临时材质 D3DXLoadMeshFromX("Arena.x",//.x文件名 D3DXMESH_MANAGED,//说明Mesh由DX管理 pDev,//刚刚创建的D3D设备 NULL,//这里可以使一个LPD3DXBUFFER对象,保存场景中每一个三角形与那个三角形相联系 &pBuffer,NULL,&nMater,&Mesh);//上面刚定义的那群东西
tMater = (D3DXMATERIAL*)pBuffer->GetBufferPointer();//得到材质的数据指针 Mater = new D3DMATERIAL9[nMater]; Tex = new LPDIRECT3DTEXTURE9[nMater]; for(DWORD i=0;i<nMater;i++) { Mater[i]=tMater[i].MatD3D; Mater[i].Ambient=Mater[i].Diffuse;//设置好Ambient材质 D3DXCreateTextureFromFile(pDev,tMater[i].pTextureFilename,&Tex[i]);//创建纹理 } pBuffer->Release();
DWORD * pAdj=new DWORD[Mesh->GetNumFaces()*3]; Mesh->GenerateAdjacency(0.0f,pAdj); Mesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE,pAdj,NULL,NULL,NULL); return -1; } void InitInput()//初始化Dinput { DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL); pInput->CreateDevice(GUID_SysMouse,&pInputDev,NULL); pInputDev->SetDataFormat(& c_dfDIMouse); pInputDev->SetCooperativeLevel(hWnd,DISCL_EXCLUSIVE|DISCL_FOREGROUND); pInputDev->Acquire(); } void ReadMouse()//读取鼠标状态 { DIMOUSESTATE mouse_stat;//鼠标状态 pInputDev->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouse_stat); mousex+=mouse_stat.lX; mousey+=mouse_stat.lY; }
void RefreshGraph() { if(mousey>314) mousey=314; if(mousey<-314) mousey=-314; eyey=y+height-tan((float)(mousey)/200); eyex=x+sin((float)(mousex)/200); eyez=z+cos((float)(mousex)/200); D3DXMATRIX matView; D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(x,y+height,z), &D3DXVECTOR3(eyex,eyey,eyez), &D3DXVECTOR3(0.0f,1.0f,0.0f)); pDev->SetTransform(D3DTS_VIEW,&matView); pDev->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); pDev->BeginScene();
for(unsigned long i=0;i<nMater;i++)//对于每一种材质 { pDev->SetMaterial(&Mater[i]);//设置材质 pDev->SetTexture(0,Tex[i]);//设置纹理 Mesh->DrawSubset(i);//渲染事第i中材质的三角形 }
pDev->EndScene(); if(pDev->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST) { //恢复设备 if(pDev->TestCooperativeLevel()==D3DERR_DEVICENOTRESET) { pDev->Reset(&d3dpp);
pDev->SetRenderState(D3DRS_LIGHTING,FALSE); pDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); pDev->SetRenderState(D3DRS_ZENABLE,TRUE);
D3DXMATRIX matWorld;//定义World矩阵 D3DXMatrixIdentity(&matWorld); pDev->SetTransform(D3DTS_WORLD,&matWorld); //设置矩阵 D3DXMATRIX matProj;//定义Projection矩阵 D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/2, 800.0f/600.0f, 0.01f, 500.0f); pDev->SetTransform(D3DTS_PROJECTION,& matProj);//设置矩阵 } } }
void CloseGraph() { //释放掉一些资源 SAFE_RELEASE(pDev); SAFE_RELEASE(pD3D); SAFE_RELEASE(pInputDev); SAFE_RELEASE(pInput); SAFE_RELEASE(pDev); SAFE_RELEASE(pD3D); }
//********************************************************************** //函数:WinMain() //功能:Windows 程序入口函数。创建主窗口,处理消息循环 //日期:2005.1.3 22:34 //编写人:张小斌 //********************************************************************** int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) //hInstance:表示该应用程序的句柄 //hPrevInstance:为了保持与16位windows应用程序的兼容性 //lpCmdLine:指向命令行参数字符串的指针 //nCmdShow:指定应用程序窗口显示方式的整数 { InitWindow(hInstance,nCmdShow); //创建主窗口,如果创建不成功则返回FALSE并同时退出程序 if(InitGraph(hWnd)!=1) { MessageBox(hWnd,"初始化图像引擎出错!","出错!",MB_OK); return -1; }
InitInput();
MSG msg; //进入消息循环 for(;;) { if(PeekMessage(& msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT)break; TranslateMessage(& msg); DispatchMessage(& msg); } else { ReadMouse(); RefreshGraph(); } } return (int)(msg.wParam); } //******************************************************************* //函数:InitWindow() //功能:创建窗口 //日期:2005.1.3 22:43 //编写人:张小斌 //******************************************************************* static BOOL InitWindow(HINSTANCE hInstance,int nCmdShow) { //定义窗口风格: WNDCLASS wc; wc.style=NULL;//窗口的风格 wc.lpfnWndProc=(WNDPROC)WinProc;//窗口消息处理函数的指针 wc.cbClsExtra=0;//分配给窗口类结构之后的额外字节数 wc.cbWndExtra=0;//分配给窗口实例之后的额外的字节数 wc.hInstance=hInstance;//窗口所对应的应用程序的句柄 wc.hIcon=NULL;//窗口图标 wc.hbrBackground=CreateSolidBrush(RGB(100,0,0));//暗红色背景 wc.lpszMenuName=NULL;//窗口的菜单资源名称 wc.lpszClassName="My_Test";//窗口类的名称 RegisterClass(&wc);//注册窗口 //按所给参数创建窗口 hWnd = CreateWindow("My_Test", "My First program",//窗口标题 WS_POPUP|WS_MAXIMIZE,0,0,800,600, //GetSystemMetrics(SM_CXSCREEN),//此函数返回屏幕宽度 //GetSystemMetrics(SM_CYSCREEN),//此函数返回屏幕高度 NULL,NULL,hInstance,NULL); if(!hWnd)return FALSE; ShowWindow(hWnd,nCmdShow);//显示窗口 UpdateWindow(hWnd);//刷新窗口 return TRUE; } //******************************************************************* //函数:WinProc() //功能:处理窗口消息 //日期:2005.1.3 22:56 //编写人:张小斌 //******************************************************************* LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_SETCURSOR: SetCursor(NULL); return 0; case WM_KEYDOWN://击键消息 switch(wParam) { case VK_ESCAPE: //MessageBox(hWnd,"ESC 键按下了!确定后推出!","KEYboard",MB_OK); //PostMessage(hWnd,WM_CLOSE,0,0);//给窗口发送WM_CLOSE消息break; CloseGraph(); DestroyWindow(hWnd); break; case 'W': x+=eyex-x; z+=eyez-z; break; case 'S': x-=eyez-z; z-=eyez-z; break; case 'A': x-=eyez-z; z+=eyex-eyez+z;//注意x刚被改变过 break; case 'd': x+=eyez-z; z-=eyex-x+eyez-z; break; } return 0;//处理完一个消息后返回0
case WM_CLOSE://准备退出 DestroyWindow(hWnd);//释放窗口 return 0;
case WM_RBUTTONDOWN: MessageBox(hWnd,"鼠标右键按下了!","Mouse",MB_OK); return 0;
case WM_DESTROY://如果窗口被释放... PostQuitMessage(0);//给窗口发送WM_QUIT消息 return 0; } //调用缺省消息处理过程 return DefWindowProc(hWnd,message,wParam,lParam); }

|