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

Can not use SDL2_gfx primitives for renderering #68

Open
OmegaLambda1998 opened this issue Aug 12, 2023 · 15 comments
Open

Can not use SDL2_gfx primitives for renderering #68

OmegaLambda1998 opened this issue Aug 12, 2023 · 15 comments

Comments

@OmegaLambda1998
Copy link

Minimum working example:

julia> using SimpleDirectMediaLayer

julia> using SimpleDirectMediaLayer.LibSDL2

julia> window = SDL_CreateWindow("test", 0, 0, 500, 500, SDL_WINDOW_SHOWN)
Ptr{SDL_Window} @0x00000000012c1230

julia> renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)
Ptr{SDL_Renderer} @0x0000000001637bf0

julia> SimpleDirectMediaLayer.LibSDL2.rectangleRGBA(renderer, 10, 10, 50, 50, 255, 255, 255, 255)
ERROR: could not load symbol "rectangleRGBA":
/home/[redacted]/.julia/artifacts/8f20658b625a577cdc6b81980bbae941cb291139/lib/libSDL2.so: undefined symbol: rectangleRGBA
Stacktrace:
 [1] rectangleRGBA(renderer::Ptr{SDL_Renderer}, x1::Int64, y1::Int64, x2::Int64, y2::Int64, r::Int64, g::Int64, b::Int64, a::Int64)
   @ SimpleDirectMediaLayer.LibSDL2 ~/.julia/packages/SimpleDirectMediaLayer/wjMsP/src/LibSDL2.jl:6142
 [2] top-level scope
   @ REPL[5]:1

Not only does this not work, it also looks like the SDL2_gfx primitives are not exported. Strangely the SDL2_framerate objects (SDL_initFramerate, SDL_getFramerate, SDL_setFramerate, etc...) which are part of SDL2_gfx do exist!

@Noremac11800
Copy link

I have the same problem. The generator does not appear to be including all of the functions in sdl_gfxPrimitives correctly. Trying to use any of the sdl_gfxPrimitive functions results in the error:
ERROR: could not load symbol "some gfxPrimitive function name"

Has anyone come up with a fix for this yet?

@Noremac11800
Copy link

Actually it appears that that isn't the problem. I believe that the problem lies in the initial bindings generated for SDL_gfx. This package SDL2_gfx_jll claims to have generated the bindings but clearly they are not working for the gfx_primitives functions. They may have to be regenerated and confirmed to work. The good news is that the original PR for adding the bindings into this repo should still work. But the SDL2_gfx_jll package will have to be updated on the registry to make the bindings work.

@mpeters2
Copy link
Contributor

Same here for thickLineRGBA()

@mpeters2
Copy link
Contributor

I noticed this in the generator.toml:
export_symbol_prefixes = ["TTF_", "IMG_", "Mix_", "SDL_", "MIX_", "RW_", "AUDIO_", "KMOD_", "HAVE_", ]

I don't remotely understand how Clang.jl works, but none of the SDL2_gfx functions have prefixes. I wonder if that is the issue?

@Kyjor
Copy link
Contributor

Kyjor commented Jan 11, 2024

Has anyone found a workaround?

@Kyjor
Copy link
Contributor

Kyjor commented Jan 18, 2024

I found a workaround. It's not pretty, but it's better than nothing at the moment. If I get time, I would like to learn more as to actually fix it.
First of all, I grabbed the sdl_gfx.dll file from https://github.com/Vladar4/sdl2_nim/blob/master/LINKS.md

Then I dropped it in my artifacts folder with my SDL2.dll file. If you can't find it through searching, you could just update one of the functions in LibSDL2.jl like this to print it out.

This file was at: C:\Users\kyjor\.julia\packages\SimpleDirectMediaLayer\wjMsP\src\LibSDL2.jl for me

function SDL_CreateRenderer(window, index, flags)
    println(libsdl2)
    ccall((:SDL_CreateRenderer, libsdl2), Ptr{SDL_Renderer}, (Ptr{SDL_Window}, Cint, Uint32), window, index, flags)
end

this returned C:\Users\kyjor\.julia\artifacts\a3822540351cc2f773be931a83adc5c844eee6f2\bin\SDL2.dll for me.

So once you dropped in your dll, go to all of the sdl_gfx functions, and change them to look like this:

function SDL_initFramerate(manager)
    ccall((:SDL_initFramerate, replace(libsdl2, "SDL2" => "SDL2_gfx")), Cvoid, (Ptr{FPSmanager},), manager)
end

instead of just libsdl2 as a parameter, change it to replace(libsdl2, "SDL2" => "SDL2_gfx")). This will use the SDL_gfx.dll instead of the SDL2.dll for these calls. I've only tested this with the framerate functions so far, and they worked for me. I hope this helps anyone. Like I said, it's a hack, and hopefully I can try and contribute a real fix.

@Noremac11800
Copy link

@Kyjor Wow, nice work! I swear I tried basically that exact hack a few weeks ago. I'll attempt your hack when I get some free time. Thanks for finding a fix. Something is better than nothing. :)

@Kyjor
Copy link
Contributor

Kyjor commented Jan 18, 2024

No problem! Like I said, I've only tried it with the framerate functions so far, so your results may vary. I'll probably be trying to work with the actual drawing functions real soon. So if there's any gotchas, I'll let you know

@Noremac11800
Copy link

Alright, so a quick update. I followed through (more carefully this time!) with your steps, and I can corroborate your results with my own. The frame-rate functions work as intended, however, when trying some of the graphics functions (I tried pixelRGBA, hlineRGBA, and circleRGBA), they are not working. On the bright side however, I am no longer getting the original error I was getting months ago which read along the lines of: could not load symbol "some gfxPrimitive function name".

So as far as I can tell, the package now has access to the SDL2_gfx functions, but for some reason the graphics primitives are not drawing. Unfortunately, this issue is still way above my current skillset, so if anyone has some further insight into how to get the drawing functions to work, that would be much appreciated.

@Kyjor
Copy link
Contributor

Kyjor commented Jan 19, 2024

@Noremac11800 can you send me a MWE of your code? I can try and mess with it.

@Kyjor
Copy link
Contributor

Kyjor commented Jan 20, 2024

@Noremac11800 Here's an example: 😄 https://gist.github.com/Kyjor/c6d9b82245f83311f10a5e4e8a41ca59
I just modified the basic.jl example.
This is what it looks like for me:
image

@Noremac11800
Copy link

Hi @Kyjor, sorry for the late reply I've been a bit busy. A MWE of my code is essentially identical to yours. I used the basic.jl example also.

I just tested out your code (making sure to add the necessary replace(libsdl2, "SDL2" => "SDL2_gfx") lines to make your graphics functions work) and my code runs without errors, however the actual graphics are not drawn still.

I believe the issue lies in the way the sdl_gfx library is communicating with SDL2. Let me explain. Because I am using MacOS and not Windows, when I followed your original fix I had to retrieve the sdl_gfx library from an alternative location. A .dll will not work so I had to either find or build the correct .dylib library for sdl_gfx. In my haste, my best fix was to install the library via Homebrew with:

brew install sdl2_gfx

I then located the two associated dylibs in my brew Cellar and manually moved them into the .julia/artifacts... directory, containing the LibSDL2.dylib libraries.

For reasons that I do not understand, I don't think I was supposed to do that... When I run your minimal example code I get the following output in my terminal:

Class SDLApplication is implemented in both /Users/cam/.julia/artifacts/8fd700de383504a22db30fc7e4193dc1b1ee471e/lib/libSDL2-2.0.0.dylib (0x1061527e8) and /opt/homebrew/Cellar/sdl2/2.28.5/lib/libSDL2-2.0.0.dylib (0x1544b88e0). One of the two will be used. Which one is undefined.

So I think your fix is working perfectly fine and this issue is close to being resolved. The problem appears to be on my end due to a lack of understanding around dylibs. So I am going to have to toy around with my setup a bit to see if I can get the libraries to look in the right locations for the code.

Out of curiosity, I may go and attempt this on my Arch desktop machine instead of my Mac because I may have more luck there. MacOS usually isn't my first choice when it comes to development.

I appreciate all of your effort though :)

@Noremac11800
Copy link

AHA! Another update. I just tried out the same process on my Arch machine and it worked flawlessly!

So for anyone who wants to know the steps I took:

  1. Install SimpleDirectMediaLayer.jl via Julia's pkg manager
  2. Install libSDL2_gfx via:
sudo pacman -S sdl2_gfx
  1. Determine the correct artifacts directory where SDL2 is located in your ~/.julia directory. Mine was located at ~/.julia/artifacts/8f20658b625a577cdc6b81980bbae941cb291139/lib/
  2. Navigate to /usr/lib/ and copy the libSDL2_gfx.so file into the artifacts directory
  3. Navigate to ~/.julia/packages/SimpleDirectMediaLayer/wjMsP/src/ and modify your desired SDL2_gfx functions according to @Kyjor's advice above.
  4. Use @Kyjor's MWE code basic.jl here and replace the function calls with your own.

As far as making a better, more permanent fix, that's a problem for later. But as an immediate hack, this fix works perfectly fine.

Nice work @Kyjor! Thanks for all the help.

@Kyjor
Copy link
Contributor

Kyjor commented Jan 24, 2024

No problem @Noremac11800 ! Good luck!

@Kyjor
Copy link
Contributor

Kyjor commented Jan 26, 2024

#75

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

No branches or pull requests

4 participants