Loading resources when they are required, good or bad idea?

Started by
11 comments, last by cyric74 18 years, 9 months ago
Hi, I'm making a Render class, that I can use between projects without having to change it much. Anyway, when other classes call the Render class's addVertices(Vertex* vertices, int verticesCount, string texture) function, the Render class would check if the texture mentioned had been loaded into memory or not, and load it as the program ran, eg you are in the game and a new object appears, the Render class would have loaded those new textures into memory if they weren't loaded already. Is this a terrible idea or an ok one?, the projects that I'd been using this for would probably be small to medium in size, nothing that would require utter most speed. I'm using c++ and directx btw. Thanks
Advertisement
I boils down to whether or not it is ok for there to be a short pause everytime a new texture is rendered.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
hmm does anyone have any ideas on how to load the resources that are used in the app, without having the specify them at start up? so its kinda automatic
i have to do this with models at work. basically i place the models into sections, and load them the first time they are needed. afterwards they stay resident. this is handy for dealing with huge amounts of data and can localize your load times (which may not be the case in your app). i would say in general games typically have a listing of what is possible to load placed into sections like i use and laod these (usually in between levels).

an alternative is the way prodctivity apps load commonly used but large resources, everything at once at startup. the theory here is that users are more tolerant of load times at application startup than lag in the middle (where they may think the app is failing).
As your leader, I encourage you from time to time, and always in a respectful manner, to question my logic. If you're unconvinced that a particular plan of action I've decided is the wisest, tell me so, but allow me to convince you and I promise you right here and now, no subject will ever be taboo. Except, of course, the subject that was just under discussion. The price you pay for bringing up either my Chinese or American heritage as a negative is - I collect your f***ing head.
you would have to specify what needs to be loaded. you could store the needed textures/data locations in a text file, with some different extension, and load that file at runtime, and load the textures, so maybe all you have to do is change the .resources file or something.

the way that i do it is load all of the textures at the beginning, and use them directly in my game state init() function. if they need to be accessed at run time, then it goes through my resource manager

RESOURCE = manager->getResource_TYPE( char* resourcePlace );

and this method will load the resource if its not already done, and return it, or return it if its already been loaded. you can load it at run time as needed, called "lazy initialization" (which is done for DB connections and stuff". if your system isnt a piece of crap, there should be no noticable slow down, but i still dont recommend it.

it may make your code "messier" to load everything at the beginning, but it runs faster, and thats the important part, right?
---------Coming soon! Microcosm II.
The first release of HL2 did this.

It caused massive stuttering for people without fast hard drives and plenty of RAM. People were very angry.

If you can begin loading the texture a short while BEFORE it's needed, then you're probably ok. But you can't very well load it in the same frame you've got to render it. The stutter will be obvious for any significantly sized texture.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Really, any size, like say 256x256 bmp?

I'll just pre load everything, as my apps won't be using a huge amount of texures, I was just trying to make creating programs much faster, but I guess I can't really do that without annoying the user.

Thanks alot.


The best way to accoomplish this is to have a dedicated thread that handles data fetching to and from the disk. This thread would then be responsible for loading any data requested by the main thread. Like the previous poseter said, you cant request data from disk in the same frame you need to draw it in. Instead, you need to have some mechanism by which you can prefetch data that will most likely be visible soon. This would most likely depend on player/camera position, orientation, and speed.

The real challenge is in creating a system the allows for resources to be managed and syncronized between the IO thread and main thread. In my system, the IO thread simply fills up buffers which I feed into the objects to fill their data and initialize them. This allows me to avoid most threading syncronization issues on the object level. All objects have a Unique ID which serves as both an identifier and object handle. Data is requested using these IDs. The buffers that are filled are associated with their destination objects through these IDs as well. I have a function which i call each frame to fill objects (up to a number specified) and then execute a callback in order to finish any last initialization or other operations.

Object lifetimes are handled through reference counting, but can optionally use a sort of Least-Recently-Used cache mechanism for added efficiency. Disk IO is absurdly slow compared to memory IO, so the goal is to avoid it as much as possible.

So far, this has worked pretty well for me. My goal is to use this system to enable a SUPER vast / continuous game world.
It's a good idea. As for loading resources, you can just load from an arbitrary file with D3DXCreateTextureFromFile. Though how you determine the filename rather varies.

Personally, I have a resource manager that does as you [and others] have described. Load the texture when necissary, use reference counting to unload it when no images are left using it. For large, or frequently used textures, I'll often pre-load the texture before it's actually needed to eliminate some of the load delay.

For example, I will load the splash screen at startup, rather than after a bunch of initialization. The first menu is loaded during the 'start splash screen fade in' code. There's still spots where it's a little slow to load, but it's good enough. Even that slowness could be mitigated by the above described threaded file loader. A little slowness is far better than the unresponsiveness of running out of memory anyways.
From the presentation Stephen White gave about Jak & Daxter at GDC 03:
Quote:
Spooling Level Data
Used two 10M data level buffers.
A single game level was composed of one or more data “levels”.
We used careful planning and layout to insure that no more than two data “levels” were visible at any one time:
The level the player was currently in.
The level the player was heading towards.
As the player approached a new level, it was loaded into the other level buffer.

Spooling Level Data (cont)
If the player changed his mind and headed towards a different level, then the level that was being loaded was abandoned, and a new level load was started.
Used “load boundaries” to determine when to start loading or when to display a new data level.
Used low resolution models to represent portions of other levels seen in the distance.

The Spooled Level Data
The level data contained:
Background (geometry, collision, textures, visibility, etc).
Foreground (geometry, collision, textures, animations, etc).
Sound.
Level specific code.


If Jak ran too fast and a level wasn't done loading in time, they would have him trip over himself to buy a second to finish loading the data (that was off a DVD, not a HD!) But it meant they could always assume that all necessary data was always loaded... a huge benefit over dynamic prefetching models.

If you do need to render something that doesn't have a resource loaded, make sure that once the resource is in, you fade the object in over a second or so instead of popping it in suddenly. Popping is terrible

This topic is closed to new replies.

Advertisement