innominate's picture

Drawing tiles with DrawElements

currently I'm using DarwArrays to draw tiles like this:

the example is rather psuedo codey. For the example I'm just rendering a tile from the tile sheet onto two locations on the screen.

//create a texture from my tile image sheet (for the sake of this example lets say it contains 4 tile images)
 
 
//create a VBO
 
number_of_tiles = 2;
 
float[] tilesBuffer = float[16*number_of_tiles]
 
tilesBuffer [0] = //left position for the first location where the tile should appear on the screen;
tilesBuffer [1] = //top position for the first location where the tile should appear on the screen;
 
tilesBuffer [2] = 0;  //left location of the tile in the tile sheet i want to render
tilesBuffer [3] = 0;  //top location of the tile in the tile sheet i want to render
 
tilesBuffer [4] = //right position for the first location where the tile should appear on the screen;
tilesBuffer [5] = //top position for the first location where the tile should appear on the screen;
 
tilesBuffer [6] = 0.5;  //right location of the tile in the tile sheet i want to render
tilesBuffer [7] = 0;  //top location of the tile in the tile sheet i want to render
 
tilesBuffer [8] = //right position for the first location where the tile should appear on the screen;
tilesBuffer [9] = //bottom position for the first location where the tile should appear on the screen;
 
tilesBuffer [10] = 0.5;  //right location of the tile in the tile sheet i want to render
tilesBuffer [11] = 0.5;  //bottom location of the tile in the tile sheet i want to render        
 
tilesBuffer [12] = //left position for the first location where the tile should appear on the screen;
tilesBuffer [13] = //bottom position for the first location where the tile should appear on the screen;
 
tilesBuffer [14] = 0;  //left location of the tile in the tile sheet i want to render
tilesBuffer [15] = 0.5;  //bottom location of the tile in the tile sheet i want to render   
 
 
 
tilesBuffer [16] = //left position for the second location where the tile should appear on the screen;
tilesBuffer [17] = //top position for the second location where the tile should appear on the screen;
 
tilesBuffer [18] = 0;  //left location of the tile in the tile sheet i want to render
tilesBuffer [19] = 0;  //top location of the tile in the tile sheet i want to render
 
tilesBuffer [20] = //right position for the second location where the tile should appear on the screen;
tilesBuffer [21] = //top position for the second location where the tile should appear on the screen;
 
tilesBuffer [22] = 0.5;  //right location of the tile in the tile sheet i want to render
tilesBuffer [23] = 0;  //top location of the tile in the tile sheet i want to render
 
tilesBuffer [24] = //right position for the second location where the tile should appear on the screen;
tilesBuffer [25] = //bottom position for the second location where the tile should appear on the screen;
 
tilesBuffer [26] = 0.5;  //right location of the tile in the tile sheet i want to render
tilesBuffer [27] = 0.5;  //bottom location of the tile in the tile sheet i want to render        
 
tilesBuffer [28] = //left position for the second location where the tile should appear on the screen;
tilesBuffer [29] = //bottom position for the second location where the tile should appear on the screen;
 
tilesBuffer [30] = 0;  //left location of the tile in the tile sheet i want to render
tilesBuffer [31] = 0.5;  //bottom location of the tile in the tile sheet i want to render   
 
 
GL.BindTexture(TextureTarget.Texture2D, textureSheetId);
 
GL.GenBuffers(1, out bufferId);
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferId);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(tilesBuffer .Length * sizeof(float)), tilesBuffer , BufferUsageHint.StreamDraw);
 
GL.VertexPointer(2, VertexPointerType.Float, (int)(4 * sizeof(float)), (IntPtr)0);
GL.TexCoordPointer(2, TexCoordPointerType.Float, (int)(4 * sizeof(float)), (IntPtr)(2 * sizeof(float)));            
GL.DrawArrays(BeginMode.Quads, 0, number_of_tiles * 4);

This works fine. But as you can see if you look at tilesBuffer array I am repeating the same numbers a lot in my VBO (and thus wasting memory).

Particularly of waste is that I will have only a small number of tiles in my tile sheet compared to the number of locations on the screen each tile gets drawn. But the coordinates for the tile in the sheet are repeated for every location it is drawn.

I feel like it should be possible to somehow use DrawElements to solve this problem. But I cant quite figure out how. Any help would be greatly appreciated.

Thanks
-Nate