Jump to content

  • Log In with Google      Sign In   
  • Create Account


DD_Shutdown


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
15 replies to this topic

#1 jtecin   Members   -  Reputation: 122

Like
Likes
Like

Posted 24 December 1999 - 11:05 AM

Okay, I can't understand why this is not working. In my Game_Shutdown function, I call the following function to shut down direct draw:


int GFX_Shutdown(void)
{
if (lpddsback)
lpddsback->Release();
if (lpddsprimary)
lpddsprimary->Release();
if (lpdd)
lpdd->Release();

return 0;
}

Now, I can run my game and stuff and it works fine. But when I quit, this screws everything up. If I don't call this function, the program exits fine. However, I'm supposed to release the surfaces' resources, right? Anyway, I'm pretty sure there is nothing wrong with the actual function, so is there some way I could have screwed this up in a previous function, like initializes it wrong or something? Thanks for any help.


Sponsor:

#2 CJ   Members   -  Reputation: 122

Like
Likes
Like

Posted 22 December 1999 - 10:57 PM

Try

int GFX_Shutdown(void)
{
if (lpddsback)
lpddsback->Release(); lpddsback=0;
if (lpddsprimary)
lpddsprimary->Release();lpddsprimary=0;
if (lpdd)
lpdd->Release();lpdd=0;
return 0;
}

------------------
Dance with me......

http://members.xoom.com/CJdeVos/index.htm


#3 STG   Members   -  Reputation: 122

Like
Likes
Like

Posted 22 December 1999 - 11:17 PM

I can't see that doing this would be any different but from memory I always use:

if (lpddsback!=null){
  lpddsback->Release();
  lpddsback=null;
}

Most likly overkill on my part but I have never had any problems with it.


#4 Melo   Members   -  Reputation: 122

Like
Likes
Like

Posted 22 December 1999 - 11:36 PM

I've read, that if you release the DDraw-Object, the surfaces are released automatically.

I think a problem like this was mentioned in the MS DirectX FAQ at http://www.microsoft.com/directx


#5 Theses   Members   -  Reputation: 122

Like
Likes
Like

Posted 22 December 1999 - 11:42 PM

i'm guessing your situation is using complex
which means when you kill the primary surface the release function for the attached back buffer gets called and so what may be going on is that you are first killing the back buffer but then you kill the primary buffer and it tries to release the back buffer again which is killed aand uh oh bad bad bad
your order of killing stuff is fine you jsut needed to point everything to NULL after killing it like the above posts say

#6 NightShade   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 December 1999 - 04:00 AM

Look in the DX docs (I'm assuming you're using DX 7.0) under "When Reference Counts Will Change" and "Reference Counts for Complex Surfaces", and "Releasing Surfaces". In short, I think if you just create the flipping chain using create surface, you can release the whole thing by just releasing the primary surface. However if you get access to the back buffer by using GetAttachedSurface (which you probably do, I dont know how else you can do it!), you have to release the back buffer explicitly because GetAttachedSurface increases its ref count.
I think setting them to NULL after the release is a good idea, but it would only find bugs from your own code trying to reuse the object.
One thing you might consider doing is watching the ref count of both surfaces as your program progresses and terminates - just write something like:
int refcount;
Surf->AddRef();
refcount = (int) Surf->Release();
This should give you the current reference count without actually changing it, and you can see what is actually going on.
Finally, IDirectDraw and IDirectDraw2 interfaces, when released, also release all their children, wheras later interfaces don't, but this shouldn't be a problem for you because you are releasing the DD object last (the problem was with releasing children after the parent)
Hope this helps a little
-ns

[This message has been edited by NightShade (edited December 23, 1999).]


#7 Jim Adams   Members   -  Reputation: 440

Like
Likes
Like

Posted 23 December 1999 - 07:05 AM

Don't release the backbuffer if it's an attached surface. Just release the primary and it should release all surfaces attached to it.

You can test it out by releasing the primary surface, then try accessing the backbuffer - it should fail since it too was released.


Jim Adams


#8 jtecin   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 December 1999 - 10:27 AM

Okay, I've tried everything but still no luck. FYI I am using DX 5.0 with VC++ 4.0(I know it is kind of out of date but can't afford anything else right now). Anyway, I thought I'd post the code for my GFX_init function:

int GFX_Init()
{
//Create DirectDraw object
if(DirectDrawCreate(NULL, &lpdd, NULL) != DD_OK)
{
MessageBox(main_window_handle,"Could Not Create Direct Draw","Error!",MB_OK);
return 0;
}
//Get exclusive mode but still allow ctrl & alt & delete
if(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT) != DD_OK)
{
MessageBox(main_window_handle,"Could Not Set ddraw cooperative","Error!",MB_OK);
return 0;
}
//Set the video mode to 640x460x16
if(lpdd->SetDisplayMode(640, 480, 16) != DD_OK)
{
MessageBox(main_window_handle,"Could Not set display mode","Error!",MB_OK);
return 0;
}
//Create the primary surface with a back buffer, make it "flipable"
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
if(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL) != DD_OK) return 0;

ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if(lpddsprimary->GetAttachedSurface(&ddscaps, &lpddsback) != DD_OK) return 0;

return 1; //Return success!
}


#9 Jim Adams   Members   -  Reputation: 440

Like
Likes
Like

Posted 23 December 1999 - 05:30 PM

Clear the ddsd structure in there:

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
...


If that doesn't help, what exactly is happening when you exit? That compiler/dx version is fine - that's what I use on one of my systems.

Jim Adams



#10 jtecin   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 December 1999 - 07:36 PM

When I try to exit, I get the usual windows "error beep", and black covers most of the screen except for a little on the right and bottom. The only way to get out is by using CTRL+ALT+DELETE and clicking on VC++ and END TASK. Ne1 know what's going on?


#11 CJ   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 December 1999 - 09:10 PM

Now I am wondering how your Window Procedure looks like

You should first release all your ddraw stuff, then call PostQuitMessage(0) or whatever......and then break.

Done that?

------------------
Dance with me......

http://members.xoom.com/CJdeVos/index.htm


#12 jtecin   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 December 1999 - 10:12 PM

Pretty sure I have that, here is my code:

if (KEY_DOWN(VK_ESCAPE))
{
Game_Shutdown(); //Close music, shutdown sound and shutdown graphics
PostQuitMessage(0);
}

It seems to work fine in my other programs.


#13 alexmoura   GDNet+   -  Reputation: 450

Like
Likes
Like

Posted 24 December 1999 - 01:08 AM

Not sure, but it seems you're trying to use the DDobjects/surfaces after they've been released. If the code from above is placed on the message handler, and you weren't setting the lpdds's and lpdd to zero or not checking in the main blitting/flipping action if they are different from zero, that would mess thing up, since it's possible the drawing will still happen after you release the objects... just a thought.

#14 CJ   Members   -  Reputation: 122

Like
Likes
Like

Posted 24 December 1999 - 02:13 AM

Hmmmm.....I'm just wndering. I don't know that much about the window procedure but I do know that you have to break after each Window message.

Try putting a break after your PostQuitMessage(0). I think it's because of that why it is doing that stuff.

My reasoning:
If you don't break, it will return DefWindowProc on the end of your Window procedure, in that case it will try to access the DirectDraw stuff again, which will crash, because they don't exist anymore. I'm not quite sure if the postQuitMessage breaks out of it, so........give this a try.

------------------
Dance with me......

http://members.xoom.com/CJdeVos/index.htm


#15 Jim Adams   Members   -  Reputation: 440

Like
Likes
Like

Posted 24 December 1999 - 05:55 AM

Actually, you'd return 0 - not break. A typical windows message function will break and fall down to the default message handler if you don't return.

I would suggest you make a very simple program that uses your init function, then immediately calls the shutdown function and exits. Don't even start the message loop. See what happens.

If it bombs, it most likely your init functions are not happening. If it works, then somewhere in the other program it's happening.

Also, when you structure your code, I would recomend you place the init function BEFORE the message loop, and the shutdown function AFTER the message loop - don't put either in the message loop under WM_DESTROY or WM_ACTIVE or whatever.


Jim



#16 jtecin   Members   -  Reputation: 122

Like
Likes
Like

Posted 24 December 1999 - 11:05 AM

I want to say thanks to all of you who replied as the problem finally got solved. I used PostQuitMessage(0) when escape is pushed and then in WM_QUIT I did Game_Shutdown and then used break. Once again, thanks.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS