strange bug
hello everyone!
I have developed a game in c++ using only win32 API (no dx at all). Game runs fine but after an hour or so, it draws a single frame on desktop that stays there no matter what i do. Game keeps working fine after that and there are no other problems whatsoever, except the fact that strange frame stays on desktop covering icons. This happens mainly when i switch between different windows during the gameplay but also when i run game in full screen mode. The strange thing is that it happens after so much time (an hour) and that game still works fine after that.
I have excluded possibilities of memory leaks or wrong window handles.
If anyone had this kind of problem or knows what caused it please let me know.
I haven't solved this problem yet. It seems that application somehow, somewhere gets a wrong DC (the screen DC) and starts rendering on top of all other windows. The game window still recieves the input but animation and all graphics are rendered outside window. I cant think of any other thing that could cause this except using wrong DC.
I belive there is no way my code could mess up DCs, but here is some code i use:
I think there is no way this code could render on desktop but something wrong happens after an hour of play. I forgot to say that after 5 minutes or so, it gets back to normal again (it starts rendering correctly - no more desktop frames).
Here is the screenshot of bug: screenshot
if anyone has any idea what can be wrong, please tell me.
I belive there is no way my code could mess up DCs, but here is some code i use:
// BACKBUFFER CLASS//==================class BackBuffer {private: HWND mhWnd; // Window handle HDC mhDC; // DC handle HBITMAP mhSurface; // Surface bitmap HBITMAP mhOldObject; // Previous bitmap int mWidth; // Bitmap width int mHeight; // Bitmap height .....public: // CONSTRUCTOR //============ BackBuffer( HWND hWnd, int width, int height ) { mhWnd = hWnd; mWidth = width; mHeight = height; HDC hWndDC = GetDC( hWnd ); mhDC = CreateCompatibleDC( hWndDC ); mhSurface = CreateCompatibleBitmap( hWndDC, width, height ); ReleaseDC( hWnd, hWndDC ); mhOldObject = (HBITMAP)SelectObject( mhDC, mhSurface ); HBRUSH White = (HBRUSH)GetStockObject( LTGRAY_BRUSH ); HBRUSH OldBrush = (HBRUSH)SelectObject( mhDC, White ); Rectangle( mhDC, 0, 0, mWidth, mHeight ); SelectObject( mhDC, OldBrush ); }; // PRESENT BUFFER //=============== void Present() { HDC hWndDC = GetDC( mhWnd ); BitBlt( hWndDC, 0, 0, mWidth, mHeight, mhDC, 0, 0, SRCCOPY ); ReleaseDC( mhWnd, hWndDC ); }; // GET DC FUNCTION //============= HDC GetHDC() { return mhDC; }; ...... // SOME OTHER FUNCTIONS ......};// SPRITE CLASS//=============class Sprite {private: HINSTANCE mhAppInstance; // Application handle HBITMAP mhImage; // Bitmap image handle HBITMAP mhMask; // Bitmap mask handle BITMAP mImageBM; // Bitmap image BITMAP mMaskBM; // Bitmap mask RECT mBitmapRect; // Bitmap rectangle POINT mCenterPosition; // Bitmap center int ImageID; // Bitmap image IDpublic: // CONSTRUCTOR //============ Sprite( HINSTANCE hAppInstance, int imageID, int maskID, POINT pos ) { mhAppInstance = hAppInstance; ImageID = imageID; mCenterPosition.x = pos.x; mCenterPosition.y = pos.y; mhImage = LoadBitmap( hAppInstance, MAKEINTRESOURCE(imageID) ); mhMask = LoadBitmap( hAppInstance, MAKEINTRESOURCE(maskID) ); GetObject( mhImage, sizeof(BITMAP), &mImageBM ); GetObject( mhMask, sizeof(BITMAP), &mMaskBM ); assert(mImageBM.bmWidth == mMaskBM.bmWidth); assert(mImageBM.bmHeight == mMaskBM.bmHeight); mBitmapRect.right = mCenterPosition.x + GetWidth()/2; mBitmapRect.bottom = mCenterPosition.y + GetHeight()/2; mBitmapRect.left = mCenterPosition.x - GetWidth()/2; mBitmapRect.top = mCenterPosition.y - GetHeight()/2; }; // SOME OTHER FUNCTIONS ...... // DRAW SPRITE FUNCTION //===================== virtual void Draw( HDC hBackBufferDC, HDC hSpriteDC ) { int w = GetWidth(); int h = GetHeight(); int x = mCenterPosition.x - (w/2); int y = mCenterPosition.y - (h/2); HGDIOBJ oldObj = SelectObject(hSpriteDC, mhMask); BitBlt(hBackBufferDC, mBitmapRect.left, mBitmapRect.top, mBitmapRect.right, mBitmapRect.bottom, hSpriteDC, 0, 0, SRCAND); SelectObject(hSpriteDC, mhImage); BitBlt(hBackBufferDC, mBitmapRect.left, mBitmapRect.top, mBitmapRect.right, mBitmapRect.bottom, hSpriteDC, 0, 0, SRCPAINT); SelectObject(hSpriteDC, oldObj); };};// GAME CLASS//===========class Game {private: HWND hMainWnd; // Window handle BackBuffer* pBackBuffer; // Pointer to backbuffer HDC hSpriteDC; // Sprite dc Sprite* Background; // example sprite ..... // DRAW FRAME FUNCTION //==================== void DrawFrame( double deltaTime ) { HDC dc = pBackBuffer->GetHDC(); // draw sprites using dc like: Background->Draw( dc, hSpriteDC ); ..... };public: ..... // INITIALIZE GAME FUNCTION //========================= int GCInitialize( HINSTANCE hInstance ) { ..... // SOME OTHER STUFF ..... hSpriteDC = CreateCompatibleDC(0); pBackBuffer = new BackBuffer( hMainWnd, Width, Height ); }; // GAME (MESSAGE) LOOP //==================== int GameLoop() { MSG Message; ZeroMemory( &Message, sizeof(MSG) ); // CALCULATE TIME PASSED ...... while( Message.message != WM_QUIT ) { if( PeekMessage( &Message, 0, 0, 0, PM_REMOVE ) ) { TranslateMessage( &Message ); DispatchMessage( &Message ); } else { if( timeElapsed >= 0.07 ) { DrawFrame( deltaTime ); pBackBuffer->Present(); timeElapsed = 0.0; } lastTime = currTime; } } ..... };};
I think there is no way this code could render on desktop but something wrong happens after an hour of play. I forgot to say that after 5 minutes or so, it gets back to normal again (it starts rendering correctly - no more desktop frames).
Here is the screenshot of bug: screenshot
if anyone has any idea what can be wrong, please tell me.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement