Media (graphics, audio) management

Started by
10 comments, last by irbaboon 12 years, 1 month ago
Hey :)

I've always just instantiated sprites directly in the main function. Like:

int main(int argc, char **argv) {
Sprite SprPlayerWalk("Graphics/PlayerWalk.png");
Sprite SprPlayerJump("Graphics/PlayerJump.png");
Sprite SprPlayerShowingMiddleFinger("Graphics/PlayerShowingMiddleFinger.png");
while (Open()) {
...
}
return 0;
}


However, I have realised that this is... pretty dumb... Especially if you're going for a project that relies on more than 20 external files.
I've Googled for a while but I can't find ANY information about managing media...
Perhaps I'm searching for the wrong thing, that may have a huge impact on the results.

I have thought about having a class "Graphics" that stores all graphics, and "Audio" for all audio... And just make a loader class that loads everything in to their respective class. However, I'm unsure how tidy that'd really be...

So if anyone has any advice or any guides to refer me to, then I'd highly appreciate it :)

Thanks in advance. ^_^
Advertisement
There's two parts to approaching this problem -- loading and retaining the resources within the app, and specifying the resources to be loaded.

The first part is usually handled by a class which is responsible for loading and hanging onto resources. This is commonly known as a "resource manager" or, less commonly, "asset manager", although "manager" is a terrible name for anything. Anyhow, it would often ensure that only one copy of a resource is loaded, and would hand out some kind of handle to the loaded resources, maintaining a reference count and doing garbage collection. Most of the examples you'll find online are based on the singleton pattern, but that's generally a poor choice. I suggest you find one that isn't based on singleton, or re-implement a similar design sans-singleton.

The second part is basically specifying the resources to load up in some kind of external file -- for example, a file containing the map for one of your game levels would list what graphics should be loaded.

throw table_exception("(? ???)? ? ???");

So for example, if I have a player class, and then the function "Render"...

Should it look like this?

void Player :: Render(GraphicsManager &Graphics) {
Graphics.Sprite(SPR_PLAYER_STANDING).Bind();
}

How tidy is this, really?
Is this how I should use the sprites in the graphics manager?

Oh, and can anyone please link me to a guide?
I really can't find anything... I just get unrelevant results. :(
The term you're looking for is "resource management". Google for that with some additional terms like "directx" or "opengl", you should get plenty of results.
Thank you. I found a site now :)

Hey smile.png

I've always just instantiated sprites directly in the main function. Like:

int main(int argc, char **argv) {
Sprite SprPlayerWalk("Graphics/PlayerWalk.png");
Sprite SprPlayerJump("Graphics/PlayerJump.png");
Sprite SprPlayerShowingMiddleFinger("Graphics/PlayerShowingMiddleFinger.png");
while (Open()) {
...
}
return 0;
}


However, I have realised that this is... pretty dumb... Especially if you're going for a project that relies on more than 20 external files.
I've Googled for a while but I can't find ANY information about managing media...
Perhaps I'm searching for the wrong thing, that may have a huge impact on the results.

I have thought about having a class "Graphics" that stores all graphics, and "Audio" for all audio... And just make a loader class that loads everything in to their respective class. However, I'm unsure how tidy that'd really be...

So if anyone has any advice or any guides to refer me to, then I'd highly appreciate it smile.png

Thanks in advance. happy.png



Initially consider a simple file cache like I describe here. The example is for caching audio files, but it is equally applicable for graphic files, or more appropriately, template it for any kind of files. Also, I recommend against using naked pointers like I have here, I only do that so in the next chapter I can show how to get rid of them. :) That said, I haven't written that next chapter yet....


A caching is pretty simple in the end. What you do is put an object in the middle that handles getting your resource.

So you do something like ResourceLoader::GetGraphic("filename.jpg");

Then in ResourceLoader, it determines if that file has been loaded already, if not, it loads and returns it. If it's already loaded, it simple returns it. Then as time goes on you can start adding whatever complexity you need, like unloading files that haven't been requested recently or the ability to pre-load commonly loaded files, etc...


This is one area XNA did quite well, if in doubt, look at what they did and rip it off.
Just a quick note, I would shy away from naming your sprite container "Graphics" and/or your sound container "Audio".
These names are more commonly used for wrapper classes that manage device-level calls.

[quote name='Segun24' timestamp='1329874398' post='4915352']
Hey smile.png

I've always just instantiated sprites directly in the main function. Like:

int main(int argc, char **argv) {
Sprite SprPlayerWalk("Graphics/PlayerWalk.png");
Sprite SprPlayerJump("Graphics/PlayerJump.png");
Sprite SprPlayerShowingMiddleFinger("Graphics/PlayerShowingMiddleFinger.png");
while (Open()) {
...
}
return 0;
}


However, I have realised that this is... pretty dumb... Especially if you're going for a project that relies on more than 20 external files.
I've Googled for a while but I can't find ANY information about managing media...
Perhaps I'm searching for the wrong thing, that may have a huge impact on the results.

I have thought about having a class "Graphics" that stores all graphics, and "Audio" for all audio... And just make a loader class that loads everything in to their respective class. However, I'm unsure how tidy that'd really be...

So if anyone has any advice or any guides to refer me to, then I'd highly appreciate it smile.png

Thanks in advance. happy.png



Initially consider a simple file cache like I describe here. The example is for caching audio files, but it is equally applicable for graphic files, or more appropriately, template it for any kind of files. Also, I recommend against using naked pointers like I have here, I only do that so in the next chapter I can show how to get rid of them. smile.png That said, I haven't written that next chapter yet....


A caching is pretty simple in the end. What you do is put an object in the middle that handles getting your resource.

So you do something like ResourceLoader::GetGraphic("filename.jpg");

Then in ResourceLoader, it determines if that file has been loaded already, if not, it loads and returns it. If it's already loaded, it simple returns it. Then as time goes on you can start adding whatever complexity you need, like unloading files that haven't been requested recently or the ability to pre-load commonly loaded files, etc...


This is one area XNA did quite well, if in doubt, look at what they did and rip it off.
[/quote]
Thanks. I skimmed a bit over the chapter, and I'll read all chapters over, properly, soon. (It's a bit long, so I'll take my time)



I have an idea on how I can do it though, I'd love some feedback on it.
I am thinking about having a class called "GraphicsManager" in a header file, "GraphicsManager.h" ... and then instantiate it in "GraphicsManager.cpp"
I will then write some functions that can be called like:
GetSprite("mysprite.png");

So whenever I want to use the graphics manager, I can just #include "GraphicsManager.h"

Does this sound like a good design? And why not if it doesn't. Thanks,
Yeah that sounds like a good idea. I would personally create like an uber resource container something like your GraphicsManager and have it contain the particular resource containers for types of resources.

Also don't store strings as the map values to lookup on, you are better of storing hashes of the string names, FNVHash is a fast hashing algorithm you can use to create your hashes. Hashes are just faster and collisions are unlikely.

Also load only the data you are going to use into the resource container, loading data is slow and load it in a format that doesn't need a lot of data processing to be able to be useful for the GPU or whatever process is going to use it.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion


Yeah that sounds like a good idea. I would personally create like an uber resource container something like your GraphicsManager and have it contain the particular resource containers for types of resources.

Also don't store strings as the map values to lookup on, you are better of storing hashes of the string names, FNVHash is a fast hashing algorithm you can use to create your hashes. Hashes are just faster and collisions are unlikely.

Also load only the data you are going to use into the resource container, loading data is slow and load it in a format that doesn't need a lot of data processing to be able to be useful for the GPU or whatever process is going to use it.


What strings? Like the "mysprite.png" string?
I'm not sure how I'm going to do that yet. Maybe I won't even use strings.
Why is it slow though?

This topic is closed to new replies.

Advertisement