As of version 4.0, XNA Game Studio no longer supports point sprites.
“The big reason is that DirectX 10 and 11 do not support point sprites, so if we kept them in our API, we would be unable to someday move that API to future DirectX versions.
A smaller reason is that point sprites behave differently on Windows and Xbox, […] not […] consistent from one Windows GPU to another […] The final reason is that point sprites are slower than triangles on some common graphics chipsets.” – Shawn Hargreaves
This is a pretty big challenge then considering that this tutorial is all about point sprites!
First we need to remove the structure defining the point sprite vertex format which is all the code in:
private struct VertexPointSprite
Also we wont be needing the VertexDeclaration so we can remove these two lines:
pointSpriteVertexDeclaration = new VertexDeclaration(device, VertexPointSprite.VertexElements);
Now what we will do is to rewrite this using quads.
A quad is made up of two triangles that form a rectangle or square. Drawing two triangles only requires four vertices, but six index entries.
To determine the location of each of the four vertices in the quad the constructor calculates the four corners from the origin, facing, width, and height.
The Quad constructor calls SetUpVertices(), which assigns UV coordinates ranging from (0,0) to (1,1), and makes the entire texture appear on the quad.
UV coordinates are derived from texture coordinates that are mapped into values along a u-axis and a v-axis.
The way we do this is by using uv-coordinates. A uv-coordinate indicates a location in the texture image that we want to use. U is the location horizontally, and V is the location vertically.
Instead of specifying a location in pixels (i.e. “10 pixels across and 40 pixels down”), we specify our coordinate as a fraction of how far to go across the entire image. The top left corner is (0, 0) the bottom right corner is (1, 1) top right is (1, 0) and bottom left is (0, 1) simple enough.
A vertex array is declared and filled with VertexPositionTexture data, then populate the vertices with position and texture coordinates.
An array of shorts is declared, data type larger than this is not necessary for a single quad giving the luxury of not having to worry which graphics profile that is being used. The array is then filled with the indices which will tell the graphics card which order to draw the vertices. The indices are specified in clockwise order since triangles drawn in counter-clockwise order would be facing away from the camera causing them to be culled.
The VertexBuffer and IndexBuffer are initialized and the vertex and index data that has just been generated is added to these buffers. The two properties in this class allow public access to this data which is necessary when finally drawing the quad on-screen.
The code for the quad class is as follows, add this just below the lines:
We also want to use a separate effect for drawing the quad and we need a quad to draw so add these declarations at the top of your Game1 class
In the LoadContent() method we need to load the effect and initialize the quad with a width and height of 1 so add these lines:
quadEffect = Content.Load(“effects”);
quad = new Quad(device, Vector3.Zero, Vector3.Up, 1, 1);
The DrawBullets() method is very similar, we still check the bullet list isn’t empty and iterate over that list. We make sure to set the current technique, the view and projection matrices and the texture outside of the loop.
The CullMode is set to none for now as explained earlier if the quad isn’t facing the camera it will be culled away, we will solve this later.
The quad is scaled down and we apply the correct position using a translation matrix, this should be quite familiar to you by now.
Use the VertexBuffer and IndexBuffer properties on the Quad to supply the primitive data, and specify four vertices for two triangles to draw.
The CullMode is then reset to CullCounterClockwise so that the rest of our rendering code isn’t affected.
private void DrawBullets()
if (bulletList.Count > 0)
quadEffect.CurrentTechnique = quadEffect.Techniques[“Textured”];
device.RasterizerState = RasterizerState.CullNone;
for (int i = 0; i < bulletList.Count; i++)
//scale down the quad
Matrix worldMatrix = Matrix.CreateScale(0.05f, 0.05f, 0.05f) * Matrix.CreateTranslation(bulletList[i].position);
foreach (EffectPass pass in quadEffect.CurrentTechnique.Passes)
device.Indices = quad.IndexBuffer;
GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 4, 0, 2);
device.RasterizerState = RasterizerState.CullCounterClockwise;
And last but not least the code to add to the end of the draw method remove:
and replace it with:
And that’s it for Quads! Next up Alpha Blending, with some billboards thrown in for good measure.