[Release] Generic DUI 2d/3d renderer

,

any guide how to use this? :smiley:

1 Like

Thereā€™s a sample code provided in the OP. Other than that thereā€™s a F.A.Q. section present, please, check it out.

Working on coding this into C# (testing for now) and have an issue with the txn (first time doing this) that in C# it expects a long and not a string. Any ideas how to progress as currently it doesnā€™t show the scaleform and this I believe is why.

public static long CreateRuntimeTextureFromDuiHandle(long txd, long txn, string duiHandle);

So I have been playing around and can confirm the JS file works fine so I know that the issue is within my C# implementation which is pretty much a copy-paste of the JS code provided in the example.

So far I can confirm the Scaleform is being loaded into memory but the rendering is failing, off to test more.

Iā€™m using Function.Call due to the fact that CREATE_RUNTIME_TEXTURE_FROM_DUI_HANDLE (Source: link) expects a long in the second parameter but in JS/LUA it seams to work as expected.

EDIT: I have this working now but took a different route.

My C# Code
using CitizenFX.Core;
using CitizenFX.Core.Native;
using System;
using System.Threading.Tasks;

namespace cef.client.net
{
    public class CefLoader : BaseScript
    {
        string url = "https://www.youtube.com";
        float scale = 0.1f;
        string sfName = "generic_texture_renderer";

        int width = 1280;
        int height = 720;

        int sfHandle = 0;
        bool txdHasBeenSet = false;
        long duiObj = 0;


        public CefLoader()
        {
            EventHandlers["onClientResourceStart"] += new Action<string>(OnClientResourceStart);
            EventHandlers["onClientResourceStop"] += new Action<string>(OnClientResourceStop);
            Tick += ShowVideo;
        }

        async void OnClientResourceStart(string resourceName)
        {
            if (API.GetCurrentResourceName() != resourceName) return;

            while (!Function.Call<bool>(Hash.HAS_SCALEFORM_MOVIE_LOADED, sfHandle))
            {
                sfHandle = Function.Call<int>(Hash.REQUEST_SCALEFORM_MOVIE, sfName);
                await Delay(0);
            }

            long txd = Function.Call<long>(Hash.CREATE_RUNTIME_TXD, "meows");
            duiObj = Function.Call<long>(Hash.CREATE_DUI, url, width, height);
            string dui = Function.Call<string>(Hash.GET_DUI_HANDLE, duiObj);

            Function.Call(Hash.CREATE_RUNTIME_TEXTURE_FROM_DUI_HANDLE, txd, "woof", dui);

            await Delay(0);
        }

        async void OnClientResourceStop(string resourceName)
        {
            if (API.GetCurrentResourceName() != resourceName) return;

            if (duiObj > 0)
            {
                Function.Call(Hash.DESTROY_DUI, duiObj);
                Function.Call(Hash.SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED, sfHandle);
                txdHasBeenSet = false;
            }

            await Delay(0);
        }

        async Task ShowVideo()
        {
            if (sfHandle > 0 && !txdHasBeenSet)
            {
                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION, sfHandle, "SET_TEXTURE");

                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_METHOD_PARAMETER_STRING, "meows");
                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_METHOD_PARAMETER_STRING, "woof");

                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_INT, 0);
                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_INT, 0);
                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_INT, width);
                Function.Call(Hash._PUSH_SCALEFORM_MOVIE_FUNCTION_PARAMETER_INT, height);

                Function.Call(Hash._POP_SCALEFORM_MOVIE_FUNCTION_VOID);

                txdHasBeenSet = true;
            }

            Vector3 vector3 = Game.PlayerPed.Position;

            if (sfHandle > 0 && Function.Call<bool>(Hash.HAS_SCALEFORM_MOVIE_LOADED, sfHandle))
            {
                Function.Call(Hash._DRAW_SCALEFORM_MOVIE_3D_NON_ADDITIVE,
                        sfHandle,
                        vector3.X - 1, vector3.Y, vector3.Z + 2,
                        0, 0, 0,
                        2, 2, 2,
                        scale * 1, scale * (9 / 16), 1
                        , 2);
            }

            await Delay(0);
        }
    }
}

Omg, that is the thing that i have been looking for :heart:

Awesome dude! first thing I did:

1 Like

hahahaha, Iā€™m surprised its not a massive cinema screen.

Hey, could you tell me how to rotate the screen? Iā€™m pretty new at coding on fivem

1 Like

Ok i found, itā€™s here:

        -42, -1113, 27,
        0, 0, >>10<<,
        2, 2, 2,

But itā€™s not the same as the ā€œheadingā€ value

How can I create multiple? I tried many things but it always spawn only 1

EDIT: Okay, Iā€™m just stupid sorryā€¦

Does that value change heading?

yes but you have to use the contrary value of your heading, exemple: if your heading is 20, you have to set -20 on the dui for it to be in the same rotation

1 Like

Anyone have an idea how to make the sound not global? So you can only hear sound when close? It seems pretty hard to do.

I cannot understand anything !!

You shouldnt try mate

did u add that to a prop name as ive never been able to get the prop name for that tv or is it just over the top of the tv

how i can make the sound on position the problem is all players on server can hear the sound

Hi there. Itā€™s working fine for me, but i wondered about whether transparency is possible or not?
It doesnā€™t seem to like backgrounds with transparency values, thats very inconvenient for my cause :cry:

I got it to work i only hear the sound the picture dont pop up what am i missing?

Please tell me the command