Hi, I’m trying to manipulate Texture2D objects as triangles, and it seems to me that using VertexPositionTexture objects would be the solution to this. However, when I try to map a red rectangle - as a Texture2D - to a triangle, I don’t see it. My code is this:
`protected override void Draw(GameTime gameTime)
{
this.GraphicsDevice.Clear(Color.White);
if (_basicEffect.Texture == null || _basicEffect.Texture.Width != 50)
{
var rectangleColorData = new Color[50 * 50];
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 50; j++)
{
rectangleColorData[i * 50 + j] = Color.Red;
}
}
var rectangleTexture = new Texture2D(this.GraphicsDevice, 50, 50);
rectangleTexture.SetData(rectangleColorData);
_basicEffect.Texture = rectangleTexture;
}
var vertices = new VertexPositionTexture[]
{
new VertexPositionTexture(new Vector3(-1, 0, 0), new Vector2(0, 0)),
new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 50)),
new VertexPositionTexture(new Vector3(0, 0, 0), new Vector2(25F, 25)),
};
_basicEffect.World = _basicEffect.View = _basicEffect.Projection = Matrix.Identity;
_basicEffect.TextureEnabled = true;
var buffer = new VertexBuffer(this.GraphicsDevice, typeof(VertexPositionTexture), vertices.Length, BufferUsage.WriteOnly);
buffer.SetData(vertices);
this.GraphicsDevice.SetVertexBuffer(buffer);
this.GraphicsDevice.RasterizerState = RasterizerState.CullNone;
foreach (var pass in _basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
this.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 1);
}
base.Draw(gameTime);
}`
Honestly, I don’t know. As you can see, I set the World, View and Projection matrices to identity matrices, so that’s nothing special. Beyond that, I just created a rectangle as an in-memory Texture2D - I don’t read it in from the pipeline - and now I’m trying to figure out how to get it working by trial and error, because there is no detailed documentation of this VertexPositionTexture and based on what I found on the net, I couldn’t get it working.
I also tried what you suggested - switching to VertexPositionColorTexture objects - but to no avail.
I don’t see anything wrong in your code in the Draw method, unless you have other unusual setting with your _basicEffect somewhere or your emulator is not working properly.
@DexterZ You were right: I had an additional setting: _basicEffect.VertexColorEnabled = true; But I don’t understand how that was a problem? Seems like if you set VertexColorEnabled first to true, and then you later set TextureEnabled to true that messes up the GraphicsDevice? Why?
You don’t want to do this part in draw you want to move it to a method call it from say load then set the texture to basic effect and call the texture from draw.
The reason im mentioning it, is that the reference to the texture is going out of scope without being disposed each frame if you do this long enough it could potentially cause your card to throw a out of memory exception or cause a memory leak on app exit. Also the data itself is generating massive garbage each second this way. So you want to make it a once shot thing.
// make it a class scoped texture2d reference
Texture2D rectangleTexture;
public CreateTriangle(int size)
{
var rectangleColorData = new Color[size* size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
rectangleColorData[i * size+ j] = Color.Red;
}
}
// instantiate the reference object
rectangleTexture = new Texture2D(this.GraphicsDevice, size, size);
rectangleTexture.SetData(rectangleColorData);
// move this to draw
//_basicEffect.Texture = rectangleTexture;
}
As you can see in my code, I included a guard: if (_basicEffect.Texture == null || _basicEffect.Texture.Width != 50) which prevents the recreation of the texture at every single frame, specifically for this reason. (The _basicEffect is a private field, so its reference is preserved.)
Whatever I wrote here is not the entire game I’m making, just a brief snippet to demonstrate the problem, so yeah, rest assured, the end result will have a well-chiseled architecture.