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'm trying to wrap my head around:

http://msdn.microsoft.com/en-us/library/bb196409.aspx

I'm trying to create a method in XNA that renders a single Triangle, then later make a method that takes a list of Triangles and renders them also. But it isn't working. I'm not understanding what all the things does and there's not enough information.

My methods:

// Triangle is a struct with A, B, C (didn't include) A, B, C = Vector3

public static void Render(GraphicsDevice device, List<Triangle> triangles, Texture2D texture)
{
    foreach (Triangle triangle in triangles)
    {
        Render(device, triangle, texture);
    }
}

public static void Render(GraphicsDevice device, Triangle triangle, Texture2D texture)
{
    BasicEffect _effect = new BasicEffect(device);
    _effect.Texture = texture;
    _effect.VertexColorEnabled = true;

    VertexPositionColor[] _vertices = new VertexPositionColor[3];

    _vertices[0].Position = triangle.A;
    _vertices[1].Position = triangle.B;
    _vertices[2].Position = triangle.B;

    foreach (var pass in _effect.CurrentTechnique.Passes)
    {
        pass.Apply();

        device.DrawUserIndexedPrimitives<VertexPositionColor>
        (
            PrimitiveType.TriangleList,
            _vertices,
            0,
            _vertices.Length,
            new int[] { 0, 1, 2 }, // example has something similiar, no idea what this is
            0,
            3 // 3 = gives me an error, 1 = works but no results
        );
    }

}

Now my method looks like this, according to your recommendations:

    public static void Render(GraphicsDevice device, Triangle triangle, Color color)
    {
        BasicEffect _effect = new BasicEffect(device);
        _effect.Texture = ColorToTexture(device, color, 1, 1);
        _effect.TextureEnabled = true;
        //_effect.VertexColorEnabled = true;

        VertexPositionTexture[] _vertices = new VertexPositionTexture[3];

        _vertices[0].Position = triangle.A;
        _vertices[1].Position = triangle.B;
        _vertices[2].Position = triangle.C;

        foreach (var pass in _effect.CurrentTechnique.Passes)
        {
            pass.Apply();

            device.DrawUserIndexedPrimitives<VertexPositionTexture>
            (
                PrimitiveType.TriangleStrip, // same result with TriangleList
                _vertices,
                0,
                _vertices.Length,
                new int[] { 0, 1, 2 },
                0,
                1
            );
        }

    }

and my method that creates a texture from color (tried this with single spriteBatch.Draw() = works)

    public static Texture2D ColorToTexture(GraphicsDevice device, Color color, int width, int height)
    {
        Texture2D texture = new Texture2D(device, 1, 1);
        texture.SetData<Color>(new Microsoft.Xna.Framework.Color[] { color });

        return texture;
    }

and in my Draw method in Main Game:

Render(GraphicsDevice, new Triangle(new Vector3(50, 50, 0), new Vector3(100, 100, 0), new Vector3(150, 50, 0)), Color.Green);

= no triangle on screen.

share|improve this question
add comment

2 Answers

up vote 0 down vote accepted

I think you should rather use VertexPositionTexture structure instead of VertexPoisitionColor to define vertex and texture coordinates. Also set: _effect.TextureEnabled to true.

And to your DrawUserIndexedPrimitives call:

  • fifth parameter is indeces to the array of vertices. So you render triangle defined by vertices _vertices[0], _vertices[1], _vertices[2].
  • Last parameter is number of primitives to render - you have only one triangle with 3 vertices. So you should really pass 1.

As r2d2rigo wrote: your two vertices are the same point:

_vertices[1].Position = triangle.B;
_vertices[2].Position = triangle.B;

UPDATE:

Vertex coordinates have to be in range <-1;1>. 0,0 is center point of the screen (window).

share|improve this answer
    
Still nothing. I pass this to the method: Render(GraphicsDevice, new Triangle(new Vector3(50, 50, 0), new Vector3(100, 100, 0), new Vector3(150, 50, 0)), Color.Green); If I pass Color.Green instead of texture, it creates a texture (1x1 texture) of a single color. This way: Texture2D texture = new Texture2D(device, 1, 1); texture.SetData<Color>(new Microsoft.Xna.Framework.Color[] { color }); Still nothing. I haven't set the camera to be anything but default, so shouldn't there be something? It shows nothing. –  Deukalion Jun 24 '12 at 15:23
    
Yes. You should set View, World and Projection matrices of BasicEffect. World matrix can be just eye matrix. View matrix can be created using method Matrix.CreateLookAt(From, To, Up) - look from 0,0,0 to your triangle with up vector equal to Vector3.Up. Projection can be created as: Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GameObject.GraphicsDevice.Viewport.AspectRatio, 1, 1000); –  zacharmarz Jun 24 '12 at 16:17
    
Ok. I've tried this, but I don't get it to work anyhow. I don't want 3D view at all, I just wanted to draw triangles first. So my Matrixes looks like this: _effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1, 1000); _effect.View = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 0)); _effect.World = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 0)); Are there anything I need to set in spriteBatch or do I even use that? –  Deukalion Jun 25 '12 at 6:08
    
Ok. So if you want only 2D, then those matrices are really needless :) But in that case, your triangle coordinates should be in range <-1;1>, which is screen coordinates. See this example: riemers.net/eng/Tutorials/XNA/Csharp/Series1/… –  zacharmarz Jun 25 '12 at 6:29
    
I'm going to need those when I move the camera, but that's a different issue I'm more familiar with. Don't I need BasicEffect (or can't I use it?) for 2D graphics too? –  Deukalion Jun 25 '12 at 9:00
show 6 more comments

The code you pasted should be drawing a line because you are assigning _vertices[1] and _vertices[2] the same triangle vertex. Fix it and change the last paramenter in DrawUserIndexedPrimitives to 1, since it's the number of primitives (in your case, triangles) that you are going to draw with that call.

share|improve this answer
add comment

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.