vc.net 游戏开发 第二章 创建3D场景

代码还有点问题,等我调试好了,我再写详细点,不过注释是非常详细了,我觉得不用再说明了。
不知道那内存溢出了 我再查查,昨天的毛病已经解决了

//****************************************************************************
//说明:
//      开发环境:.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;
 //if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pDev)))
 //{
 // return false;
 //}
 //****************************************************************************************************************************************
 //-------------------------------------------------------------------------------------------------------------
 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("tiger.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:指定应用程序窗口显示方式的整数
{
 if(!InitWindow(hInstance,nCmdShow))
 {
  MessageBox(hWnd,"创建窗口错误","ERROR!",MB_OK);
   return FALSE;
 }
 //创建主窗口,如果创建不成功则返回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.hCursor=NULL;
 wc.hbrBackground=NULL;//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);
}

 


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值