Closed tlgkccampbell closed 8 years ago
Awesome that would be cool, im having few issues with mixing Surface2D and Texture2D, the texture is updated but i get weird bahaviors, here is a gif: http://i.imgur.com/3xYSn6b.gifv
As you can see it starts to flicker as soon as the texture is edited
If i fill the texture in one time, there is no problem, but as i edit it it starts to be buggy
Here is how i do:
I store colors of a texture using Surface2D
var fileName = Path.GetFileNameWithoutExtension(path);
var texture = content.Load<Texture2D>("textures/sheets/" + fileName + ".png");
var surface = Surface2D.Create(texture.Width, texture.Height);
surface = Surface2D.Create(SurfaceSource.Create(File.Open(path, FileMode.Open)));
Color[] colors = new Color[texture.Width * texture.Height];
surface.GetData(colors);
Then once i want to edit a texture i do this:
public class Chunk
{
private Texture2D m_texture;
public Vector2 Position;
private Color[] m_chunkPixels;
private bool m_dirty;
public Chunk(int offsetX, int offsetY)
{
Position = new Vector2(offsetX, offsetY);
m_texture = Texture2D.Create(TileMap.CHUNK_SIZE * TileMap.TILE_SIZE, TileMap.CHUNK_SIZE * TileMap.TILE_SIZE);
m_chunkPixels = new Color[m_texture.Width * m_texture.Height];
}
public void Draw(SpriteBatch batch)
{
batch.Draw(m_texture, new Vector2(Position.X,Position.Y), Color.White);
}
public void Update(int time, int delta)
{
if (m_dirty)
{
m_texture.SetData(m_chunkPixels);
m_dirty = false;
}
}
public void Paint(int x, int y, TextureData textureData)
{
var textureRegion = AssetManager.Instance.GetRegion(textureData);
int world_x = x * TileMap.TILE_SIZE;
int world_y = y * TileMap.TILE_SIZE;
for (int tex = 0; tex < textureRegion.Width; tex++)
{
for (int tey = 0; tey < textureRegion.Height; tey++)
{
Color colorHex = textureRegion.GetColor(tex, tey);
int width = TileMap.CHUNK_SIZE*TileMap.TILE_SIZE;
int pix_x = world_x + tex;
int pix_y = world_y + tey;
int pix_index = pix_x + pix_y * width;
m_chunkPixels[pix_index] = colorHex;
}
}
m_dirty = true;
}
}
I don't know why it does this, the code works fine with MonoGame Is it Thread Safe?
Interacting with Ultraviolet resources like surfaces and textures is not thread safe. Generally speaking, if you're on a background thread and you're going to modify an Ultraviolet resource, you should queue the operation as a work item using the QueueWorkItem()
method on UltravioletContext
.
Looking at the MonoGame source code, it looks like it does the equivalent for you automatically as part of SetData()
, which is probably where the difference lies.
Also, there's some redundancy in your surface loading code. You can load a Surface2D
directly through ContentManager
:
var surface = content.Load<Surface2D>("textures/sheets/" + fileName + ".png");
And then create the texture from it:
var texture = surface.CreateTexture();
In fact, this is what Ultraviolet does internally when you load a texture.
These topics will be covered in Sample 14 and Sample 15, which have been merged to the develop branch and will be available in 1.3.9.
Awesome thanks :p
Multiple people have expressed confusion over the lack of a
GetData()
method on theTexture2D
class. A new sample project, and perhaps additional documentation, could probably be useful for helping Ultraviolet's users find the proper alternative.