diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..498dbb3 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,157 @@ +# download at https://api.cirrus-ci.com/v1/artifact/github/electronstudio/raylib-python-cffi/pi/binary.zip +# https://api.cirrus-ci.com/v1/artifact/github/electronstudio/raylib-python-cffi/mac/binary.zip + +pi_task: + arm_container: + matrix: + - image: dtcooper/raspberrypi-os:python3.12-bullseye + - image: dtcooper/raspberrypi-os:python3.11-bullseye + - image: dtcooper/raspberrypi-os:python3.10-bullseye + - image: dtcooper/raspberrypi-os:python3.9-bullseye + env: + matrix: + - RAYLIB_PLATFORM: "Desktop" + RAYLIB_OPENGL: "2.1" + - RAYLIB_PLATFORM: "SDL" + RAYLIB_OPENGL: "2.1" + - RAYLIB_PLATFORM: "DRM" + RAYLIB_OPENGL: "ES 2.0" + setup_script: + - apt update + - apt -y install cmake libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev libwayland-dev libxkbcommon-dev libgbm-dev libdrm-dev + build_sdl_script: + - wget https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.30.7.tar.gz + - tar xvfz release-2.30.7.tar.gz + - mkdir buildsdl + - cd buildsdl + - cmake ../SDL-release-2.30.7 -DSDL_SHARED=OFF -DSDL_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release + - cmake --build . --config Release + - cmake --install . + - cd .. + build_raylib_script: + - git submodule update --init --recursive + - cd raylib-c + - mkdir build + - cd build + - cmake -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + - make -j2 + - make install + build_raylib_again_script: + - cd raylib-c + - mkdir build2 + - cd build2 + - cmake -DPLATFORM=${RAYLIB_PLATFORM} -DOPENGL_VERSION="${RAYLIB_OPENGL}" -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + - make -j2 + - cp raylib/libraylib.a /usr/local/lib/libraylib.a + build_script: + - cp -r raylib-c/src/external/glfw/include/GLFW /usr/local/include/ + - cp physac/src/physac.h /usr/local/include/ + - cp raygui/src/raygui.h /usr/local/include/ + - python -m pip install --break-system-packages --upgrade pip + - python -m pip install --break-system-packages cffi + - python -m pip install --break-system-packages setuptools + - python -m pip install --break-system-packages wheel + - python setup.py bdist_wheel --plat-name manylinux2014_aarch64 + test_script: + - python -m pip install --break-system-packages dist/*.whl + - cd / + - python -c 'import pyray; pyray.init_window(100,100,"test")' >/tmp/output 2>&1 || true + - cat /tmp/output + - if grep -q "INFO: Initializing raylib" /tmp/output; then + - echo "Passed" + - exit 0 + - else + - echo "Failed" + - exit 1 + - fi + artifacts: + path: "dist/*" + +mac_task: + macos_instance: + matrix: + - image: ghcr.io/cirruslabs/macos-sonoma-xcode:latest + env: + MACOSX_DEPLOYMENT_TARGET: "11.0" + matrix: + - env: + PY_VER: "3.9" + RAYLIB_PLATFORM: Desktop + - env: + PY_VER: "3.9" + RAYLIB_PLATFORM: SDL + - env: + PY_VER: "3.10" + RAYLIB_PLATFORM: Desktop + - env: + PY_VER: "3.10" + RAYLIB_PLATFORM: SDL + - env: + PY_VER: "3.11" + RAYLIB_PLATFORM: Desktop + - env: + PY_VER: "3.11" + RAYLIB_PLATFORM: SDL + - env: + PY_VER: "3.12" + RAYLIB_PLATFORM: Desktop + - env: + PY_VER: "3.12" + RAYLIB_PLATFORM: SDL + - env: + PY_VER: "3.13" + RAYLIB_PLATFORM: Desktop + - env: + PY_VER: "3.13" + RAYLIB_PLATFORM: SDL + + + setup_script: + - brew update + - brew install python@${PY_VER} + build_sdl_script: + - wget https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.30.7.tar.gz + - tar xvfz release-2.30.7.tar.gz + - mkdir buildsdl + - cd buildsdl + - cmake ../SDL-release-2.30.7 -DSDL_SHARED=OFF -DSDL_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release + - cmake --build . --config Release + - sudo cmake --install . + - cd .. + build_raylib_script: + - git submodule update --init --recursive + - cd raylib-c + - mkdir build + - cd build + - cmake -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + - make -j8 + - sudo make install + build_raylib_again_script: + - cd raylib-c + - mkdir build2 + - cd build2 + - cmake -DPLATFORM=${RAYLIB_PLATFORM} -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + - make -j8 + - sudo cp raylib/libraylib.a /usr/local/lib/libraylib.a + build_script: + - sudo cp -r raylib-c/src/external/glfw/include/GLFW /usr/local/include/ + - sudo cp physac/src/physac.h /usr/local/include/ + - sudo cp raygui/src/raygui.h /usr/local/include/ + - /opt/homebrew/bin/python${PY_VER} -m pip install --break-system-packages cffi + - /opt/homebrew/bin/python${PY_VER} -m pip install --break-system-packages setuptools + - /opt/homebrew/bin/python${PY_VER} -m pip install --break-system-packages wheel + - /opt/homebrew/bin/python${PY_VER} setup.py bdist_wheel + test_script: + - /opt/homebrew/bin/python${PY_VER} -m pip install --break-system-packages dist/*.whl + - cd / + - /opt/homebrew/bin/python${PY_VER} -c 'import pyray; pyray.init_window(100,100,"test")' >/tmp/output 2>&1 || true + - cat /tmp/output + - if grep -q "INFO: Initializing raylib" /tmp/output; then + - echo "Passed" + - exit 0 + - else + - echo "Failed" + - exit 1 + - fi + artifacts: + path: "dist/*" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b162258..2a3c7f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,30 +4,39 @@ name: Build on: # Triggers the workflow on push or pull request events but only for the master branch push: - branches: [ master ] pull_request: - branches: [ master ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: - build-mac: - runs-on: macos-11 + build-mac-intel: + runs-on: macos-13 strategy: matrix: - python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10.0-rc.2' ] + python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.9', 'pypy-3.10', 'pypy-3.11' ] + raylib-platform: ['Desktop', 'SDL'] env: - MACOSX_DEPLOYMENT_TARGET: 10.14 + MACOSX_DEPLOYMENT_TARGET: '10.13' steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive + - name: Build SDL + run: | + wget https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.30.7.tar.gz + tar xvfz release-2.30.7.tar.gz + mkdir build + cd build + cmake ../SDL-release-2.30.7 -DSDL_SHARED=OFF -DSDL_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release + cmake --build . --config Release + sudo cmake --install . + - name: Setup Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version }} @@ -35,72 +44,226 @@ jobs: architecture: x64 # Runs a set of commands using the runners shell - - name: Build raylib + - name: Build raylib without SDL because SDL version has incorrect pkg-config run: | cd raylib-c - cd src + mkdir build + cd build + cmake -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. make -j2 - sudo cp libraylib.a /usr/local/lib/libraylib.a + sudo make install + + - name: Build raylib with SDL if selected + run: | + cd raylib-c + mkdir build2 + cd build2 + cmake -DPLATFORM=${{ matrix.raylib-platform }} -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + make -j2 + sudo cp raylib/libraylib.a /usr/local/lib/libraylib.a + + - name: Copy extras + run: | + sudo cp -r raylib-c/src/external/glfw/include/GLFW /usr/local/include/ + sudo cp physac/src/physac.h /usr/local/include/ + sudo cp raygui/src/raygui.h /usr/local/include/ + - name: Build raylib-python-cffi + env: + RAYLIB_PLATFORM: ${{ matrix.raylib-platform }} run: | python -m pip install --upgrade pip - pip3 install cffi + pip3 install "cffi>=1.17.1" pip3 install wheel - python setup.py bdist_wheel + pip3 install setuptools + python setup.py bdist_wheel --plat-name macosx_10_13_x86_64 + + - name: Test + run: | + pip3 install dist/*.whl + cd / + python3 -c 'import pyray; pyray.init_window(100,100,"test")' >/tmp/output 2>&1 || true + cat /tmp/output + if grep -q "INFO: Initializing raylib" /tmp/output; then + echo "Passed" + exit 0 + else + echo "Failed" + exit 1 + fi - name: Upload build Artifact wheel - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4 with: - name: wheel + name: wheel-mac-${{ matrix.raylib-platform }}-${{ matrix.python-version }} path: dist/* +# build-mac-universal: +# runs-on: macos-14 +# strategy: +# matrix: +# python-version: [ '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.8', 'pypy-3.9', 'pypy-3.10' ] +# raylib-platform: ['Desktop', 'SDL'] +# env: +# MACOSX_DEPLOYMENT_TARGET: 11.0 +# steps: +# # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it +# - uses: actions/checkout@v4 +# with: +# submodules: recursive +# +# - name: Build SDL +# run: | +# wget https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.30.7.tar.gz +# tar xvfz release-2.30.7.tar.gz +# mkdir build +# cd build +# cmake ../SDL-release-2.30.7 -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DSDL_SHARED=OFF -DSDL_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release +# cmake --build . --config Release +# sudo cmake --install . +# +# - name: Setup Python +# uses: actions/setup-python@v5 +# with: +# # Version range or exact version of a Python version to use, using SemVer's version range syntax. +# python-version: ${{ matrix.python-version }} +# architecture: arm64 +# +# # Runs a set of commands using the runners shell +# - name: Build raylib without SDL because SDL version has incorrect pkg-config +# run: | +# cd raylib-c +# mkdir build +# cd build +# cmake -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. +# make -j2 +# sudo make install +# +# - name: Build raylib with SDL if selected +# run: | +# cd raylib-c +# mkdir build2 +# cd build2 +# cmake -DPLATFORM=${{ matrix.raylib-platform }} -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DPLATFORM=SDL -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. +# make -j2 +# sudo cp raylib/libraylib.a /usr/local/lib/libraylib.a +# +# - name: Copy extras +# run: | +# sudo cp -r raylib-c/src/external/glfw/include/GLFW /usr/local/include/ +# sudo cp physac/src/physac.h /usr/local/include/ +# sudo cp raygui/src/raygui.h /usr/local/include/ +# +# - name: Build raylib-python-cffi +# run: | +# python -m pip install --upgrade pip +# pip3 install "cffi>=1.17.1" +# pip3 install wheel +# pip3 install setuptools +# RAYLIB_PLATFORM=${{ matrix.raylib-platform }} python setup.py bdist_wheel +# +# - name: Upload build Artifact wheel +# uses: actions/upload-artifact@v3.2.1 +# with: +# name: wheel +# path: dist/* + +# +# # Name defaults to universal2 and it technically is, but we override name to arm64. Why don't we make a working universal2 wheel? Because +# # I'd rather have a separate x86_64 that I can test, and I want it to work on 10_15 but I'm not sure a 'macosx_10_15_universal2' is valid +# # given that there is no SDK for universal until macosx_11_0 +# - name: Build raylib-python-cffi +# run: | +# python -m pip install --upgrade pip +# pip3 install cffi +# pip3 install wheel +# python setup.py bdist_wheel --plat-name macosx_12_0_arm64 + + build-linux: - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 strategy: # You can use PyPy versions in python-version. # For example, pypy2 and pypy3 matrix: - python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10.0-rc.2', 'pypy-3.6', 'pypy-3.7' ] + python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.9', 'pypy-3.10', 'pypy-3.11' ] + raylib-platform: ['Desktop', 'SDL', 'DRM'] steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - name: Setup Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version }} # The target architecture (x86, x64) of the Python interpreter. architecture: x64 + - name: install prereqs + run: | + sudo apt update + sudo apt install libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev libwayland-dev libxkbcommon-dev + - name: Build SDL + run: | + wget https://github.com/libsdl-org/SDL/archive/refs/tags/release-2.30.7.tar.gz + tar xvfz release-2.30.7.tar.gz + mkdir build + cd build + cmake ../SDL-release-2.30.7 -DSDL_SHARED=OFF -DSDL_STATIC=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release + cmake --build . --config Release + sudo cmake --install . + # Runs a set of commands using the runners shell - name: Build raylib run: | - sudo apt update - sudo apt install libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev cd raylib-c mkdir build cd build - cmake -DINCLUDE_EVERYTHING=on -DWITH_PIC=on -DCMAKE_BUILD_TYPE=Release .. + cmake -DPLATFORM=${{ matrix.raylib-platform }} -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release -DOpenGL_GL_PREFERENCE=GLVND .. make -j2 sudo make install + - name: Copy extras + run: | + sudo cp -r raylib-c/src/external/glfw/include/GLFW /usr/local/include/ + sudo cp physac/src/physac.h /usr/local/include/ + sudo cp raygui/src/raygui.h /usr/local/include/ - name: Build raylib-python-cffi + env: + RAYLIB_PLATFORM: ${{ matrix.raylib-platform }} run: | python -m pip install --upgrade pip - pip3 install cffi + pip3 install "cffi>=1.17.1" pip3 install wheel + pip3 install setuptools python setup.py bdist_wheel --plat-name manylinux2014_x86_64 + - name: Test + run: | + pip3 install dist/*.whl + cd / + python3 -c 'import pyray; pyray.init_window(100,100,"test")' >/tmp/output 2>&1 || true + cat /tmp/output + if grep -q "INFO: Initializing raylib" /tmp/output; then + echo "Passed" + exit 0 + else + echo "Failed" + exit 1 + fi + - name: Upload build Artifact wheel - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4 with: - name: wheel + name: wheel-linux-${{ matrix.raylib-platform }}-${{ matrix.python-version }} path: dist/* + + build-windows: # The type of runner that the job will run on runs-on: windows-2019 @@ -108,15 +271,27 @@ jobs: # You can use PyPy versions in python-version. # For example, pypy2 and pypy3 matrix: - python-version: [ '3.6', '3.7', '3.8', '3.9', '3.10.0-rc.2' ] + python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy-3.9', 'pypy-3.10', 'pypy-3.11' ] + raylib-platform: ['Desktop', 'SDL'] steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive + - name: Download SDL2 + run: curl -L -o SDL2.zip https://github.com/libsdl-org/SDL/releases/download/release-2.30.8/SDL2-devel-2.30.8-VC.zip + + - name: Create extraction directory + run: mkdir ${{ runner.temp }}\SDL2 + + - name: Unzip SDL2 + run: tar -xf SDL2.zip -C ${{ runner.temp }}\SDL2 --strip-components=1 + + - name: Set SDL2_DIR environment variable + run: echo SDL2_DIR=${{ runner.temp }}\SDL2\cmake >> $env:GITHUB_ENV + - name: Setup Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version }} @@ -124,94 +299,142 @@ jobs: architecture: x64 - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@v2 - name: Build raylib run: | cd raylib-c mkdir build cd build - cmake -DINCLUDE_EVERYTHING=on -DWITH_PIC=on -DCMAKE_BUILD_TYPE=Release .. + cmake -DPLATFORM=${{ matrix.raylib-platform }} -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. msbuild raylib.sln /target:raylib /property:Configuration=Release copy raylib\Release\raylib.lib ..\.. cd ..\.. shell: cmd - name: Build raylib-python-cffi + env: + RAYLIB_PLATFORM: ${{ matrix.raylib-platform }} run: | + copy ${{ runner.temp }}\SDL2\lib\x64\SDL2.lib . + copy ${{ runner.temp }}\SDL2\lib\x64\SDL2.dll raylib\ python -m pip install --upgrade pip - pip3 install cffi + pip3 install "cffi>=1.17.1" pip3 install wheel + pip3 install setuptools del raylib\dynamic\*.so* >nul 2>&1 del raylib\dynamic\*.dll >nul 2>&1 del raylib\dynamic\*.dylib >nul 2>&1 del raylib\dynamic\32bit\* >nul 2>&1 python setup.py bdist_wheel shell: cmd + + - name: Test + shell: bash + run: | + pip3 install --no-deps dist/*.whl + cd / + python3 -c 'import pyray; pyray.init_window(100,100,"test")' >/tmp/output 2>&1 || true + cat /tmp/output + if grep -q "INFO: Initializing raylib" /tmp/output; then + echo "Passed" + exit 0 + else + echo "Failed" + exit 1 + fi - name: Upload build Artifact wheel - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4 with: - name: wheel + name: wheel-windows-${{ matrix.raylib-platform }}-${{ matrix.python-version }} path: dist/* source-distro: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - name: Setup Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. - python-version: '3.9' + python-version: '3.12' # The target architecture (x86, x64) of the Python interpreter. architecture: x64 + - name: Build raylib + run: | + sudo apt update + sudo apt install libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev libwayland-dev libxkbcommon-dev + cd raylib-c + mkdir build + cd build + cmake -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + make -j2 + sudo make install + - name: Copy extras + run: | + sudo cp -r raylib-c/src/external/glfw/include/GLFW /usr/local/include/ + sudo cp physac/src/physac.h /usr/local/include/ + sudo cp raygui/src/raygui.h /usr/local/include/ + - name: Build raylib-python-cffi run: | python -m pip install --upgrade pip - pip3 install cffi + pip3 install "cffi>=1.17.1" pip3 install wheel + pip3 install setuptools python setup.py sdist - name: Upload build Artifact wheel - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4 with: - name: wheel + name: wheel-source path: dist/* dynamic-distro: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - name: Setup Python - uses: actions/setup-python@v2.2.2 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. - python-version: '3.9' + python-version: '3.12' # The target architecture (x86, x64) of the Python interpreter. architecture: x64 - name: Build raylib-python-cffi-dynamic run: | python -m pip install --upgrade pip - pip3 install cffi + pip3 install "cffi>=1.17.1" pip3 install wheel + pip3 install setuptools cd dynamic python setup.py sdist - name: Upload build Artifact wheel - uses: actions/upload-artifact@v2.2.4 + uses: actions/upload-artifact@v4 + with: + name: wheel-dynamic + path: dynamic/dist/* + + merge: + needs: [build-mac-intel, build-windows, build-linux, source-distro, dynamic-distro] + runs-on: ubuntu-latest + steps: + - name: Merge All Artifacts + uses: actions/upload-artifact/merge@v4 with: name: wheel - path: dynamic/dist/* + pattern: wheel-* diff --git a/.gitignore b/.gitignore index f8d6014..7947899 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ __pycache__/ # Distribution / packaging +docs-src/_build +.idea/ .Python build/ develop-eggs/ diff --git a/.gitmodules b/.gitmodules index 36278dc..f6c3e1d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "raylib-c"] path = raylib-c - url = https://github.com/raysan5/raylib.git + url = https://git.terah.dev/UnrealXR/raylib.git +[submodule "raygui"] + path = raygui + url = https://github.com/raysan5/raygui.git +[submodule "physac"] + path = physac + url = https://github.com/victorfisac/Physac.git diff --git a/BUILDING.rst b/BUILDING.rst index 9c9185d..a32dd6f 100644 --- a/BUILDING.rst +++ b/BUILDING.rst @@ -4,16 +4,32 @@ Building from source Have Pip build from source -------------------------- -Useful if the binaries don’t work on your system. +This is useful if the binaries don’t work on your system, or you want to use a newer version of Raylib. -Make sure Raylib is installed and then: +First make sure Raylib is installed. On Linux/Mac it must include the pkg-config files. Best way to ensure this +is to compile and install Raylib using CMake: https://github.com/raysan5/raylib/wiki/Working-on-GNU-Linux#build-raylib-using-cmake + +Requirements for build: cmake, pkg-config. :: - pip3 install --no-binary raylib --upgrade --force-reinstall raylib + cd raylib-5.0 + mkdir build + cd build + cmake -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + make + sudo make install -Build from source manually --------------------------- + + +Then ask Pip to build from source: + +:: + + pip3 install --no-cache-dir --no-binary raylib --upgrade --force-reinstall raylib + +Or, Build from source manually +------------------------------ Useful if the Pip build doesn’t work and you want to debug it, or you want to contribute to the project. @@ -22,7 +38,7 @@ project. If the Pip build doesn’t work, please submit a bug. (And if you have fixed it, a PR.) -Manual instructions follow, but see also how we actually build the wheels +Manual instructions follow, but are probably outdated, so see instead how we actually build the wheels at https://github.com/electronstudio/raylib-python-cffi/blob/master/.github/workflows/build.yml Windows manual build @@ -56,9 +72,7 @@ Build and install Raylib from the raylib-c directory. copy raylib\Release\raylib.lib ..\.. cd ..\.. -To update the dynamic libs, download the official release, -e.g. https://github.com/raysan5/raylib/releases/download/3.7.0/raylib-3.7.0_win64_msvc16.zip -and extract ``raylib.dll`` into ``dynamic/raylib``. + To build a binary wheel distribution: @@ -69,13 +83,6 @@ To build a binary wheel distribution: pip3 install wheel python setup.py bdist_wheel -Alternatively, if you don’t want the static binaries and just want to -use DLLs with raylib.dynamic: - -:: - - python3 setup_dynamic.py bdist_wheel - Then install it: :: @@ -88,8 +95,6 @@ here.) Linux manual build ~~~~~~~~~~~~~~~~~~~~~~ -These instructions have been tested on Ubuntu 20.10 and 16.04. - Clone this repo including submodules so you get correct version of Raylib. @@ -99,13 +104,17 @@ Raylib. Build and install Raylib from the raylib-c directory. +.. note:: + You can instead use a different version of Raylib you installed from elsewhere, and it should still + work! + :: - sudo apt install cmake libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev + sudo apt install cmake libasound2-dev mesa-common-dev libx11-dev libxrandr-dev libxi-dev xorg-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config cmake cd raylib-python-cffi/raylib-c mkdir build cd build - cmake -DWITH_PIC=on -DCMAKE_BUILD_TYPE=Release .. + cmake -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. sudo make install .. note:: Optional: Build the Raylib shared libs, if you plan to use @@ -123,18 +132,7 @@ Build and install Raylib from the raylib-c directory. cd ../.. -.. note:: Optional: Make a patched version of raylib header. (**Not necessary** if - you’ve already got raylib_modifed.h from repo and haven’t changed - anything.) - - :: - - cd raylib - cp raylib.h raylib_modified.h - patch -p0 `__ -for a Raspberry Pi wheel) diff --git a/MANIFEST.in b/MANIFEST.in index 9446b73..6c6394e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,8 +1,16 @@ include raylib/*.so include raylib/*.pyi +include pyray/*.pyi include raylib/*.pyd +include raylib/*.dll exclude raylib/*.a include raylib/*.h -include raylib/*.pyi +include raylib/*.h.modified exclude raylib/*.c exclude raylib/*.o +include version.py +exclude tests/* +include raylib/py.typed +include pyray/py.typed + + diff --git a/README.md b/README.md index 6bf01f1..64c695b 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,266 @@ -# Python Bindings for Raylib 3.7 +# Python Bindings for Raylib 5.5 +## Libraries: raymath, raygui, rlgl, physac and GLFW +## Backends: Desktop, SDL, DRM, Web +## Platforms: Windows, Mac, Linux, Raspberry Pi, Web + +![PyPI - Downloads](https://img.shields.io/pypi/dm/raylib) + +Chatroom: [Discord](https://discord.gg/fKDwt85aX6) + +HELP WANTED: [writing examples](https://github.com/electronstudio/raylib-python-cffi/issues/155) + +Features: + +* CFFI API static bindings. +* Automatically generated to be as close as possible to +original Raylib. +* Faster, fewer bugs and easier to maintain than ctypes. +* Commercial-friendly license. +* Docstrings and auto-completion. +* Type checking with Mypy -New CFFI API static bindings. Automatically generated to be as close as possible to -original Raylib. Faster, fewer bugs and easier to maintain than ctypes. [Full documentation](http://electronstudio.github.io/raylib-python-cffi) -# License (updated) +# Quickstart -The bindings are now under the Eclipse Public License, so you are free to -statically link and use in non-free / proprietary / commercial projects! +`pip3 install raylib==5.5.0.2 --break-system-packages` +```python +from pyray import * +init_window(800, 450, "Hello") +while not window_should_close(): + begin_drawing() + clear_background(WHITE) + draw_text("Hello world", 190, 200, 20, VIOLET) + end_drawing() +close_window() +``` # Installation - python3 -m pip install raylib +If you are on a modern Linux you will probably want to create a venv: -If it doesn't work, first make sure you have latest pip installed: + python3 -m venv venv + source venv/bin/activate + +Then make sure you have the latest pip installed: python3 -m pip install --upgrade pip -On most platforms it should install a binary wheel (Windows 10 x64, MacOS 10.15 x64, Linux Ubuntu1804 x64). +Then install -If yours isn't available then pip will attempt to build from source, in which case you will need to have Raylib development libs installed, e.g. + python3 -m pip install setuptools + python3 -m pip install raylib==5.5.0.2 + +On most platforms it should install a binary wheel. If yours isn't available then pip will attempt to build from +source, in which case you will need to have Raylib development libs installed, e.g. using homebrew, apt, etc. -[If it doesn't work, you can build manually.](BUILDING.md) +## Windows + +Binaries require x64 Windows 10 or newer. (For x86 or older Windows you will have to build from source.) + +Use an [official Windows Python release](https://www.python.org/downloads/windows/) rather than WSL, MSYS, etc. + +## MacOS + +Binaries require: + * arm64 MacOS 14 + * x64 MacOS 10.13, or newer. + +Older MacOS requires building from source but this is usually simple: + + brew install pkg-config + brew install raylib + python3 -m pip install raylib==5.5.0.2 + +(I do have binaries for arm64 MacOS 11, 12 and 13 but I have no way of testing they work, so post an issue +if you want to test them.) + +## Linux + +Binaries require OS newer than Ubuntu 2020, x64 or arm64. Otherwise build from source. +(Pip should attempt automatically but will need Raylib itself installed and also pkg-config.) + +The arm64 binaries are built on Raspberry Pi arm64 Bullseye with OpenGL 2.0 +so may not work on other boards. + +## Raspberry Pi + +[Using on Rasperry Pi](RPI.rst) + +# Backends ## Dynamic binding version There is now a separate dynamic version of this binding: + python3 -m pip uninstall raylib python3 -m pip install raylib_dynamic -[Read this before using raylib_dynamic](https://electronstudio.github.io/raylib-python-cffi/dynamic.html) +It works on some systems where the static version doesn't, [but be sure to read these caveats before using it](https://electronstudio.github.io/raylib-python-cffi/dynamic.html) + +You can't have multiple raylib packages installed at once. + +## SDL backend + +This is not well tested but has better support for controllers: + + python3 -m pip uninstall raylib + python3 -m pip install raylib_sdl + +You can't have multiple raylib packages installed at once. + +## DRM backend + +This uses the Linux framebuffer for devices that don't run X11/Wayland: + + python3 -m pip uninstall raylib + python3 -m pip install raylib_drm + +You can't have multiple raylib packages installed at once. + +## Problems? + +If it doesn't work, [try to build manually.](BUILDING.rst). If that works then [submit an issue](https://github.com/electronstudio/raylib-python-cffi/issues) +to let us know what you did. + +If you need help you can try asking on [our discord](https://discord.gg/fKDwt85aX6). There is also a large [Raylib discord](https://discord.gg/raylib) +for issues that are not Python-specific. + +If it still doesn't work, [submit an issue](https://github.com/electronstudio/raylib-python-cffi/issues). # How to use -There are two APIs, you can use either or both: +There are *two* modules in the raylib package, `raylib` and `pyray`. (There is no separate package for +pyray. Do *not* `pip install pyray`). You can use either or both: ### If you are familiar with C coding and the Raylib C library and you want to use an exact copy of the C API -Use [the C API](https://electronstudio.github.io/raylib-python-cffi/raylib.html). +Use [the raylib module](https://electronstudio.github.io/raylib-python-cffi/raylib.html). -### If you prefer a slightly more Pythonistic API and don't mind it might be slightly slower +### If you prefer a more Pythonistic API -Use [the Python API](https://electronstudio.github.io/raylib-python-cffi/pyray.html). +Use [the pyray module](https://electronstudio.github.io/raylib-python-cffi/pyray.html). +# Running in a web browser +[Pygbag](https://pypi.org/project/pygbag/) >=0.8.7 supports running in a web browser. Usually the latest git version +is recommended. +Make a folder `my_project` with a file `main.py`: + +```python +# /// script +# dependencies = [ +# "cffi", +# "raylib" +# ] +# /// +import asyncio +import platform +from pyray import * + +async def main(): # You MUST have an async main function + init_window(500, 500, "Hello") + platform.window.window_resize() # You MAY want to add this line + while not window_should_close(): + begin_drawing() + clear_background(WHITE) + draw_text("Hello world", 190, 200, 20, VIOLET) + end_drawing() + await asyncio.sleep(0) # You MUST call this in your main loop + close_window() + +asyncio.run(main()) +``` + +Then to create the web files and launch a web server: + + python3.12 -m pip install --user --upgrade pygbag + python3.12 -m pygbag --PYBUILD 3.12 --ume_block 0 --template noctx.tmpl --git my_project + +Point your browser to http://localhost:8000 + +Some features may not work, so you can disable them like this: + +```python +if platform.system() != "Emscripten": # audio may not work on current version of emscripten + init_audio_device() +``` + +This is all done by Pygbag rather than by me, so you should probably contact them with any issues. +Carefully read all their [documentation](https://pygame-web.github.io/). + +It does work for most of [these examples](https://electronstudio.github.io/raylib-python-cffi-pygbag-examples/) + +# App showcase + +[Tempest-raylib](https://github.com/Emtyloc/tempest-raylib) + +[KarabinerKeyboard](https://github.com/bilbofroggins/KarabinerKeyboard) + +[PyTaiko](https://github.com/Yonokid/PyTaiko) + +[DOOM-Clone](https://github.com/StanislavPetrovV/DOOM-Clone) + +[Tanki](https://github.com/pkulev/tanki) + +[Alloy Bloxel Editor](https://pebaz.itch.io/alloy-bloxel-editor) + +[Eidolon](https://github.com/Miou-zora/Eidolon) + +Add your app here! # RLZero -Work in progress: +A related library (that is a work in progress!): [A simplified API for Raylib for use in education and to enable beginners to create 3d games](https://github.com/electronstudio/rlzero) # Help wanted - * converting more examples from C to python - * testing and building on more platforms + * Converting more examples from C to Python + * Testing on more platforms + +# License + +Eclipse Public License, so you are free to +statically link and use in non-free / proprietary / commercial projects! # Performance -For fastest performance use Pypy rather than standard python. +If you need more performance, do in this order: -Every call to C is costly, so it's slightly faster if you use Python data structures and functions when calculating +1. Use Pypy rather than standard CPython. It is much, much faster and will make more difference than any other optimisations you might do. + +2. Every call to C is costly, so it's slightly faster if you use Python data structures and functions when calculating in your update loop and then only convert them to C data structures when you have to call the C functions for drawing. +3. The raylib.* functions are potentially *slightly* faster than the pyray.* equivalents, so if you need a tiny bit more performance +you can switch your inner loop functions to these. + +4. There is a version of Python that is faster than Pypy: GraalPy. However it's not fully compatible with all Python +packages. It doesn't work with CFFI and so doesn't work with this binding. But it *is* compatible with the +*Java* binding, Jaylib! There is an example of this here: https://github.com/electronstudio/megabunny/tree/master/raylib-python-jaylib + ## Bunnymark -| Library | Implementation | Bunnies (60 FPS) | Percentage | -| ------------- | ------------- | ------------- | ------------- | -| Raylib 3.7 | C | 168100 | 100% | -| Raylib Python CFFI 3.7 | Pypy 3.7 | 33800 | 20% | -| Raylib Python CFFI 3.7 | Python 3.9 | 7700 | 4.5% | -| Raylib Python CFFI 3.7 | Python 3.9 Nuitka | 8600 | 5.1% | -| Raylib Python CFFI 3.7 Dynamic | Python 3.9 | 6300 | 3.7% | +| Library | Implementation | Bunnies (60 FPS) | Percentage | +|--------------------------------|-------------------|------------------|------------| +| Raylib 5.0 | C | 180000 | 100% | +| Raylib Python CFFI 5.0.0.2 | Python 3.12 | 10500 | 5.8% | +| Raylib Python CFFI 5.0.0.2 | Pypy 3.10 | 95000 | 53% | +| Raylib 3.7 | C | 168100 | 100% | +| Raylib Python CFFI 3.7 | Pypy 3.7 | 33800 | 20% | +| Raylib Python CFFI 3.7 | Python 3.9 | 7700 | 4.5% | +| Raylib Python CFFI 3.7 | Python 3.9 Nuitka | 8600 | 5.1% | +| Raylib Python CFFI 3.7 Dynamic | Python 3.9 | 6300 | 3.7% | + +See also https://github.com/electronstudio/megabunny/ # Packaging your app @@ -92,4 +275,4 @@ You can create a standalone binary using the Nuitka compiler. For example, here [RetroWar: 8-bit Party Battle](https://store.steampowered.com/app/664240/RetroWar_8bit_Party_Battle/?git) is out now. Defeat up to 15 of your friends in a tournament of 80s-inspired retro mini games. [Coding Games With Pygame Zero & Python](https://github.com/electronstudio/pygame-zero-book) is -a book for Python beginners. \ No newline at end of file +a book for Python beginners. diff --git a/RPI.rst b/RPI.rst new file mode 100644 index 0000000..a5c62e3 --- /dev/null +++ b/RPI.rst @@ -0,0 +1,97 @@ +Raspberry Pi +==================== + +Please use Raspberry Pi OS Bookworm. Bullseye should also work. Older OSes are not tested. + +Option 1: Binary wheel +---------------------- + +We have published binary wheels compiled for 64-bit Raspberry OS Bullseye in X11 mode. + +:: + + python -m pip install --break-system-packages raylib + +Alternatively there is a DRM wheel called ``raylib_drm`` to use the framebuffer without X11. You can't have both wheels +installed at once. + +If it doesn't work, or you're not on Bullseye, or you're 32 bit, you will need to compile your own raylib. See below. +For full instructions on this, see https://github.com/raysan5/raylib/wiki/Working-on-Raspberry-Pi . If you need help with this ask Raylib. + +Option 2: Compile Raylib from source X11 mode +--------------------------------------------- + +This should work for everyone. + +:: + + sudo apt update + sudo apt install python3-pip cmake libegl1-mesa-dev libgbm-dev libgles2-mesa-dev libdrm-dev libglfw3-dev + git clone https://github.com/raysan5/raylib.git --branch 5.0 --single-branch + cd raylib + mkdir build + rm -rf build/* + cd build + cmake -DPLATFORM="Desktop" -DOPENGL_VERSION=2.1 -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DWITH_PIC=ON -DCMAKE_BUILD_TYPE=Release .. + make + sudo make install + sudo cp -r ../src/external/glfw/include/GLFW /usr/local/include/ + +Then have pip compile and install the wheel: + +:: + + python3 -m pip install --break-system-packages setuptools + python3 -m pip install --no-cache-dir --no-binary raylib --upgrade --force-reinstall --break-system-packages raylib==5.5.0.0 + +Option 3: Compile Raylib from source DRM mode +--------------------------------------------- + +This seems to work on Raspberry Pi 4. Note you must not be running X11 when you run your programs. + +If you have ever installed Raylib or raylib-python-cffi before, remove all traces of it: + +:: + + sudo apt remove raylib raylib-dev libraylib libraylib-dev + sudo rm /usr/local/lib/pkgconfig/raylib.pc + sudo rm -rf /usr/local/lib/libraylib.* /usr/lib/libraylib.* + +Remove all GLFW: + +:: + + sudo apt remove libglfw3-dev libglfw3 + sudo rm -rf /usr/local/include/GLFW + +Build a shared lib version of Raylib in DRM mode and install to /usr: + +:: + + sudo apt update + sudo apt install python3-pip cmake libegl1-mesa-dev libgbm-dev libgles2-mesa-dev libdrm-dev + git clone https://github.com/raysan5/raylib.git --branch 5.0 --single-branch + cd raylib + mkdir build + rm rf build/* + cd build + cmake -DPLATFORM="DRM" -DBUILD_EXAMPLES=OFF -DCUSTOMIZE_BUILD=ON -DSUPPORT_FILEFORMAT_JPG=ON -DSUPPORT_FILEFORMAT_FLAC=ON -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=/usr .. + make + sudo make install + + +Then have pip compile and install the wheel: + +:: + + python3 -m pip install --break-system-packages setuptools + python3 -m pip install --no-cache-dir --no-binary raylib --upgrade --force-reinstall --break-system-packages raylib==5.5.0.0 + + + + +.. attention:: + + If you intend to use the Broadcom proprietary Open GL ES 2.0 drivers (the ones installed by Raspbian into ``/opt/vc`` and compiled in Raylib + with ``PLATFORM_RPI``) be aware they not work with Bullseye and have not been tested with the bindings. They will probably + require additional linker arguments to be added to ``build.py``. Suggest you try ``PLATFORM_DRM`` instead. diff --git a/create_define_consts.py b/create_define_consts.py new file mode 100644 index 0000000..6817e4c --- /dev/null +++ b/create_define_consts.py @@ -0,0 +1,105 @@ +# Copyright (c) 2021 Richard Smith and others +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0. +# +# This Source Code may also be made available under the following Secondary +# licenses when the conditions for such availability set forth in the Eclipse +# Public License, v. 2.0 are satisfied: GNU General Public License, version 2 +# with the GNU Classpath Exception which is +# available at https://www.gnu.org/software/classpath/license.html. +# +# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + +from raylib import rl, ffi + +from inspect import ismethod, getmembers, isbuiltin +import inflection, sys, json, re + +two_or = re.compile(r'''\(\s*([^\s]*)\s*\|\s*([^\s]*)\s*\)''') +three_or = re.compile(r'''\(\s*([^\s]*)\s*\|\s*([^\s]*)\s*\|\s*(^\s*)\s*\)''') +two_mult = re.compile(r'''\(\s*([^\s]*)\s*\*\s*([^\s]*)\s*\)''') +two_div = re.compile(r'''\(\s*([^\s]*)\s*/\s*([^\s]*)\s*\)''') + +def process(filename): + f = open(filename, "r") + js = json.load(f) + known_define = [] + known_enum = [] + for e in js['enums']: + if e['name'] and e['values']: + for v in e['values']: + if v['name']: + known_enum.append(str(v['name']).strip()) + for e in js['defines']: + if e['type'] in ('INT', 'FLOAT', 'STRING'): + if e['type'] == 'INT': + print(e['name'] + ": int = " + str(e['value']).strip()) + elif e['type'] == 'FLOAT': + print(e['name'] + ": float = " + str(e['value']).strip()) + else: + print(e['name'] + ": str = \"" + str(e['value']).strip() + '"') + known_define.append(str(e['name']).strip()) + elif e['type'] == "UNKNOWN": + strval = str(e['value']).strip() + if strval.startswith("__"): + continue + if strval in known_enum: + print(e['name'] + " = raylib." + strval) + elif strval in known_define: + print(e['name'] + " = " + strval) + else: + matches = two_or.match(strval) + if not matches: + matches = three_or.match(strval) + if matches: + match_defs = [str(m).strip() for m in matches.groups()] + if all(d in known_enum for d in match_defs): + print(e['name'] + " = " + " | ".join(("raylib."+m) for m in match_defs)) + elif all(d in known_define for d in match_defs): + print(e['name'] + " = " + " | ".join(match_defs)) + else: + continue + known_define.append(str(e['name']).strip()) + elif e['type'] == "FLOAT_MATH": + strval = str(e['value']).strip() + matches = two_mult.match(strval) + if matches: + match_defs = [str(m).strip() for m in matches.groups()] + match_parts = [] + for m in match_defs: + if "." in m: + match_parts.append(m.rstrip("f")) + else: + match_parts.append(m) + if all(d in known_enum for d in match_parts): + print(e['name'] + " = " + " * ".join(("raylib." + m) for m in match_parts)) + elif all(d in known_define for d in match_parts): + print(e['name'] + " = " + " * ".join(match_parts)) + else: + matches = two_div.match(strval) + if matches: + match_defs = [str(m).strip() for m in matches.groups()] + match_parts = [] + for m in match_defs: + if "." in m: + match_parts.append(m.rstrip("f")) + else: + match_parts.append(m) + if any(d in known_enum for d in match_parts): + print(e['name'] + " = " + " / ".join(("raylib." + m) for m in match_parts)) + elif any(d in known_define for d in match_parts): + print(e['name'] + " = " + " / ".join(match_parts)) + else: + continue + +print("import raylib\n") + +process("raylib.json") +process("raymath.json") +process("rlgl.json") +process("raygui.json") +process("physac.json") +process("glfw3.json") + diff --git a/create_enums.py b/create_enums.py new file mode 100644 index 0000000..d7fbeec --- /dev/null +++ b/create_enums.py @@ -0,0 +1,38 @@ +# Copyright (c) 2021 Richard Smith and others +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0. +# +# This Source Code may also be made available under the following Secondary +# licenses when the conditions for such availability set forth in the Eclipse +# Public License, v. 2.0 are satisfied: GNU General Public License, version 2 +# with the GNU Classpath Exception which is +# available at https://www.gnu.org/software/classpath/license.html. +# +# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + +from raylib import rl, ffi + +from inspect import ismethod, getmembers, isbuiltin +import inflection, sys, json + +def process(filename): + f = open(filename, "r") + js = json.load(f) + + for e in js['enums']: + if e['name'] and e['values']: + print ("class "+e['name']+"("+"IntEnum):") + print(f' """{e['description']}."""') + for value in e['values']: + print(" "+value['name']+" = "+str(value['value'])) + print("") + +print("""from enum import IntEnum +""") + +process("raylib.json") +process("raygui.json") +process("glfw3.json") +process("physac.json") diff --git a/create_stub_pyray.py b/create_stub_pyray.py index 61dc6b3..fb334e7 100644 --- a/create_stub_pyray.py +++ b/create_stub_pyray.py @@ -12,13 +12,32 @@ # # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 +from pathlib import Path from raylib import rl, ffi - +from pyray import _underscore from inspect import ismethod, getmembers, isbuiltin import inflection, sys, json -f = open("raylib_api.json", "r") -js = json.load(f) +known_functions = {} +known_structs = {} +for filename in (Path("raylib.json"), Path("raymath.json"), Path("rlgl.json"), Path("raygui.json"), Path("physac.json"), + Path("glfw3.json")): + f = open(filename, "r") + js = json.load(f) + for fn in js["functions"]: + if fn["name"] not in known_functions: + known_functions[fn["name"]] = fn + for st in js["structs"]: + if st["name"] not in known_structs: + known_structs[st["name"]] = st + for e in js['enums']: + if e['name'] and e['values']: + print("class "+e['name']+"(int):") + print(f' """{e['description']}."""') + for value in e['values']: + print(" "+value['name']+" = "+str(value['value'])) + print("") + def ctype_to_python_type(t): if t == '_Bool': @@ -27,49 +46,72 @@ def ctype_to_python_type(t): return 'None' elif t == "long": return "int" + elif t == "unsigned long long": + return "int" + elif t == "uint64_t": + return "int" + elif t == "short": + return "int" + elif t == "unsigned short": + return "int" elif t == "double": return "float" + elif "char * *" in t: + return "list[str]" elif "char *" in t: return "str" - elif "char" in t: + elif t == "char": return "str" # not sure about this one + elif t == "unsigned char": + return "int" elif "*" in t: return "Any" + elif "[" in t: + return "list" # TODO FIXME type of items in the list elif t.startswith("struct"): - return t.replace("struct ","") + return t.replace("struct ", "") elif t.startswith("unsigned"): return t.replace("unsigned ", "") + elif t.startswith("enum"): + return t.replace("enum ", "") else: return t -print("""from typing import Any -class PyRay: - def pointer(self, struct): - return ffi.addressof(struct) +print("""from typing import Any +from warnings import deprecated +import _cffi_backend # type: ignore + +ffi: _cffi_backend.FFI +PhysicsShapeType = int """) - - +# These words can be used for c arg names, but not in python +reserved_words = ("in", "list", "tuple", "set", "dict", "from", "range", "min", "max", "any", "all", "len") for name, attr in getmembers(rl): - uname = inflection.underscore(name).replace('3_d', '_3d').replace('2_d', '_2d') + uname = _underscore(name) if isbuiltin(attr) or str(type(attr)) == "": - json_array = [x for x in js['functions'] if x['name'] == name] - json_object = {} - if len(json_array) > 0: - json_object = json_array[0] + json_object = known_functions.get(name, None) + if json_object is None: + # this is _not_ an exported function from raylib, raymath, rlgl raygui or physac + # so we don't want it in the pyray API + continue sig = "" for i, arg in enumerate(ffi.typeof(attr).args): param_name = arg.cname.replace("struct", "").replace("char *", "str").replace("*", "_pointer").replace( - " ", "")+"_"+str(i) + " ", "") + "_" + str(i) if 'params' in json_object: p = json_object['params'] - param_name = list(p)[i] - + param_name = list(p)[i]['name'] + # don't use a python reserved word: + if param_name in reserved_words: + param_name = param_name + "_" + str(i) param_type = ctype_to_python_type(arg.cname) - sig += f", {param_name}: {param_type}" + if "struct" in arg.cname: + param_type += "|list|tuple" + sig += f"{param_name}: {param_type}," return_type = ffi.typeof(attr).result.cname @@ -78,40 +120,77 @@ for name, attr in getmembers(rl): if 'description' in json_object: description = json_object['description'] - print( - f' def {uname}(self{sig}) -> {ctype_to_python_type(return_type)}:\n """{description}"""\n ...') + if 'physics' in uname: + print('@deprecated("Raylib no longer recommends the use of Physac library")') + print(f'def {uname}({sig}) -> {ctype_to_python_type(return_type)}:') + print(f' """{description}."""') + print(f' ...') elif str(type(attr)) == "": return_type = ffi.typeof(attr).result.cname print( - f' def {uname}(self, *args) -> {ctype_to_python_type(return_type)}:\n """VARARG FUNCTION - MAY NOT BE SUPPORTED BY CFFI"""\n ...') + f'def {uname}(*args) -> {ctype_to_python_type(return_type)}:\n """VARARG FUNCTION - MAY NOT BE SUPPORTED BY CFFI"""\n ...') else: - #print("*****", str(type(attr))) - print(f" {name}: {str(type(attr))[8:-2]}") # this isolates the type + # print("*****", str(type(attr))) + t = str(type(attr))[8:-2] # this isolates the type + if t != "int": + print(f"{name}: {t}") for struct in ffi.list_types()[0]: print("processing", struct, file=sys.stderr) - # json_array = [x for x in js['structs'] if x['name'] == name] - # json_object = {} - # if len(json_array) > 0: - # json_object = json_array[0] + if ffi.typeof(struct).kind == "struct": + json_object = known_structs.get(struct, None) + if json_object is None: + # this is _not_ an exported struct from raylib, raymath, rlgl raygui or physac + # so we don't want it in the pyray API + continue if ffi.typeof(struct).fields is None: - print("weird empty struct, skipping", file=sys.stderr) - break - print(f" class {struct}:") - print(f' """ comment """') + print("weird empty struct, skipping " + struct, file=sys.stderr) + continue + print(f"class {struct}:") + print(f' """{known_structs[struct]['description']}."""') sig = "" for arg in ffi.typeof(struct).fields: - sig += ", " + arg[0] - print(f" def __init__(self{sig}):") + ptype = ctype_to_python_type(arg[1].type.cname) + if arg[1].type.kind == "struct": + ptype += "|list|tuple" + sig += f", {arg[0]}: {ptype}|None = None" + print(f" def __init__(self{sig}):") for arg in ffi.typeof(struct).fields: - print(f" self.{arg[0]}={arg[0]}") + print(f" self.{arg[0]}:{ctype_to_python_type(arg[1].type.cname)} = {arg[0]} # type: ignore") - elif ffi.typeof(struct).kind == "enum": - print(f" {struct}: int") + # elif ffi.typeof(struct).kind == "enum": + # print(f"{struct}: int") else: - print("ERROR UNKNOWN TYPE", ffi.typeof(struct), file=sys.stderr) - + print("WARNING: SKIPPING UNKNOWN TYPE", ffi.typeof(struct), file=sys.stderr) +print(""" +LIGHTGRAY : Color +GRAY : Color +DARKGRAY : Color +YELLOW : Color +GOLD : Color +ORANGE : Color +PINK : Color +RED : Color +MAROON : Color +GREEN : Color +LIME : Color +DARKGREEN : Color +SKYBLUE : Color +BLUE : Color +DARKBLUE : Color +PURPLE : Color +VIOLET : Color +DARKPURPLE : Color +BEIGE : Color +BROWN : Color +DARKBROWN : Color +WHITE : Color +BLACK : Color +BLANK : Color +MAGENTA : Color +RAYWHITE : Color +""") diff --git a/create_stub_static.py b/create_stub_static.py index 26631ec..0c43c6d 100644 --- a/create_stub_static.py +++ b/create_stub_static.py @@ -12,15 +12,23 @@ # # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 +from pathlib import Path from raylib import rl, ffi - from inspect import ismethod, getmembers, isbuiltin import inflection, sys, json -f = open("raylib_api.json", "r") -js = json.load(f) - - +known_functions = {} +known_structs = {} +for filename in (Path("raylib.json"), Path("raymath.json"), Path("rlgl.json"), Path("raygui.json"), Path("physac.json"), + Path("glfw3.json")): + f = open(filename, "r") + js = json.load(f) + for fn in js["functions"]: + if fn["name"] not in known_functions: + known_functions[fn["name"]] = fn + for st in js["structs"]: + if st["name"] not in known_structs: + known_structs[st["name"]] = st def ctype_to_python_type(t): @@ -30,44 +38,75 @@ def ctype_to_python_type(t): return 'None' elif t == "long": return "int" + elif t == "unsigned long long": + return "int" + elif t == "uint64_t": + return "int" + elif t == "short": + return "int" + elif t == "unsigned short": + return "int" elif t == "double": return "float" + elif "char * *" in t: + return "list[bytes]" elif "char *" in t: - return "str" + return "bytes" elif "char" in t: - return "str" # not sure about this one + return "bytes" # not sure about this one elif "*" in t: return "Any" + elif "[" in t: + return "list" # TODO FIXME type of items in the list elif t.startswith("struct"): - return t.replace("struct ","") + return t.replace("struct ", "") elif t.startswith("unsigned"): return t.replace("unsigned ", "") + elif t.startswith("enum"): + return t.replace("enum ", "") else: return t print("""from typing import Any +from warnings import deprecated +import _cffi_backend # type: ignore + +ffi: _cffi_backend.FFI +rl: _cffi_backend.Lib +PhysicsShapeType = int class struct: ... """) +# These words can be used for c arg names, but not in python +reserved_words = ("in", "list", "tuple", "set", "dict", "from", "range", "min", "max", "any", "all", "len") + for name, attr in getmembers(rl): uname = name if isbuiltin(attr) or str(type(attr)) == "": - json_array = [x for x in js['functions'] if x['name'] == name] - json_object = {} - if len(json_array) > 0: - json_object = json_array[0] + json_object = known_functions.get(name, {}) sig = "" for i, arg in enumerate(ffi.typeof(attr).args): - param_name = arg.cname.replace("struct", "").replace("char *", "str").replace("*", - "_pointer").replace( - " ", "")+"_"+str(i) + if ")(" in arg.cname: + # fn signature in arg types + param_name = str(arg.cname).split("(", 1)[0] + "_callback_" + str(i) + else: + param_name = arg.cname.replace("struct", "").replace("char *", "str").replace("*", + "_pointer").replace(" ", + "") + "_" + str( + i) if 'params' in json_object: p = json_object['params'] - param_name = list(p)[i] + # print("param_name: ", param_name, "i", i, "params: ",p,file=sys.stderr) + param_name = list(p)[i]['name'] + # don't use a python reserved word: + if param_name in reserved_words: + param_name = param_name + "_" + str(i) param_type = ctype_to_python_type(arg.cname) + if "struct" in arg.cname: + param_type += "|list|tuple" sig += f"{param_name}: {param_type}," return_type = ffi.typeof(attr).result.cname @@ -76,15 +115,19 @@ for name, attr in getmembers(rl): if 'description' in json_object: description = json_object['description'] - print( - f'def {uname}({sig}) -> {ctype_to_python_type(return_type)}:\n """{description}"""\n ...') + if 'Physics' in uname: + print('@deprecated("Raylib no longer recommends the use of Physac library")') + print(f'def {uname}({sig}) -> {ctype_to_python_type(return_type)}:') + print(f' """{description}."""') + print(f' ...') + elif str(type(attr)) == "": return_type = ffi.typeof(attr).result.cname print( f'def {uname}(*args) -> {ctype_to_python_type(return_type)}:\n """VARARG FUNCTION - MAY NOT BE SUPPORTED BY CFFI"""\n ...') else: - #print("*****", str(type(attr))) + # print("*****", str(type(attr))) print(f"{name}: {str(type(attr))[8:-2]}") # this isolates the type for struct in ffi.list_types()[0]: @@ -92,19 +135,52 @@ for struct in ffi.list_types()[0]: if ffi.typeof(struct).kind == "struct": # if ffi.typeof(struct).fields is None: # print("weird empty struct, skipping", file=sys.stderr) - # break - print(f"{struct}: struct") + # continue + print(f"class {struct}:") # sig = "" - # for arg in ffi.typeof(struct).fields: - # sig += ", " + arg[0] + fields = ffi.typeof(struct).fields + if fields is not None: + #print(ffi.typeof(struct).fields) + #print(f" {arg}: {arg}") # print(f" def __init__(self{sig}):") # - # for arg in ffi.typeof(struct).fields: + for arg in ffi.typeof(struct).fields: + print(f" {arg[0]}: {ctype_to_python_type(arg[1].type.cname)}") + else: + print(" ...") # print(f" self.{arg[0]}={arg[0]}") elif ffi.typeof(struct).kind == "enum": - print(f"{struct}: int") + print(f"{struct} = int") else: - print("ERROR UNKNOWN TYPE", ffi.typeof(struct), file=sys.stderr) + print("WARNING: SKIPPING UNKNOWN TYPE", ffi.typeof(struct), file=sys.stderr) +print(""" +LIGHTGRAY : Color +GRAY : Color +DARKGRAY : Color +YELLOW : Color +GOLD : Color +ORANGE : Color +PINK : Color +RED : Color +MAROON : Color +GREEN : Color +LIME : Color +DARKGREEN : Color +SKYBLUE : Color +BLUE : Color +DARKBLUE : Color +PURPLE : Color +VIOLET : Color +DARKPURPLE : Color +BEIGE : Color +BROWN : Color +DARKBROWN : Color +WHITE : Color +BLACK : Color +BLANK : Color +MAGENTA : Color +RAYWHITE : Color +""") diff --git a/docs-src/RPI.rst b/docs-src/RPI.rst new file mode 120000 index 0000000..60349ff --- /dev/null +++ b/docs-src/RPI.rst @@ -0,0 +1 @@ +../RPI.rst \ No newline at end of file diff --git a/docs-src/_build/doctrees/BUILDING.doctree b/docs-src/_build/doctrees/BUILDING.doctree deleted file mode 100644 index 5367a9f..0000000 Binary files a/docs-src/_build/doctrees/BUILDING.doctree and /dev/null differ diff --git a/docs-src/_build/doctrees/README.doctree b/docs-src/_build/doctrees/README.doctree deleted file mode 100644 index 1acdc8b..0000000 Binary files a/docs-src/_build/doctrees/README.doctree and /dev/null differ diff --git a/docs-src/_build/doctrees/dynamic.doctree b/docs-src/_build/doctrees/dynamic.doctree deleted file mode 100644 index c748669..0000000 Binary files a/docs-src/_build/doctrees/dynamic.doctree and /dev/null differ diff --git a/docs-src/_build/doctrees/environment.pickle b/docs-src/_build/doctrees/environment.pickle deleted file mode 100644 index cf901f3..0000000 Binary files a/docs-src/_build/doctrees/environment.pickle and /dev/null differ diff --git a/docs-src/_build/doctrees/generated/raylib.pyray.PyRay.doctree b/docs-src/_build/doctrees/generated/raylib.pyray.PyRay.doctree deleted file mode 100644 index 1746b95..0000000 Binary files a/docs-src/_build/doctrees/generated/raylib.pyray.PyRay.doctree and /dev/null differ diff --git a/docs-src/_build/doctrees/index.doctree b/docs-src/_build/doctrees/index.doctree deleted file mode 100644 index 3a51c5a..0000000 Binary files a/docs-src/_build/doctrees/index.doctree and /dev/null differ diff --git a/docs-src/_build/doctrees/pyray.doctree b/docs-src/_build/doctrees/pyray.doctree deleted file mode 100644 index 9687740..0000000 Binary files a/docs-src/_build/doctrees/pyray.doctree and /dev/null differ diff --git a/docs-src/_build/doctrees/raylib.doctree b/docs-src/_build/doctrees/raylib.doctree deleted file mode 100644 index dd53d02..0000000 Binary files a/docs-src/_build/doctrees/raylib.doctree and /dev/null differ diff --git a/docs-src/_build/html/.buildinfo b/docs-src/_build/html/.buildinfo deleted file mode 100644 index 7ec31ce..0000000 --- a/docs-src/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c6c8605a01fab3fc8b4c8636342889f3 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs-src/conf.py b/docs-src/conf.py index 5e66fff..9cf3c85 100644 --- a/docs-src/conf.py +++ b/docs-src/conf.py @@ -30,7 +30,7 @@ author = 'Richard Smith' # ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'myst_parser', 'autoapi.extension', "sphinx_rtd_theme", 'sphinx.ext.todo'] -autoapi_dirs = ['../raylib'] +autoapi_dirs = ['../raylib', '../pyray'] autoapi_file_patterns = ['*.pyi', '*.py'] diff --git a/docs-src/generated/raylib.pyray.PyRay.rst b/docs-src/generated/raylib.pyray.PyRay.rst deleted file mode 100644 index 435e35e..0000000 --- a/docs-src/generated/raylib.pyray.PyRay.rst +++ /dev/null @@ -1,836 +0,0 @@ -raylib.pyray.PyRay -================== - -.. currentmodule:: raylib.pyray - -.. autoclass:: PyRay - - - .. automethod:: __init__ - - - .. rubric:: Methods - - .. autosummary:: - - ~PyRay.AudioStream - ~PyRay.BlendMode - ~PyRay.BoneInfo - ~PyRay.BoundingBox - ~PyRay.Camera - ~PyRay.Camera2D - ~PyRay.Camera3D - ~PyRay.CameraMode - ~PyRay.CameraProjection - ~PyRay.CharInfo - ~PyRay.Color - ~PyRay.ConfigFlags - ~PyRay.CubemapLayout - ~PyRay.Font - ~PyRay.FontType - ~PyRay.GamepadAxis - ~PyRay.GamepadButton - ~PyRay.Gestures - ~PyRay.Image - ~PyRay.KeyboardKey - ~PyRay.Material - ~PyRay.MaterialMap - ~PyRay.MaterialMapIndex - ~PyRay.Matrix - ~PyRay.Mesh - ~PyRay.Model - ~PyRay.ModelAnimation - ~PyRay.MouseButton - ~PyRay.MouseCursor - ~PyRay.Music - ~PyRay.NPatchInfo - ~PyRay.NPatchLayout - ~PyRay.PixelFormat - ~PyRay.Quaternion - ~PyRay.Ray - ~PyRay.RayHitInfo - ~PyRay.Rectangle - ~PyRay.RenderTexture - ~PyRay.RenderTexture2D - ~PyRay.Shader - ~PyRay.ShaderLocationIndex - ~PyRay.ShaderUniformDataType - ~PyRay.Sound - ~PyRay.Texture - ~PyRay.Texture2D - ~PyRay.TextureCubemap - ~PyRay.TextureFilter - ~PyRay.TextureWrap - ~PyRay.TraceLogLevel - ~PyRay.Transform - ~PyRay.Vector2 - ~PyRay.Vector3 - ~PyRay.Vector4 - ~PyRay.VrDeviceInfo - ~PyRay.VrStereoConfig - ~PyRay.Wave - ~PyRay.__init__ - ~PyRay.begin_blend_mode - ~PyRay.begin_drawing - ~PyRay.begin_mode_2d - ~PyRay.begin_mode_3d - ~PyRay.begin_scissor_mode - ~PyRay.begin_shader_mode - ~PyRay.begin_texture_mode - ~PyRay.begin_vr_stereo_mode - ~PyRay.change_directory - ~PyRay.check_collision_box_sphere - ~PyRay.check_collision_boxes - ~PyRay.check_collision_circle_rec - ~PyRay.check_collision_circles - ~PyRay.check_collision_lines - ~PyRay.check_collision_point_circle - ~PyRay.check_collision_point_rec - ~PyRay.check_collision_point_triangle - ~PyRay.check_collision_ray_box - ~PyRay.check_collision_ray_sphere - ~PyRay.check_collision_ray_sphere_ex - ~PyRay.check_collision_recs - ~PyRay.check_collision_spheres - ~PyRay.clear_background - ~PyRay.clear_directory_files - ~PyRay.clear_dropped_files - ~PyRay.clear_window_state - ~PyRay.close_audio_device - ~PyRay.close_audio_stream - ~PyRay.close_window - ~PyRay.codepoint_to_utf8 - ~PyRay.color_alpha - ~PyRay.color_alpha_blend - ~PyRay.color_from_hsv - ~PyRay.color_from_normalized - ~PyRay.color_normalize - ~PyRay.color_to_hsv - ~PyRay.color_to_int - ~PyRay.compress_data - ~PyRay.decompress_data - ~PyRay.directory_exists - ~PyRay.disable_cursor - ~PyRay.draw_billboard - ~PyRay.draw_billboard_rec - ~PyRay.draw_bounding_box - ~PyRay.draw_circle - ~PyRay.draw_circle_3d - ~PyRay.draw_circle_gradient - ~PyRay.draw_circle_lines - ~PyRay.draw_circle_sector - ~PyRay.draw_circle_sector_lines - ~PyRay.draw_circle_v - ~PyRay.draw_cube - ~PyRay.draw_cube_texture - ~PyRay.draw_cube_v - ~PyRay.draw_cube_wires - ~PyRay.draw_cube_wires_v - ~PyRay.draw_cylinder - ~PyRay.draw_cylinder_wires - ~PyRay.draw_ellipse - ~PyRay.draw_ellipse_lines - ~PyRay.draw_fps - ~PyRay.draw_grid - ~PyRay.draw_line - ~PyRay.draw_line_3d - ~PyRay.draw_line_bezier - ~PyRay.draw_line_bezier_quad - ~PyRay.draw_line_ex - ~PyRay.draw_line_strip - ~PyRay.draw_line_v - ~PyRay.draw_mesh - ~PyRay.draw_mesh_instanced - ~PyRay.draw_model - ~PyRay.draw_model_ex - ~PyRay.draw_model_wires - ~PyRay.draw_model_wires_ex - ~PyRay.draw_pixel - ~PyRay.draw_pixel_v - ~PyRay.draw_plane - ~PyRay.draw_point_3d - ~PyRay.draw_poly - ~PyRay.draw_poly_lines - ~PyRay.draw_ray - ~PyRay.draw_rectangle - ~PyRay.draw_rectangle_gradient_ex - ~PyRay.draw_rectangle_gradient_h - ~PyRay.draw_rectangle_gradient_v - ~PyRay.draw_rectangle_lines - ~PyRay.draw_rectangle_lines_ex - ~PyRay.draw_rectangle_pro - ~PyRay.draw_rectangle_rec - ~PyRay.draw_rectangle_rounded - ~PyRay.draw_rectangle_rounded_lines - ~PyRay.draw_rectangle_v - ~PyRay.draw_ring - ~PyRay.draw_ring_lines - ~PyRay.draw_sphere - ~PyRay.draw_sphere_ex - ~PyRay.draw_sphere_wires - ~PyRay.draw_text - ~PyRay.draw_text_codepoint - ~PyRay.draw_text_ex - ~PyRay.draw_text_rec - ~PyRay.draw_text_rec_ex - ~PyRay.draw_texture - ~PyRay.draw_texture_ex - ~PyRay.draw_texture_n_patch - ~PyRay.draw_texture_poly - ~PyRay.draw_texture_pro - ~PyRay.draw_texture_quad - ~PyRay.draw_texture_rec - ~PyRay.draw_texture_tiled - ~PyRay.draw_texture_v - ~PyRay.draw_triangle - ~PyRay.draw_triangle_3d - ~PyRay.draw_triangle_fan - ~PyRay.draw_triangle_lines - ~PyRay.draw_triangle_strip - ~PyRay.draw_triangle_strip_3d - ~PyRay.enable_cursor - ~PyRay.end_blend_mode - ~PyRay.end_drawing - ~PyRay.end_mode_2d - ~PyRay.end_mode_3d - ~PyRay.end_scissor_mode - ~PyRay.end_shader_mode - ~PyRay.end_texture_mode - ~PyRay.end_vr_stereo_mode - ~PyRay.export_image - ~PyRay.export_image_as_code - ~PyRay.export_mesh - ~PyRay.export_wave - ~PyRay.export_wave_as_code - ~PyRay.fade - ~PyRay.file_exists - ~PyRay.gen_image_cellular - ~PyRay.gen_image_checked - ~PyRay.gen_image_color - ~PyRay.gen_image_font_atlas - ~PyRay.gen_image_gradient_h - ~PyRay.gen_image_gradient_radial - ~PyRay.gen_image_gradient_v - ~PyRay.gen_image_perlin_noise - ~PyRay.gen_image_white_noise - ~PyRay.gen_mesh_cube - ~PyRay.gen_mesh_cubicmap - ~PyRay.gen_mesh_cylinder - ~PyRay.gen_mesh_heightmap - ~PyRay.gen_mesh_hemi_sphere - ~PyRay.gen_mesh_knot - ~PyRay.gen_mesh_plane - ~PyRay.gen_mesh_poly - ~PyRay.gen_mesh_sphere - ~PyRay.gen_mesh_torus - ~PyRay.gen_texture_mipmaps - ~PyRay.get_camera_matrix - ~PyRay.get_camera_matrix_2d - ~PyRay.get_char_pressed - ~PyRay.get_clipboard_text - ~PyRay.get_codepoints - ~PyRay.get_codepoints_count - ~PyRay.get_collision_ray_ground - ~PyRay.get_collision_ray_mesh - ~PyRay.get_collision_ray_model - ~PyRay.get_collision_ray_triangle - ~PyRay.get_collision_rec - ~PyRay.get_color - ~PyRay.get_current_monitor - ~PyRay.get_directory_files - ~PyRay.get_directory_path - ~PyRay.get_dropped_files - ~PyRay.get_file_extension - ~PyRay.get_file_mod_time - ~PyRay.get_file_name - ~PyRay.get_file_name_without_ext - ~PyRay.get_font_default - ~PyRay.get_fps - ~PyRay.get_frame_time - ~PyRay.get_gamepad_axis_count - ~PyRay.get_gamepad_axis_movement - ~PyRay.get_gamepad_button_pressed - ~PyRay.get_gamepad_name - ~PyRay.get_gesture_detected - ~PyRay.get_gesture_drag_angle - ~PyRay.get_gesture_drag_vector - ~PyRay.get_gesture_hold_duration - ~PyRay.get_gesture_pinch_angle - ~PyRay.get_gesture_pinch_vector - ~PyRay.get_glyph_index - ~PyRay.get_image_alpha_border - ~PyRay.get_key_pressed - ~PyRay.get_monitor_count - ~PyRay.get_monitor_height - ~PyRay.get_monitor_name - ~PyRay.get_monitor_physical_height - ~PyRay.get_monitor_physical_width - ~PyRay.get_monitor_position - ~PyRay.get_monitor_refresh_rate - ~PyRay.get_monitor_width - ~PyRay.get_mouse_position - ~PyRay.get_mouse_ray - ~PyRay.get_mouse_wheel_move - ~PyRay.get_mouse_x - ~PyRay.get_mouse_y - ~PyRay.get_music_time_length - ~PyRay.get_music_time_played - ~PyRay.get_next_codepoint - ~PyRay.get_pixel_color - ~PyRay.get_pixel_data_size - ~PyRay.get_prev_directory_path - ~PyRay.get_random_value - ~PyRay.get_screen_data - ~PyRay.get_screen_height - ~PyRay.get_screen_to_world_2d - ~PyRay.get_screen_width - ~PyRay.get_shader_location - ~PyRay.get_shader_location_attrib - ~PyRay.get_sounds_playing - ~PyRay.get_texture_data - ~PyRay.get_time - ~PyRay.get_touch_points_count - ~PyRay.get_touch_position - ~PyRay.get_touch_x - ~PyRay.get_touch_y - ~PyRay.get_window_handle - ~PyRay.get_window_position - ~PyRay.get_window_scale_dpi - ~PyRay.get_working_directory - ~PyRay.get_world_to_screen - ~PyRay.get_world_to_screen_2d - ~PyRay.get_world_to_screen_ex - ~PyRay.hide_cursor - ~PyRay.image_alpha_clear - ~PyRay.image_alpha_crop - ~PyRay.image_alpha_mask - ~PyRay.image_alpha_premultiply - ~PyRay.image_clear_background - ~PyRay.image_color_brightness - ~PyRay.image_color_contrast - ~PyRay.image_color_grayscale - ~PyRay.image_color_invert - ~PyRay.image_color_replace - ~PyRay.image_color_tint - ~PyRay.image_copy - ~PyRay.image_crop - ~PyRay.image_dither - ~PyRay.image_draw - ~PyRay.image_draw_circle - ~PyRay.image_draw_circle_v - ~PyRay.image_draw_line - ~PyRay.image_draw_line_v - ~PyRay.image_draw_pixel - ~PyRay.image_draw_pixel_v - ~PyRay.image_draw_rectangle - ~PyRay.image_draw_rectangle_lines - ~PyRay.image_draw_rectangle_rec - ~PyRay.image_draw_rectangle_v - ~PyRay.image_draw_text - ~PyRay.image_draw_text_ex - ~PyRay.image_flip_horizontal - ~PyRay.image_flip_vertical - ~PyRay.image_format - ~PyRay.image_from_image - ~PyRay.image_mipmaps - ~PyRay.image_resize - ~PyRay.image_resize_canvas - ~PyRay.image_resize_nn - ~PyRay.image_rotate_ccw - ~PyRay.image_rotate_cw - ~PyRay.image_text - ~PyRay.image_text_ex - ~PyRay.image_to_pot - ~PyRay.init_audio_device - ~PyRay.init_audio_stream - ~PyRay.init_window - ~PyRay.is_audio_device_ready - ~PyRay.is_audio_stream_playing - ~PyRay.is_audio_stream_processed - ~PyRay.is_cursor_hidden - ~PyRay.is_cursor_on_screen - ~PyRay.is_file_dropped - ~PyRay.is_file_extension - ~PyRay.is_gamepad_available - ~PyRay.is_gamepad_button_down - ~PyRay.is_gamepad_button_pressed - ~PyRay.is_gamepad_button_released - ~PyRay.is_gamepad_button_up - ~PyRay.is_gamepad_name - ~PyRay.is_gesture_detected - ~PyRay.is_key_down - ~PyRay.is_key_pressed - ~PyRay.is_key_released - ~PyRay.is_key_up - ~PyRay.is_model_animation_valid - ~PyRay.is_mouse_button_down - ~PyRay.is_mouse_button_pressed - ~PyRay.is_mouse_button_released - ~PyRay.is_mouse_button_up - ~PyRay.is_music_playing - ~PyRay.is_sound_playing - ~PyRay.is_window_focused - ~PyRay.is_window_fullscreen - ~PyRay.is_window_hidden - ~PyRay.is_window_maximized - ~PyRay.is_window_minimized - ~PyRay.is_window_ready - ~PyRay.is_window_resized - ~PyRay.is_window_state - ~PyRay.load_file_data - ~PyRay.load_file_text - ~PyRay.load_font - ~PyRay.load_font_data - ~PyRay.load_font_ex - ~PyRay.load_font_from_image - ~PyRay.load_font_from_memory - ~PyRay.load_image - ~PyRay.load_image_anim - ~PyRay.load_image_colors - ~PyRay.load_image_from_memory - ~PyRay.load_image_palette - ~PyRay.load_image_raw - ~PyRay.load_material_default - ~PyRay.load_materials - ~PyRay.load_model - ~PyRay.load_model_animations - ~PyRay.load_model_from_mesh - ~PyRay.load_music_stream - ~PyRay.load_music_stream_from_memory - ~PyRay.load_render_texture - ~PyRay.load_shader - ~PyRay.load_shader_from_memory - ~PyRay.load_sound - ~PyRay.load_sound_from_wave - ~PyRay.load_storage_value - ~PyRay.load_texture - ~PyRay.load_texture_cubemap - ~PyRay.load_texture_from_image - ~PyRay.load_vr_stereo_config - ~PyRay.load_wave - ~PyRay.load_wave_from_memory - ~PyRay.load_wave_samples - ~PyRay.maximize_window - ~PyRay.measure_text - ~PyRay.measure_text_ex - ~PyRay.mem_alloc - ~PyRay.mem_free - ~PyRay.mem_realloc - ~PyRay.mesh_binormals - ~PyRay.mesh_bounding_box - ~PyRay.mesh_tangents - ~PyRay.minimize_window - ~PyRay.open_url - ~PyRay.pause_audio_stream - ~PyRay.pause_music_stream - ~PyRay.pause_sound - ~PyRay.play_audio_stream - ~PyRay.play_music_stream - ~PyRay.play_sound - ~PyRay.play_sound_multi - ~PyRay.pointer - ~PyRay.rAudioBuffer - ~PyRay.restore_window - ~PyRay.resume_audio_stream - ~PyRay.resume_music_stream - ~PyRay.resume_sound - ~PyRay.save_file_data - ~PyRay.save_file_text - ~PyRay.save_storage_value - ~PyRay.set_audio_stream_buffer_size_default - ~PyRay.set_audio_stream_pitch - ~PyRay.set_audio_stream_volume - ~PyRay.set_camera_alt_control - ~PyRay.set_camera_mode - ~PyRay.set_camera_move_controls - ~PyRay.set_camera_pan_control - ~PyRay.set_camera_smooth_zoom_control - ~PyRay.set_clipboard_text - ~PyRay.set_config_flags - ~PyRay.set_exit_key - ~PyRay.set_gamepad_mappings - ~PyRay.set_gestures_enabled - ~PyRay.set_master_volume - ~PyRay.set_material_texture - ~PyRay.set_model_mesh_material - ~PyRay.set_mouse_cursor - ~PyRay.set_mouse_offset - ~PyRay.set_mouse_position - ~PyRay.set_mouse_scale - ~PyRay.set_music_pitch - ~PyRay.set_music_volume - ~PyRay.set_pixel_color - ~PyRay.set_shader_value - ~PyRay.set_shader_value_matrix - ~PyRay.set_shader_value_texture - ~PyRay.set_shader_value_v - ~PyRay.set_shapes_texture - ~PyRay.set_sound_pitch - ~PyRay.set_sound_volume - ~PyRay.set_target_fps - ~PyRay.set_texture_filter - ~PyRay.set_texture_wrap - ~PyRay.set_trace_log_level - ~PyRay.set_window_icon - ~PyRay.set_window_min_size - ~PyRay.set_window_monitor - ~PyRay.set_window_position - ~PyRay.set_window_size - ~PyRay.set_window_state - ~PyRay.set_window_title - ~PyRay.show_cursor - ~PyRay.stop_audio_stream - ~PyRay.stop_music_stream - ~PyRay.stop_sound - ~PyRay.stop_sound_multi - ~PyRay.take_screenshot - ~PyRay.text_append - ~PyRay.text_copy - ~PyRay.text_find_index - ~PyRay.text_insert - ~PyRay.text_is_equal - ~PyRay.text_join - ~PyRay.text_length - ~PyRay.text_replace - ~PyRay.text_split - ~PyRay.text_subtext - ~PyRay.text_to_integer - ~PyRay.text_to_lower - ~PyRay.text_to_pascal - ~PyRay.text_to_upper - ~PyRay.text_to_utf8 - ~PyRay.toggle_fullscreen - ~PyRay.unload_file_data - ~PyRay.unload_file_text - ~PyRay.unload_font - ~PyRay.unload_font_data - ~PyRay.unload_image - ~PyRay.unload_image_colors - ~PyRay.unload_image_palette - ~PyRay.unload_material - ~PyRay.unload_mesh - ~PyRay.unload_model - ~PyRay.unload_model_animation - ~PyRay.unload_model_animations - ~PyRay.unload_model_keep_meshes - ~PyRay.unload_music_stream - ~PyRay.unload_render_texture - ~PyRay.unload_shader - ~PyRay.unload_sound - ~PyRay.unload_texture - ~PyRay.unload_vr_stereo_config - ~PyRay.unload_wave - ~PyRay.unload_wave_samples - ~PyRay.update_audio_stream - ~PyRay.update_camera - ~PyRay.update_mesh_buffer - ~PyRay.update_model_animation - ~PyRay.update_music_stream - ~PyRay.update_sound - ~PyRay.update_texture - ~PyRay.update_texture_rec - ~PyRay.upload_mesh - ~PyRay.wave_copy - ~PyRay.wave_crop - ~PyRay.wave_format - ~PyRay.window_should_close - - - - - - .. rubric:: Attributes - - .. autosummary:: - - ~PyRay.BLEND_ADDITIVE - ~PyRay.BLEND_ADD_COLORS - ~PyRay.BLEND_ALPHA - ~PyRay.BLEND_CUSTOM - ~PyRay.BLEND_MULTIPLIED - ~PyRay.BLEND_SUBTRACT_COLORS - ~PyRay.CAMERA_CUSTOM - ~PyRay.CAMERA_FIRST_PERSON - ~PyRay.CAMERA_FREE - ~PyRay.CAMERA_ORBITAL - ~PyRay.CAMERA_ORTHOGRAPHIC - ~PyRay.CAMERA_PERSPECTIVE - ~PyRay.CAMERA_THIRD_PERSON - ~PyRay.CUBEMAP_LAYOUT_AUTO_DETECT - ~PyRay.CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE - ~PyRay.CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR - ~PyRay.CUBEMAP_LAYOUT_LINE_HORIZONTAL - ~PyRay.CUBEMAP_LAYOUT_LINE_VERTICAL - ~PyRay.CUBEMAP_LAYOUT_PANORAMA - ~PyRay.FLAG_FULLSCREEN_MODE - ~PyRay.FLAG_INTERLACED_HINT - ~PyRay.FLAG_MSAA_4X_HINT - ~PyRay.FLAG_VSYNC_HINT - ~PyRay.FLAG_WINDOW_ALWAYS_RUN - ~PyRay.FLAG_WINDOW_HIDDEN - ~PyRay.FLAG_WINDOW_HIGHDPI - ~PyRay.FLAG_WINDOW_MAXIMIZED - ~PyRay.FLAG_WINDOW_MINIMIZED - ~PyRay.FLAG_WINDOW_RESIZABLE - ~PyRay.FLAG_WINDOW_TOPMOST - ~PyRay.FLAG_WINDOW_TRANSPARENT - ~PyRay.FLAG_WINDOW_UNDECORATED - ~PyRay.FLAG_WINDOW_UNFOCUSED - ~PyRay.FONT_BITMAP - ~PyRay.FONT_DEFAULT - ~PyRay.FONT_SDF - ~PyRay.GAMEPAD_AXIS_LEFT_TRIGGER - ~PyRay.GAMEPAD_AXIS_LEFT_X - ~PyRay.GAMEPAD_AXIS_LEFT_Y - ~PyRay.GAMEPAD_AXIS_RIGHT_TRIGGER - ~PyRay.GAMEPAD_AXIS_RIGHT_X - ~PyRay.GAMEPAD_AXIS_RIGHT_Y - ~PyRay.GAMEPAD_BUTTON_LEFT_FACE_DOWN - ~PyRay.GAMEPAD_BUTTON_LEFT_FACE_LEFT - ~PyRay.GAMEPAD_BUTTON_LEFT_FACE_RIGHT - ~PyRay.GAMEPAD_BUTTON_LEFT_FACE_UP - ~PyRay.GAMEPAD_BUTTON_LEFT_THUMB - ~PyRay.GAMEPAD_BUTTON_LEFT_TRIGGER_1 - ~PyRay.GAMEPAD_BUTTON_LEFT_TRIGGER_2 - ~PyRay.GAMEPAD_BUTTON_MIDDLE - ~PyRay.GAMEPAD_BUTTON_MIDDLE_LEFT - ~PyRay.GAMEPAD_BUTTON_MIDDLE_RIGHT - ~PyRay.GAMEPAD_BUTTON_RIGHT_FACE_DOWN - ~PyRay.GAMEPAD_BUTTON_RIGHT_FACE_LEFT - ~PyRay.GAMEPAD_BUTTON_RIGHT_FACE_RIGHT - ~PyRay.GAMEPAD_BUTTON_RIGHT_FACE_UP - ~PyRay.GAMEPAD_BUTTON_RIGHT_THUMB - ~PyRay.GAMEPAD_BUTTON_RIGHT_TRIGGER_1 - ~PyRay.GAMEPAD_BUTTON_RIGHT_TRIGGER_2 - ~PyRay.GAMEPAD_BUTTON_UNKNOWN - ~PyRay.GESTURE_DOUBLETAP - ~PyRay.GESTURE_DRAG - ~PyRay.GESTURE_HOLD - ~PyRay.GESTURE_NONE - ~PyRay.GESTURE_PINCH_IN - ~PyRay.GESTURE_PINCH_OUT - ~PyRay.GESTURE_SWIPE_DOWN - ~PyRay.GESTURE_SWIPE_LEFT - ~PyRay.GESTURE_SWIPE_RIGHT - ~PyRay.GESTURE_SWIPE_UP - ~PyRay.GESTURE_TAP - ~PyRay.KEY_A - ~PyRay.KEY_APOSTROPHE - ~PyRay.KEY_B - ~PyRay.KEY_BACK - ~PyRay.KEY_BACKSLASH - ~PyRay.KEY_BACKSPACE - ~PyRay.KEY_C - ~PyRay.KEY_CAPS_LOCK - ~PyRay.KEY_COMMA - ~PyRay.KEY_D - ~PyRay.KEY_DELETE - ~PyRay.KEY_DOWN - ~PyRay.KEY_E - ~PyRay.KEY_EIGHT - ~PyRay.KEY_END - ~PyRay.KEY_ENTER - ~PyRay.KEY_EQUAL - ~PyRay.KEY_ESCAPE - ~PyRay.KEY_F - ~PyRay.KEY_F1 - ~PyRay.KEY_F10 - ~PyRay.KEY_F11 - ~PyRay.KEY_F12 - ~PyRay.KEY_F2 - ~PyRay.KEY_F3 - ~PyRay.KEY_F4 - ~PyRay.KEY_F5 - ~PyRay.KEY_F6 - ~PyRay.KEY_F7 - ~PyRay.KEY_F8 - ~PyRay.KEY_F9 - ~PyRay.KEY_FIVE - ~PyRay.KEY_FOUR - ~PyRay.KEY_G - ~PyRay.KEY_GRAVE - ~PyRay.KEY_H - ~PyRay.KEY_HOME - ~PyRay.KEY_I - ~PyRay.KEY_INSERT - ~PyRay.KEY_J - ~PyRay.KEY_K - ~PyRay.KEY_KB_MENU - ~PyRay.KEY_KP_0 - ~PyRay.KEY_KP_1 - ~PyRay.KEY_KP_2 - ~PyRay.KEY_KP_3 - ~PyRay.KEY_KP_4 - ~PyRay.KEY_KP_5 - ~PyRay.KEY_KP_6 - ~PyRay.KEY_KP_7 - ~PyRay.KEY_KP_8 - ~PyRay.KEY_KP_9 - ~PyRay.KEY_KP_ADD - ~PyRay.KEY_KP_DECIMAL - ~PyRay.KEY_KP_DIVIDE - ~PyRay.KEY_KP_ENTER - ~PyRay.KEY_KP_EQUAL - ~PyRay.KEY_KP_MULTIPLY - ~PyRay.KEY_KP_SUBTRACT - ~PyRay.KEY_L - ~PyRay.KEY_LEFT - ~PyRay.KEY_LEFT_ALT - ~PyRay.KEY_LEFT_BRACKET - ~PyRay.KEY_LEFT_CONTROL - ~PyRay.KEY_LEFT_SHIFT - ~PyRay.KEY_LEFT_SUPER - ~PyRay.KEY_M - ~PyRay.KEY_MENU - ~PyRay.KEY_MINUS - ~PyRay.KEY_N - ~PyRay.KEY_NINE - ~PyRay.KEY_NULL - ~PyRay.KEY_NUM_LOCK - ~PyRay.KEY_O - ~PyRay.KEY_ONE - ~PyRay.KEY_P - ~PyRay.KEY_PAGE_DOWN - ~PyRay.KEY_PAGE_UP - ~PyRay.KEY_PAUSE - ~PyRay.KEY_PERIOD - ~PyRay.KEY_PRINT_SCREEN - ~PyRay.KEY_Q - ~PyRay.KEY_R - ~PyRay.KEY_RIGHT - ~PyRay.KEY_RIGHT_ALT - ~PyRay.KEY_RIGHT_BRACKET - ~PyRay.KEY_RIGHT_CONTROL - ~PyRay.KEY_RIGHT_SHIFT - ~PyRay.KEY_RIGHT_SUPER - ~PyRay.KEY_S - ~PyRay.KEY_SCROLL_LOCK - ~PyRay.KEY_SEMICOLON - ~PyRay.KEY_SEVEN - ~PyRay.KEY_SIX - ~PyRay.KEY_SLASH - ~PyRay.KEY_SPACE - ~PyRay.KEY_T - ~PyRay.KEY_TAB - ~PyRay.KEY_THREE - ~PyRay.KEY_TWO - ~PyRay.KEY_U - ~PyRay.KEY_UP - ~PyRay.KEY_V - ~PyRay.KEY_VOLUME_DOWN - ~PyRay.KEY_VOLUME_UP - ~PyRay.KEY_W - ~PyRay.KEY_X - ~PyRay.KEY_Y - ~PyRay.KEY_Z - ~PyRay.KEY_ZERO - ~PyRay.LOG_ALL - ~PyRay.LOG_DEBUG - ~PyRay.LOG_ERROR - ~PyRay.LOG_FATAL - ~PyRay.LOG_INFO - ~PyRay.LOG_NONE - ~PyRay.LOG_TRACE - ~PyRay.LOG_WARNING - ~PyRay.MATERIAL_MAP_ALBEDO - ~PyRay.MATERIAL_MAP_BRDG - ~PyRay.MATERIAL_MAP_CUBEMAP - ~PyRay.MATERIAL_MAP_DIFFUSE - ~PyRay.MATERIAL_MAP_EMISSION - ~PyRay.MATERIAL_MAP_HEIGHT - ~PyRay.MATERIAL_MAP_IRRADIANCE - ~PyRay.MATERIAL_MAP_METALNESS - ~PyRay.MATERIAL_MAP_NORMAL - ~PyRay.MATERIAL_MAP_OCCLUSION - ~PyRay.MATERIAL_MAP_PREFILTER - ~PyRay.MATERIAL_MAP_ROUGHNESS - ~PyRay.MATERIAL_MAP_SPECULAR - ~PyRay.MOUSE_CURSOR_ARROW - ~PyRay.MOUSE_CURSOR_CROSSHAIR - ~PyRay.MOUSE_CURSOR_DEFAULT - ~PyRay.MOUSE_CURSOR_IBEAM - ~PyRay.MOUSE_CURSOR_NOT_ALLOWED - ~PyRay.MOUSE_CURSOR_POINTING_HAND - ~PyRay.MOUSE_CURSOR_RESIZE_ALL - ~PyRay.MOUSE_CURSOR_RESIZE_EW - ~PyRay.MOUSE_CURSOR_RESIZE_NESW - ~PyRay.MOUSE_CURSOR_RESIZE_NS - ~PyRay.MOUSE_CURSOR_RESIZE_NWSE - ~PyRay.MOUSE_LEFT_BUTTON - ~PyRay.MOUSE_MIDDLE_BUTTON - ~PyRay.MOUSE_RIGHT_BUTTON - ~PyRay.NPATCH_NINE_PATCH - ~PyRay.NPATCH_THREE_PATCH_HORIZONTAL - ~PyRay.NPATCH_THREE_PATCH_VERTICAL - ~PyRay.PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA - ~PyRay.PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA - ~PyRay.PIXELFORMAT_COMPRESSED_DXT1_RGB - ~PyRay.PIXELFORMAT_COMPRESSED_DXT1_RGBA - ~PyRay.PIXELFORMAT_COMPRESSED_DXT3_RGBA - ~PyRay.PIXELFORMAT_COMPRESSED_DXT5_RGBA - ~PyRay.PIXELFORMAT_COMPRESSED_ETC1_RGB - ~PyRay.PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA - ~PyRay.PIXELFORMAT_COMPRESSED_ETC2_RGB - ~PyRay.PIXELFORMAT_COMPRESSED_PVRT_RGB - ~PyRay.PIXELFORMAT_COMPRESSED_PVRT_RGBA - ~PyRay.PIXELFORMAT_UNCOMPRESSED_GRAYSCALE - ~PyRay.PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R32 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R32G32B32 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R5G6B5 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R8G8B8 - ~PyRay.PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 - ~PyRay.SHADER_LOC_COLOR_AMBIENT - ~PyRay.SHADER_LOC_COLOR_DIFFUSE - ~PyRay.SHADER_LOC_COLOR_SPECULAR - ~PyRay.SHADER_LOC_MAP_ALBEDO - ~PyRay.SHADER_LOC_MAP_BRDF - ~PyRay.SHADER_LOC_MAP_CUBEMAP - ~PyRay.SHADER_LOC_MAP_DIFFUSE - ~PyRay.SHADER_LOC_MAP_EMISSION - ~PyRay.SHADER_LOC_MAP_HEIGHT - ~PyRay.SHADER_LOC_MAP_IRRADIANCE - ~PyRay.SHADER_LOC_MAP_METALNESS - ~PyRay.SHADER_LOC_MAP_NORMAL - ~PyRay.SHADER_LOC_MAP_OCCLUSION - ~PyRay.SHADER_LOC_MAP_PREFILTER - ~PyRay.SHADER_LOC_MAP_ROUGHNESS - ~PyRay.SHADER_LOC_MAP_SPECULAR - ~PyRay.SHADER_LOC_MATRIX_MODEL - ~PyRay.SHADER_LOC_MATRIX_MVP - ~PyRay.SHADER_LOC_MATRIX_NORMAL - ~PyRay.SHADER_LOC_MATRIX_PROJECTION - ~PyRay.SHADER_LOC_MATRIX_VIEW - ~PyRay.SHADER_LOC_VECTOR_VIEW - ~PyRay.SHADER_LOC_VERTEX_COLOR - ~PyRay.SHADER_LOC_VERTEX_NORMAL - ~PyRay.SHADER_LOC_VERTEX_POSITION - ~PyRay.SHADER_LOC_VERTEX_TANGENT - ~PyRay.SHADER_LOC_VERTEX_TEXCOORD01 - ~PyRay.SHADER_LOC_VERTEX_TEXCOORD02 - ~PyRay.SHADER_UNIFORM_FLOAT - ~PyRay.SHADER_UNIFORM_INT - ~PyRay.SHADER_UNIFORM_IVEC2 - ~PyRay.SHADER_UNIFORM_IVEC3 - ~PyRay.SHADER_UNIFORM_IVEC4 - ~PyRay.SHADER_UNIFORM_SAMPLER2D - ~PyRay.SHADER_UNIFORM_VEC2 - ~PyRay.SHADER_UNIFORM_VEC3 - ~PyRay.SHADER_UNIFORM_VEC4 - ~PyRay.TEXTURE_FILTER_ANISOTROPIC_16X - ~PyRay.TEXTURE_FILTER_ANISOTROPIC_4X - ~PyRay.TEXTURE_FILTER_ANISOTROPIC_8X - ~PyRay.TEXTURE_FILTER_BILINEAR - ~PyRay.TEXTURE_FILTER_POINT - ~PyRay.TEXTURE_FILTER_TRILINEAR - ~PyRay.TEXTURE_WRAP_CLAMP - ~PyRay.TEXTURE_WRAP_MIRROR_CLAMP - ~PyRay.TEXTURE_WRAP_MIRROR_REPEAT - ~PyRay.TEXTURE_WRAP_REPEAT - ~PyRay.TextFormat - ~PyRay.TraceLog - - \ No newline at end of file diff --git a/docs-src/index.rst b/docs-src/index.rst index de6618c..2177832 100644 --- a/docs-src/index.rst +++ b/docs-src/index.rst @@ -15,6 +15,7 @@ Raylib Python raylib dynamic BUILDING + RPI * :ref:`search` diff --git a/docs-src/pyray.rst b/docs-src/pyray.rst index 3284b9b..2a2ac0e 100644 --- a/docs-src/pyray.rst +++ b/docs-src/pyray.rst @@ -1,18 +1,18 @@ Python API ============== -.. comment:: - - Link to API reference: - toctree:: - :maxdepth: 1 - - autoapi/raylib/pyray/index - - This is a wrapper around the C API with some syntactic sugar. -The API is *still the same as Raylib*, so you should still reply on `the official Raylib docs `_, except: +The API is *still the same as Raylib*, so you should still reply on: + +* `the C Raylib docs `_ + +* `the C Raylib examples `_ + +* `the C Raylib header file `_ + + +The *differences* are: * the function names are in **snake_case**. @@ -20,22 +20,22 @@ The API is *still the same as Raylib*, so you should still reply on `the officia * There are some helper functions to create structures. +Examples +-------- + Example program: .. code-block:: - import raylib - - pr = raylib.PyRay() + import pyray as pr pr.init_window(800, 450, "Hello Pyray") pr.set_target_fps(60) camera = pr.Camera3D([18.0, 16.0, 18.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0], 45.0, 0) - pr.set_camera_mode(camera, pr.CAMERA_ORBITAL) while not pr.window_should_close(): - pr.update_camera(camera) + pr.update_camera(camera, pr.CAMERA_ORBITAL) pr.begin_drawing() pr.clear_background(pr.RAYWHITE) pr.begin_mode_3d(camera) @@ -45,12 +45,24 @@ Example program: pr.end_drawing() pr.close_window() +.. tip:: New in 3.7.0.post9: + + You can also now import the functions with no prefix: + + .. code-block:: + + from pyray import * + + init_window(800, 450, "Raylib texture test") + ... + + +`See all examples here `_ -See also https://github.com/electronstudio/raylib-python-cffi/blob/master/test_pyray.py API reference ------------- -.. autoapimodule:: raylib.pyray +.. autoapimodule:: pyray :members: :undoc-members: diff --git a/docs-src/raylib.rst b/docs-src/raylib.rst index 7ca4a46..b3119dd 100644 --- a/docs-src/raylib.rst +++ b/docs-src/raylib.rst @@ -1,7 +1,8 @@ C API ============= -The goal of the C API is make usage as similar to the original C as CFFI will allow. The `example programs `_ +The goal of the C API is make usage as similar to the original C as CFFI will allow. +So the `example programs `_ are very, very similar to the C originals. Example program: @@ -14,10 +15,9 @@ Example program: 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]) - SetCameraMode(camera[0], CAMERA_ORBITAL) while not WindowShouldClose(): - UpdateCamera(camera) + UpdateCamera(camera, CAMERA_ORBITAL) BeginDrawing() ClearBackground(RAYWHITE) BeginMode3D(camera[0]) @@ -27,7 +27,7 @@ Example program: EndDrawing() CloseWindow() -If you want to be more portable you can prefix the functions like this: +If you want to be more portable (i.e. same code will work with dynamic bindings) you can prefix the functions like this: .. code-block:: @@ -39,11 +39,16 @@ If you want to be more portable you can prefix the functions like this: ... -See also https://github.com/electronstudio/raylib-python-cffi/blob/master/test_static.py .. note:: Whenever you need to convert stuff between C and Python see https://cffi.readthedocs.io -.. important:: Your **primary reference** should always be `the official Raylib docs `_ +.. important:: Your **primary reference** should always be + + * `the C Raylib docs `_ + + * `the C Raylib examples `_ + + * `the C Raylib header file `_ However, here is a list of available functions: diff --git a/docs/.buildinfo b/docs/.buildinfo index 7ec31ce..48257a1 100644 --- a/docs/.buildinfo +++ b/docs/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c6c8605a01fab3fc8b4c8636342889f3 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: f2032a6434b52f7c68551d0ad70d555b tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/BUILDING.html b/docs/BUILDING.html index d9b5e45..b3a1d99 100644 --- a/docs/BUILDING.html +++ b/docs/BUILDING.html @@ -1,21 +1,26 @@ + + - + - + + - Building from source — Raylib Python documentation - - - - - - - + Building from source — Raylib Python documentation + + + + + + + + + + + @@ -24,24 +29,32 @@