Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gif player #2833

Open
wants to merge 99 commits into
base: master
Choose a base branch
from
Open

Conversation

MobinYengejehi
Copy link

@MobinYengejehi MobinYengejehi commented Dec 16, 2022

hi
i made a gif player which load and play gifs as fast as possible
you can create a gif like:

local gif = gifCreate(file_path or gif_buffer) -- "logo.gif" for example

local size = Vector2(dxGetMaterialSize(gif))

addEventHandler("onClientRender",getRootElement(),function()
    if isElement(gif) then
        dxDrawImage(0,0,size,gif)
    end
end)

cuz it is a texture element you can use it, inside shaders or inside all dx related functions

@patrikjuvonen patrikjuvonen added the enhancement New feature or request label Dec 16, 2022
@patrikjuvonen
Copy link
Contributor

Thanks for the pull request! Cool idea!

I'm wondering if there is an open source Gif loader library out there that we could use instead of implementing the intricacies ourselves, thinking from a future maintainability and security perspective.

@tederis
Copy link
Collaborator

tederis commented Dec 16, 2022

Great. But I think you should use the new Lua parser.

@MobinYengejehi
Copy link
Author

MobinYengejehi commented Dec 16, 2022

Thanks for the pull request! Cool idea!

I'm wondering if there is an open source Gif loader library out there that we could use instead of implementing the intricacies ourselves, thinking from a future maintainability and security perspective.

yeah we can
i just used https://github.com/hidefromkgb/gif_load and made it a little better because it needed some changes. you can go and see the real code. it is from @hidefromkgb
i thought that we must write code like this
this is my first time trying to contribute mta-blue

Client/mods/deathmatch/logic/CClientGifDisplay.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/CClientGifDisplay.cpp Outdated Show resolved Hide resolved
Client/sdk/core/CRenderItemManagerInterface.h Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/luadefs/CLuaGifDefs.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/CClientGif.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/CClientGif.cpp Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/CClientGif.h Outdated Show resolved Hide resolved
Client/mods/deathmatch/logic/CClientGif.h Outdated Show resolved Hide resolved
@MobinYengejehi
Copy link
Author

MobinYengejehi commented Apr 8, 2023

😔

@lopezloo
Copy link
Member

lopezloo commented Jul 9, 2023

Do we really need this?

@CrosRoad95
Copy link
Contributor

Do we really need this?

actualy, no. If you for example want to have gif in mta, i bet there is a program that can turn it into atlas texture with every frame.
If you want to have dynamic gifs, let's say gif avatars then use for example: https://www.npmjs.com/package/gif-to-png

@dmi7ry
Copy link

dmi7ry commented Jul 10, 2023

Do we really need this?

actualy, no. If you for example want to have gif in mta, i bet there is a program that can turn it into atlas texture with every frame. If you want to have dynamic gifs, let's say gif avatars then use for example: https://www.npmjs.com/package/gif-to-png

Keep in mind that GIF is not just a collection of pictures displayed one after the other. GIF allows you to set pauses between frames and other things. If such GIF is directly converted to a png set, then the size of the textures will be much MUCH larger.
And to avoid this, you still have to write a sequencer that will take into account all the pauses between frames, etc. I think that this will be somewhat difficult for many developers.

@CrosRoad95
Copy link
Contributor

take into account all the pauses between frames, etc.

Probably along with frames you can use some tool to extract metadata.

@dmi7ry
Copy link

dmi7ry commented Jul 10, 2023

take into account all the pauses between frames, etc.
Probably along with frames you can use some tool to extract metadata.

Me personally prefer to use Rive and Spine. But how about not very experienced deveopers? Of course this means that just no one will use animations, and therefore the interfaces will look less interesting than they could be.

@MobinYengejehi
Copy link
Author

MobinYengejehi commented Jul 22, 2023

Do we really need this?

actualy, no. If you for example want to have gif in mta, i bet there is a program that can turn it into atlas texture with every frame. If you want to have dynamic gifs, let's say gif avatars then use for example: https://www.npmjs.com/package/gif-to-png

well then you won't be able to use shaders to control the texture pixels
this feature is not that important cuz developers can use browsers which is much better
but my experience says CEF sometimes doesn't work properly on weak cpus
actually it happened to me multiple times and it wasn't only me who experienced that
mta created browser and also onClientBrowserCreated event was triggered but my display was empty
it seemed like cef didn't change browser texture pixels and all of those was 0x00000000
so i decided to contribute mta and add this feature that is fast and allows developers save some frames inside a gif and use that frames the way they want
and also because this gif element is a dx texture developers can use shaders for it and also apply this shaders on models
for example animated labels on vehicles or something like that
and the way to use it is like this:

local gif = gifCreate("label.gif");

local shader = dxCreateShader("shader.fx");
assert(shader, "couldn't create the shader!");

dxSetShaderValue(shader, "gif", gif);

addCommandHandler("startanim", function()
    gifPlay(gif);
);

addCommandHandler("stopanim", function()
    gifStop(gif);
end);

addCommandHandler("setlabel", function()
    -- engineApplyShaderToWorldTexture ...
end);
texture gif;
sampler2D gifSampler{
    Texture = gif;
};

float4 pixels(float2 coords : TEXCOORD0) : COLOR0 {
    // and for example i want to remove green background here
    float4 color = tex2D(gifSampler, coords);
    
    if (color == float4(0, 1, 0, 1)) {
        return (float4)0;
    }
    
    return color;
}

technique Render{
    pass p0 {
        PixelShader = compile ps_2_a pixels();
    }
}

this feature has less fps drop than the render target or other possible methods
with this api also the clients who use weak systems can experience this animated labels on their vehicles

@PlatinMTA
Copy link
Contributor

The shader idea is kinda cool, I can see myself using it. I would use it to display some forum avatars aswell.

this feature has less fps drop than the render target or other possible methods
Just out of curiosity, do you have some benchmarks about that? Just having the easy implementation is enough, but having it be faster is a no brainer if you need to use .gifs.

@MobinYengejehi
Copy link
Author

MobinYengejehi commented Jul 25, 2023

The shader idea is kinda cool, I can see myself using it. I would use it to display some forum avatars aswell.

this feature has less fps drop than the render target or other possible methods Just out of curiosity, do you have some benchmarks about that? Just having the easy implementation is enough, but having it be faster is a no brainer if you need to use .gifs.

actually i was thinking about playing videos on mta client
i know we can play videos or other medias with CEF
but as i mentioned mta sometimes can't load browser textures
so i decided to somehow create my own library to load videos but i knew lua isn't that fast that i can load my webm buffer and display it on screen
i thought maybe if we had some features in mta that we could allocate memory to save frames and use them can help me.
at first i used textures for that
when i tested it, it took 30 seconds to load only 50 frames and after all frames loaded when i displayed them on screen it was using 8% of my cpu
and most important thing was that creating the texture occupied the memory of graphic card
so i thought if i create only one texture and allocate some bytes from computer memory to save my frames and send that bytes to graphic card memory this can fix my problem (and this is exactly what this gif player does)
then i came up with this gif player idea and decided to make it and ask mta team if they like my idea add it to the launcher
when i used gif player to load my webm frames, it took less than 100 ms to load more than 700 frames and on display, it was
only using something like 0.5% of my cpu
and you can control your player to display frames with gifSetProperty and gifGetProperty functions

new functions:

gifGetProperty(element [gif (dx material)], [int (frame index)] string [property]);
gifSetProperty(element [gif (dx material)], [int (frame index)] string [property], string or number [value]);

gif get properties:
Frame:

delay : gets the frame delay
default_delay : gets the frame default delay

Global:

showing_frame : gets the showing frame
frame_count : gets the loaded frames count
format : gets the gif format GIF89a or GIF87a
tick : gets last updated tick

gif set properties:
Frame:

delay : sets frame delay

Global:

showing_frame : sets showing frame

you know i don't want to open another application in my computers background and create other vm s to display a simple gif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants