Draw simple circle in XNA - c#

I want to draw a 2d, filled, circle. I've looked everywhere and cannot seem to find anything that will even remotely help me draw a circle. I simply want to specify a height and width and location on my canvas.
Anyone know how?
Thanks!

XNA doesn't normally have an idea of a canvas you can paint on. Instead you can either create a circle in your favorite paint program and render it as a sprite or create a series vertexes in a 3D mesh to approximate a circle and render that.

You could also check out the sample framework that Jeff Weber uses in Farseer:
http://www.codeplex.com/FarseerPhysics
The demos have a dynamic texture generator that let's him make circles and rectangles (which the samples then use as the visualization of the physics simulation). You could just re-use that :-)

Had the same problem, as others already suggested you need to draw a square or rectangle with a circle texture on it. Here follows my method to create a circle texture runtime. Not the most efficient or fancy way to do it, but it works.
Texture2D createCircleText(int radius)
{
Texture2D texture = new Texture2D(GraphicsDevice, radius, radius);
Color[] colorData = new Color[radius*radius];
float diam = radius / 2f;
float diamsq = diam * diam;
for (int x = 0; x < radius; x++)
{
for (int y = 0; y < radius; y++)
{
int index = x * radius + y;
Vector2 pos = new Vector2(x - diam, y - diam);
if (pos.LengthSquared() <= diamsq)
{
colorData[index] = Color.White;
}
else
{
colorData[index] = Color.Transparent;
}
}
}
texture.SetData(colorData);
return texture;
}

Out of the box, there's no support for this in XNA. I'm assuming you're coming from some GDI background and just want to see something moving around onscreen. In a real game though, this is seldom if ever needed.
There's some helpful info here:
http://forums.xna.com/forums/t/7414.aspx
My advice to you would be to just fire up paint or something, and create the basic shapes yourself and use the Content Pipeline.

Another option (if you want to use a more complex gradient brush or something) is to draw a quad aligned to the screen and use a pixel shader.

What I did to solve this was to paint a rectangular texture, leaving the area of the rectangle which doesn't contain the circle transparent. You check to see if a point in the array is contained within a circle originating from the center of the rectangle.
Using the color data array is a bit weird because its not a 2D array. My solution was to bring in some 2D array logic into the scenario.
public Texture2D GetColoredCircle(float radius, Color desiredColor)
{
radius = radius / 2;
int width = (int)radius * 2;
int height = width;
Vector2 center = new Vector2(radius, radius);
Circle circle = new Circle(center, radius,false);
Color[] dataColors = new Color[width * height];
int row = -1; //increased on first iteration to zero!
int column = 0;
for (int i = 0; i < dataColors.Length; i++)
{
column++;
if(i % width == 0) //if we reach the right side of the rectangle go to the next row as if we were using a 2D array.
{
row++;
column = 0;
}
Vector2 point = new Vector2(row, column); //basically the next pixel.
if(circle.ContainsPoint(point))
{
dataColors[i] = desiredColor; //point lies within the radius. Paint it.
}
else
{
dataColors[i] = Color.Transparent; //point lies outside, leave it transparent.
}
}
Texture2D texture = new Texture2D(GraphicsDevice, width, height);
texture.SetData(0, new Rectangle(0, 0, width, height), dataColors, 0, width * height);
return texture;
}
And here's the method to check whether or not a point is contained within your circle:
public bool ContainsPoint(Vector2 point)
{
return ((point - this.Center).Length() <= this.Radius);
}
Hope this helps!

public Texture2D createCircleText(int radius, GraphicsDevice Devise,Color color,int tickenes)
{
Texture2D texture = new Texture2D(Devise, radius, radius);
Color[] colorData = new Color[radius * radius];
if (tickenes >= radius) tickenes = radius - 5;
float diam = radius / 2f;
float diamsq = diam * diam;
float intdiam = (radius-tickenes) / 2f;
float intdiamsq = intdiam * intdiam;
for (int x = 0; x < radius; x++)
{
for (int y = 0; y < radius; y++)
{
int index = x * radius + y;
Vector2 pos = new Vector2(x - diam, y - diam);
if (pos.LengthSquared() <= diamsq)
{
colorData[index] = color;
}
else
{
colorData[index] = Color.Transparent;
}
if (pos.LengthSquared() <= intdiamsq)
{
colorData[index] = Color.Transparent;
}
}
}
texture.SetData(colorData);
return texture;
}

Related

Split Audio Waveform sprite that it width is out of range in a Scroll Rect

I'm new to Unity 3D and trying to split a texture2D sprite that contains an audio waveform in a Scroll Rect. The waveform comes from an audio source imported by the user and added to a scroll rect horizontally like a timeline. The script that creates the waveform works but the variable of the width (that came from another script, but this is not the problem) exceeds the limits of a Texture2D, only if I put manually a width less than 16000 the waveform appear but not to the maximum of the scroll rect. Usually, a song with 3-4min has a width of 55000-60000 width, and this can't be rendered. I need to split that waveform texture2D sprite horizontally into multiple parts (or Childs) together and render them only when appearing on the screen. How can I do that? Thank you in advance.
This creates the Waveform Sprite, and should split the sprite into multiple sprites and put together horizontally, render them only when appear on the screen):
public void LoadWaveform(AudioClip clip)
{
Texture2D texwav = waveformSprite.GetWaveform(clip);
Rect rect = new Rect(Vector2.zero, new Vector2(Realwidth, 180));
waveformImage.sprite = Sprite.Create(texwav, rect, Vector2.zero);
waveformImage.SetNativeSize();
}
This creates the waveform from an audio clip (getting from the internet and modifying for my project) :
public class WaveformSprite : MonoBehaviour
{
private int width = 16000; //This should be the variable from another script
private int height = 180;
public Color background = Color.black;
public Color foreground = Color.yellow;
private int samplesize;
private float[] samples = null;
private float[] waveform = null;
private float arrowoffsetx;
public Texture2D GetWaveform(AudioClip clip)
{
int halfheight = height / 2;
float heightscale = (float)height * 0.75f;
// get the sound data
Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
waveform = new float[width];
Debug.Log("NUMERO DE SAMPLES: " + clip.samples);
var clipSamples = clip.samples;
samplesize = clipSamples * clip.channels;
samples = new float[samplesize];
clip.GetData(samples, 0);
int packsize = (samplesize / width);
for (int w = 0; w < width; w++)
{
waveform[w] = Mathf.Abs(samples[w * packsize]);
}
// map the sound data to texture
// 1 - clear
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
tex.SetPixel(x, y, background);
}
}
// 2 - plot
for (int x = 0; x < width; x++)
{
for (int y = 0; y < waveform[x] * heightscale; y++)
{
tex.SetPixel(x, halfheight + y, foreground);
tex.SetPixel(x, halfheight - y, foreground);
}
}
tex.Apply();
return tex;
}
}
Instead of reading all the samples in one loop to populate waveform[], read only the amount needed for the current texture (utilizing an offset to track position in the array).
Calculate the number of textures your function will output.
var textureCount = Mathf.CeilToInt(totalWidth / maxTextureWidth); // max texture width 16,000
Create an outer loop to generate each texture.
for (int i = 0; i < textureCount; i++)
Calculate the current textures width (used for the waveform array and drawing loops).
var textureWidth = Mathf.CeilToInt(Mathf.Min(totalWidth - (maxTextureWidth * i), maxWidth));
Utilize an offset for populating the waveform array.
for (int w = 0; w < textureWidth; w++)
{
waveform[w] = Mathf.Abs(samples[(w + offset) * packSize]);
}
With offset increasing at the end of the textures loop by the number of samples used for that texture (ie texture width).
offset += textureWidth;
In the end the function will return an array of Texture2d instead of one.

XNA Isometric tile collision

Im a C#/XNA student and I've recently been working on an isometric tile engine and so far it works fairly well. But im having problem trying to figure out on how to do collision, this is what my tile engine does at the moment:
Draws the world from an image and place a tile depending on what color is on my image. For instance color red would draw a grass tile. (Tiles are 64x32)
Camera following player, and my draw loop only draws what the camera sees.
This is how my game looks if that would be of any help:
I don't know what sort of collision would work best. Should i do collision points, or intersects or any other sort of collision. I've read somewhere that you could do Worldtoscreen/Screentoworld but im far to inexperienced and don't know how that works nor how the code would look like.
Here is my code drawing tiles etc:
class MapRow
{
public List<MapCell> Columns = new List<MapCell>();
}
class TileMap
{
public List<MapRow> Rows = new List<MapRow>();
public static Texture2D image;
Texture2D tileset;
TileInfo[,] tileMap;
Color[] pixelColor;
public TileMap(string TextureImage, string Tileset)
{
tileset = Game1.Instance.Content.Load<Texture2D>(Tileset);
image = Game1.Instance.Content.Load<Texture2D>(TextureImage);
pixelColor = new Color[image.Width * image.Height]; // pixelColor array that is holding all pixel in the image
image.GetData<Color>(pixelColor); // Save all the pixels in image to the array pixelColor
tileMap = new TileInfo[image.Height, image.Width];
int counter = 0;
for (int y = 0; y < image.Height; y++)
{
MapRow thisRow = new MapRow();
for (int x = 0; x < image.Width; x++)
{
tileMap[y, x] = new TileInfo();
if (pixelColor[counter] == new Color(0, 166, 81))
{
tileMap[y, x].cellValue = 1;//grass
}
if (pixelColor[counter] == new Color(0, 74, 128))
{
tileMap[y, x].cellValue = 2;//water
}
if (pixelColor[counter] == new Color(255, 255, 0))
{
tileMap[y, x].cellValue = 3;//Sand
}
tileMap[y, x].LoadInfoFromCellValue();//determine what tile it should draw depending on cellvalue
thisRow.Columns.Add(new MapCell(tileMap[y, x]));
counter++;
}
Rows.Add(thisRow);
}
}
public static int printx;
public static int printy;
public static int squaresAcross = Settings.screen.X / Tile.TileWidth;
public static int squaresDown = Settings.screen.Y / Tile.TileHeight;
int baseOffsetX = -32;
int baseOffsetY = -64;
public void draw(SpriteBatch spriteBatch)
{
printx = (int)Camera.Location.X / Tile.TileWidth;
printy = (int)Camera.Location.Y / Tile.TileHeight;
squaresAcross = (int)Camera.Location.X / Tile.TileWidth + Settings.screen.X / Tile.TileWidth;
squaresDown = 2*(int)Camera.Location.Y / Tile.TileHeight + Settings.screen.Y / Tile.TileHeight + 7;
for (printy = (int)Camera.Location.Y / Tile.TileHeight; printy < squaresDown; printy++)
{
int rowOffset = 0;
if ((printy) % 2 == 1)
rowOffset = Tile.OddRowXOffset;
for (printx = (int)Camera.Location.X / Tile.TileWidth; printx < squaresAcross; printx++)
{
if (tileMap[printy, printx].Collides(MouseCursor.mousePosition))
Console.WriteLine(tileMap[printy, printx].tileRect);
foreach (TileInfo tileID in Rows[printy].Columns[printx].BaseTiles)
{
spriteBatch.Draw(
tileset,
tileMap[printy, printx].tileRect = new Rectangle(
(printx * Tile.TileStepX) + rowOffset + baseOffsetX,
(printy * Tile.TileStepY) + baseOffsetY,
Tile.TileWidth, Tile.TileHeight),
Tile.GetSourceRectangle(tileID.cellValue),
Color.White,
0.0f,
Vector2.Zero,
SpriteEffects.None,
tileID.drawDepth);
}
}
}
}
}
Why don't you just draw stuff just like in normal tile based games, and then rotate the camera with a 45degree? Of course then you'd need to make your graphics a bit odd, but would be easier to handle the tiles.
But if you prefer your way, then I'd suggest using simple math to calculate the "tile to the right", "tile to the left" , "tile to the up" and "tile to the down" ones, you know, the tiles around the player(or another tile). You can simply work with your lists, and with some math, basic math, like getting the next tile, is quite simple.
Edit:
You could get the player's next position's tile value with a code something like this:
tileMap[Math.Floor((player.y+playerVelociy.Y)/tileHeight)]
[Math.Floor((player.x+playerVelocity.X)/tileWidth)]
In this code, I assume that the first tile is at 0,0 and you're drawing to right and down. (If not, then just change the Math.Floor to Math.Ceil)
THIS link could help you get the idea, however it's in AS3.0, only the syntax is different.

XNA How to make xna not to read transparent color

I am fairly new to xna. I just created a sprite with transparent background(magenta). Problem is my Rectangle is reading the coordinates of whole sprite not of visible one. How do I make it read only the visible sprite.
myrectangle = new Rectangle(0, 0, box.Width, box.Height);
I want to place my visible part not transparent at that position. Thanks in advance.
To transform a color to transparent, go to the texture properties, content processor, and enable Color Key, and set the key Color to magenta.
Then to positioning the sprite where you want, you need to set the proper origin.
To set the ship center in the desired position, is needed to set the origin as shown:
So when you draw it, you need doing similar to this:
var origin = new Vector2(40,40);
spritebatch.Draw(shipTexture, shipPosition, null, Color, origin, ...)
You can change your texture rectangle source too:
var texSource = new Rectangle( 25,25, 30,30);
spritebatch.Draw(shipTexture, shipPosition, texSource, Color)
Although you may need to change the origin if you want to position the ship at its center
You need to manually measure the offset of the point you need using a program like Paint and then set that offset in the parameter Origin in the Draw method.
A better idea is to measure the size in pixel of your sprite (without the background) and the set it as the sourceRectangle in the Draw method.
spritebatch.Draw(textureToDraw, Position, sourceRectangle, Color.White)
SourceRectangle is nullable, its defalut value is null, and in that case XNA will draw the whole texture, and you don't need that.
Using transparent color coding like Magenta is very old-fashioned. Nowadays we use the alpha in the images to achieve this.
I guess the only real way to do what you want to do is to search through the color-data to find the smallest and the largest x and y coordinates which have alpha > 0, or != Color.Magenta in your case.
Texture2D sprite = Content.Load<Texture2D>(.....);
int width = sprite.Width;
int height = sprite.Height;
Rectangle sourceRectangle = new Rectangle(int.Max, int.Max, 0, 0);
Color[] data = new Color[width*height];
sprite.GetData<Color>(data);
int maxX = 0;
int maxY = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int index = width * y + x;
if (data[index] != Color.Magenta)
{
if (x < sourceRectangle.X)
sourceRectangle.X = x;
else if (x > maxX)
maxX = x;
if (y < sourceRectangle.Y)
sourceRectangle.Y = y;
else if (y > maxY)
maxY = y;
}
}
}
sourceRectangle.Width = maxX - sourceRectangle.X;
sourceRectangle.Height = maxY - sourceRectange.Y;
I use a cheat method in VB.Net, which I assume you could make work in C#:
Private Function MakeTexture(ByVal b As Bitmap) As Texture2D
Using MemoryStream As New MemoryStream
b.Save(MemoryStream, System.Drawing.Imaging.ImageFormat.Png)
Return Texture2D.FromStream(XNAGraphics.GraphicsDevice, MemoryStream)
End Using
End Function
As long as your bitmap is loaded with a transparent color, this works slick.

XNA how to select tiles with mouse

public void Draw(SpriteBatch spriteBatch)
{
for(int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
spriteBatch.Draw(tiles[index[x, y]], tileRect = new Rectangle(x * tileWidth, y * tileHeight, tileWidth, tileHeight),
Color.White);
}
}
}
I have a random tile engine and I am wondering how I could make the tiles have a black square texture around it and selectable by clicking on them. and how I could change that tile texture when I click on it.
Since your storing the tiles in an array, You can use something like this to do it:
MouseState ms = Mouse.GetState();
if (ms.LeftButton == ButtonState.Pressed)
{
int x = Convert.ToInt32(ms.X) /16;
int y = Convert.ToInt32(ms.Y) /16 +1;
tiles[x, y] = //Left button Clicked, Change Texture here!
}
if (ms.RightButton == ButtonState.Pressed)
{
int x = Convert.ToInt32(ms.X) / 16;
int y = Convert.ToInt32(ms.Y) / 16 + 1;
tiles[x, y] = //Right button Clicked, Change Texture here!
}
/ 16 is for the tiles size in pixels, and for some reason in my game I have to add +1 to the y value, for you it might not be the case.
For adding a Black Texture, You can either create one on the go, Or load it in LoadContent()
and then draw it like;
if (tiles[x,y].HasBlackTexture = true)
spriteBatch.Draw(blah,Color.Black)
I am wondering how I could make the tiles have a black square texture around it.
and selectable by clicking on them.
and how I could change that tile texture when I click on it.
you'd need:
a separate black square 'tile' that you draw on top when desired. Ex:
private Texture2D mBlackTile;
...
public void LoadContent()
{
...
mBlackTile = ContentManager.Load<Texture2D>("blackTile");
...
}
a reference to the selected tile (a coordinate), which would be used so you'd know where to draw the black square tile. Ex:
private Vector2 mSelectedTileCoordinate = new Vector2();
to handle the mouse click. Ex:
public void Update(GameTime pGameTime)
{
...
MouseState mouseState = Mouse.GetState();
Vector2 mousePosition = new Vector2(mouseState.X, mouseState.Y);
if (mouseState.LeftButton == ButtonState.Pressed)
DoMouseClick(mousePosition);
...
}
to convert the clicked screen coordinate to the map tile coordinate. Ex:
public void DoMouseClick(Vector2 pMouseXY)
{
...
Vector2 tileXY = ScreenToTile(pMouseXY);
...
}
private Vector2 ScreenToTile(Vector2 pScreenXY)
{
// you need to get the position of the map here
// ex: if the 'camera' is looking at (100, 100), then the map is drawn to (-100, -100)
Vector2 mapOffset = GetMapOffset();
// you may need to add or subtract depending what value you are using
// if mapOffset is the coordinate you are 'looking at', add
// if mapOffset is the coordinate that the map is being drawn to, subtract
Vector2 mapXY = pScreenXY +/- mapOffset;
// you need to get the width and height of the tiles
Vector2 tileSize = GetTileSize();
// this should now be the tile coordinate
// you may or may not want to have rounded the XY values as well
Vector2 tileXY = mapXY / tileSize;
return new Vector2((int)tileXY.X, (int)tileXY.Y);
}
to change the selected tile based on the clicked coordinate. Ex:
public void DoMouseClick(Vector2 pMouseXY)
{
...
Vector2 tileXY = ScreenToTile(pMouseXY);
mSelectedTileCoordinate = tileXY;
}
and to draw the tile in your draw code. Ex:
public void Draw(SpriteBatch spriteBatch)
{
for(int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
spriteBatch.Draw(tiles[index[x, y]], tileRect = new Rectangle(x * tileWidth, y * tileHeight, tileWidth, tileHeight),
Color.White);
}
}
// draw selection
Vector2 screenXY = TileToScreen(mSelectedTileCoordinate);
Rectangle drawArea = new Rectangle(screenXY.X, screenXY.Y, tileWidth, tileHeight);
spriteBatch.Draw(mBlackTile, drawArea, Color.White);
}
private Vector2 TileToScreen(Vector2 pTileXY)
{
// this does the reverse of ScreenToTile
Vector2 tileSize = GetTileSize();
Vector2 mapXY = pTileXY * tileSize;
Vector2 mapOffset = GetMapOffset();
// you'll have to do this the opposite way from ScreenToTile()
Vector2 screenXY = mapXY +/- mapOffset;
return screenXY;
}

XNA is pulling the wrong texture?

I am making (another) MineCraft clone, and I've run into an interesting problem. I have a public enum that lists all the cube types a particular cube can be, and I have a 3d array that holds cubes. Each cube has a specific type, and I iterate through this array to get the vertices for each cube, then pass those vertices to a vertex buffer designated for a particular cube type. When I create a random array of cubes, or a single cube, and tell it what texture it should be everything draws as expected. I'm now trying to figure out how to draw a random "surface" of grass cubes, and fill everything below those on the y-axis with dirt cubes. The strangest thing is happening though, the top most cube is dirt and it fills all the bottom ones with grass cubes! When I disable the loop to fill the underground with dirt, the top most cube is displaying grass as intended.
Here is what I believe to be the relevant parts of the code. Here is where the cube type is set:
// Create a random surface level
Perlin perlin = new Perlin();
for (int x = 0; x < Game.ChunkWidth_X; x++)
{
for (int z = 0; z < Game.ChunkDepth_Z; z++)
{
double XVal = Convert.ToDouble(x) * 1.1;
double ZVal = Convert.ToDouble(z) * 1.1;
double YVal = Game.ChunkHeight_Y / 2 * 1.1;
double PerlinValue = perlin.GetValue(XVal, YVal, ZVal);
int YVal_new = Convert.ToInt32(YVal + (PerlinValue * 10));
if (YVal_new > Game.ChunkHeight_Y - 1) { YVal_new = Game.ChunkHeight_Y - 1; }
if (YVal_new < 0) { YVal_new = 0; }
// Set the grass cube
Cube NewCube = new Cube(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(x, YVal_new, z));
NewCube.cubeType = CubeType.Grass;
CubeGrid[x, YVal_new, z] = NewCube;
// Fill below it with dirt
for (int y = YVal_new - 1; y >= 0; y--)
{
Cube NewCube2 = new Cube(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(x, y, z));
NewCube2.cubeType = CubeType.Dirt;
CubeGrid[x, y, z] = NewCube2;
}
// Fill above it with air
for (int y = YVal_new + 1; y < Game.ChunkHeight_Y; y++)
{
Cube NewCube2 = new Cube(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(x, y, z));
NewCube2.cubeType = CubeType.Air;
CubeGrid[x, y, z] = NewCube2;
}
}
}
This is where I pull the vertices to put into the appropriate buffer:
Dictionary<CubeType, List<VertexPositionNormalTexture>> DrawableVertices = new Dictionary<CubeType, List<VertexPositionNormalTexture>>();
// Get the proper vertices for each cube type and put in the appropriate dictionary
for (int x = 0; x < Game.ChunkWidth_X; x++)
{
for (int z = 0; z < Game.ChunkDepth_Z; z++)
{
for (int y = 0; y < Game.ChunkHeight_Y; y++)
{
CubeGrid[x,y,z].CreateVertices();
string test = CubeGrid[x, y, z].cubeType.ToString();
foreach (VertexPositionNormalTexture TargetVertex in CubeGrid[x, y, z].DisplayableVertices)
{
if (!DrawableVertices.ContainsKey(CubeGrid[x, y, z].cubeType))
{
List<VertexPositionNormalTexture> NewList = new List<VertexPositionNormalTexture>();
NewList.Add(TargetVertex);
DrawableVertices.Add(CubeGrid[x, y, z].cubeType, NewList);
}
else
{
DrawableVertices[CubeGrid[x, y, z].cubeType].Add(TargetVertex);
}
}
}
}
}
Here is the second part of it:
foreach (KeyValuePair<CubeType, List<VertexPositionNormalTexture>> KVP in DrawableVertices)
{
VertexBuffer cubeBuffer = new VertexBuffer(device, typeof(VertexPositionNormalTexture), KVP.Value.Count, BufferUsage.WriteOnly);
cubeBuffer.SetData(KVP.Value.ToArray());
// Update our collection of vertex buffers
CubeType_VertexBuffers[KVP.Key] = cubeBuffer;
// Get the triangle count for the buffer
CubeType_TriangleCount[KVP.Key] = KVP.Value.Count / 3;
}
Lastly, here is my draw:
// Go through each vertex buffer we have created, and draw it.
foreach (KeyValuePair<CubeType, VertexBuffer> KVP in CubeType_VertexBuffers)
{
foreach (EffectPass pass in testEffect.CurrentTechnique.Passes)
{
if (CubeType_TriangleCount[KVP.Key] > 0) // if this buffer has triangles, draw it.
{
pass.Apply();
testEffect.View = camera.ViewMatrix;
testEffect.TextureEnabled = true;
testEffect.Projection = camera.ProjectionMatrix;
testEffect.World = worldMatrix;
testEffect.Texture = CubeType_Texture[KVP.Key];
device.SetVertexBuffer(KVP.Value);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, CubeType_TriangleCount[KVP.Key]);
}
}
}
base.Draw(gameTime);
The weirdest thing is that when I manually set cube types everything draws with the proper texture as expected. What other things should I try to troubleshoot? I tried making a specific effect for each cube type to no avail.
After trying a bunch of random things in desperation, I found a fix for this. It turns out that if you use the same BasicEffect for different textures, it only uses the last texture assigned to it. I was iterating through a list of VertexBuffers and assigning a different texture for each one. By the time everything made it over to the video card, only the last texture used was rendered, or so it appears.
The solution was to create a separate BasicEffect for each texture I needed and assign only the VertexBuffers needed to the particular BasicEffect.

Categories