3d Game Walkman

3d图形渲染,网络引擎 — tonykee's Blog
随笔 - 45, 文章 - 0, 评论 - 309, 引用 - 0
数据加载中……

晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把

网络和流协议,文件打包,读取,等等一工作基本工作总算是完工了,现在人物可以在我的场景中漫游,人物和人物之间通过网络能相互通讯,都已经实现了,但是回头再看看我的场景,实在是汗颜啊,场景十分单调,之前我是把场景对象放入到一个大的XML文件中的,完全手工来编辑XML,因为没有自己的场景编辑器,唉,一直下不了决心去写啊。

从今天开始,我打算自己自作一个场景编辑器,这可是一个大工程啊,不过应该是很值的,如果能完善,那才真就有引擎的架式了
可能你会问,现在也有很多免费的引擎还自己写?
是啊,我的无限大地形是核心,里面溶入了我太多的心血,很多实现和别人的自然“不完全兼容”了,如今是时候了……

进行了简单的设计之后,初步我打算用MDI窗口来制作场景编辑器,工具,参数调节面板在两旁,中间是D3D窗口
可才开始,就碰到问题了,天哪,MFC的主循环在哪里呢?How about Continuous Updating and Rending in MFC ?

不过功夫不负有心人,总算查到了,不过研究了好一会儿,还好有了结果

那么说到正题,怎么在MFC应用程序里面加入主循环呢,MFC的WinMain可是看不到的哦,消息处理都做了高度封装

其实也是有解决方法的,请看下文:

//你需要重写你的应用程序的Run()方法,把原方法里面的代码统统复制过来下面都是copy的CWinApp::Run()的源码

int CMapEditorApp::Run()
{
 //return CWinApp::Run();
 if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
 {
  // Not launched /Embedding or /Automation, but has no main window!
  TRACE(traceAppMsg, 0, "Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n");
  AfxPostQuitMessage(0);
 }


 ASSERT_VALID(this);
 _AFX_THREAD_STATE* pState = AfxGetThreadState();

 // for tracking the idle time state
 BOOL bIdle = TRUE;
 LONG lIdleCount = 0;

 // acquire and dispatch messages until a WM_QUIT message is received.
 for (;;)
 {
 
 //偷看消息队列,如果没有消息的话,就执行游戏的主循环框架完成渲染的Update
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 while(!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
  {
   //这里就可以放游戏的主循环了
   //GameLoop();
   DBWindowWrite("hello \r\n");
  }
//加入上面这段就搞定了,这个方法里面的其他的代码就不要去动他们的了,否则 ^_^!
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  // phase1: check to see if we can do idle work,处理线程
  while (bIdle &&
   !::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
  {
   // call OnIdle while in bIdle state
   if (!OnIdle(lIdleCount++))
    bIdle = FALSE; // assume "no idle" state
  }
       
  // phase2: pump messages while available
  do
  {
   //windows自己的GetMessage消息处理机制,类似于消息泵,有消息就处理消息
   // pump message, but quit on WM_QUIT,
   if (!PumpMessage())
    return ExitInstance();

   // reset "no idle" state after pumping "normal" message
   //if (IsIdleMessage(&m_msgCur))
   if (IsIdleMessage(&(pState->m_msgCur)))
   {
    bIdle = TRUE;
    lIdleCount = 0;
   }

  } while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));
 }
}



这只是一个初步的开始,MFC可不是一个好东西,这到不算什么,地图编辑器才是最麻烦的东西。
唉~~~

无论如何,现在开工吧!

posted on 2008-03-18 00:42 李侃 阅读(4385) 评论(13)  编辑 收藏 引用 所属分类: 前台客户端

评论

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

呵呵,我做的时候,直接放到OnIdle消息处理函数里面
2008-03-18 11:57 | mm

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

对哟,试过了,果真是可以
呵呵,简单多了
2008-03-18 13:20 | 李侃

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   


int CMapEditorApp::Run()
{
//loop
return CWinApp::Run();
}
是不是就可以了?
2008-03-18 22:28 | eyye

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

无限大地形 不错 期待你的作品!`
2008-03-19 01:23 | shaker(太子)

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

我也把循环放OnIdle里了,但是效果不好,鼠标不动,键盘不按,他根本不渲染
2008-07-17 00:32 | FO

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

我还是使用了以前的方案,没有放在OnIdle里面
这个函数在优先级别太低了。
2008-07-23 21:17 | 李侃

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把[未登录]  回复  更多评论   

楼主认为peekmessage和OnIdle难道不是一样的吗?
2008-09-29 11:21 | christanxw

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

我也把循环放OnIdle里了,但是效果不好,鼠标不动,键盘不按,他根本不渲染 ? 你不会用了 DialogBase 工程吧。。 用单文档和多文档构架下的,都是用OnIdle哦。
2008-11-25 16:46 | yilog

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

可是多文档的时候 ,怎样得到字窗口的句柄,在哪创建d3d设备啊
2009-03-10 17:35 | yun

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

我郁闷了好几天了,还没有得到子窗口的句柄呢
2009-03-10 17:36 | yun

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把  回复  更多评论   

我现在也在用onidle写一个编辑器,我发现打开这个编辑器窗口的时候,放在它前面的其它程序窗口就会死掉(也不是死掉, 就是反应特别慢),我有些怀疑是onidle的问题
2009-08-09 19:23 | 李现民

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把[未登录]  回复  更多评论   

最佳方法:
重载OnIdle
OnIdle中代码修改为:
TRACE0(_T("Game loop!\n"));
CWinApp::OnIdle(lCount);
return !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE);
2010-04-20 17:13 | Jason

# re: 晚上查了些资料,总算找到了MFC的游戏主循环,并好好研究了一把[未登录]  回复  更多评论   

OnIdle是利用的程序空闲时间,本不应该把耗时长的处理放在其中,楼上几位说的其他的程序假死也好反应慢也好,都是因为OnIdle把空闲时间占用太久的缘故,因此争取的做法还是应该放在run中。
2011-06-24 16:30 | zzz

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理