FNA-XNA / FNA

FNA - Accuracy-focused XNA4 reimplementation for open platforms
https://fna-xna.github.io/
2.61k stars 265 forks source link

OpenGL wrong image? #132

Closed andreakarasho closed 6 years ago

andreakarasho commented 7 years ago

Hello! im trying FNA to update a xna native project. This project has shaders file (.fx).

This is the problem (1st image, 2nd image it's the original game made from EA): https://imgur.com/a/odsZH The image (castle and gothic frame) has no color (it's taken from game files and draw on screen withtout changes). The words "Log in to Ultima Online" has colored thanks to shader .fx and works good! Whats happen? OpenGL mades this mistake? look this https://github.com/ZaneDubya/UltimaXNA/issues/432

ps: shader was compiled with fxc with fx_2_0 profile, because with ps_2 gives to me accessvilolation

flibitijibibo commented 7 years ago

What does the fx source look like?

flibitijibibo commented 7 years ago

Glancing through the source for the first time, I only see 2 things:

  1. The VertexShaderFunction's half-pixel offset needs to be removed
  2. Maybe it's our Bgra5551 XNAToGL map? Try this line...

https://github.com/FNA-XNA/FNA/blob/master/src/FNAPlatform/OpenGLDevice_GL.cs#L40

Change it from 8034 to 8366 and see if that solves it. Maybe I just have the order wrong...

ZaneDubya commented 6 years ago

UltimaXNA is my project from years ago!

@Pack4Duck - I don't believe that removing the half-pixel offset will change the output image. Go ahead and remove it! If you can't get the 16bit color working - I also had trouble with that color format when making a project cross platform - my recommendation is to just change the texture format from 5551 to Color. You will need to change the texture unpacking algorithm for all the files listed here.

This is a naive implementation of a bgra5551 -> Color format I used in UltimaXNA back in 2009:

const int multiplier = 0xFF / 0x1F;
uint color32 = 0xFF000000 + (
    ((((color >> 10) & 0x1F) * multiplier)) |
    ((((color >> 5) & 0x1F) * multiplier) << 8) |
    (((color & 0x1F) * multiplier) << 16)
);

I would accept a PR to UltimaXNA that changed all the texture formats to Color.

@flibitijibibo - FNA is a fantastic project. I use it in my personal projects and I'm so impressed with how seamlessly it works as an XNA replacement. Sincere kudos for all that you've accomplished!

andreakarasho commented 6 years ago

Ei! @ZaneDubya nice to meet you!!! I found this solution shortly before @flibitijibibo wrote here :P I want to update UltimaXNA to support latest client. I make a new project and i look uoxna to undestand how XNA engine works. If you want more details you can send me a msg on discord: https://discordapp.com/invite/P3Q7mKT im karasho

ZaneDubya commented 6 years ago

@flibitijibibo Sounds like you can close this. Thanks for letting us use your issues board!

andreakarasho commented 6 years ago

@flibitijibibo yeah sorry man, i forgot to say to you it's a src code mistake!

Very nice project FNA!

flibitijibibo commented 6 years ago

Not sure if it's producing that image above but I tested and can confirm FNA was loading Bgra5551 incorrectly. Both 5551 and 4444 should load correctly now:

https://github.com/FNA-XNA/FNA/commit/15a3f0e1111f6c3037bba05c57b60b4b4f01d3ee

Test program if anyone wants to verify the other formats (I think they should all be okay?):

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Graphics.PackedVector;

class Program : Game
{
    // Use these to test color channels as well as alpha blending!
    static readonly Vector4 texColor = new Vector4(0.0f, 0.0f, 1.0f, 0.5f);
    static readonly Vector4 clearColor = new Vector4(1.0f, 0.0f, 0.0f, 1.0f);

    Texture2D tex;
    SpriteBatch batch;

    Program() : base()
    {
        new GraphicsDeviceManager(this);
    }

    protected override void LoadContent()
    {
        // The code below is what you care about!
        SurfaceFormat testFormat = SurfaceFormat.Bgra4444;
        ushort[] pixels = new ushort[800 * 480];
        ushort pixel = (new Bgra4444(texColor)).PackedValue;
        for (int i = 0; i < pixels.Length; i += 1)
        {
            pixels[i] = pixel;
        }
        // The code above is what you care about!

        tex = new Texture2D(
            GraphicsDevice,
            800,
            480,
            false,
            testFormat
        );
        tex.SetData(pixels);
        batch = new SpriteBatch(GraphicsDevice);
    }

    protected override void UnloadContent()
    {
        batch.Dispose();
        tex.Dispose();
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(
            ClearOptions.Target,
            clearColor,
            0.0f,
            0
        );
        batch.Begin();
        batch.Draw(tex, Vector2.Zero, Color.White);
        batch.End();
    }
    static void Main(string[] args)
    {
        using (Program p = new Program())
        {
            p.Run();
        }
    }
}
flibitijibibo commented 6 years ago

Extra note: Rgba1010102 was not okay:

https://github.com/FNA-XNA/FNA/commit/6ee03e464fa71779ad033307af40cb8e11417a47

All the others seem to work, though I only tested the ones that had unique input values for GLenum type.