citizenfx / fivem

The source code for the Cfx.re modification frameworks, such as FiveM, RedM and LibertyM, as well as FXServer.
https://cfx.re/
3.47k stars 2.05k forks source link

DrawOrigin Single Frame Positional Bug #2450

Open kono5alive opened 4 months ago

kono5alive commented 4 months ago

What happened?

RDR2 - When drawing text or sprites in a loop and using draworigin within the loop, if an item decides to stop drawing itself, but others are still drawing, for one single frame before disappearing, it overlaps itself on to an incorrect position (or another draw origin in the list, possibly the first or last one used/drawn? unsure entirely). I've submitted this issue on the forums with full description, reproducible code, and screenshots, which can be viewed here: https://forum.cfx.re/t/draworigin-single-frame-positional-issue/5223033

I wanted to submit this to github issues to potentially get some more eyes on it.

Expected result

DrawOrigin should not make something being drawn jump positions for one frame before dissapearing

Reproduction steps

  1. For full context and walkthrough, please view the forum post at: https://forum.cfx.re/t/draworigin-single-frame-positional-issue/5223033

  2. Reproducible Code below:

public class DrawOriginTest : BaseScript
{
    private static int _gameTimeSinceLastSwap = 0;
    private static bool _showSecond = false;

    [Tick]
    private async Task DrawSprites()
    {
        // CHANGE THESE FOR CORRECT RESOLUTION SCALING (so scale calcs make things look good on current resolution)
        var overallScaleFactor = 1.0f;
        var screenResolution = new Vector2(1920f, 1080f);

        List<Vector3> spriteLocations = new List<Vector3>()
        {
            new Vector3(-800.9131f, -1238.78f, 43.81535f),
            new Vector3(-802.5263f, -1238.749f, 43.82928f),
            new Vector3(-804.2942f, -1238.716f, 43.82634f)
        };

        var textureName = "blip_mp_base_";
        var index = 1;

        // LOOP AND DRAW
        foreach (var spriteLoc in spriteLocations)
        {
            if (API.GetGameTimer() - _gameTimeSinceLastSwap > 2000)
            {
                _showSecond = !_showSecond;
                _gameTimeSinceLastSwap = API.GetGameTimer();
            }

            if (index != 2 || _showSecond)
            {
                // DRAW ORIGIN
                Function.Call((Hash)((ulong)0xE10198D5 & 0xFFFFFFFF), spriteLoc.X, spriteLoc.Y, spriteLoc.Z, 0);

                DrawSpriteRespectResolution("blips_mp", textureName + index, new Vector2(0f, 0f),
                    new Vector2(46f * overallScaleFactor, 46f * overallScaleFactor), screenResolution,
                    new Vector2(512f, 512f), 0f, Color.FromArgb(255, 255, 255, 255), false);

                Function.Call((Hash)((ulong)0xDD76B263 & 0xFFFFFFFF));
            }

            index++;
        }
    }

    private async void DrawSpriteRespectResolution(string textureDictionary, string textureName, Vector2 positionInPixels, Vector2 scaleInPixels, Vector2 screenResolution,
        Vector2 textureResolution, float heading, Color color, bool p11)
    {
        var requestTimeout = API.GetGameTimer() + 5000;

        if (Function.Call<bool>((Hash)0x54D6900929CCF162, textureDictionary) == false)
        {
            Function.Call((Hash)0xC1BA29DF5631B0F8, textureDictionary, false);

            while (Function.Call<bool>((Hash)0x54D6900929CCF162, textureDictionary) == false && requestTimeout > API.GetGameTimer())
            {
                Function.Call((Hash)0xC1BA29DF5631B0F8, textureDictionary, true);
                await BaseScript.Delay(0);
            }
        }

        var widthScale = (scaleInPixels.X / screenResolution.X); // * scale.X;
        var heightScale = (scaleInPixels.Y / screenResolution.Y); //* scale.Y;

        var posX = (positionInPixels.X / screenResolution.X);
        var posY = (positionInPixels.Y / screenResolution.Y);

        // DRAW_SPRITE
        Function.Call((Hash)0xC9884ECADE94CB34, textureDictionary, textureName, posX, posY, widthScale, heightScale, heading, color.R, color.G, color.B, color.A, p11);
    }
}

Importancy

Slight inconvenience

Area(s)

RedM

Specific version(s)

RedM b1491 Production and Canary

Additional information

No response

kono5alive commented 4 months ago

Is there any other information I can help provide to deduce or further identify the issue? Willing to help in anyway possible that I am able.