Mayor901

Hello all.

I'm poking around the official Monogame runtime just to get a feel for how everything works before implementing it into my game. However, when loading Spineboy's skeleton file at 0.8 scale, I notice black outlines around the eye and mouth textures, like so.



When setting PreMultipliedAlpha to true, the effect is even worse with thicker white outlines. How can I fix this so that the textures overlap properly?

---

So I actually managed to fix this by adding optional boolean parameters to the Atlas and XNATextureLoader classes so I can choose to load the atlas png texture from the Content Pipeline, rather than directly from the data folder, as well as adding a method to the TextureLoader interface and XNATextureLoader to load from the pipeline, and then setting skeletonRenderer.PremultipliedAlpha to true. Now the images are rendered properly without the seams. I can show the full code changes if anyone is interested.
Mayor901
  • Bài viết: 3

Harald

Thanks for reporting! We could also reproduce this behaviour.
Mayor901 đã viết:I can show the full code changes if anyone is interested.
If you don't mind the effort, we would be happy if you could share your changes with us and other users.
Hình đại diện của thành viên
Harald

Harri
  • Bài viết: 1951

Mayor901

No problem. Excuse it if it's a bit lengthy/messy.

So first off, I added a boolean field to the Atlas class.
bool loadFromContent = false;
Then I set it in the main Atlas constructor by adding a "fromContent" parameter, so it becomes
public Atlas (string path, TextureLoader textureLoader, bool fromContent = false) {
if (fromContent)
{
loadFromContent = true;
}
...
I added the below method signature to the TextureLoader interface.
void LoadFromContentPipeline(AtlasPage page, string imgName);
In the XnaTextureLoader class, I added the Microsoft.Xna.Framework.Content namespace and a contentManager field.
using Microsoft.Xna.Framework.Content;
public class XnaTextureLoader : TextureLoader {
GraphicsDevice device;
string[] textureLayerSuffixes = null;
ContentManager contentManager = null;
...
In the XnaTextureLoader constructor, I added an optional parameter to pass in a content manager, so it becomes
public XnaTextureLoader (GraphicsDevice device, bool loadMultipleTextureLayers = false, string[] textureSuffixes = null, ContentManager content = null) {
this.device = device;
if (loadMultipleTextureLayers)
this.textureLayerSuffixes = textureSuffixes;

if (content != null)
{
contentManager = content;
}
}
I then added a new method that loads a texture from the ContentManager. As of now I only have it working for single textures.
public void LoadFromContentPipeline(AtlasPage page, String imgName)
{
if (contentManager != null)
{
Texture2D texture = contentManager.Load<Texture2D>(imgName);
page.width = texture.Width;
page.height = texture.Height;

page.rendererObject = texture;
}
else
{
throw new Exception("ContentManager cannot be null.");
}
}
Back in the Atlas class, in the load method, where it calls the textureLoader.Load method, I check if "loadFromContent" is true, and call the LoadFromContentPipeline method if so.
textureLoader.Load(page, Path.Combine(imagesDir, line));
becomes
if (loadFromContent)
{
textureLoader.LoadFromContentPipeline(page, "Content\\" + line.Substring(0, line.Length - 4)); //stripping the .png extension from the filename in accordance to syntax used when loading from the ContentManager
}
else
{
textureLoader.Load(page, Path.Combine(imagesDir, line));
}
In the ExampleGame class, in the SpineboySceen constructor, I set PremultipliedAlpha to true, and create the atlas with the new parameters for the atlas and texture loader.
public SpineboyScreen(Example game) : base(game) {
skeletonRenderer.PremultipliedAlpha = true;
...
And finally
atlas = new Atlas("data/spineboy.atlas", new XnaTextureLoader(game.GraphicsDevice));
becomes
atlas = new Atlas("data/spineboy.atlas", new XnaTextureLoader(game.GraphicsDevice, false, null, game.Content), true);
Also, when testing with my own assets, I noticed when doing it this way, that I had to export my atlas from Spine with Premultiplied Alpha UNchecked, otherwise I would still get the outlines. I'm assuming that the content pipeline also premultiplies when processing the assets, but I could be wrong.
Mayor901
  • Bài viết: 3

Harald

Sorry for the late reply as well, I must have missed your post.
Thanks very much for the in-depth writeup!
Mayor901 đã viết:Also, when testing with my own assets, I noticed when doing it this way, that I had to export my atlas from Spine with Premultiplied Alpha UNchecked, otherwise I would still get the outlines. I'm assuming that the content pipeline also premultiplies when processing the assets, but I could be wrong.
I think there should be a property Content Processor - Premultiply Alpha at the png file / texture that can be disabled to not apply PMA upon import:

From this website:
By default, the Content Pipeline now converts all textures into premultiplied format. If you do not want this, or if your source texture files are already in premultiplied format, turn off the "Premultiply Alpha" processor parameter:
Hình đại diện của thành viên
Harald

Harri
  • Bài viết: 1951

Mayor901

Thanks. I just checked and that is indeed an option in the Pipeline Tool. I will keep that in mind.
Mayor901
  • Bài viết: 3

Harald

Thanks as well for letting us know.
Hình đại diện của thành viên
Harald

Harri
  • Bài viết: 1951


Quay về Runtimes