   [MDX] "100 tiles as textures on the wall..."
  Just a quick question...In a tile based game (Sprite.Draw2D) with several hundred 16x16 tiles, is it wise to store each tile as its own texture?What happens if the video memory becomes full? Will textures get stored in system memory? Whats the best way to manage texture memory?   
  Memory will be the least of your concerns (at least on decent hardware). Keeping each tile on a seperate texture is going to kill your performance. For 3D hardware to work well you must batch as many primitives into a single call as possible. To change vertex data, render states, or textures all means a new batch of primitives.Ooops. Gotta go. Sorry i can't give more details. Read some docs or wait for another post from someone for more info.   ;  It's not wise to have each tile occupy it's own texture space. SetTexture() and DrawPrimitive() are supposed to be batched.So while it's a lot easier (Avoiding math problems for texture offsets, etc) to just use seperate textures for each tile, it's an unwise thing to do.   ;  What Thevenin said; put everything in as few bitmaps as possible. It is better to draw 10 times 1000 faces as 1000 times 10 faces; to this make one big texture holding every tile (the 'tileset').When moving lock your vertex buffer and change mapping coördinates of new tiles accordingly. If you do it smartly you'll only have to update the buffer when moving so much new tiles are visible.   ;  I'm using Sprite.Draw2D almost exclusively, I don't know what a Vertex Buffer is...You guys are recommending that I use textures that contain several tile textures on and than call Sprite.Draw2D several times with the same texture each time?eg..Sprite.Draw2D(Texture1,rectsrc,rectdst,x,y);Sprite.Draw2D(Texture1,rectsrc+offset,rectdst+nextTile,x,y);instead of....Sprite.Draw2D(Texture1,rectsrc,rectdst,x,y);Sprite.Draw2D(Texture2,rectsrc,rectdst+nextTile,x,y);..?   ;  If it helps in explaining to me why its bad, here is my source code atm.using System;using System.Drawing;using System.Windows.Forms;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;public class cWindow : Form{    int x = 0;    Device MyDevice = null;    Texture MyLogo = null;    Sprite MySprite = null;    static void Main()    {   using (cWindow MyWindow = new cWindow())   {  MyWindow.InitializeComponent();  MyWindow.Show();  while (MyWindow.Created)  { MyWindow.Render(); Application.DoEvents();  }   }    }    public cWindow()    {   AdapterInformation MyAdapter = Manager.Adapters.Default;   PresentParameters MyPresentation = new PresentParameters();   MyPresentation.BackBufferFormat = MyAdapter.CurrentDisplayMode.Format;   MyPresentation.BackBufferWidth = this.Width;   MyPresentation.BackBufferHeight = this.Height;   MyPresentation.SwapEffect = SwapEffect.Flip;   MyPresentation.Windowed = true;   try   {  MyDevice = new Device(MyAdapter.Adapter,  DeviceType.Hardware,this,  CreateFlags.HardwareVertexProcessing,  MyPresentation);   }   catch (DirectXException)   {  MessageBox.Show("An error occured while configuring DirectX9.0c to 'HardwareVertextProc' and 'HardWare'");  return;   }   /* Initialize the Sprite and a Texture. */   MyLogo = TextureLoader.FromFile(MyDevice, "Pic.bmp");   MySprite = new Sprite(MyDevice);    }    public void Render()    {   MyDevice.Clear(ClearFlags.Target, Color.Blue, 0.0f, 0);   MyDevice.BeginScene();   MySprite.Begin(SpriteFlags.None);   MySprite.Draw2D(MyLogo, Rectangle.Empty, SizeF.Empty,  new PointF(0.0f+x,0.0f),Color.White);   MySprite.End();   MyDevice.EndScene();   MyDevice.Present();   x++;  }    private void InitializeComponent()    {   this.SuspendLayout();   //    // cWindow   //    this.ClientSize = new System.Drawing.Size(800, 600);   this.MinimumSize = new System.Drawing.Size(640, 480);   this.Name = "cWindow";   this.ResumeLayout(false);    }}Basically, if my understanding is correct. For every new texture used inbetween the Scene() - EndScene() lines, results in a state change, so if many tiles can be rendered on one tile set, before switching to the other, than the performance is good. However, if I bunch the tiles, but end up switching between them for each tile (eg. the tiles were not logically organized), than the performance gain is insiginicant and probably even worse?Edit: .. and by switching between them, I mean calling Draw2D with a texture reference that is not idential to the previous call.   ;  Back now [lol][edit] Sorry if I insult your intelligence or wisdom. I just want to make everything clear[/edit]Ok, a vertex buffer is just what it sounds like. A buffer that holds vertex data. Since 3D graphics are almost entirely based around vertex data it can't hurt for you to do a bit of research. Luckily for you, the Sprite interface (class, or whatever they are called in VB =) and it's 'Draw2D' call hides all the details of working with the vertex data. All the vertex data *should* be batched togther internally and automatically, and so everything will appear as though you were using a simple 2D API. Well... almost...3D hardware, and thus, APIs based around that hardware work much differently than traditional 2D. Many people new to a 3D API assume a 2D blitter operation and a 3D primitive-draw operation are effectively the same. That is, they both cause some form of data to be rendered. This is not entirely the case. There is a large ammout of overhead associated with a draw-primitive call. And calling it too often just kills you (on my Radeon 9600 I could get about 500 calls and just hold 34 FPS!).There are many effects that can be set for a single draw-primitve call. These effects are called Render States. As well, a set of vertex data and the texture to be applied to that vertex data must be supplied. As you can determine from this, any time a texture, the vertex data, or render states need to be changed a new call the draw-primitve is implied. Thus, organizing resources and performing sorting operations so that the same data is reused as often and as soon as possible is necessary to avoid extra draw calls.So finally we come to your situation. As I stated above, that class you are using *should* (check out the docs to be sure) batch the vertex data automatically, so all you have to worry about is render states and textures. Textures are always the biggest problem. So the solution here is to place as many tile images as possible onto a few textures as possible. With tiles at 16x16 you can easily fit most onto a single texture of 256x256 or 512x512. The Draw2D call should have a parameter labled 'srcRect' or something similar. This defines the location on the texture that is to be used as the source data during the "blit".One last thing, that class may even be nice enough to sort rendering based on textures as well. That is to say, if you call it three times, the first time passing texture1, the second passing texture2, and the third passing texture1 again, under certain circumstances it *may* (again, check the docs) sort the rendering sequence so that the two images using the same texture are rendered together.   ;Quote:Original post by lack o commentsthat class you are using *should* (check out the docs to be sure) batch the vertex data automatically, so all you have to worry about is render states and textures. Textures are always the biggest problem. So the solution here is to place as many tile images as possible onto a few textures as possible. With tiles at 16x16 you can easily fit most onto a single texture of 256x256 or 512x512. The Draw2D call should have a parameter labled 'srcRect' or something similar. This defines the location on the texture that is to be used as the source data during the "blit".Can I use 512x512 textures and still have it support older video cards (eg.. by using 512x512 will I be breaking compatibilty?).If I use 512x512 I will be able to hold ALL my tiles on one texture (Horray), but... the character sprites will still need to be put on a texture. The character sprites arn't all of the same proportions, it would be very handy to have them as separate textures, but it sounds like this isn't what I want todo.It sounds as though I should break up my sprites into blocks of 16x16 and store them just as I did with my tiles, except, I won't use the same surface as my tiles since I'd run out of room.Therefor, I'd be continously calling Sprite.Draw2D first with my tiles texture, and than I'd be continously calling Sprite.Draw2D afterwards with my sprite texture.This is how it should be done right?btw. you've been very helpful. [smile]-ratings++   ;  In general, 256x256 is considered Lowest Common Denominator. However, only very ancient (and crappy even for there time) cards probably require it. As well, I believe Direct3D is capable of filtering down the image in such a crap-card case (with ugly results). I wouldn't worry too much about it. The way I see it, anyone playing games on their PC is more than likely to be equipped for such.As for the sprites: That depends entirely on the situation.The major difficulty with sprites is that they often require many different images for a single entity. This goes against the nature of 3D hardware. In 3D, shape and motion (animation, in this case) is represented with vertex data and so hardware and APIs are designed around that. In 2D, shape and motion is represented by pixel data. These are pretty conflicting elements =)In my games I never see more than twenty-odd sprites onscreen at any given time. As well, they are usually very large and oddly shaped. This all makes it difficult and sometimes even counter-productive to try and perform batching on them, so I don't really bother about the sprites.If you find a way to store your sprites in texture batches, then great! Go for it! I don't think you'll need to split them into 16x16 sections. Just make sure that you make them reasonable sizes and shapes, and don't waste space. If you need more than one texture for your sprites (which is likely), try to organize these sprite-sheets so images that are likely to be found in a single scene at the same time are on the same texture.   