Jump to content



Media (graphics, audio) management

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

#1 Segun24   Members   -  Reputation: 108

Like
0Likes
Like

Posted 21 February 2012 - 07:33 PM

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. ^_^

Ad:

#2 Ravyne   Members   -  Reputation: 1507

Like
2Likes
Like

Posted 21 February 2012 - 09:33 PM

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.

#3 Segun24   Members   -  Reputation: 108

Like
0Likes
Like

Posted 22 February 2012 - 11:33 AM

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. :(

#4 turch   Members   -  Reputation: 147

Like
1Likes
Like

Posted 22 February 2012 - 11:43 AM

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.

#5 Segun24   Members   -  Reputation: 108

Like
0Likes
Like

Posted 22 February 2012 - 11:53 AM

Thank you. I found a site now :)

#6 Serapth   Members   -  Reputation: 858

Like
1Likes
Like

Posted 22 February 2012 - 01:09 PM

View PostSegun24, on 21 February 2012 - 07:33 PM, said:

Hey Posted Image

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 Posted Image

Thanks in advance. Posted Image


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.

#7 SeiryuEnder   Members   -  Reputation: 151

Like
0Likes
Like

Posted 22 February 2012 - 01:13 PM

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.

#8 Segun24   Members   -  Reputation: 108

Like
0Likes
Like

Posted 22 February 2012 - 01:38 PM

View PostSerapth, on 22 February 2012 - 01:09 PM, said:

View PostSegun24, on 21 February 2012 - 07:33 PM, said:

Hey Posted Image

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 Posted Image

Thanks in advance. Posted Image


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. Posted Image 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.
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,

#9 NightCreature83   Members   -  Reputation: 176

Like
-1Likes
Like

Posted 22 February 2012 - 06:29 PM

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.
FE Programmer Racing Studio: CMR:DiRT2, DiRT 3

#10 Segun24   Members   -  Reputation: 108

Like
0Likes
Like

Posted 22 February 2012 - 06:50 PM

View PostNightCreature83, on 22 February 2012 - 06:29 PM, said:

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?

#11 Serapth   Members   -  Reputation: 858

Like
0Likes
Like

Posted 22 February 2012 - 09:57 PM

View PostSegun24, on 22 February 2012 - 06:50 PM, said:

View PostNightCreature83, on 22 February 2012 - 06:29 PM, said:

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 collisKiions 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?


At this point, it doesnt matter. Premature optimization and needless complexity at your stage. Worry about details like that later, much later.

#12 Segun24   Members   -  Reputation: 108

Like
0Likes
Like

Posted 22 February 2012 - 10:01 PM

View PostSerapth, on 22 February 2012 - 09:57 PM, said:

View PostSegun24, on 22 February 2012 - 06:50 PM, said:

View PostNightCreature83, on 22 February 2012 - 06:29 PM, said:

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 collisKiions 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?


At this point, it doesnt matter. Premature optimization and needless complexity at your stage. Worry about details like that later, much later.

Yeah, you're right.






We are working on generating results for this topic
PARTNERS