Surface Flip doesn't work the way it should...
Hi
I''ve started creating my own DDraw class (mabScreen). I can create the Primary Surface and also a Back Buffer for it. The Compiler doesn''t give my any errors. My Class has a member function, which is call fillBB(dword col). This function fills the Back Buffer with a specific color. Until here everything works great. Then I call flip(), which flips the Primary with the Back Buffer.
Now here is the problem: The color the Back Buffer was filled with (I think it is red in the example) pops up and after a few milliseconds the screen goes black again. The strange thing about all this is that sometimes the screen stays red (as it should), I can move the mouse and nothing happens. But I can''t use a program the works sometimes and sometimes it doesn''t...
section of main.cpp
-------------------
mabScreen.fillBB(1);
mabScreen.flip();
while( ... // main application loop
Please help me, I going crazy, tnx...
MaB
It sounds like you might be losing your backbuffer. Sometimes with DirectX, surfaces are ''lost''. You need to check if your surface is lost before attempting to fill it. If you are filling it yourself, a good time to check is when you Lock the surface. If you''re doing it in hardware with a DDBLTFX structure, check when you call Blt. Like this:
HRESULT hr;
if(FAILED(hr=back_buffer->Blt(blah,blah)))
{
if (hr == DDERR_SURFACELOST)
// handle the lost surface
}
What you can do if the surface is lost is call the surface''s restore function. Then, repeat the call to the Blt (or lock) function. If it fails a second time, exit the function with an error.
HRESULT hr;
if(FAILED(hr=back_buffer->Blt(blah,blah)))
{
if (hr == DDERR_SURFACELOST)
// handle the lost surface
}
What you can do if the surface is lost is call the surface''s restore function. Then, repeat the call to the Blt (or lock) function. If it fails a second time, exit the function with an error.
--- Official D Blog | Learning D | The One With D | D Bits
You probably want to set both (all) pages to red before entering the main loop. You set 1 page to red, but the others are still blank/random. Call fill() and flip() for each page, then enter the main loop.
Rock
Rock
Hi again, here is the source code of the two member functions mentioned above...
// ---------------
// FILL BACKBUFFER
// ---------------
int mabScreen::fillBB(dword fillColor)
{
// Check whether createEx..or createWind.. has been
called sucessfully
if(_state == 0)
errorProc(-920, ERR, gblShowErrMsg);
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX);
ddBltFx.dwFillColor = fillColor;
HRESULT retVal = _ptBB->Blt(NULL, NULL, NULL, DDBLT_WAIT
/ DDBLT_COLORFILL, &ddBltFx);
if(retVal == DDERR_SURFACELOST)
{
restore();
return LOST;
}
if(retVal != DD_OK)
return errorProc(-921, ERR, gblShowErrMsg);
return OK;
}
// -------------
// FLIP SURFACES
// -------------
void mabScreen::flip()
{
HRESULT retVal;
// Choose Exclusive or Windowed Mode, then flip
if(_exclMode)
retVal = _ptPS->Flip(NULL, DDFLIP_WAIT);
else
{
GetClientRect(_hWnd, &_ScreenRect);
ClientToScreen(_hWnd, (LPPOINT)&_ScreenRect.left);
ClientToScreen(_hWnd, (LPPOINT)&_ScreenRect.right);
retVal = _ptPS->Blt(&_ScreenRect, _ptBB, NULL,
DDFLIP_WAIT, NULL);
}
// Restore Surface if it is lost
if(retVal == DDERR_SURFACELOST)
{
exit(1);
restore();
}
if(_ptBB->IsLost() == DDERR_SURFACELOST)
exit(1);
}
...the two functions exit(1); (which I put there for testing) are never called, which means that neither Primary Surface nor Back Buffer were ''lost''. (I am using Exclusive Mode by the way)
OK, I did some more tests, consider this...
parts of main.cpp
-----------------
mabScreen.fillBB(1); // fills Back Buffer with red
mabScreen.flip(); // flips PS and BB
mabScreen.fillBB(1); // now both are filled with red
mabScreen.flip(); // flip again
mabScreen.fillBB(2); // fills BB with green
mabScreen.flip(); // flip (screen should become
// green)
Sleep(2000);
while( ... // main application loop
If I execute this code I get different results...
result 1: screen is red
result 2: screen is green (as it should)
why, WHY WHY!!??????
MaB
mabScreen.fillBB(1); // fills Back Buffer with red ==> *** OK
mabScreen.flip(); // flips PS and BB ==> *** OK
mabScreen.fillBB(1); // now both are filled with red ==> *** OK
mabScreen.flip(); // flip again ==> *** OK
mabScreen.fillBB(2); // fills BB with green
// *** Front is still Red
mabScreen.flip(); // flip (screen should become green)
// *** Front is Green, Back is Red
Sleep(2000);
while( ... // main application loop
If I execute this code I get different results...
result 1: screen is red
result 2: screen is green (as it should)
*** The screen should flip between Red and Green because one of them is still Red... ***
mabScreen.flip(); // flips PS and BB ==> *** OK
mabScreen.fillBB(1); // now both are filled with red ==> *** OK
mabScreen.flip(); // flip again ==> *** OK
mabScreen.fillBB(2); // fills BB with green
// *** Front is still Red
mabScreen.flip(); // flip (screen should become green)
// *** Front is Green, Back is Red
Sleep(2000);
while( ... // main application loop
If I execute this code I get different results...
result 1: screen is red
result 2: screen is green (as it should)
*** The screen should flip between Red and Green because one of them is still Red... ***
You could always try something like this
//wait until the surface can be flipped
//and then flip it
//If there is an error, fix it
if(PrimBuff->Flip(NULL, DDFLIP_WAIT)!=DD_OK)
{
//blah, blah, ect.
}
This way, you can it waits to flip before flipping
//wait until the surface can be flipped
//and then flip it
//If there is an error, fix it
if(PrimBuff->Flip(NULL, DDFLIP_WAIT)!=DD_OK)
{
//blah, blah, ect.
}
This way, you can it waits to flip before flipping
D:
move a fillBB and flip into the main application loop and see how it looks.
Carl "trixter"[email=carl@trixoft.com]carl@trixoft.com[/email]http://www.trixoft.com
Hi everybody
There is nothing wrong with my class code or Direct X. The problem is that in my code fillBB() and flip() are called
right after creating the main window and a call to show it.
main.cpp
--------
mainWnd.create();
mainWnd.show(); // Windows needs time to activate (update) the main window
mabScreen.fillBB(1);
mabScreen.flip();
while( ... // main application loop
I guess the screen became black because Windows sometimes lets the flip occures before my main window is active. This means the BB is filled with red, then it is fliped, and afterwards the main window (which has a black background) becomes active. Thats why it red is flashing up sometimes and then the screen goes black. (Answer to First Message)
Sorry folks, my fault...tnx anyway...
MaB
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement