Accessing the dd surface directly in xna?

Started by
2 comments, last by Koder4Fun 11 years, 8 months ago
In an attempt to learn xna, I'm currently trying to convert an old directdraw game that I wrote in c to xna (c#). The game is a 2d top down multi-directional scrolling game. It renders all the game tiles in memory (to a very large memory surface) and then blits a section to the backbuffer line by line using a memcpy function (with y value look-up table) . The result is a very fast and very smooth scrolling mechanism.

What I'm trying to get my head around with xna is how to keep the rendering mechanism of my game in tact. I could be wrong, but I would rather not iterate through a nested loop to render each tile as the screen scrolls. I've looked at several xna tile engines that use that sort of algorithm and I can't help but think it's not optimal. I would much rather pre-render the entire map in memory and then blit the window to the screen as it scrolls around.

Is there a way to create a large surface in memory (several screens wide) and then simply execute some sort of copy rectangle function?

I considered creating a memory surface using several max sized Texture2d objects and then creating a memcpy like blit routine, but I'm not sure if that's the correct way to maximize the performance of a 2d scroller in xna.
Advertisement

I could be wrong, but I would rather not iterate through a nested loop to render each tile as the screen scrolls. I've looked at several xna tile engines that use that sort of algorithm and I can't help but think it's not optimal. I would much rather pre-render the entire map in memory and then blit the window to the screen as it scrolls around.


Unless there are other considerations I don't know of, I can guarantee that such an approach will be fast enough (as long as you are not iterating far beyond the extents of the screen). I can also almost guarantee this approach will be far easier to implement than what you are describing as an alternative. I am also 80% sure that just iterating through and drawing all the tiles will actually be quicker than creating some sort of memcpy routine.

In short, SpriteBatch can throw many, many, many sprites onto the screen without a hiccup, unless you are doing something incorrect. If you haven't already, try out a quick prototype, you may be suprised.

If for some reason you do want to pre-render the entire map, just use a rendertarget to do so (you will need to stay within the limits of the graphics card constraints for texture size, however).

If you really, really want to implement a way to transfer data to a texture (not recommended!), then look at Texture2D.SetData and GetData methods.

[quote name='00Kevin' timestamp='1343759525' post='4964940']
I could be wrong, but I would rather not iterate through a nested loop to render each tile as the screen scrolls. I've looked at several xna tile engines that use that sort of algorithm and I can't help but think it's not optimal. I would much rather pre-render the entire map in memory and then blit the window to the screen as it scrolls around.


Unless there are other considerations I don't know of, I can guarantee that such an approach will be fast enough (as long as you are not iterating far beyond the extents of the screen). I can also almost guarantee this approach will be far easier to implement than what you are describing as an alternative. I am also 80% sure that just iterating through and drawing all the tiles will actually be quicker than creating some sort of memcpy routine.

In short, SpriteBatch can throw many, many, many sprites onto the screen without a hiccup, unless you are doing something incorrect. If you haven't already, try out a quick prototype, you may be suprised.

If for some reason you do want to pre-render the entire map, just use a rendertarget to do so (you will need to stay within the limits of the graphics card constraints for texture size, however).

If you really, really want to implement a way to transfer data to a texture (not recommended!), then look at Texture2D.SetData and GetData methods.
[/quote]

ok thanks a lot I suspected that I might be a bit too concerned, but I just wanted to make sure.
I know that changing code may be a risk to insert bugs, but on that case see this as an opportunity to start learn about 2D XNA rendering.

A method far simpler is to pack all the tiles you need in a paint program to create a theme, and use them to render the level.
The rendering of the tiles can be done with calls to SpriteBatch methods. This way you can achieve a maximum of 60 fps.

To increase performace you can skip all tiles completely outside current viewing position.
Also you can unlock XNA from vsync to check real performace adding IsFixedTimeStep = false; to the game object constructor.

Here http://msdn.microsof...y/bb194908.aspx you find all you need to load a texture (your packed tiles) and draw a sprite (in your case a tile).

Also you can use the same class to draw the ship, projectiles, etc.

At last notes:

Keep in mind that accessing resources at low level must be done only if no other ways are found. And that C# is a managed language and it's a little slower than C/C++.

To move blocks of data on .NET 4 you can use Buffer object http://msdn.microsoft.com/en-us/library/System.Buffer(v=vs.100).aspx .
Please vote usefull replies.
Marco Sacchi
Coding is a challenge ... but solving problems is the fun part
My Blog - XNA Italian portal

This topic is closed to new replies.

Advertisement