0
\$\begingroup\$

I've been starting to write some XNA / Monogame code lately, and wanted to draw a quad with a Texture2D attached to it.

After searching the internet for a while, I've come up with this render code:

public void Draw(GraphicsDevice gd)
{
    BasicEffect effect = new(gd);
    effect.Texture = this.texture;
    effect.TextureEnabled = true;

    VertexPositionTexture[] vertices = new VertexPositionTexture[4];
    vertices[0].Position = this.pointA;
    vertices[1].Position = this.pointB;
    vertices[2].Position = this.pointC;
    vertices[3].Position = this.pointD;

    foreach (EffectPass pass in effect.CurrentTechnique.Passes) {
        pass.Apply();
        gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices,
        0, 3, new[] { 0, 1, 2, 1, 2, 3 }, 0, 2);
    }
}

in a Quad class:

internal sealed class Quad
{
    Vector3 pointA;
    Vector3 pointB;
    Vector3 pointC;
    Vector3 pointD;
    Texture2D texture;
}

with this initialization code:

Quad quad = new Quad(new Vector3[] 
{ new Vector3(-0.5f, -0.5f, 1f), new Vector3(-0.5f, +0.5f, 1f),
  new Vector3(+0.5f, -0.5f, 1f), new Vector3(+0.5f, +0.5f, 1f) } //points
debugTexture);

Currently, nothing appears on the screen. I've tried drawing 1 triangle only, switching out the debugTexture, using DrawUserPrimitives instead, and none of them seem to work.

After doing some testing, I found that it did actually work. I was just clearing the screen with white, which, coincidentally, the quad I was drawing was also white.

This means that the only problem now was that the quad didn't have the texture attached.

\$\endgroup\$
2
  • \$\begingroup\$ Please post your solution as an answer and mark it as the accepted solution. \$\endgroup\$
    – user122973
    Commented Nov 5, 2022 at 1:03
  • \$\begingroup\$ Sorry, I don't use SO often. Thanks for the suggestion. \$\endgroup\$
    – Mickey
    Commented Nov 5, 2022 at 7:14

1 Answer 1

0
\$\begingroup\$

The VertexPositionTexture requires a .TextureCoordinate aswell.
(where 0f being the start, 1f being the end.)

The solution is just:

// VertexPositionTexture 
//     Vector2 position (Viewport coordinate [-1.0->1.0]),
//     Vector2 texturePosition (Texture coordinate [0.0->1.0]
VertexPositionTexture[] vertices = new VertexPositionTexture[4]
{
    new VertexPositionTexture(pointA, new Vector2(0f, 1f)),
    new VertexPositionTexture(pointB, new Vector2(0f, 0f)),
    new VertexPositionTexture(pointC, new Vector2(1f, 1f)),
    new VertexPositionTexture(pointD, new Vector2(1f, 0f)),
};

and replace the DrawUserIndexedPrimitives with

GraphicsDevice.DrawUserIndexedPrimitives(
    PrimitiveType.TriangleList, // Specify tri-based quad assembly
    vertices,                   // Your input vertices
    0,                          // Offset in vertex array (0 for no offset)
    4,                          // Length of the input vertices array
    new[] { 0, 1, 2, 1, 2, 3 }, // Indicies (a tri with index (0, 1, 2), and (1, 2, 3))
    0,                          // Offset in index array (0 for none)
    2                           // Number of tris to draw (2 for a square)
);

Note that the input vertex array is order-sensitive and you might get wrongly assembled quads if the order isn't correct.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .