Game Development Community

Cleanup of Custom SceneObject/RenderDelegate

by Edward Rotberg · in Torque 3D Professional · 12/17/2009 (2:21 pm) · 5 replies

So I've created my custom SceneObject/RenderDelegate. In this code I am going around Torque in a big way: I'm loading my own shader code, loading custom assets, creating vertex buffers, index buffers, textures, etc., all in Direct3D( directly (as this is strictly a PC project for the time being).

Everything works splendidly. I can create my object in the World Editor, change some custom parameters that the object exposes, move it around, rotate, etc. The problems come in when I: A) try to go from the game to the World Editor or vise versa, or B) try to quit either one, I end up crashing.

So the problem is definitely a cleanup issue. I thought that de-allocating my memory allocations in the OnRemove() function was the way to go, but when I try problem A) above, I crash in my render code when it tries to call pEffect->Begin(). I believe this is due to a swap chain reset, but I don't know how to tell that this is going on, or even why my rendering code is still being called at this time.

While I'm asking this question,let me add one more. When the game is loaded there are apparently two copies of my object being created, one of which is in the client, and another is in the server (the ghost object?). Can I set this as a non-ghostable object? What are the ramifications of this? Anything else I can do to minimize the load-time effect of loading this twice?

Thanks in advance,

= Ed =

#1
12/17/2009 (4:14 pm)
The server object is the "real" object which then gets ghosted to the client. So the client-side object is the ghost. The rendering code only gets executed on the client, so in the Torque paradigm, if you want something to render onscreen, it's gotta exist client-side. You could probably do some sneaky things in the engine code to create and register a SceneObject-derived object only on the client, but you won't be able to do that through the World Editor or through script. And I don't know what kind of ramifications that would have, since you're kinda breaking the client-server model.

Having two copies of the object shouldn't be a big deal, though. If you do it right, your custom assets need only be loaded client-side, all vextex buffers, etc. are only created client-side, and the resource manager only loads your textures once. So the server object basically becomes an empty, place-holder type object that defines your object's position and attributes and communicates these to the client when they change. Your client object is the real work horse that holds all the data and is doing all the rendering related stuff.
#2
12/17/2009 (4:29 pm)
Ryan,

Thanks for the speedy reply! So I need to check in my custom code to see if I'm client-side or server-side, and for the server, don't do any actual graphics initialization, correct? How do I tell if this is for client-side or for server-side in the OnAdd() call, which I presume is where I would need to check for this (as well as in the OnRemove, but I can deal with that).

Thanks again,

= Ed =
#3
12/17/2009 (4:58 pm)
No problem! :) Since you're following the RenderObjectExample, you've probably got everything in the right place... creating your vextex buffers, etc. in createGeometry (this is client-side) and setting up the render state and render delegate in prepRenderImage (this is client-side). In your onAdd() method, simply put:

if(isClientObject())
{
  // your custom asset loading here
  ...
}

OnAdd() gets called both server- and client-side, so this ensures your data loading only happens client-side.
#4
12/18/2009 (7:22 pm)
OK, so thanks to Ryan, I've been able to streamline what gets initialized server-side when the game loads. I still have no idea what all I need to clean up and when it needs to be cleaned up to resolve my problems A & B in my initial post.

Anyone?

= Ed =
#5
12/19/2009 (2:01 am)
Hi Ed.

Quote:I believe this is due to a swap chain reset, but I don't know how to tell that this is going on, or even why my rendering code is still being called at this time.

That sounds likely. We do reset the device when switching in and out of the editors.

Look at GFXTextureManager::addEventDelegate/removeEventDelegate. These will let you register a function which will give you an event when the device is resetting and textures/resources should be released and reloaded.

You can find quite a few examples of how it works in the code base.