nonworking dynamic bindings
This commit is contained in:
parent
2335c5275f
commit
790ff3fcf6
8 changed files with 119 additions and 31 deletions
13
README.md
13
README.md
|
@ -1,12 +1,14 @@
|
||||||
# Python Bindings for Raylib
|
# Python Bindings for Raylib
|
||||||
|
|
||||||
These bindings use CFFI rather than ctypes. Hopefully this will be faster, the static type knowledge from the C
|
This uses CFFI API static bindins rather than ctypes. Hopefully this will be faster, the static type knowledge from the C
|
||||||
headers will result in fewer bugs, and using the original headers will make it easier to maintain.
|
headers will result in fewer bugs, and using the original headers will make it easier to maintain.
|
||||||
|
|
||||||
Currently the goal is make usage as similar to the original C as CFFI will allow. There are a few differences
|
Currently the goal is make usage as similar to the original C as CFFI will allow. There are a few differences
|
||||||
you can see in the examples. Making a 'Pythonic' library would be an additional layer on top which hasn't been
|
you can see in the examples. Making a 'Pythonic' library would be an additional layer on top which hasn't been
|
||||||
done yet.
|
done yet.
|
||||||
|
|
||||||
|
See test.py and examples/*.py for how to use.
|
||||||
|
|
||||||
# Platforms tested
|
# Platforms tested
|
||||||
|
|
||||||
* MacOS 10.12.6
|
* MacOS 10.12.6
|
||||||
|
@ -16,3 +18,12 @@ done yet.
|
||||||
* converting more examples from C to python
|
* converting more examples from C to python
|
||||||
* testing and building on more platforms
|
* testing and building on more platforms
|
||||||
|
|
||||||
|
### Dynamic bindings
|
||||||
|
|
||||||
|
I have attempted to do CFFI ABI dynamic bindings too in order to avoid the need to compile a C extension module,
|
||||||
|
but they don't work properly. They fails to work in the same place the ctypes binding fails, accessing
|
||||||
|
materials of a model, because Python can't dynamically tell the difference between a pointer and an array. There's probably
|
||||||
|
some way to specify this (e.g. in raylib_modified.h) but it's difficult to be sure we fixed them all, and the errors
|
||||||
|
are often completely silent.
|
||||||
|
|
||||||
|
See test_static.py for the non-working example.
|
|
@ -2,33 +2,9 @@ __version__ = "2.5.dev1"
|
||||||
|
|
||||||
from ._raylib_cffi import ffi, lib as rl
|
from ._raylib_cffi import ffi, lib as rl
|
||||||
from _raylib_cffi.lib import *
|
from _raylib_cffi.lib import *
|
||||||
|
from .colors import *
|
||||||
|
from .helpers import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def Vector3(x, y, z):
|
|
||||||
return ffi.new("struct Vector3 *", [x, y, z])[0]
|
|
||||||
|
|
||||||
LIGHTGRAY =( 200, 200, 200, 255 )
|
|
||||||
GRAY =( 130, 130, 130, 255 )
|
|
||||||
DARKGRAY =( 80, 80, 80, 255 )
|
|
||||||
YELLOW =( 253, 249, 0, 255 )
|
|
||||||
GOLD =( 255, 203, 0, 255 )
|
|
||||||
ORANGE =( 255, 161, 0, 255 )
|
|
||||||
PINK =( 255, 109, 194, 255 )
|
|
||||||
RED =( 230, 41, 55, 255 )
|
|
||||||
MAROON =( 190, 33, 55, 255 )
|
|
||||||
GREEN =( 0, 228, 48, 255 )
|
|
||||||
LIME =( 0, 158, 47, 255 )
|
|
||||||
DARKGREEN =( 0, 117, 44, 255 )
|
|
||||||
SKYBLUE =( 102, 191, 255, 255 )
|
|
||||||
BLUE =( 0, 121, 241, 255 )
|
|
||||||
DARKBLUE =( 0, 82, 172, 255 )
|
|
||||||
PURPLE =( 200, 122, 255, 255 )
|
|
||||||
VIOLET =( 135, 60, 190, 255 )
|
|
||||||
DARKPURPLE =( 112, 31, 126, 255 )
|
|
||||||
BEIGE =( 211, 176, 131, 255 )
|
|
||||||
BROWN =( 127, 106, 79, 255 )
|
|
||||||
DARKBROWN =( 76, 63, 47, 255 )
|
|
||||||
WHITE =( 255, 255, 255, 255 )
|
|
||||||
BLACK =( 0, 0, 0, 255 )
|
|
||||||
BLANK =( 0, 0, 0, 0 )
|
|
||||||
MAGENTA =( 255, 0, 255, 255 )
|
|
||||||
RAYWHITE =( 245, 245, 245, 255 )
|
|
26
raylib/colors.py
Normal file
26
raylib/colors.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
LIGHTGRAY =( 200, 200, 200, 255 )
|
||||||
|
GRAY =( 130, 130, 130, 255 )
|
||||||
|
DARKGRAY =( 80, 80, 80, 255 )
|
||||||
|
YELLOW =( 253, 249, 0, 255 )
|
||||||
|
GOLD =( 255, 203, 0, 255 )
|
||||||
|
ORANGE =( 255, 161, 0, 255 )
|
||||||
|
PINK =( 255, 109, 194, 255 )
|
||||||
|
RED =( 230, 41, 55, 255 )
|
||||||
|
MAROON =( 190, 33, 55, 255 )
|
||||||
|
GREEN =( 0, 228, 48, 255 )
|
||||||
|
LIME =( 0, 158, 47, 255 )
|
||||||
|
DARKGREEN =( 0, 117, 44, 255 )
|
||||||
|
SKYBLUE =( 102, 191, 255, 255 )
|
||||||
|
BLUE =( 0, 121, 241, 255 )
|
||||||
|
DARKBLUE =( 0, 82, 172, 255 )
|
||||||
|
PURPLE =( 200, 122, 255, 255 )
|
||||||
|
VIOLET =( 135, 60, 190, 255 )
|
||||||
|
DARKPURPLE =( 112, 31, 126, 255 )
|
||||||
|
BEIGE =( 211, 176, 131, 255 )
|
||||||
|
BROWN =( 127, 106, 79, 255 )
|
||||||
|
DARKBROWN =( 76, 63, 47, 255 )
|
||||||
|
WHITE =( 255, 255, 255, 255 )
|
||||||
|
BLACK =( 0, 0, 0, 255 )
|
||||||
|
BLANK =( 0, 0, 0, 0 )
|
||||||
|
MAGENTA =( 255, 0, 255, 255 )
|
||||||
|
RAYWHITE =( 245, 245, 245, 255 )
|
15
raylib/dynamic_binding/__init__.py
Normal file
15
raylib/dynamic_binding/__init__.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
"""
|
||||||
|
This is an attempt at a CFFI dynamic (ABI) binding. However, it fails to work in the exactly same place the ctypes binding fails, accessing
|
||||||
|
materials of a model.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
MODULE = pathlib.Path(__file__).parent.parent
|
||||||
|
|
||||||
|
from cffi import FFI
|
||||||
|
ffi = FFI()
|
||||||
|
ffi.cdef(open(MODULE / "raylib_modified.h").read().replace('RLAPI ', ''))
|
||||||
|
|
||||||
|
raylib = ffi.dlopen(str(MODULE)+"/dynamic_binding/libraylib.2.dylib")
|
||||||
|
|
BIN
raylib/dynamic_binding/libraylib.2.dylib
Executable file
BIN
raylib/dynamic_binding/libraylib.2.dylib
Executable file
Binary file not shown.
5
raylib/helpers.py
Normal file
5
raylib/helpers.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from ._raylib_cffi import ffi
|
||||||
|
|
||||||
|
def Vector3(x, y, z):
|
||||||
|
return ffi.new("struct Vector3 *", [x, y, z])[0]
|
||||||
|
|
52
test_dynamic.py
Normal file
52
test_dynamic.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
"""
|
||||||
|
This is an attempt at a CFFI dynamic (ABI) binding. However, it fails to work in the same place the ctypes binding fails, accessing
|
||||||
|
materials of a model, because Python can't dynamically tell the difference between a pointer and an array. There's probably
|
||||||
|
some way to specify this (e.g. in raylib_modified.h) but it's difficult to be sure we fixed them all, and the errors
|
||||||
|
are often completely silent.
|
||||||
|
"""
|
||||||
|
import pathlib
|
||||||
|
MODULE = pathlib.Path(__file__).parent
|
||||||
|
print(MODULE)
|
||||||
|
|
||||||
|
from raylib.dynamic_binding import ffi, raylib as rl
|
||||||
|
from raylib.colors import *
|
||||||
|
|
||||||
|
rl.InitWindow(800,450,b"foo")
|
||||||
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
camera = ffi.new("struct Camera3D *", [[ 18.0, 16.0, 18.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ])
|
||||||
|
|
||||||
|
imageFile = str(MODULE / "examples/models/resources/heightmap.png").encode('utf-8')
|
||||||
|
image = rl.LoadImage(imageFile) # Load heightmap image (RAM)
|
||||||
|
print(image)
|
||||||
|
texture = rl.LoadTextureFromImage(image) # Convert image to texture (VRAM)
|
||||||
|
|
||||||
|
mesh = rl.GenMeshHeightmap(image, [ 16, 8, 16 ]) # Generate heightmap mesh (RAM and VRAM)
|
||||||
|
|
||||||
|
print(mesh)
|
||||||
|
|
||||||
|
model = rl.LoadModelFromMesh(mesh) # Load model from generated mesh
|
||||||
|
|
||||||
|
print(model.materials) # SHOULD BE A pointer to a 'struct Material' but instead is NULL pointer to 'Material'
|
||||||
|
|
||||||
|
#model.materials[0].maps[rl.MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
||||||
|
mapPosition = ( -8.0, 0.0, -8.0 ) # Define model position
|
||||||
|
|
||||||
|
rl.UnloadImage(image) # Unload heightmap image from RAM, already uploaded to VRAM
|
||||||
|
|
||||||
|
rl.SetCameraMode(camera[0], rl.CAMERA_ORBITAL) # Set an orbital camera mode
|
||||||
|
|
||||||
|
|
||||||
|
while not rl.WindowShouldClose():
|
||||||
|
rl.UpdateCamera(camera)
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(RAYWHITE)
|
||||||
|
rl.BeginMode3D(camera[0])
|
||||||
|
rl.DrawModel(model, mapPosition, 1.0, RED)
|
||||||
|
rl.DrawGrid(20, 1.0)
|
||||||
|
rl.EndMode3D()
|
||||||
|
rl.DrawText(b"sdfsdf", 190, 200, 20, BLACK)
|
||||||
|
rl.EndDrawing()
|
||||||
|
rl.CloseWindow()
|
|
@ -4,17 +4,20 @@ from raylib import *
|
||||||
InitWindow(800,450,b"foo")
|
InitWindow(800,450,b"foo")
|
||||||
SetTargetFPS(60)
|
SetTargetFPS(60)
|
||||||
|
|
||||||
|
print(Vector3(1,1,1))
|
||||||
|
|
||||||
camera = ffi.new("struct Camera3D *", [[ 18.0, 16.0, 18.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ])
|
camera = ffi.new("struct Camera3D *", [[ 18.0, 16.0, 18.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0 ], 45.0, 0 ])
|
||||||
|
|
||||||
|
|
||||||
image = LoadImage(b"resources/heightmap.png") # Load heightmap image (RAM)
|
image = LoadImage(b"examples/models/resources/heightmap.png") # Load heightmap image (RAM)
|
||||||
texture = LoadTextureFromImage(image) # Convert image to texture (VRAM)
|
texture = LoadTextureFromImage(image) # Convert image to texture (VRAM)
|
||||||
|
|
||||||
mesh = GenMeshHeightmap(image, ( 16, 8, 16 )) # Generate heightmap mesh (RAM and VRAM)
|
mesh = GenMeshHeightmap(image, ( 16, 8, 16 )) # Generate heightmap mesh (RAM and VRAM)
|
||||||
|
print(mesh)
|
||||||
model = LoadModelFromMesh(mesh) # Load model from generated mesh
|
model = LoadModelFromMesh(mesh) # Load model from generated mesh
|
||||||
|
|
||||||
|
print(model.materials)
|
||||||
|
|
||||||
model.materials[0].maps[MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
model.materials[0].maps[MAP_DIFFUSE].texture = texture # Set map diffuse texture
|
||||||
mapPosition = ( -8.0, 0.0, -8.0 ) # Define model position
|
mapPosition = ( -8.0, 0.0, -8.0 ) # Define model position
|
||||||
|
|
Reference in a new issue