Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have two issues which I wish to solve by creating 2D primitives in XNA.

  1. In my game, I wish to have a "debug mode" which will draw a red box around all hitboxes in the game (Red outline, transparent inside). This would allow us to see where the hitboxes are being drawn AND still have the sprite graphics being drawn.

  2. I wish to further understand how matrices work within computer graphics. I have a basic theoretical grasp of how they work, but I really just want to apply some of my knowledge or find a good tutorial on it. To do this, I wish to draw my own 2D primitives (With Vertex3's) and apply different transormation matrices to them.

I was trying to find a tutorial on drawing primitives using Direct3D, but most tutorials are only for c++, and just tell me to use XNA's Spritebatch. I wish to have more control over my program than just with Spritebatch.

Any Help on using Direct3D or any other suggestions would greatly be appreciated.

Thank you.

share|improve this question
    
I don't see a question nor can I tell what you are trying to accomplish. If you simply want a wire frame of all your hit boxes that is very easy but I'm not sure what your goal is. –  ClassicThunder Nov 20 '11 at 23:01
    
I'm trying to wireframe my hitboxes, yes. However, i'm trying to do that by drawing primitive shapes, which im unsure of how to do. If I can figure out how to draw primitive shapes, I can both draw my hitboxes wireframes AND start applying different kinds of matrix translations to them (to mess around with) –  MintyAnt Nov 21 '11 at 3:34
    
You are probably looking for DrawUserIndexedPrimitives in conjunction with LineList. –  Jonathan Dickinson Nov 22 '11 at 10:19

3 Answers 3

If you are dead-set on using Matrix math and wanting a wireframe hitbox, DrawUserIndexedPrimitives is probably the way to go. (As Jonathan said)

However, the whole point of a debug mode is to be quick, with little overhead, is it not? I wish to suggest an alternative that I personally use in my game:

public void CollisionRectToDraw(GameObject G, int RedValue, int GreenValue, int BlueValue)
    {
        SpriteBatch.Draw(Pixel, new Rectangle((int)G.position.X - (int)G.center.X, (int)G.position.Y - (int)G.center.Y, G.sprite.Width, G.sprite.Height),
            new Color((byte)RedValue, (byte)GreenValue, (byte)BlueValue, (byte)120));
    }

Now, this will stretch a single-pixel Texture2D (that's a white pixel) to the size of your sprite's width and height. It will be solid, however. If you want to only draw the wire-frame of it (which may take more time) you simply need to make the stretched rectangle slightly larger, and use a Rectangular Region (which would be your Sprite.Position.X, Sprite.Position.Y, Sprite.Width, Sprite.Height) to "cut out" the part that overlaps your sprite.

This method is both quick, and accurate. While not as pretty as what I'm sure you're imagining in your head, it gets the job done and could be much less expensive than actually having to drawing many LineLists.


EDIT:

This will draw four lines as Drackir suggested.

public void CollisionWireFrameToDraw(Gameobject G, int LineThickness, int RedValue, int GreenValue, int BlueValue)
    {
        Rectangle ObjectRect = new Rectangle((int)G.position.X - (int)G.center.X, (int)G.position.Y - (int)G.center.Y, G.sprite.Width, G.sprite.Height);

        game.SpriteBatch.Draw(Pixel, new Rectangle(ObjectRect.Left - LineThickness, ObjectRect.Y,LineThickness,ObjectRect.Height),
            new Color((byte)RedValue, (byte)GreenValue, (byte)BlueValue, (byte)255));//This is the line on the Left

        game.SpriteBatch.Draw(Pixel, new Rectangle(ObjectRect.Right, ObjectRect.Y, LineThickness, ObjectRect.Height),
            new Color((byte)RedValue, (byte)GreenValue, (byte)BlueValue, (byte)255)); //This is the line on the Right

        game.SpriteBatch.Draw(Pixel, new Rectangle(ObjectRect.X, ObjectRect.Top - LineThickness, ObjectRect.Width, LineThickness),
            new Color((byte)RedValue, (byte)GreenValue, (byte)BlueValue, (byte)255)); //This is the line on the Top

        game.SpriteBatch.Draw(Pixel, new Rectangle(ObjectRect.X, ObjectRect.Bottom, ObjectRect.Width, LineThickness),
            new Color((byte)RedValue, (byte)GreenValue, (byte)BlueValue, (byte)255)); //This is the line on the Bottom

    }

This draws a line on each of the four sides (left, right, top, bottom). You can change the thickness of the line by passing in a larger (or smaller) LineThickness.

The important thing to note here is that on the Left and Top line, you have to subtract the LineThickness from it's position. (X for Left, Y for Top).

But why?

Because if you don't, the line will "creep" on top of your source sprite. By subtracting your LineThickness, you move the line back out (by offsetting it, so the width of the line doesn't widen onto the sprite.

One thing to note here is that you will have a gap in the four corners where the lines don't meet up. You simply have to choose two lines (Left and Right, or Top and Bottom) and add an offset to them to make it a complete Wire Frame. If you need help with that, I can update my code - but I thought it would be fun for you to solve.

share|improve this answer
1  
You could also draw four lines using the same technique. –  Richard Marskell - Drackir Nov 28 '11 at 17:14
    
@Drackir Updated my answer, thanks for the suggestion! I hadn't thought of using it like that. –  electroflame Nov 28 '11 at 21:03
    
Cool. Thanks for updating. :) –  Richard Marskell - Drackir Nov 28 '11 at 21:13
    
You claim that SpriteBatch is going to be less overhead than drawing user indexed lines. This is ridiculous. Drawing a colored line doesn't do any alpha blending or color interpolation, using SpriteBatch obviously does. Also, SpriteBatch is drawing textured quads. This is texture interpolation, AND it's occurring even for pixels that never get drawn. Using a simple primitive drawer has MUCH less overhead. –  Christopher Harris Nov 28 '11 at 22:31
    
Also, since when is drawing 4 textured quads (16 vertices and 24 indicies) faster than drawing 4 line segments (4 vertices and 8 indicies) ? –  Christopher Harris Nov 28 '11 at 22:33

Debug Drawing

My suggestion is to create a simple "DebugDraw" class with a few methods for drawing lines, circles, and convex polygons. You can have two flavors of these methods: One for drawing outlines and the other for drawing solids.

The solid shapes would be stored in one set of vertex and index lists, and the outline shapes would be stored in the second.

All shapes should be converted to either line segments or triangles (depending on outline vs solid), and stored in the appropriate vertex or index list. When the lists get to their maximum size, automatically draw them using the BasicEffect with vertex coloring turned on.

I would use VertexPositionColor for the vertices, and I would allow the color of each shape to be specified when drawing ("myDebugDraw.DrawCircle(24, 128, 255, 0);" - where 24 is the number of sides).

I'll try to post an actual class later.

Matricies

I don't have any matrix resources, other than my math books. :)

I will say this though... Unless your doing something complex with matricies that no-one has thought of yet, as a game designer, you should probably just look at matrices as "black boxes"... It doesn't matter how they work, it just matters that you know when you transform a certain vector by a certain matrix, you get a certain result. Take a world space vector, multiply it by a view and projection matrix, and magically it's turned into a screen space vector. What more do you need to know?

share|improve this answer

If you are still looking for a simple way to draw shapes check this out:

http://drippingflames.com/xna/

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.