winapi – 为什么我的Win32 gdi游戏在Windows 7上速度非常慢?
[本条目底部的重要新信息如下]
我相信使用GDI是一个非常标准的游戏循环.它工作得相当好(复杂游戏大约25 fps, 对我来说,像这样的简单GDI游戏循环会在Windows 7上消失似乎很疯狂.我知道存在一些差异 谢谢你的帮助. #define CLIENT_WIDTH 320 #define CLIENT_HEIGHT 480 Graphics *graphics; HDC memoryDC; HBITMAP memoryBitmap; bool paintIsPending = false; void InitializeEngine( HDC screenDC ) { memoryDC = CreateCompatibleDC( screenDC ); memoryBitmap = CreateCompatibleBitmap( screenDC,CLIENT_WIDTH,CLIENT_HEIGHT ); SelectObject( memoryDC,memoryBitmap ); graphics = new Graphics( memoryDC ); ... } BOOL InitInstance( HINSTANCE hInstance,int nCmdShow ) { ... InitializeEngine( GetWindowDC( hWnd ) ); ... myTimer = SetTimer( hWnd,timerID,1000 / 60,NULL ); ... } void DrawScreen( HDC hdc ) { graphics->Clear( Color( 255,200,255 ) ); DrawGameStuff( graphics ); BitBlt( hdc,CLIENT_HEIGHT,memoryDC,SRCCOPY ); } LRESULT CALLBACK WndProc( HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam ) { ... case WM_TIMER: if ( !paintIsPending ) { paintIsPending = true; InvalidateRect( hWnd,NULL,false ); /////// START OPTIONAL SECTION UpdateWindow( hWnd ); ValidateRect( hWnd,NULL ); /////// END OPTIONAL SECTION } break; case WM_PAINT: hdc = BeginPaint( hWnd,&ps ); DrawScreen( hdc ); EndPaint( hWnd,&ps ); paintIsPending = false; break; ... } 啊哈!根据Chris Becke的线索,我现在有更多非常相关的信息.我确信这是BitBlt()很慢而不是图形 – > Clear(),但是当我注释掉图形时,我看到了> Clear()我在Windows 7上突然得到40 FPS.所以然后我将graphics-> Clear()更改为 // graphics->Clear( Color( 255,255 ) ); SolidBrush brush( Color( 255,255 ) ); graphics->FillRectangle( &brush,CLIENT_HEIGHT ); 并且它看起来仍然以40 FPS运行.我不知道为什么FillRectangle()调用比Clear()调用更快. 然后我开始添加我的游戏绘图代码,我立即找到另一个杀死它的调用:绘制游戏内容我使用精灵将精灵绘制到memoryDC中 graphics->DrawImage( myImageThatCameFromAPngFile,destx,desty,srcx,srcy,width,height,UnitPixel ); 那些电话也很慢.作为实验,我从PNG文件预先绘制到与screenDC兼容的第二个memoryDC中.然后,为了绘制我的精灵,我从这个辅助memoryDC绘制到我的主memoryDC中.所以我没有上面的DrawImage调用,而是: BitBlt( memoryDC,secondaryMemoryDC,SRCCOPY ); 并且,当我这样做时,整个游戏在Windows 7上以40 FPS运行. 然而,这不是一个真正的解决方案,因为在预渲染到二级存储器DC时,我丢失了PNG文件中的透明度信息,所以我的精灵现在都是不透明和丑陋的. 所以我的问题似乎是memoryDC(创建与screenDC兼容)和PNG源文件之间不兼容.我不明白为什么这种不兼容性存在(或者至少,为什么它会减慢这么多东西)只在Windows 7上.有没有办法保存PNG文件从一开始就与屏幕兼容?或者在一开始就在内部重新渲染它以获得与屏幕兼容的新PNG文件?嗯…. 好的,所以我能够通过将其渲染到32bpp HBITMAP来正确渲染我的PNG文件,如下所示: HDC hdc = CreateCompatibleDC( GetWindowDC( hWnd ) ); Bitmap *bitmap = new Bitmap( image->GetWidth(),image->GetHeight(),PixelFormat32bppARGB ); HBITMAP hbitmap; bitmap->GetHBITMAP( Color( 0,0 ),&hbitmap ); SelectObject( hdc,hbitmap ); Graphics *g = new Graphics( hdc ); g->DrawImage( pngImage,pngImage->GetWidth(),pngImage->GetHeight(),UnitPixel ); 然后使用AlphaBlend()渲染它: _BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; AlphaBlend( memoryDC,hdc,bf ); 所以现在我的游戏在Windows 7上运行得很快. 但是我仍然不明白为什么我必须为Windows 7完成所有这些操作.为什么使用DrawImage()的PNG图像的默认绘图在Windows 7上如此之慢? 解决方法
我不知道这是否是您当前代码速度慢的原因,但更有效的双缓冲解决方案是仅在WM_PAINT处理程序中执行BitBlt,并在WM_TIMER处理程序中调用DrawGameStuff.这样你在绘画过程中唯一要做的就是将后台缓冲区复制到屏幕上,实际的绘图逻辑可以在不同的时间发生.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Windows Phone开发使用wpf?
- 如何调用window.alert(“message”);从C#
- Windows – 设计键盘快捷键的最佳做法
- windows-phone-7 – Windows Phone应用程序中的组合根目录在
- 部署 – 从KB修补程序中提取产品代码以在引导程序中使用
- windows中为php安装mongodb与memcache
- Windows Powershell命令行相当于dd
- windows-phone-8 – 为什么在XAML TextBox中没有PlaceHolde
- windows-phone-7 – Windows Phone 7游戏引擎?
- windows – Active Directory的备份
- wpf – 如何将MenuItem.Header绑定到Window / Us
- windows-server-2012 – Windows Server 2012默认
- wix – 错误4:SELECT`Fessage` FROM`Error` WHE
- windows-xp – Windows XP显示磁盘空间不足 – W
- windows – 从光学介质中恢复,忽略读取错误
- WiX检查.NET Framework 4
- Buildtool类似于Windows的bitbake
- IIS错误:不支持远程连接
- windows – Angular 4错误:在Karma-Jasmine Tes
- windows – 一个很好的免费屏幕共享程序,用于配对