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\$ Commented Nov 5, 2022 at 1:03
  • \$\begingroup\$ Sorry, I don't use SO often. Thanks for the suggestion. \$\endgroup\$ 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.