Which one of the two would be better to read images

Started by
10 comments, last by L. Spiro 9 years, 6 months ago

1) Read a sprite sheet and draw the appropriate section of the sprite sheet given arguments "coordinate" and "dimensions"?

2) Read one image after the other and draw the image without any overhead of providing arguments.

I have been choosing method #2 for writing my games mainly because I have not figured out an algorithm of drawing a "desired section of a loaded image". Since thinking an algorithm takes time, method #2 was my exit strategy.

Is there any performance gain choosing one method or does it not matter given the performance of modern computers and consoles?

Advertisement

Method 1 is definitely preferable, as it means you load one texture and just render different parts of it, where as method 2 has to load a new texture for every frame of your animation. How you go about drawing your images with method 1 rather depends on what the graphics API you are using.

If you are using OpenGL/DirectX, you draw a quad, and pass in the UV coordinates of the frame you are trying to draw.

If you're using some kind of higher level framework like SFML, then typically they will have methods for rendering part of an texture for you based off some UV rect, simplifying the process a great deal.

-Jawshttp://uploading.com/files/eff2c24d/TGEpre.zip/

I'm using Java. So I never used method #1 in my hobby game programming life. I only use method #2 for all my games.

Are you asking permission to keep building on code that you suspect is inefficient?

Hobby projects only need to run on the target machines you want them to. If that's just your computer at home and you're happy with your code's performance then great. If you want to distribute it to other people, you can't guarantee that everyone has a modern screaming machine at home. You could just arbitrarily say that you need X for minimum specs to run your game. But then you're probably cutting out a lot of people from playing your game. And if your game is something that's on a more simple order of things... well I can tell you that I'm not upgrading my machine to play a beginning developer's platformer or tetris clone. But if that doesn't bother you then focus on areas that you want to focus on for the time being (that may sound judgmental but actually I mean that in a sincere way... code what you want to code).

However, I don't think your language choice is an excuse for the technique that you're using. You can use classes in Java so I see no reason you couldn't do method #2. Even without classes you could probably figure something out.

In any case, ideally you want to load each image file once because it takes quite a bit of time to read an image from disk and then (as I understand) to also load that image to a texture on the GPU. Doing both of these per frame of animation sounds like you're going to have some very slow animations. (unless I misunderstand the technique you're using).

In my projects I have currently have a sprite class, an animation class, and an actor class. The sprite class is where I load the image data to when the program is first initialized. The animation class is where I keep co-ordinates, widths, and frame durations. And the actor class (and other sub-classes) would be where I keep stuff like a character's position in the game world (I currently use it for items as well). The actor class also has a pointer to the sprite object that it's going to be using and its own copy of animation data in an array (one array element per animation) and one variable for what animation is being used and one for what the current frame is. I used to have a pointer to animation data that I loaded up once per sprite but I found that I sometimes wanted to manipulate that data on a per actor basis.

When it's time to do the draw for an actor, I look at the animation data for the current animation and frame for the co-ordinates and widths to use. I pass all this stuff to my paint function and the character is blt to the screen. The actual code that I have for all this is crap. It's a real mess of spaghetti and the above description isn't quite accurate. Each of those classes I've mentioned I've had in a variety of configurations and combinations and coupled together in all sorts of ways. It's taken time and experimentation to sort it out to what it is now.

I suspect that you may not have a way currently to determine co-ordinates and widths of frames for your sprites. It takes some time and work to get something going to store the data as well as to determine what the data actually is. As my code is currently, I often manually hard-code data for every animation despite having created my own tool to create files to load the same data from. It's not really fun but it's part of development.

tldr;

Just try writing a simple test project or two to test out different techniques for getting images to the screen. See what you're happy with and go from there.

Good luck.


I'm using Java. So I never used method #1 in my hobby game programming life. I only use method #2 for all my games.

The reason you haven't done it is (1) you do not know how and (2) this hasn't been important enough to you to learn how. That's it. It has nothing to do with Java.

I really doubt your code would be all that different if you had chosen C++ and some API to go along with it instead.

Is there any performance gain choosing one method...


Yes, your way is slower.

Is there any performance gain choosing one method or does it not matter given the performance of modern computers and consoles?


Well, let me state the second option correctly.

2) Read one image after the other and draw the image without any overhead of providing arguments, and instead the significantly larger overhead of swapping textures.



Preferring to avoid the “overhead” of passing arguments in preference of the overhead involved in activating and deactivating textures, sometimes incurring flushes, simply doesn’t make sense.

Yes, there is performance to be gained by using #1. The only reason ever to use #2 is if you are a complete beginner, and that would only last for 1 project.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


The reason you haven't done it is (1) you do not know how and (2) this hasn't been important enough to you to learn how.

Or 3) Java programmers are lazy, or 4) most Java programers have already conceded to the fact that there's no way around the generally poor performance of Java. :)

Are you asking permission to keep building on code that you suspect is inefficient?

Hobby projects only need to run on the target machines you want them to. If that's just your computer at home and you're happy with your code's performance then great. If you want to distribute it to other people, you can't guarantee that everyone has a modern screaming machine at home. You could just arbitrarily say that you need X for minimum specs to run your game. But then you're probably cutting out a lot of people from playing your game. And if your game is something that's on a more simple order of things... well I can tell you that I'm not upgrading my machine to play a beginning developer's platformer or tetris clone. But if that doesn't bother you then focus on areas that you want to focus on for the time being (that may sound judgmental but actually I mean that in a sincere way... code what you want to code).

However, I don't think your language choice is an excuse for the technique that you're using. You can use classes in Java so I see no reason you couldn't do method #2. Even without classes you could probably figure something out.

In any case, ideally you want to load each image file once because it takes quite a bit of time to read an image from disk and then (as I understand) to also load that image to a texture on the GPU. Doing both of these per frame of animation sounds like you're going to have some very slow animations. (unless I misunderstand the technique you're using).

In my projects I have currently have a sprite class, an animation class, and an actor class. The sprite class is where I load the image data to when the program is first initialized. The animation class is where I keep co-ordinates, widths, and frame durations. And the actor class (and other sub-classes) would be where I keep stuff like a character's position in the game world (I currently use it for items as well). The actor class also has a pointer to the sprite object that it's going to be using and its own copy of animation data in an array (one array element per animation) and one variable for what animation is being used and one for what the current frame is. I used to have a pointer to animation data that I loaded up once per sprite but I found that I sometimes wanted to manipulate that data on a per actor basis.

When it's time to do the draw for an actor, I look at the animation data for the current animation and frame for the co-ordinates and widths to use. I pass all this stuff to my paint function and the character is blt to the screen. The actual code that I have for all this is crap. It's a real mess of spaghetti and the above description isn't quite accurate. Each of those classes I've mentioned I've had in a variety of configurations and combinations and coupled together in all sorts of ways. It's taken time and experimentation to sort it out to what it is now.

I suspect that you may not have a way currently to determine co-ordinates and widths of frames for your sprites. It takes some time and work to get something going to store the data as well as to determine what the data actually is. As my code is currently, I often manually hard-code data for every animation despite having created my own tool to create files to load the same data from. It's not really fun but it's part of development.

tldr;

Just try writing a simple test project or two to test out different techniques for getting images to the screen. See what you're happy with and go from there.

Good luck.

What do you mean "from disk"? My images are in a folder in the Eclipse IDE, not in a hard drive.


Preferring to avoid the “overhead” of passing arguments in preference of the overhead involved in activating and deactivating textures, sometimes incurring flushes, simply doesn’t make sense.

Yes, there is performance to be gained by using #1. The only reason ever to use #2 is if you are a complete beginner, and that would only last for 1 project.

When you say swapping textures is that the same thing as activating and deactivating textures?

I don't think I am swapping textures when reading the images. But I am doing that when I am drawing an animation since those images read are stored in a list. I'm more like overwriting the old images because once I read the images, I write them to an array list that can contain images. So I am essentially reusing the same image object for reading images.


// load the images
for(int i = 0; i < animations.length;i++)
{
try {
image = ImageIO.read(new FileInputStream(new File(animations[i])));
 
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
animList.add(image);
 
}

So flushing is a bad thing?

Since I read and write the images into a ArrayList, am I essentially "caching" the images in the Cpu level 1 cache(since the images is data) for better access?

This topic is closed to new replies.

Advertisement