nonworking dynamic bindings

This commit is contained in:
Richard Smith 2019-05-21 17:51:54 +01:00
parent 2335c5275f
commit 790ff3fcf6
8 changed files with 119 additions and 31 deletions

View file

@ -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.

View file

@ -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
View 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 )

View 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")

Binary file not shown.

5
raylib/helpers.py Normal file
View 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
View 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()

View file

@ -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