Open milen-prg opened 1 year ago
Hi, @milen-prg.
The purpose of this project is to facilitate customization according to the user case. It is possible to add support for RayGui and Phyac and it is quite easy to do so. The only thing I'll not be able is to provide you with the binaries compiled with these extensions. Why not? Because I suck with C development and I can't build the project for except win32 x86 64. So, to keep things simple, I avoid doing customization on the C side of the binding.
If you're looking for shared libs, it may be worth to check out vaiorabbit's repo. The only thing I haven't found yet is the json for physac.h, but in that repo you can find instructions on how to generate it.
On the other hand, in case you know how to build or already have the binaries with RayGuy and Physac extensions included, I can give you directions on how to use the generator to do include them in the binding.
Honestly speaking, I have almost no experience in system programming (I use C and Python for simple physics simulations), so as I learn about vaiorabbit's repo, I try to generate the RayGui and Phyac DLLs (seems successfully), but when I try to use JSON generator, it turned out that must to add clang package to my Python, then to install enormous LLVM-16.0.0-win64.exe and at the end, again errors:
from folder: \raylib-bindings-0.5.5\generator
I try:
`
generator .\batch_generate.cmd
Traceback (most recent call last):
File "C:\Users\mlap\Documents\my\raylib-bindings-0.5.5\generator\generate_raylib.py", line 37, in
KeyError: 'DrawModelEx'
`
and also python script directly:
`
generator .\generate_raygui.py
Error parsing translation unit.
# Yet another raylib wrapper for Ruby
#
# * https://github.com/vaiorabbit/raylib-bindings
#
# [NOTICE] Autogenerated. Do not edit.
require 'ffi'
module Raylib
extend FFI::Library
end
`
And no files was generated.
This is too complex for me.
I see. I tried to use some of the DLLs from there too, with no success. When they're loaded, an OSError is raised complaining that they're not valid win32 application.
I guess I'll try to build raygui one more time. It is quite some time since my last attempt. Hopefully things are a little bit easier now.
I generate DLLs with Visual Studio 2022 64bit compiler, it did not return error and succeed, but, after that the generate_raygui.py script to make JSON for the raygui.h fails.
I'm too dumb even with Visual Studio 😢. I managed to generate the raygui.dll but for some strange reason it fails when I try to load it with ctypes: it can't find the raygui C functions:
Can you send me a copy of your binaries so I can try them?
@milen-prg, I have good news.
The funny thing is that we both managed to build the same DLLs with no actual implementation of the functions (having even the same size). When I tried to load your DLL, ctypes gave the same complaint from the print above.
After felling lost, frustrated, despaired and shaking my fist to the pseudo C compiler gods, I decided to try and make a new project based on the raylib examples. That stuff is not intuitive, I got to say.
The end result is that I finally managed to compile raygui and physac. The only proof I have ATM to back this claim is this print:
You can see a button on the top left part of the window, which is the result of calling
gui_button(Rectangle(30, 30, 60, 25), "Quit")
To accomplish all this, I had to tweak the bind generator but didn't commit the changes yet. This tweak made possible to have a single binding code that spans across multiple binaries.
If you want to compile on you machine, this raylibguiphys.zip contains the visual studio project. You can clone the raylib repo and unzip it inside projects/VS2022 directory. Then compile it.
Otherwise, this Release.zip contains the DLL.
In any case, you need to install raylibpy with the tweaks: raylib_py-4.5.0.post1-py3-none-any.zip. Change file the extension to .whl in case pip complain about this being a zip. To reinstall you can do:
py -m pip install raylib_py-4.5.0.post1-py3-none-any.whl --force-reinstall
On your python project, two new requirements will need to be fullfilled:
First is to create a .raylib
file somewhere in you project, which is justa a JSON file having at least this as content:
{
"rayguiphys": {
"win32": {
"64bit": "change/this/to/indicate/where/the/dll/is"
}
}
}
It is important to know that raylibpy will look for this file wherever the current working directory points to when loading. This is the second requirement.
Hopefully, this weekend I'll commit the changes made so far.
Let me know if you find any loading the DLL with raylibpy.
I successfully install raylib_py-4.5.0.post1-py3-none-any.whl, then copied the raylibguiphys.dll in project folder. I copied there also the generated file myout, renamed to myraylib.py, with commant:
python raylibpyctbg -typeAnnotate -snakecase -attribSwizzling -bindApi -addVectorMath --libBaseDir ./ --win32LibFilename raylibguiphys.dll --include rmath --include rlgl --out ./myout --markdown ./mydoc
then I try the example:
`
from raylibpy import * ## 1
def main():
init_window(800, 450, "raylib [core] example - basic window")
set_target_fps(60)
while not window_should_close():
begin_drawing()
clear_background(RAYWHITE)
draw_text("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY)
end_drawing()
close_window()
if name == 'main': main() `
This not work, the error messages are:
Library loading info: platform: win32 bitness: 64bit absolute path: c:\python311\lib\site-packages\raylibpy\bin\64bit\raylib.dll using .raylib file: no exists: yes is file: yes
Shared library loaded succesfully <CDLLEx 'c:\python311\lib\site-packages\raylibpy\bin\64bit\raylib.dll', handle 7ffae9850000 at 0x2283bfb36d0> Library loading info: platform: win32 bitness: 64bit .raylib load info: ERROR: Platform (rayguiphys), bitness (win32) or valid filename not specified in .raylib file for 64bit extension absolute path: using .raylib file: no exists: no is file: no
Failed to load Shared library rayguiphys
Other:
Library loading info: platform: win32 bitness: 64bit current working dir: C:\Users\mlap\Documents\Milen\MilenWork\raylibpyctbg_prbs1 absolute path: c:\users\mlap\documents\milen\milenwork\raylibpyctbg_prbs1\raylibguiphys.dll using .raylib file: yes exists: yes is file: yes
Shared library loaded succesfully. <CDLLEx 'c:\users\mlap\documents\milen\milenwork\raylibpyctbg_prbs1\raylibguiphys.dll', handle 7ffb133c0000 at 0x2d9350bf890>
Traceback (most recent call last):
File "C:\Users\mlap\Documents\Milen\MilenWork\raylibpyctbg_prbs1\example1.py", line 2, in
Seems that the DLL loads, but there are problems with the names.
Also the .raylib must be: { "win32": { "64bit": "raylibguiphys.dll" } }
otherwise at:
{ "rayguiphys": { "win32": { "64bit": "raylibguiphys.dll" } }
the result was:
Library loading info: platform: win32 bitness: 64bit .raylib load info: Could not decode .raylib file absolute path: ..\lib\bin\64bit\raylibguiphys.dll using .raylib file: no exists: no is file: no
Unable to load raylibguiphys.dll. Failed to load shared library.
I apologize, but I really never dig in system programming, always use Python only for simple simulations play etc.
I forgot to tell you there was no need to generate anything else. The raylibpy and the dlls are all you need.
The raylibpy package above is an updated one that have de dll only for C raylib (I mean, without raygui and physac) but include the binding code for raylib, raygui and physac. This means an extra dll is required, which is the one provided above in Release.zip.
Having said that, the following steps are:
from raylibpy import *
executes. If you don't want to do this on the command line, you can do the following:In utils.py:
import os
import os.path as path
from contextlib import contextmanager
__all__ = [
'context_dir'
]
def context_dir(ctxdir):
'''Temporarily changes the current working directory'''
current_dir = os.getcwd()
is path.isfile(ctxdir):
ctx_dir = path.basename(ctxdir)
else:
ctx_dir = ctxdir
os.chdir(ctx_dir)
yield
os.chdir(current_dir)
Then in your main module:
# between other imports...
from utils import context_dir
with context_dir(__file__):
from raylibpy import *
This will cause raylib to assume that .raylib file is in the same directory of the current python module.
Regarding the contents of .raylib file, you are using the default dll for raylib along with an extra dll for raygui and physac. The only file location that needs to be indicated in it is the extra dll location. If you wanted to use an alternative dll for raylib, you could indicate its location in it too. In any case, when an extra or alternative dll needs to be used, it is necessary to indicate 4 things (4 in the updated package you have installed, 3 on old versions): the lib name, the platform, whether it is 32 or 64 bits and the file path. In your case, the .raylib must be like the example above: the extra dll have 'rayguiphys' as lib name, platform 'win32', '64bit' and is located wherewer you put it.
{
"rayguiphys": {
"win32": {
"64bit": "path/to/file.dll"
}
}
}
It may sound a bit complicated but you'll get used to it.
I have example.py, .raylib, raylib.dll and raylibguiphys.dll in one folder.
example.py:
`from raylibpy import *
def main():
init_window(800, 450, "raylib [core] example - basic window")
set_target_fps(60)
while not window_should_close():
begin_drawing()
clear_background(RAYWHITE)
draw_text("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY)
end_drawing()
close_window()
if name == 'main': main()`
.raylib:
`{ "rayguiphys": { "win32": { "64bit": "raylibguiphys.dll" } }, "raylib": { "win32": { "64bit": "raylib.dll" } } }
`
and the result:
py example1.py
Library loading info: platform: win32 bitness: 64bit absolute path: raylib.dll using .raylib file: no exists: yes is file: yes
Shared library loaded succesfully <CDLLEx 'raylib.dll', handle 7ff972890000 at 0x10642568390> Library loading info: platform: win32 bitness: 64bit absolute path: raylibguiphys.dll using .raylib file: no exists: yes is file: yes
Shared library loaded succesfully <CDLLEx 'raylibguiphys.dll', handle 7ff973780000 at 0x106426abe90>
Traceback (most recent call last):
File "C:\Users\mlap\Documents\Milen\MilenWork\raylibpyctbg_prbs1\example1.py", line 1, in
Seems, the two DLL are successfully loaded, but there is problem with name definitions.
Sadly I come to the conclusion that Physac can't be wrapped in Python. Or, at least, I don't know how to solve it.
I solved the PhysicsShapeType
error but ended up with another problem even worse than this.
Physac has circular references in its structure definitions that render impossible do wrap with ctypes. If you take a look in the header file, you'll see that PhysicsBodyData
struct have a field named shape
that is of type PhysicsShape
, which in turn have a field named body
of type PhysiscBody
that is no other than a pointer to PhysicsBodyData
.
Although this works in C, It will always cause a NameError in Python.
Python allows circular type refs if one of them is quoted:
thing: 'Thing' # quotes allow a forward reference
Please, if it is possible, add support (by json files) for Raylib GUI and Physics addons.