Merge branch 'master' into gltf-animation-support

This commit is contained in:
Hristo Stamenov 2021-01-26 16:48:47 +02:00
commit 8e0e6e7776
60 changed files with 5056 additions and 2863 deletions

93
.github/workflows/cmake.yml vendored Normal file
View File

@ -0,0 +1,93 @@
name: CMake Builds
on:
push:
pull_request:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build_windows:
name: Windows Build
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
run: cmake -E make_directory ${{github.workspace}}/build
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
# access regardless of the host operating system
shell: powershell
working-directory: ${{github.workspace}}/build
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run: cmake $env:GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE -DPLATFORM=Desktop
- name: Build
working-directory: ${{github.workspace}}/build
shell: powershell
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $env:BUILD_TYPE
- name: Test
working-directory: ${{github.workspace}}/build
shell: powershell
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C $env:BUILD_TYPE
build_linux:
name: Linux Build
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory
# We'll use this as our working directory for all subsequent commands
run: cmake -E make_directory ${{github.workspace}}/build
- name: Setup Environment
run: |
sudo apt-get update -qq
sudo apt-get install gcc-multilib
sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
# access regardless of the host operating system
shell: bash
working-directory: ${{github.workspace}}/build
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPLATFORM=Desktop
- name: Build
working-directory: ${{github.workspace}}/build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $BUILD_TYPE
- name: Test
working-directory: ${{github.workspace}}/build
shell: bash
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C $BUILD_TYPE

2
.gitignore vendored
View File

@ -82,7 +82,7 @@ DerivedData/
# Jetbrains project # Jetbrains project
.idea/ .idea/
cmake-build-debug/ cmake-build-*/
# CMake stuff # CMake stuff
CMakeCache.txt CMakeCache.txt

View File

@ -6,9 +6,9 @@ Here it is a list with the ones I'm aware of:
| name | raylib version | language | repo | | name | raylib version | language | repo |
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------| |:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
| raylib | **3.1-dev** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib | | raylib | **3.5** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
| raylib-cpp | 3.5 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp | | raylib-cpp | 3.5 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
| Raylib-cs | 3.0 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs | | Raylib-cs | 3.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs |
| raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp | | raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp |
| raylib-boo | 3.5 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo | | raylib-boo | 3.5 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo |
| RaylibFS | 2.5 | [F#](https://fsharp.org/) | https://github.com/dallinbeutler/RaylibFS | | RaylibFS | 2.5 | [F#](https://fsharp.org/) | https://github.com/dallinbeutler/RaylibFS |
@ -19,7 +19,7 @@ Here it is a list with the ones I'm aware of:
| raylib-go | 3.0 | [Go](https://golang.org/) | https://github.com/gen2brain/raylib-go | | raylib-go | 3.0 | [Go](https://golang.org/) | https://github.com/gen2brain/raylib-go |
| raylib-goplus | 2.6-dev | [Go](https://golang.org/) | https://github.com/Lachee/raylib-goplus | | raylib-goplus | 2.6-dev | [Go](https://golang.org/) | https://github.com/Lachee/raylib-goplus |
| ray-go | 2.6-dev | [Go](https://golang.org/) | https://github.com/hecate-tech/ray-go | | ray-go | 2.6-dev | [Go](https://golang.org/) | https://github.com/hecate-tech/ray-go |
| go-raylib | 3.1-dev | [Go](https://golang.org/) | https://github.com/chunqian/go-raylib | | go-raylib | 3.5 | [Go](https://golang.org/) | https://github.com/chunqian/go-raylib |
| raylib-rs | 3.0 | [Rust](https://www.rust-lang.org/) | https://github.com/deltaphc/raylib-rs | | raylib-rs | 3.0 | [Rust](https://www.rust-lang.org/) | https://github.com/deltaphc/raylib-rs |
| raylib-lua | 1.7 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib-lua | | raylib-lua | 1.7 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib-lua |
| raylib-lua-ffi | 2.0 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib/issues/693 | | raylib-lua-ffi | 2.0 | [Lua](http://www.lua.org/) | https://github.com/raysan5/raylib/issues/693 |
@ -33,6 +33,7 @@ Here it is a list with the ones I'm aware of:
| raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim | | raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim |
| raylib-Forever | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/Guevara-chan/Raylib-Forever | | raylib-Forever | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/Guevara-chan/Raylib-Forever |
| nim-raylib | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/tomc1998/nim-raylib | | nim-raylib | 3.1-dev | [Nim](https://nim-lang.org/) | https://github.com/tomc1998/nim-raylib |
| NimraylibNow! | 3.5-dev | [Nim](https://nim-lang.org/) | https://github.com/greenfork/nimraylib_now |
| raylib-haskell | 2.0 | [Haskell](https://www.haskell.org/) | https://github.com/DevJac/raylib-haskell | | raylib-haskell | 2.0 | [Haskell](https://www.haskell.org/) | https://github.com/DevJac/raylib-haskell |
| raylib-cr | 2.5-dev | [Crystal](https://crystal-lang.org/) | https://github.com/AregevDev/raylib-cr | | raylib-cr | 2.5-dev | [Crystal](https://crystal-lang.org/) | https://github.com/AregevDev/raylib-cr |
| cray | 1.8 | [Crystal](https://crystal-lang.org/) | https://gitlab.com/Zatherz/cray | | cray | 1.8 | [Crystal](https://crystal-lang.org/) | https://gitlab.com/Zatherz/cray |
@ -45,12 +46,12 @@ Here it is a list with the ones I'm aware of:
| raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby | | raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby |
| raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby | | raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby |
| raylib-py | 2.0 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py | | raylib-py | 2.0 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py |
| raylib-python-cffi | 3.1-dev | [Python](https://www.python.org/) | https://github.com/electronstudio/raylib-python-cffi | | raylib-python-cffi | 3.5 | [Python](https://www.python.org/) | https://github.com/electronstudio/raylib-python-cffi |
| raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg | | raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg |
| jaylib | 3.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/electronstudio/jaylib/ | | jaylib | 3.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/electronstudio/jaylib/ |
| raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java | | raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java |
| clj-raylib | 3.0 | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib | | clj-raylib | 3.0 | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib |
| node-raylib | 3.0 | [Node.js](https://nodejs.org/en/) | https://github.com/RobLoach/node-raylib | | node-raylib | 3.5 | [Node.js](https://nodejs.org/en/) | https://github.com/RobLoach/node-raylib |
| QuickJS-raylib | 3.0 | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib | | QuickJS-raylib | 3.0 | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib |
| raylib-js | 2.6 | [JavaScript](https://en.wikipedia.org/wiki/JavaScript) | https://github.com/RobLoach/raylib-js | | raylib-js | 2.6 | [JavaScript](https://en.wikipedia.org/wiki/JavaScript) | https://github.com/RobLoach/raylib-js |
| raylib-chaiscript | 2.6 | [ChaiScript](http://chaiscript.com/) | https://github.com/RobLoach/raylib-chaiscript | | raylib-chaiscript | 2.6 | [ChaiScript](http://chaiscript.com/) | https://github.com/RobLoach/raylib-chaiscript |

View File

@ -1,57 +1,29 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
project(raylib)
# Directory for easier includes
# Anywhere you see include(...) you can check <root>/cmake for that file
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# RAYLIB_IS_MAIN determines whether the project is being used from root
# or if it is added as a dependency (through add_subdirectory for example).
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(RAYLIB_IS_MAIN TRUE) set(RAYLIB_IS_MAIN TRUE)
else() else()
set(RAYLIB_IS_MAIN FALSE) set(RAYLIB_IS_MAIN FALSE)
endif() endif()
# Config options # Sets compiler flags and language standard
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN}) include(CompilerFlags)
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
# This helps support the case where emsdk toolchain file is used # Registers build options that are exposed to cmake
# either by setting it with -DCMAKE_TOOLCHAIN_FILE=<path_to_emsdk>/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake include(CMakeOptions.txt)
# or by using "emcmake cmake -B build -S ." as described in https://emscripten.org/docs/compiling/Building-Projects.html
if(EMSCRIPTEN)
SET(PLATFORM Web CACHE STRING "Forcing PLATFORM_WEB because EMSCRIPTEN was detected")
endif()
if(CMAKE_VERSION VERSION_LESS "3.1") # Enforces a few environment and compiler configurations
if(CMAKE_C_COMPILER_ID STREQUAL "GNU") include(BuildOptions)
set(CMAKE_C_FLAGS "-std=gnu99 ${CMAKE_C_FLAGS}")
endif()
else()
set (CMAKE_C_STANDARD 99)
endif()
include(AddIfFlagCompiles) # Main sources directory (the second parameter sets the output directory name to raylib)
add_if_flag_compiles(-Werror=pointer-arith CMAKE_C_FLAGS) add_subdirectory(src raylib)
add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
# src/external/jar_xm.h does shady stuff
add_if_flag_compiles(-fno-strict-aliasing CMAKE_C_FLAGS)
if (ENABLE_ASAN)
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=address CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
endif()
if (ENABLE_UBSAN)
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=undefined CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
endif()
if (ENABLE_MSAN)
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=memory CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
endif()
if (ENABLE_MSAN AND ENABLE_ASAN)
MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
endif()
add_subdirectory(src)
if (${BUILD_EXAMPLES}) if (${BUILD_EXAMPLES})
MESSAGE(STATUS "Building examples is enabled") MESSAGE(STATUS "Building examples is enabled")

89
CMakeOptions.txt Normal file
View File

@ -0,0 +1,89 @@
### Config options ###
include(CMakeDependentOption)
include(EnumOption)
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM" "Platform to build for.")
enum_option(OPENGL_VERSION "OFF;3.3;2.1;1.1;ES 2.0" "Force a specific OpenGL Version?")
# Configuration options
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN})
option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF)
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
option(WITH_PIC "Compile static library as position-independent code" OFF)
option(BUILD_SHARED_LIBS "Build raylib as a shared library" OFF)
option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF)
cmake_dependent_option(USE_AUDIO "Build raylib with audio module" ON CUSTOMIZE_BUILD ON)
enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one")
if(UNIX AND NOT APPLE)
option(USE_WAYLAND "Use Wayland for window creation" OFF)
endif()
option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage" OFF)
set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option")
# core.c
cmake_dependent_option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_DATA_STORAGE "Support for persistent data storage" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON)
# rlgl.h
cmake_dependent_option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON CUSTOMIZE_BUILD ON)
# shapes.c
cmake_dependent_option(SUPPORT_FONT_TEXTURE "Draw rectangle shapes using font texture white character instead of default white texture. Allows drawing rectangles and text with a single draw call, very useful for GUI systems!" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON CUSTOMIZE_BUILD ON)
# textures.c
cmake_dependent_option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF)
# text.c
cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON CUSTOMIZE_BUILD ON)
# models.c
cmake_dependent_option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON CUSTOMIZE_BUILD ON)
# raudio.c
cmake_dependent_option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF} CUSTOMIZE_BUILD OFF)
# utils.c
cmake_dependent_option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON CUSTOMIZE_BUILD ON)

View File

@ -79,6 +79,14 @@ You can download and install raylib using the [vcpkg](https://github.com/Microso
*The raylib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.* *The raylib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.*
#### Installing and building raylib via conan
You can download and install raylib using the [conan](https://conan.io) dependency manager:
https://docs.conan.io/en/latest/getting_started.html
*The raylib recipe in conan is kept up to date by conan team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the conan-center-index repository.*
#### Building raylib on multiple platforms #### Building raylib on multiple platforms
[raylib Wiki](https://github.com/raysan5/raylib/wiki#development-platforms) contains detailed instructions on building and usage on multiple platforms. [raylib Wiki](https://github.com/raysan5/raylib/wiki#development-platforms) contains detailed instructions on building and usage on multiple platforms.

18
cmake/BuildOptions.cmake Normal file
View File

@ -0,0 +1,18 @@
if(${PLATFORM} MATCHES "Desktop" AND APPLE)
if(MACOS_FATLIB)
if (CMAKE_OSX_ARCHITECTURES)
message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
else()
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
endif()
endif()
endif()
# This helps support the case where emsdk toolchain file is used
# either by setting it with -DCMAKE_TOOLCHAIN_FILE=<path_to_emsdk>/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
# or by using "emcmake cmake -B build -S ." as described in https://emscripten.org/docs/compiling/Building-Projects.html
if(EMSCRIPTEN)
SET(PLATFORM Web CACHE STRING "Forcing PLATFORM_WEB because EMSCRIPTEN was detected")
endif()
# vim: ft=cmake

View File

@ -1,43 +0,0 @@
# Set a default build type if none was specified
set(default_build_type "Release")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(default_build_type "Debug")
endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
# Taken from the https://github.com/OpenChemistry/tomviz project
# Copyright (c) 2014-2017, Kitware, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,109 @@
# Adding compile definitions
target_compile_definitions("raylib" PUBLIC "${PLATFORM_CPP}")
target_compile_definitions("raylib" PUBLIC "${GRAPHICS}")
function(define_if target variable)
if (${${variable}})
target_compile_definitions(${target} PUBLIC "${variable}")
endif ()
endfunction()
if (${CUSTOMIZE_BUILD})
target_compile_definitions("raylib" PUBLIC EXTERNAL_CONFIG_FLAGS)
define_if("raylib" SUPPORT_CAMERA_SYSTEM)
define_if("raylib" SUPPORT_GESTURES_SYSTEM)
define_if("raylib" SUPPORT_MOUSE_GESTURES)
define_if("raylib" SUPPORT_SSH_KEYBOARD_RPI)
define_if("raylib" SUPPORT_BUSY_WAIT_LOOP)
define_if("raylib" SUPPORT_EVENTS_WAITING)
define_if("raylib" SUPPORT_SCREEN_CAPTURE)
define_if("raylib" SUPPORT_GIF_RECORDING)
define_if("raylib" SUPPORT_HIGH_DPI)
define_if("raylib" SUPPORT_COMPRESSION_API)
define_if("raylib" SUPPORT_DATA_STORAGE)
define_if("raylib" SUPPORT_VR_SIMULATOR)
define_if("raylib" SUPPORT_FONT_TEXTURE)
define_if("raylib" SUPPORT_QUADS_DRAW_MODE)
define_if("raylib" SUPPORT_FILEFORMAT_PNG)
define_if("raylib" SUPPORT_FILEFORMAT_DDS)
define_if("raylib" SUPPORT_FILEFORMAT_HDR)
define_if("raylib" SUPPORT_FILEFORMAT_KTX)
define_if("raylib" SUPPORT_FILEFORMAT_ASTC)
define_if("raylib" SUPPORT_FILEFORMAT_BMP)
define_if("raylib" SUPPORT_FILEFORMAT_TGA)
define_if("raylib" SUPPORT_FILEFORMAT_JPG)
define_if("raylib" SUPPORT_FILEFORMAT_GIF)
define_if("raylib" SUPPORT_FILEFORMAT_PSD)
define_if("raylib" SUPPORT_FILEFORMAT_PKM)
define_if("raylib" SUPPORT_FILEFORMAT_PVR)
define_if("raylib" ORT_IMAGE_EXPORT)
define_if("raylib" SUPPORT_IMAGE_MANIPULATION)
define_if("raylib" SUPPORT_IMAGE_GENERATION)
define_if("raylib" SUPPORT_DEFAULT_FONT)
define_if("raylib" SUPPORT_FILEFORMAT_FNT)
define_if("raylib" SUPPORT_FILEFORMAT_TTF)
define_if("raylib" SUPPORT_TEXT_MANIPULATION)
define_if("raylib" SUPPORT_FILEFORMAT_OBJ)
define_if("raylib" SUPPORT_FILEFORMAT_MTL)
define_if("raylib" SUPPORT_FILEFORMAT_IQM)
define_if("raylib" SUPPORT_FILEFORMAT_GLTF)
define_if("raylib" SUPPORT_MESH_GENERATION)
define_if("raylib" SUPPORT_FILEFORMAT_WAV)
define_if("raylib" SUPPORT_FILEFORMAT_OGG)
define_if("raylib" SUPPORT_FILEFORMAT_XM)
define_if("raylib" SUPPORT_FILEFORMAT_MOD)
define_if("raylib" SUPPORT_FILEFORMAT_FLAC)
define_if("raylib" SUPPORT_FILEFORMAT_MP3)
define_if("raylib" SUPPORT_TRACELOG)
define_if("raylib" SUPPORT_COMPRESSION_API)
if (UNIX AND NOT APPLE)
target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=4096")
else ()
target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=512")
endif ()
target_compile_definitions("raylib" PUBLIC "MAX_GAMEPADS=4")
target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_AXIS=8")
target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_BUTTONS=32")
target_compile_definitions("raylib" PUBLIC "MAX_TOUCH_POINTS=10")
target_compile_definitions("raylib" PUBLIC "MAX_KEY_PRESSED_QUEUE=16")
target_compile_definitions("raylib" PUBLIC "STORAGE_DATA_FILE=\"storage.data\"")
target_compile_definitions("raylib" PUBLIC "MAX_KEY_PRESSED_QUEUE=16")
target_compile_definitions("raylib" PUBLIC "MAX_DECOMPRESSION_SIZE=64")
if (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_33" OR ${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_11")
target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=8192")
elseif (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES2")
target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=2048")
endif ()
target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_DRAWCALLS=256")
target_compile_definitions("raylib" PUBLIC "MAX_MATRIX_STACK_SIZE=32")
target_compile_definitions("raylib" PUBLIC "MAX_SHADER_LOCATIONS=32")
target_compile_definitions("raylib" PUBLIC "MAX_MATERIAL_MAPS=12")
target_compile_definitions("raylib" PUBLIC "RL_CULL_DISTANCE_NEAR=0.01")
target_compile_definitions("raylib" PUBLIC "RL_CULL_DISTANCE_FAR=1000.0")
target_compile_definitions("raylib" PUBLIC "DEFAULT_SHADER_ATTRIB_NAME_POSITION=\"vertexPosition\"")
target_compile_definitions("raylib" PUBLIC "DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD=\"vertexTexCoord\"")
target_compile_definitions("raylib" PUBLIC "DEFAULT_SHADER_ATTRIB_NAME_NORMAL=\"vertexNormal\"")
target_compile_definitions("raylib" PUBLIC "DEFAULT_SHADER_ATTRIB_NAME_COLOR=\"vertexColor\"")
target_compile_definitions("raylib" PUBLIC "DEFAULT_SHADER_ATTRIB_NAME_TANGENT=\"vertexTangent\"")
target_compile_definitions("raylib" PUBLIC "DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2=\"vertexTexCoord2\"")
target_compile_definitions("raylib" PUBLIC "MAX_TEXT_BUFFER_LENGTH=1024")
target_compile_definitions("raylib" PUBLIC "MAX_TEXT_UNICODE_CHARS=512")
target_compile_definitions("raylib" PUBLIC "MAX_TEXTSPLIT_COUNT=128")
target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_FORMAT=ma_format_f32")
target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_CHANNELS=2")
target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_SAMPLE_RATE=44100")
target_compile_definitions("raylib" PUBLIC "DEFAULT_AUDIO_BUFFER_SIZE=4096")
target_compile_definitions("raylib" PUBLIC "MAX_TRACELOG_MSG_LENGTH=128")
target_compile_definitions("raylib" PUBLIC "MAX_UWP_MESSAGES=512")
endif ()

79
cmake/CompilerFlags.cmake Normal file
View File

@ -0,0 +1,79 @@
include(AddIfFlagCompiles)
# Makes +/- operations on void pointers be considered an error
# https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
add_if_flag_compiles(-Werror=pointer-arith CMAKE_C_FLAGS)
# Generates error whenever a function is used before being declared
# https://gcc.gnu.org/onlinedocs/gcc-4.0.1/gcc/Warning-Options.html
add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
# Allows some casting of pointers without generating a warning
add_if_flag_compiles(-fno-strict-aliasing CMAKE_C_FLAGS)
if (ENABLE_MSAN AND ENABLE_ASAN)
# MSAN and ASAN both work on memory - ASAN does more things
MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
endif()
if (ENABLE_ASAN)
# If enabled it would generate errors/warnings for all kinds of memory errors
# (like returning a stack variable by reference)
# https://clang.llvm.org/docs/AddressSanitizer.html
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=address CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
endif()
if (ENABLE_UBSAN)
# If enabled this will generate errors for undefined behavior points
# (like adding +1 to the maximum int value)
# https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=undefined CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
endif()
if (ENABLE_MSAN)
# If enabled this will generate warnings for places where uninitialized memory is used
# https://clang.llvm.org/docs/MemorySanitizer.html
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=memory CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
endif()
if(CMAKE_VERSION VERSION_LESS "3.1")
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_if_flag_compiles(-std=gnu99 CMAKE_C_FLAGS)
endif()
else()
set (CMAKE_C_STANDARD 99)
endif()
if(${PLATFORM} MATCHES "Android")
# If enabled will remove dead code during the linking process
# https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html
add_if_flag_compiles(-ffunction-sections CMAKE_C_FLAGS)
# If enabled will generate some exception data (usually disabled for C programs)
# https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Code-Gen-Options.html
add_if_flag_compiles(-funwind-tables CMAKE_C_FLAGS)
# If enabled adds stack protection guards around functions that allocate memory
# https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_cjh1548250046139.htm
add_if_flag_compiles(-fstack-protector-strong CMAKE_C_FLAGS)
# Marks that the library will not be compiled with an executable stack
add_if_flag_compiles(-Wa,--noexecstack CMAKE_C_FLAGS)
# Do not expand symbolic links or resolve paths like "/./" or "/../", etc.
# https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
add_if_flag_compiles(-no-canonical-prefixes CMAKE_C_FLAGS)
endif()

34
cmake/GlfwImport.cmake Normal file
View File

@ -0,0 +1,34 @@
if(USE_EXTERNAL_GLFW STREQUAL "ON")
find_package(glfw3 3.2.1 REQUIRED)
elseif(USE_EXTERNAL_GLFW STREQUAL "IF_POSSIBLE")
find_package(glfw3 3.2.1 QUIET)
endif()
if (glfw3_FOUND)
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
endif()
# Explicitly check against "ON", because USE_EXTERNAL_GLFW is a tristate option
# Also adding only on desktop (web also uses glfw but it is more limited and is added using an emcc linker flag)
if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MATCHES "Desktop")
MESSAGE(STATUS "Using raylib's GLFW")
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
set(WAS_SHARED ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
add_subdirectory(external/glfw)
set(BUILD_SHARED_LIBS ${WAS_SHARED} CACHE BOOL " " FORCE)
unset(WAS_SHARED)
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>)
include_directories(BEFORE SYSTEM external/glfw/include)
else()
MESSAGE(STATUS "Using external GLFW")
set(GLFW_PKG_DEPS glfw3)
endif()

View File

@ -0,0 +1,29 @@
install(
TARGETS raylib EXPORT raylib-targets
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
# PKG_CONFIG_LIBS_PRIVATE is used in raylib.pc.in
if (NOT BUILD_SHARED_LIBS)
include(LibraryPathToLinkerFlags)
library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}")
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS})
string(REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}")
elseif (BUILD_SHARED_LIBS)
set(PKG_CONFIG_LIBS_EXTRA "")
endif ()
join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(../raylib.pc.in raylib.pc @ONLY)
configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
install(FILES ${PROJECT_SOURCE_DIR}/../cmake/raylib-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
# populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS}
include(PopulateConfigVariablesLocally)
populate_config_variables_locally(raylib)

View File

@ -0,0 +1,105 @@
if (${PLATFORM} MATCHES "Desktop")
set(PLATFORM_CPP "PLATFORM_DESKTOP")
if (APPLE)
# Need to force OpenGL 3.3 on OS X
# See: https://github.com/raysan5/raylib/issues/341
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
find_library(OPENGL_LIBRARY OpenGL)
set(LIBS_PRIVATE ${OPENGL_LIBRARY})
link_libraries("${LIBS_PRIVATE}")
if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
add_definitions(-DGL_SILENCE_DEPRECATION)
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
endif ()
elseif (WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm)
else ()
find_library(pthread NAMES pthread)
find_package(OpenGL QUIET)
if ("${OPENGL_LIBRARIES}" STREQUAL "")
set(OPENGL_LIBRARIES "GL")
endif ()
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
find_library(OSS_LIBRARY ossaudio)
endif ()
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
endif ()
elseif (${PLATFORM} MATCHES "Web")
set(PLATFORM_CPP "PLATFORM_WEB")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 --profiling")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
elseif (${PLATFORM} MATCHES "Android")
set(PLATFORM_CPP "PLATFORM_ANDROID")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_definitions(-DANDROID -D__ANDROID_API__=21)
include_directories(external/android/native_app_glue)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -uANativeActivity_onCreate")
find_library(OPENGL_LIBRARY OpenGL)
set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c)
elseif (${PLATFORM} MATCHES "Raspberry Pi")
set(PLATFORM_CPP "PLATFORM_RPI")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
add_definitions(-D_DEFAULT_SOURCE)
find_library(GLESV2 brcmGLESv2 HINTS /opt/vc/lib)
find_library(EGL brcmEGL HINTS /opt/vc/lib)
find_library(BCMHOST bcm_host HINTS /opt/vc/lib)
include_directories(/opt/vc/include /opt/vc/include/interface/vmcs_host/linux /opt/vc/include/interface/vcos/pthreads)
link_directories(/opt/vc/lib)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl)
elseif (${PLATFORM} MATCHES "DRM")
set(PLATFORM_CPP "PLATFORM_DRM")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
add_definitions(-D_DEFAULT_SOURCE)
add_definitions(-DEGL_NO_X11)
add_definitions(-DPLATFORM_DRM)
find_library(GLESV2 GLESv2)
find_library(EGL EGL)
find_library(DRM drm)
find_library(GBM gbm)
include_directories(/usr/include/libdrm)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl)
endif ()
if (${OPENGL_VERSION})
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
if (${OPENGL_VERSION} MATCHES "3.3")
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
elseif (${OPENGL_VERSION} MATCHES "2.1")
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
elseif (${OPENGL_VERSION} MATCHES "1.1")
set(GRAPHICS "GRAPHICS_API_OPENGL_11")
elseif (${OPENGL_VERSION} MATCHES "ES 2.0")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
endif ()
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
endif ()
endif ()
if (NOT GRAPHICS)
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
endif ()
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
if (${PLATFORM} MATCHES "Desktop")
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
endif ()

View File

@ -0,0 +1,13 @@
# Packaging
SET(CPACK_PACKAGE_NAME "raylib")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to enjoy videogames programming")
SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/../README.md")
SET(CPACK_RESOURCE_FILE_WELCOME "${PROJECT_SOURCE_DIR}/../README.md")
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE")
SET(CPACK_PACKAGE_FILE_NAME "raylib-${PROJECT_VERSION}$ENV{RAYLIB_PACKAGE_SUFFIX}")
SET(CPACK_GENERATOR "ZIP;TGZ") # Remove this, if you want the NSIS installer on Windows
include(CPack)

View File

@ -1,23 +0,0 @@
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR x86)
if (CMAKE_HOST_WIN32)
SET(EMSCRIPTEN_EXTENSION ".bat")
else ()
SET(EMSCRIPTEN_EXTENSION "")
endif()
SET(CMAKE_C_COMPILER emcc${EMSCRIPTEN_EXTENSION})
SET(CMAKE_CXX_COMPILER em++${EMSCRIPTEN_EXTENSION})
if(NOT DEFINED CMAKE_AR)
find_program(CMAKE_AR NAMES emar${EMSCRIPTEN_EXTENSION})
endif()
if(NOT DEFINED CMAKE_RANLIB)
find_program(CMAKE_RANLIB NAMES emranlib${EMSCRIPTEN_EXTENSION})
endif()
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -1,21 +0,0 @@
#!/bin/sh
# Test if including/linking/running an installed raylib works
set -x
export LD_RUN_PATH=/usr/local/lib
CFLAGS="-Wall -Wextra -Werror $CFLAGS"
if [ "$ARCH" = "i386" ]; then
CFLAGS="-m32 $CLFAGS"
fi
cat << EOF | ${CC:-cc} -otest -xc - $(pkg-config --libs --cflags $@ raylib.pc) $CFLAGS && exec ./test
#include <stdlib.h>
#include <raylib.h>
int main(void)
{
int num = GetRandomValue(42, 1337);
return 42 <= num && num <= 1337 ? EXIT_SUCCESS : EXIT_FAILURE;
}
EOF

View File

@ -1,137 +1,138 @@
# Setup the project and settings # Setup the project and settings
project(examples) project(examples)
# Get the sources together # Directories that contain examples
set(example_dirs audio core models others shaders shapes text textures) set(example_dirs
audio
core
models
others
shaders
shapes
text
textures
)
# Next few lines will check for existence of symbols or header files
# They are needed for the physac example and threads examples
set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=199309L) set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=199309L)
include(CheckSymbolExists) include(CheckSymbolExists)
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC) check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC) check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC)
set(CMAKE_REQUIRED_DEFINITIONS) set(CMAKE_REQUIRED_DEFINITIONS)
if(HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
set(example_dirs ${example_dirs} physac)
endif()
set(example_sources) if (HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
set(example_resources) set(example_dirs ${example_dirs} physac)
foreach(example_dir ${example_dirs}) endif ()
# Get the .c files
file(GLOB sources ${example_dir}/*.c)
list(APPEND example_sources ${sources})
# Any any resources
file(GLOB resources ${example_dir}/resources/*)
list(APPEND example_resources ${resources})
endforeach()
if (APPLE AND NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
add_definitions(-DGL_SILENCE_DEPRECATION)
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
endif()
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
include(CheckIncludeFile) include(CheckIncludeFile)
CHECK_INCLUDE_FILE("stdatomic.h" HAVE_STDATOMIC_H) CHECK_INCLUDE_FILE("stdatomic.h" HAVE_STDATOMIC_H)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads) find_package(Threads)
if (CMAKE_USE_PTHREADS_INIT AND HAVE_STDATOMIC_H) if (CMAKE_USE_PTHREADS_INIT AND HAVE_STDATOMIC_H)
add_if_flag_compiles("-std=c11" CMAKE_C_FLAGS) add_if_flag_compiles("-std=c11" CMAKE_C_FLAGS)
if(THREADS_HAVE_PTHREAD_ARG) if (THREADS_HAVE_PTHREAD_ARG)
add_if_flag_compiles("-pthread" CMAKE_C_FLAGS) add_if_flag_compiles("-pthread" CMAKE_C_FLAGS)
endif() endif ()
if(CMAKE_THREAD_LIBS_INIT) if (CMAKE_THREAD_LIBS_INIT)
link_libraries("${CMAKE_THREAD_LIBS_INIT}") link_libraries("${CMAKE_THREAD_LIBS_INIT}")
endif() endif ()
else() endif ()
# Items requiring pthreads
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_loading_thread.c)
endif()
if (APPLE AND NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
add_definitions(-DGL_SILENCE_DEPRECATION)
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
endif ()
if(${PLATFORM} MATCHES "Android") # Collect all source files and resource files
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c) # into a CMake variable
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c) set(example_sources)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_picking.c) set(example_resources)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_vr_simulator.c) foreach (example_dir ${example_dirs})
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_camera_free.c) # Get the .c files
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_camera_first_person.c) file(GLOB sources ${example_dir}/*.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_world_screen.c) list(APPEND example_sources ${sources})
# Any any resources
file(GLOB resources ${example_dir}/resources/*)
list(APPEND example_resources ${resources})
endforeach ()
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c) if(NOT CMAKE_USE_PTHREADS_INIT OR NOT HAVE_STDATOMIC_H)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_material_pbr.c) # Items requiring pthreads
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_cubicmap.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_loading_thread.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_skybox.c) endif ()
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_generation.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_heightmap.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_billboard.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_full_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_obj_viewer.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_animation.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_first_person_maze.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c) if (${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_picking.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_vr_simulator.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_camera_free.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_camera_first_person.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_world_screen.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_material_pbr.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_cubicmap.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_skybox.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_generation.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_heightmap.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_billboard.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_full_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_solar_system.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_obj_viewer.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_animation.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_first_person_maze.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
elseif(${PLATFORM} MATCHES "Web") elseif (${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads # Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
set(CMAKE_EXECUTABLE_SUFFIX ".html") set(CMAKE_EXECUTABLE_SUFFIX ".html")
# Remove the -rdynamic flag because otherwise emscripten # Remove the -rdynamic flag because otherwise emscripten
# does not generate HTML+JS+WASM files, only a non-working # does not generate HTML+JS+WASM files, only a non-working
# and fat HTML # and fat HTML
string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}") string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}")
endif() endif ()
include_directories(BEFORE SYSTEM others/external/include) include_directories(BEFORE SYSTEM others/external/include)
if (NOT TARGET raylib) if (NOT TARGET raylib)
find_package(raylib 2.0 REQUIRED) find_package(raylib 2.0 REQUIRED)
endif() endif ()
# Do each example # Do each example
foreach(example_source ${example_sources}) foreach (example_source ${example_sources})
# Create the basename for the example
get_filename_component(example_name ${example_source} NAME)
string(REPLACE ".c" "" example_name ${example_name})
# Setup the example
add_executable(${example_name} ${example_source})
target_link_libraries(${example_name} raylib)
string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
string(APPEND resources_dir "resources")
if(${PLATFORM} MATCHES "Web" AND EXISTS ${resources_dir})
# The local resources path needs to be mapped to /resources virtual path
string(APPEND resources_dir "@resources")
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}")
endif()
endforeach()
if (${PLATFORM} MATCHES "Desktop")
# rlgl_standalone can't be linked with raylib because of duplicate rlgl symbols
foreach (example_source "others/rlgl_standalone.c")
# Create the basename for the example # Create the basename for the example
get_filename_component(example_name ${example_source} NAME) get_filename_component(example_name ${example_source} NAME)
string(REPLACE ".c" "" example_name ${example_name}) string(REPLACE ".c" "" example_name ${example_name})
# Setup the example
add_executable(${example_name} ${example_source}) add_executable(${example_name} ${example_source})
add_dependencies(${example_name} raylib)
target_link_libraries(${example_name} ${raylib_LDFLAGS}) target_link_libraries(${example_name} raylib)
target_include_directories(${example_name} PRIVATE ${raylib_INCLUDE_DIRS})
string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
endforeach() string(APPEND resources_dir "resources")
endif()
if (${PLATFORM} MATCHES "Web" AND EXISTS ${resources_dir})
# The local resources path needs to be mapped to /resources virtual path
string(APPEND resources_dir "@resources")
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}")
endif ()
endforeach ()
# Copy all of the resource files to the destination # Copy all of the resource files to the destination
file(COPY ${example_resources} DESTINATION "resources/") file(COPY ${example_resources} DESTINATION "resources/")

View File

@ -41,27 +41,27 @@ float RadicalInverseVdC(uint bits)
// Compute Hammersley coordinates // Compute Hammersley coordinates
vec2 Hammersley(uint i, uint N) vec2 Hammersley(uint i, uint N)
{ {
return vec2(float(i)/float(N), RadicalInverseVdC(i)); return vec2(float(i)/float(N), RadicalInverseVdC(i));
} }
// Integrate number of importance samples for (roughness and NoV) // Integrate number of importance samples for (roughness and NoV)
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
{ {
float a = roughness*roughness; float a = roughness*roughness;
float phi = 2.0 * PI * Xi.x; float phi = 2.0 * PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y)); float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta); float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
// Transform from spherical coordinates to cartesian coordinates (halfway vector) // Transform from spherical coordinates to cartesian coordinates (halfway vector)
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta); vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
// Transform from tangent space H vector to world space sample vector // Transform from tangent space H vector to world space sample vector
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0)); vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
vec3 tangent = normalize(cross(up, N)); vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent); vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z; vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
return normalize(sampleVec); return normalize(sampleVec);
} }
float GeometrySchlickGGX(float NdotV, float roughness) float GeometrySchlickGGX(float NdotV, float roughness)

View File

@ -54,26 +54,26 @@ float RadicalInverse_VdC(uint bits)
vec2 Hammersley(uint i, uint N) vec2 Hammersley(uint i, uint N)
{ {
return vec2(float(i)/float(N), RadicalInverse_VdC(i)); return vec2(float(i)/float(N), RadicalInverse_VdC(i));
} }
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
{ {
float a = roughness*roughness; float a = roughness*roughness;
float phi = 2.0*PI*Xi.x; float phi = 2.0*PI*Xi.x;
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y)); float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta); float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
// Transform from spherical coordinates to cartesian coordinates (halfway vector) // Transform from spherical coordinates to cartesian coordinates (halfway vector)
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta); vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
// Transform from tangent space H vector to world space sample vector // Transform from tangent space H vector to world space sample vector
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0)); vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
vec3 tangent = normalize(cross(up, N)); vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent); vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z; vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
return normalize(sampleVec); return normalize(sampleVec);
} }
void main() void main()

View File

@ -4,7 +4,7 @@
* *
* Copyright (c) 2017 Victor Fisac * Copyright (c) 2017 Victor Fisac
* *
* 19-Jun-2020 - modified by Giuseppe Mastrangelo (@peppemas) - VFlip Support * 19-Jun-2020 - modified by Giuseppe Mastrangelo (@peppemas) - VFlip Support
* *
**********************************************************************************************/ **********************************************************************************************/

View File

@ -1,24 +1,19 @@
/******************************************************************************************* /*******************************************************************************************
* *
* Physac - Physics demo * raylib [physac] example - physics demo
* *
* NOTE 1: Physac requires multi-threading, when InitPhysics() a second thread is created to manage physics calculations. * This example has been created using raylib 1.5 (www.raylib.com)
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Use the following line to compile: * This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
* *
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / * Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
* Copyright (c) 2016-2018 Victor Fisac
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#define PHYSAC_NO_THREADS
#include "physac.h" #include "physac.h"
int main(void) int main(void)
@ -29,12 +24,11 @@ int main(void)
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics demo"); InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics demo");
// Physac logo drawing position // Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoX = screenWidth - MeasureText("Physac", 30) - 10;
int logoY = 15; int logoY = 15;
bool needsReset = false;
// Initialize physics and default physics bodies // Initialize physics and default physics bodies
InitPhysics(); InitPhysics();
@ -55,25 +49,17 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Delay initialization of variables due to physics reset async UpdatePhysics(); // Update physics system
RunPhysicsStep();
if (needsReset) if (IsKeyPressed('R')) // Reset physics system
{ {
ResetPhysics();
floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2, screenHeight }, 500, 100, 10); floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2, screenHeight }, 500, 100, 10);
floor->enabled = false; floor->enabled = false;
circle = CreatePhysicsBodyCircle((Vector2){ screenWidth/2, screenHeight/2 }, 45, 10); circle = CreatePhysicsBodyCircle((Vector2){ screenWidth/2, screenHeight/2 }, 45, 10);
circle->enabled = false; circle->enabled = false;
needsReset = false;
}
// Reset physics input
if (IsKeyPressed('R'))
{
ResetPhysics();
needsReset = true;
} }
// Physics body creation inputs // Physics body creation inputs

View File

@ -1,24 +1,19 @@
/******************************************************************************************* /*******************************************************************************************
* *
* Physac - Physics friction * raylib [physac] example - physics friction
* *
* NOTE 1: Physac requires multi-threading, when InitPhysics() a second thread is created to manage physics calculations. * This example has been created using raylib 1.5 (www.raylib.com)
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Use the following line to compile: * This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
* *
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / * Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
* Copyright (c) 2016-2018 Victor Fisac
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#define PHYSAC_NO_THREADS
#include "physac.h" #include "physac.h"
int main(void) int main(void)
@ -29,7 +24,7 @@ int main(void)
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics friction"); InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics friction");
// Physac logo drawing position // Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoX = screenWidth - MeasureText("Physac", 30) - 10;
@ -73,9 +68,9 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
RunPhysicsStep(); UpdatePhysics(); // Update physics system
if (IsKeyPressed('R')) // Reset physics input if (IsKeyPressed('R')) // Reset physics system
{ {
// Reset dynamic physics bodies position, velocity and rotation // Reset dynamic physics bodies position, velocity and rotation
bodyA->position = (Vector2){ 35, screenHeight*0.6f }; bodyA->position = (Vector2){ 35, screenHeight*0.6f };

View File

@ -1,24 +1,19 @@
/******************************************************************************************* /*******************************************************************************************
* *
* Physac - Physics movement * raylib [physac] example - physics movement
* *
* NOTE 1: Physac requires multi-threading, when InitPhysics() a second thread is created to manage physics calculations. * This example has been created using raylib 1.5 (www.raylib.com)
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Use the following line to compile: * This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
* *
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / * Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
* Copyright (c) 2016-2018 Victor Fisac
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#define PHYSAC_NO_THREADS
#include "physac.h" #include "physac.h"
#define VELOCITY 0.5f #define VELOCITY 0.5f
@ -31,7 +26,7 @@ int main(void)
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics movement"); InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics movement");
// Physac logo drawing position // Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoX = screenWidth - MeasureText("Physac", 30) - 10;
@ -66,9 +61,9 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
RunPhysicsStep(); UpdatePhysics(); // Update physics system
if (IsKeyPressed('R')) // Reset physics input if (IsKeyPressed('R')) // Reset physics input
{ {
// Reset movement physics body position, velocity and rotation // Reset movement physics body position, velocity and rotation
body->position = (Vector2){ screenWidth/2, screenHeight/2 }; body->position = (Vector2){ screenWidth/2, screenHeight/2 };

View File

@ -1,24 +1,19 @@
/******************************************************************************************* /*******************************************************************************************
* *
* Physac - Physics restitution * raylib [physac] example - physics restitution
* *
* NOTE 1: Physac requires multi-threading, when InitPhysics() a second thread is created to manage physics calculations. * This example has been created using raylib 1.5 (www.raylib.com)
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Use the following line to compile: * This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
* *
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / * Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
* Copyright (c) 2016-2018 Victor Fisac
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#define PHYSAC_NO_THREADS
#include "physac.h" #include "physac.h"
int main(void) int main(void)
@ -29,7 +24,7 @@ int main(void)
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics restitution"); InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics restitution");
// Physac logo drawing position // Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoX = screenWidth - MeasureText("Physac", 30) - 10;
@ -62,9 +57,9 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
RunPhysicsStep(); UpdatePhysics(); // Update physics system
if (IsKeyPressed('R')) // Reset physics input if (IsKeyPressed('R')) // Reset physics input
{ {
// Reset circles physics bodies position and velocity // Reset circles physics bodies position and velocity
circleA->position = (Vector2){ screenWidth*0.25f, screenHeight/2 }; circleA->position = (Vector2){ screenWidth*0.25f, screenHeight/2 };
@ -124,6 +119,7 @@ int main(void)
DestroyPhysicsBody(circleB); DestroyPhysicsBody(circleB);
DestroyPhysicsBody(circleC); DestroyPhysicsBody(circleC);
DestroyPhysicsBody(floor); DestroyPhysicsBody(floor);
ClosePhysics(); // Unitialize physics ClosePhysics(); // Unitialize physics
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context

View File

@ -1,24 +1,19 @@
/******************************************************************************************* /*******************************************************************************************
* *
* Physac - Body shatter * raylib [physac] example - physics shatter
* *
* NOTE 1: Physac requires multi-threading, when InitPhysics() a second thread is created to manage physics calculations. * This example has been created using raylib 1.5 (www.raylib.com)
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Use the following line to compile: * This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
* *
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static / * Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
*
* Copyright (c) 2016-2018 Victor Fisac
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#define PHYSAC_NO_THREADS
#include "physac.h" #include "physac.h"
int main(void) int main(void)
@ -29,12 +24,11 @@ int main(void)
const int screenHeight = 450; const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Body shatter"); InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics shatter");
// Physac logo drawing position // Physac logo drawing position
int logoX = screenWidth - MeasureText("Physac", 30) - 10; int logoX = screenWidth - MeasureText("Physac", 30) - 10;
int logoY = 15; int logoY = 15;
bool needsReset = false;
// Initialize physics and default physics bodies // Initialize physics and default physics bodies
InitPhysics(); InitPhysics();
@ -49,31 +43,23 @@ int main(void)
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
// Update
RunPhysicsStep();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Delay initialization of variables due to physics reset asynchronous UpdatePhysics(); // Update physics system
if (needsReset)
{ if (IsKeyPressed('R')) // Reset physics input
// Create random polygon physics body to shatter
CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
needsReset = false;
}
if (IsKeyPressed('R')) // Reset physics input
{ {
ResetPhysics(); ResetPhysics();
needsReset = true;
CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
} }
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) // Physics shatter input if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) // Physics shatter input
{ {
// Note: some values need to be stored in variables due to asynchronous changes during main thread
int count = GetPhysicsBodiesCount(); int count = GetPhysicsBodiesCount();
for (int i = count - 1; i >= 0; i--) for (int i = count - 1; i >= 0; i--)
{ {
PhysicsBody currentBody = GetPhysicsBody(i); PhysicsBody currentBody = GetPhysicsBody(i);
if (currentBody != NULL) PhysicsShatter(currentBody, GetMousePosition(), 10/currentBody->inverseMass); if (currentBody != NULL) PhysicsShatter(currentBody, GetMousePosition(), 10/currentBody->inverseMass);
} }
} }

View File

@ -14,7 +14,7 @@ uniform vec4 colDiffuse;
const vec2 size = vec2(800, 450); // render size const vec2 size = vec2(800, 450); // render size
const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance
const float quality = 2.5; // lower = smaller glow, better quality const float quality = 2.5; // lower = smaller glow, better quality
void main() void main()
{ {

View File

@ -34,4 +34,4 @@ void main()
color = color/9.5; color = color/9.5;
gl_FragColor = color; gl_FragColor = color;
} }

View File

@ -42,7 +42,7 @@ uniform vec2 resolution;
float sdPlane( vec3 p ) float sdPlane( vec3 p )
{ {
return p.y; return p.y;
} }
float sdSphere( vec3 p, float s ) float sdSphere( vec3 p, float s )
@ -85,9 +85,9 @@ float sdHexPrism( vec3 p, vec2 h )
float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
{ {
vec3 pa = p-a, ba = b-a; vec3 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h ) - r; return length( pa - ba*h ) - r;
} }
float sdEquilateralTriangle( in vec2 p ) float sdEquilateralTriangle( in vec2 p )
@ -154,19 +154,19 @@ float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
float length2( vec2 p ) float length2( vec2 p )
{ {
return sqrt( p.x*p.x + p.y*p.y ); return sqrt( p.x*p.x + p.y*p.y );
} }
float length6( vec2 p ) float length6( vec2 p )
{ {
p = p*p*p; p = p*p; p = p*p*p; p = p*p;
return pow( p.x + p.y, 1.0/6.0 ); return pow( p.x + p.y, 1.0/6.0 );
} }
float length8( vec2 p ) float length8( vec2 p )
{ {
p = p*p; p = p*p; p = p*p; p = p*p; p = p*p; p = p*p;
return pow( p.x + p.y, 1.0/8.0 ); return pow( p.x + p.y, 1.0/8.0 );
} }
float sdTorus82( vec3 p, vec2 t ) float sdTorus82( vec3 p, vec2 t )
@ -195,7 +195,7 @@ float opS( float d1, float d2 )
vec2 opU( vec2 d1, vec2 d2 ) vec2 opU( vec2 d1, vec2 d2 )
{ {
return (d1.x<d2.x) ? d1 : d2; return (d1.x<d2.x) ? d1 : d2;
} }
vec3 opRep( vec3 p, vec3 c ) vec3 opRep( vec3 p, vec3 c )
@ -216,25 +216,25 @@ vec3 opTwist( vec3 p )
vec2 map( in vec3 pos ) vec2 map( in vec3 pos )
{ {
vec2 res = opU( vec2( sdPlane( pos), 1.0 ), vec2 res = opU( vec2( sdPlane( pos), 1.0 ),
vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) ); vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) );
res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) ); res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) );
res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) ); res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) );
res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) ); res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) );
res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) ); res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) );
res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) ); res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) );
res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) ); res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) );
res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) ); res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) );
res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) ); res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) );
res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) ); res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) );
res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) ); res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) );
res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) ); res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) );
res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) ); res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) );
res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05),
sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) ); sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) );
res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)),
sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) ); sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) );
res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) ); res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) );
res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) ); res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) );
res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) ); res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) );
res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) ); res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) );
@ -257,11 +257,11 @@ vec2 castRay( in vec3 ro, in vec3 rd )
float m = -1.0; float m = -1.0;
for( int i=0; i<64; i++ ) for( int i=0; i<64; i++ )
{ {
float precis = 0.0005*t; float precis = 0.0005*t;
vec2 res = map( ro+rd*t ); vec2 res = map( ro+rd*t );
if( res.x<precis || t>tmax ) break; if( res.x<precis || t>tmax ) break;
t += res.x; t += res.x;
m = res.y; m = res.y;
} }
if( t>tmax ) m=-1.0; if( t>tmax ) m=-1.0;
@ -271,11 +271,11 @@ vec2 castRay( in vec3 ro, in vec3 rd )
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
{ {
float res = 1.0; float res = 1.0;
float t = mint; float t = mint;
for( int i=0; i<16; i++ ) for( int i=0; i<16; i++ )
{ {
float h = map( ro + rd*t ).x; float h = map( ro + rd*t ).x;
res = min( res, 8.0*h/t ); res = min( res, 8.0*h/t );
t += clamp( h, 0.02, 0.10 ); t += clamp( h, 0.02, 0.10 );
if( h<0.001 || t>tmax ) break; if( h<0.001 || t>tmax ) break;
@ -287,22 +287,22 @@ vec3 calcNormal( in vec3 pos )
{ {
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize( e.xyy*map( pos + e.xyy ).x + return normalize( e.xyy*map( pos + e.xyy ).x +
e.yyx*map( pos + e.yyx ).x + e.yyx*map( pos + e.yyx ).x +
e.yxy*map( pos + e.yxy ).x + e.yxy*map( pos + e.yxy ).x +
e.xxx*map( pos + e.xxx ).x ); e.xxx*map( pos + e.xxx ).x );
/* /*
vec3 eps = vec3( 0.0005, 0.0, 0.0 ); vec3 eps = vec3( 0.0005, 0.0, 0.0 );
vec3 nor = vec3( vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x, map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x, map(pos+eps.yxy).x - map(pos-eps.yxy).x,
map(pos+eps.yyx).x - map(pos-eps.yyx).x ); map(pos+eps.yyx).x - map(pos-eps.yyx).x );
return normalize(nor); return normalize(nor);
*/ */
} }
float calcAO( in vec3 pos, in vec3 nor ) float calcAO( in vec3 pos, in vec3 nor )
{ {
float occ = 0.0; float occ = 0.0;
float sca = 1.0; float sca = 1.0;
for( int i=0; i<5; i++ ) for( int i=0; i<5; i++ )
{ {
@ -331,7 +331,7 @@ vec3 render( in vec3 ro, in vec3 rd )
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd); vec2 res = castRay(ro,rd);
float t = res.x; float t = res.x;
float m = res.y; float m = res.y;
if( m>-0.5 ) if( m>-0.5 )
{ {
vec3 pos = ro + t*rd; vec3 pos = ro + t*rd;
@ -339,7 +339,7 @@ vec3 render( in vec3 ro, in vec3 rd )
vec3 ref = reflect( rd, nor ); vec3 ref = reflect( rd, nor );
// material // material
col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
if( m<1.5 ) if( m<1.5 )
{ {
@ -349,9 +349,9 @@ vec3 render( in vec3 ro, in vec3 rd )
// lighting // lighting
float occ = calcAO( pos, nor ); float occ = calcAO( pos, nor );
vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
vec3 hal = normalize( lig-rd ); vec3 hal = normalize( lig-rd );
float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
float dom = smoothstep( -0.1, 0.1, ref.y ); float dom = smoothstep( -0.1, 0.1, ref.y );
@ -360,31 +360,31 @@ vec3 render( in vec3 ro, in vec3 rd )
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
dif * dif *
(0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
vec3 lin = vec3(0.0); vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55); lin += 1.30*dif*vec3(1.00,0.80,0.55);
lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ; lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ;
lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ; lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ;
lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ; lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ;
lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ; lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ;
col = col*lin; col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70); col += 10.00*spe*vec3(1.00,0.90,0.70);
col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
} }
return vec3( clamp(col,0.0,1.0) ); return vec3( clamp(col,0.0,1.0) );
} }
mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{ {
vec3 cw = normalize(ta-ro); vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0); vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) ); vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) ); vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw ); return mat3( cu, cv, cw );
} }
@ -402,7 +402,7 @@ void main()
vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y; vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y;
#endif #endif
// RAY: Camera is provided from raylib // RAY: Camera is provided from raylib
//vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) ); //vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) );
vec3 ro = viewEye; vec3 ro = viewEye;
@ -413,10 +413,10 @@ void main()
// ray direction // ray direction
vec3 rd = ca * normalize( vec3(p.xy,2.0) ); vec3 rd = ca * normalize( vec3(p.xy,2.0) );
// render // render
vec3 col = render( ro, rd ); vec3 col = render( ro, rd );
// gamma // gamma
col = pow( col, vec3(0.4545) ); col = pow( col, vec3(0.4545) );
tot += col; tot += col;

View File

@ -15,26 +15,26 @@ vec2 resolution = vec2(800.0, 450.0);
void main() void main()
{ {
float x = 1.0/resolution.x; float x = 1.0/resolution.x;
float y = 1.0/resolution.y; float y = 1.0/resolution.y;
vec4 horizEdge = vec4(0.0); vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0); vec4 vertEdge = vec4(0.0);
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb));
gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a); gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a);
} }

View File

@ -5,9 +5,9 @@ precision mediump float;
#define MAX_SPOTS 3 #define MAX_SPOTS 3
struct Spot { struct Spot {
vec2 pos; // window coords of spot vec2 pos; // window coords of spot
float inner; // inner fully transparent centre radius float inner; // inner fully transparent centre radius
float radius; // alpha fades out to this radius float radius; // alpha fades out to this radius
}; };
uniform Spot spots[MAX_SPOTS]; // Spotlight positions array uniform Spot spots[MAX_SPOTS]; // Spotlight positions array
@ -15,63 +15,63 @@ uniform float screenWidth; // Width of the screen
void main() void main()
{ {
float alpha = 1.0; float alpha = 1.0;
// Get the position of the current fragment (screen coordinates!) // Get the position of the current fragment (screen coordinates!)
vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y); vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
// Find out which spotlight is nearest // Find out which spotlight is nearest
float d = 65000.0; // some high value float d = 65000.0; // some high value
int fi = -1; // found index int fi = -1; // found index
for (int i = 0; i < MAX_SPOTS; i++) for (int i = 0; i < MAX_SPOTS; i++)
{ {
for (int j = 0; j < MAX_SPOTS; j++) for (int j = 0; j < MAX_SPOTS; j++)
{ {
float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius; float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
if (d > dj) if (d > dj)
{ {
d = dj; d = dj;
fi = i; fi = i;
} }
} }
} }
// d now equals distance to nearest spot... // d now equals distance to nearest spot...
// allowing for the different radii of all spotlights // allowing for the different radii of all spotlights
if (fi == 0) if (fi == 0)
{ {
if (d > spots[0].radius) alpha = 1.0; if (d > spots[0].radius) alpha = 1.0;
else else
{ {
if (d < spots[0].inner) alpha = 0.0; if (d < spots[0].inner) alpha = 0.0;
else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner); else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner);
} }
} }
else if (fi == 1) else if (fi == 1)
{ {
if (d > spots[1].radius) alpha = 1.0; if (d > spots[1].radius) alpha = 1.0;
else else
{ {
if (d < spots[1].inner) alpha = 0.0; if (d < spots[1].inner) alpha = 0.0;
else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner); else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner);
} }
} }
else if (fi == 2) else if (fi == 2)
{ {
if (d > spots[2].radius) alpha = 1.0; if (d > spots[2].radius) alpha = 1.0;
else else
{ {
if (d < spots[2].inner) alpha = 0.0; if (d < spots[2].inner) alpha = 0.0;
else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner); else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner);
} }
} }
// Right hand side of screen is dimly lit, // Right hand side of screen is dimly lit,
// could make the threshold value user definable // could make the threshold value user definable
if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9; if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
// could make the black out colour user definable... // could make the black out colour user definable...
gl_FragColor = vec4(0, 0, 0, alpha); gl_FragColor = vec4(0, 0, 0, alpha);
} }

View File

@ -22,15 +22,15 @@ uniform float speedX;
uniform float speedY; uniform float speedY;
void main() { void main() {
float pixelWidth = 1.0 / size.x; float pixelWidth = 1.0 / size.x;
float pixelHeight = 1.0 / size.y; float pixelHeight = 1.0 / size.y;
float aspect = pixelHeight / pixelWidth; float aspect = pixelHeight / pixelWidth;
float boxLeft = 0.0; float boxLeft = 0.0;
float boxTop = 0.0; float boxTop = 0.0;
vec2 p = fragTexCoord; vec2 p = fragTexCoord;
p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth;
p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight;
gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor; gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor;
} }

View File

@ -12,7 +12,7 @@ uniform vec4 colDiffuse;
const vec2 size = vec2(800, 450); // render size const vec2 size = vec2(800, 450); // render size
const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance
const float quality = 2.5; // lower = smaller glow, better quality const float quality = 2.5; // lower = smaller glow, better quality
void main() void main()
{ {

View File

@ -32,4 +32,4 @@ void main()
color = color/9.5; color = color/9.5;
gl_FragColor = color; gl_FragColor = color;
} }

View File

@ -13,26 +13,26 @@ vec2 resolution = vec2(800.0, 450.0);
void main() void main()
{ {
float x = 1.0/resolution.x; float x = 1.0/resolution.x;
float y = 1.0/resolution.y; float y = 1.0/resolution.y;
vec4 horizEdge = vec4(0.0); vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0); vec4 vertEdge = vec4(0.0);
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb));
gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a); gl_FragColor = vec4(edge, texture2D(texture0, fragTexCoord).a);
} }

View File

@ -15,7 +15,7 @@ out vec4 finalColor;
const vec2 size = vec2(800, 450); // render size const vec2 size = vec2(800, 450); // render size
const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance
const float quality = 2.5; // lower = smaller glow, better quality const float quality = 2.5; // lower = smaller glow, better quality
void main() void main()
{ {

View File

@ -31,4 +31,4 @@ void main()
color = color/9.5; color = color/9.5;
fragColor = color; fragColor = color;
} }

View File

@ -38,9 +38,9 @@ vec4 Colorizer(float counter, float maxSize)
void main() void main()
{ {
vec4 color = vec4(1.0); vec4 color = vec4(1.0);
float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid. float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid.
int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values
if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0); if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0);
else else

View File

@ -43,7 +43,7 @@ uniform vec2 resolution;
float sdPlane( vec3 p ) float sdPlane( vec3 p )
{ {
return p.y; return p.y;
} }
float sdSphere( vec3 p, float s ) float sdSphere( vec3 p, float s )
@ -86,9 +86,9 @@ float sdHexPrism( vec3 p, vec2 h )
float sdCapsule( vec3 p, vec3 a, vec3 b, float r ) float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
{ {
vec3 pa = p-a, ba = b-a; vec3 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h ) - r; return length( pa - ba*h ) - r;
} }
float sdEquilateralTriangle( in vec2 p ) float sdEquilateralTriangle( in vec2 p )
@ -155,19 +155,19 @@ float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
float length2( vec2 p ) float length2( vec2 p )
{ {
return sqrt( p.x*p.x + p.y*p.y ); return sqrt( p.x*p.x + p.y*p.y );
} }
float length6( vec2 p ) float length6( vec2 p )
{ {
p = p*p*p; p = p*p; p = p*p*p; p = p*p;
return pow( p.x + p.y, 1.0/6.0 ); return pow( p.x + p.y, 1.0/6.0 );
} }
float length8( vec2 p ) float length8( vec2 p )
{ {
p = p*p; p = p*p; p = p*p; p = p*p; p = p*p; p = p*p;
return pow( p.x + p.y, 1.0/8.0 ); return pow( p.x + p.y, 1.0/8.0 );
} }
float sdTorus82( vec3 p, vec2 t ) float sdTorus82( vec3 p, vec2 t )
@ -196,7 +196,7 @@ float opS( float d1, float d2 )
vec2 opU( vec2 d1, vec2 d2 ) vec2 opU( vec2 d1, vec2 d2 )
{ {
return (d1.x<d2.x) ? d1 : d2; return (d1.x<d2.x) ? d1 : d2;
} }
vec3 opRep( vec3 p, vec3 c ) vec3 opRep( vec3 p, vec3 c )
@ -217,25 +217,25 @@ vec3 opTwist( vec3 p )
vec2 map( in vec3 pos ) vec2 map( in vec3 pos )
{ {
vec2 res = opU( vec2( sdPlane( pos), 1.0 ), vec2 res = opU( vec2( sdPlane( pos), 1.0 ),
vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) ); vec2( sdSphere( pos-vec3( 0.0,0.25, 0.0), 0.25 ), 46.9 ) );
res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) ); res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.25) ), 3.0 ) );
res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) ); res = opU( res, vec2( udRoundBox( pos-vec3( 1.0,0.25, 1.0), vec3(0.15), 0.1 ), 41.0 ) );
res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) ); res = opU( res, vec2( sdTorus( pos-vec3( 0.0,0.25, 1.0), vec2(0.20,0.05) ), 25.0 ) );
res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) ); res = opU( res, vec2( sdCapsule( pos,vec3(-1.3,0.10,-0.1), vec3(-0.8,0.50,0.2), 0.1 ), 31.9 ) );
res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) ); res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.25,-1.0), vec2(0.25,0.05) ),43.5 ) );
res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) ); res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.30,-1.0), vec2(0.1,0.2) ), 8.0 ) );
res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) ); res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.50,-1.0), vec3(0.8,0.6,0.3) ), 55.0 ) );
res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) ); res = opU( res, vec2( sdTorus82( pos-vec3( 0.0,0.25, 2.0), vec2(0.20,0.05) ),50.0 ) );
res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) ); res = opU( res, vec2( sdTorus88( pos-vec3(-1.0,0.25, 2.0), vec2(0.20,0.05) ),43.0 ) );
res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) ); res = opU( res, vec2( sdCylinder6( pos-vec3( 1.0,0.30, 2.0), vec2(0.1,0.2) ), 12.0 ) );
res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) ); res = opU( res, vec2( sdHexPrism( pos-vec3(-1.0,0.20, 1.0), vec2(0.25,0.05) ),17.0 ) );
res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) ); res = opU( res, vec2( sdPryamid4( pos-vec3(-1.0,0.15,-2.0), vec3(0.8,0.6,0.25) ),37.0 ) );
res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05), res = opU( res, vec2( opS( udRoundBox( pos-vec3(-2.0,0.2, 1.0), vec3(0.15),0.05),
sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) ); sdSphere( pos-vec3(-2.0,0.2, 1.0), 0.25)), 13.0 ) );
res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)), res = opU( res, vec2( opS( sdTorus82( pos-vec3(-2.0,0.2, 0.0), vec2(0.20,0.1)),
sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) ); sdCylinder( opRep( vec3(atan(pos.x+2.0,pos.z)/6.2831, pos.y, 0.02+0.5*length(pos-vec3(-2.0,0.2, 0.0))), vec3(0.05,1.0,0.05)), vec2(0.02,0.6))), 51.0 ) );
res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) ); res = opU( res, vec2( 0.5*sdSphere( pos-vec3(-2.0,0.25,-1.0), 0.2 ) + 0.03*sin(50.0*pos.x)*sin(50.0*pos.y)*sin(50.0*pos.z), 65.0 ) );
res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) ); res = opU( res, vec2( 0.5*sdTorus( opTwist(pos-vec3(-2.0,0.25, 2.0)),vec2(0.20,0.05)), 46.7 ) );
res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) ); res = opU( res, vec2( sdConeSection( pos-vec3( 0.0,0.35,-2.0), 0.15, 0.2, 0.1 ), 13.67 ) );
res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) ); res = opU( res, vec2( sdEllipsoid( pos-vec3( 1.0,0.35,-2.0), vec3(0.15, 0.2, 0.05) ), 43.17 ) );
@ -258,11 +258,11 @@ vec2 castRay( in vec3 ro, in vec3 rd )
float m = -1.0; float m = -1.0;
for( int i=0; i<64; i++ ) for( int i=0; i<64; i++ )
{ {
float precis = 0.0005*t; float precis = 0.0005*t;
vec2 res = map( ro+rd*t ); vec2 res = map( ro+rd*t );
if( res.x<precis || t>tmax ) break; if( res.x<precis || t>tmax ) break;
t += res.x; t += res.x;
m = res.y; m = res.y;
} }
if( t>tmax ) m=-1.0; if( t>tmax ) m=-1.0;
@ -272,11 +272,11 @@ vec2 castRay( in vec3 ro, in vec3 rd )
float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax ) float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
{ {
float res = 1.0; float res = 1.0;
float t = mint; float t = mint;
for( int i=0; i<16; i++ ) for( int i=0; i<16; i++ )
{ {
float h = map( ro + rd*t ).x; float h = map( ro + rd*t ).x;
res = min( res, 8.0*h/t ); res = min( res, 8.0*h/t );
t += clamp( h, 0.02, 0.10 ); t += clamp( h, 0.02, 0.10 );
if( h<0.001 || t>tmax ) break; if( h<0.001 || t>tmax ) break;
@ -288,22 +288,22 @@ vec3 calcNormal( in vec3 pos )
{ {
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005; vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize( e.xyy*map( pos + e.xyy ).x + return normalize( e.xyy*map( pos + e.xyy ).x +
e.yyx*map( pos + e.yyx ).x + e.yyx*map( pos + e.yyx ).x +
e.yxy*map( pos + e.yxy ).x + e.yxy*map( pos + e.yxy ).x +
e.xxx*map( pos + e.xxx ).x ); e.xxx*map( pos + e.xxx ).x );
/* /*
vec3 eps = vec3( 0.0005, 0.0, 0.0 ); vec3 eps = vec3( 0.0005, 0.0, 0.0 );
vec3 nor = vec3( vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x, map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x, map(pos+eps.yxy).x - map(pos-eps.yxy).x,
map(pos+eps.yyx).x - map(pos-eps.yyx).x ); map(pos+eps.yyx).x - map(pos-eps.yyx).x );
return normalize(nor); return normalize(nor);
*/ */
} }
float calcAO( in vec3 pos, in vec3 nor ) float calcAO( in vec3 pos, in vec3 nor )
{ {
float occ = 0.0; float occ = 0.0;
float sca = 1.0; float sca = 1.0;
for( int i=0; i<5; i++ ) for( int i=0; i<5; i++ )
{ {
@ -332,7 +332,7 @@ vec3 render( in vec3 ro, in vec3 rd )
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8; vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd); vec2 res = castRay(ro,rd);
float t = res.x; float t = res.x;
float m = res.y; float m = res.y;
if( m>-0.5 ) if( m>-0.5 )
{ {
vec3 pos = ro + t*rd; vec3 pos = ro + t*rd;
@ -340,7 +340,7 @@ vec3 render( in vec3 ro, in vec3 rd )
vec3 ref = reflect( rd, nor ); vec3 ref = reflect( rd, nor );
// material // material
col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) ); col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
if( m<1.5 ) if( m<1.5 )
{ {
@ -350,9 +350,9 @@ vec3 render( in vec3 ro, in vec3 rd )
// lighting // lighting
float occ = calcAO( pos, nor ); float occ = calcAO( pos, nor );
vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) ); vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
vec3 hal = normalize( lig-rd ); vec3 hal = normalize( lig-rd );
float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 ); float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
float dom = smoothstep( -0.1, 0.1, ref.y ); float dom = smoothstep( -0.1, 0.1, ref.y );
@ -361,31 +361,31 @@ vec3 render( in vec3 ro, in vec3 rd )
dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
dom *= calcSoftshadow( pos, ref, 0.02, 2.5 ); dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)* float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
dif * dif *
(0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 )); (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
vec3 lin = vec3(0.0); vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55); lin += 1.30*dif*vec3(1.00,0.80,0.55);
lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ; lin += 0.40*amb*vec3(0.40,0.60,1.00)*occ;
lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ; lin += 0.50*dom*vec3(0.40,0.60,1.00)*occ;
lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ; lin += 0.50*bac*vec3(0.25,0.25,0.25)*occ;
lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ; lin += 0.25*fre*vec3(1.00,1.00,1.00)*occ;
col = col*lin; col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70); col += 10.00*spe*vec3(1.00,0.90,0.70);
col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) ); col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
} }
return vec3( clamp(col,0.0,1.0) ); return vec3( clamp(col,0.0,1.0) );
} }
mat3 setCamera( in vec3 ro, in vec3 ta, float cr ) mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{ {
vec3 cw = normalize(ta-ro); vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0); vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) ); vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) ); vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw ); return mat3( cu, cv, cw );
} }
@ -403,7 +403,7 @@ void main()
vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y; vec2 p = (-resolution.xy + 2.0*gl_FragCoord.xy)/resolution.y;
#endif #endif
// RAY: Camera is provided from raylib // RAY: Camera is provided from raylib
//vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) ); //vec3 ro = vec3( -0.5+3.5*cos(0.1*time + 6.0*mo.x), 1.0 + 2.0*mo.y, 0.5 + 4.0*sin(0.1*time + 6.0*mo.x) );
vec3 ro = viewEye; vec3 ro = viewEye;
@ -414,10 +414,10 @@ void main()
// ray direction // ray direction
vec3 rd = ca * normalize( vec3(p.xy,2.0) ); vec3 rd = ca * normalize( vec3(p.xy,2.0) );
// render // render
vec3 col = render( ro, rd ); vec3 col = render( ro, rd );
// gamma // gamma
col = pow( col, vec3(0.4545) ); col = pow( col, vec3(0.4545) );
tot += col; tot += col;

View File

@ -15,26 +15,26 @@ uniform float time; // Total run time (in secods)
// Draw circle // Draw circle
vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color) vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color)
{ {
float d = length(position - fragCoord) - radius; float d = length(position - fragCoord) - radius;
float t = clamp(d, 0.0, 1.0); float t = clamp(d, 0.0, 1.0);
return vec4(color, 1.0 - t); return vec4(color, 1.0 - t);
} }
void main() void main()
{ {
vec2 fragCoord = gl_FragCoord.xy; vec2 fragCoord = gl_FragCoord.xy;
vec2 position = vec2(mouse.x, resolution.y - mouse.y); vec2 position = vec2(mouse.x, resolution.y - mouse.y);
float radius = 40.0; float radius = 40.0;
// Draw background layer // Draw background layer
vec4 colorA = vec4(0.2,0.2,0.8, 1.0); vec4 colorA = vec4(0.2,0.2,0.8, 1.0);
vec4 colorB = vec4(1.0,0.7,0.2, 1.0); vec4 colorB = vec4(1.0,0.7,0.2, 1.0);
vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1))); vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1)));
// Draw circle layer // Draw circle layer
vec3 color = vec3(0.9, 0.16, 0.21); vec3 color = vec3(0.9, 0.16, 0.21);
vec4 layer2 = DrawCircle(fragCoord, position, radius, color); vec4 layer2 = DrawCircle(fragCoord, position, radius, color);
// Blend the two layers // Blend the two layers
finalColor = mix(layer1, layer2, layer2.a); finalColor = mix(layer1, layer2, layer2.a);
} }

View File

@ -16,26 +16,26 @@ uniform vec2 resolution = vec2(800, 450);
void main() void main()
{ {
float x = 1.0/resolution.x; float x = 1.0/resolution.x;
float y = 1.0/resolution.y; float y = 1.0/resolution.y;
vec4 horizEdge = vec4(0.0); vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0); vec4 vertEdge = vec4(0.0);
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y - y))*2.0;
vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0; vertEdge -= texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x , fragTexCoord.y + y))*2.0;
vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0; vertEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb)); vec3 edge = sqrt((horizEdge.rgb*horizEdge.rgb) + (vertEdge.rgb*vertEdge.rgb));
finalColor = vec4(edge, texture2D(texture0, fragTexCoord).a); finalColor = vec4(edge, texture2D(texture0, fragTexCoord).a);
} }

View File

@ -12,9 +12,9 @@ out vec4 finalColor;
#define MAX_SPOTS 3 #define MAX_SPOTS 3
struct Spot { struct Spot {
vec2 pos; // window coords of spot vec2 pos; // window coords of spot
float inner; // inner fully transparent centre radius float inner; // inner fully transparent centre radius
float radius; // alpha fades out to this radius float radius; // alpha fades out to this radius
}; };
uniform Spot spots[MAX_SPOTS]; // Spotlight positions array uniform Spot spots[MAX_SPOTS]; // Spotlight positions array
@ -22,44 +22,44 @@ uniform float screenWidth; // Width of the screen
void main() void main()
{ {
float alpha = 1.0; float alpha = 1.0;
// Get the position of the current fragment (screen coordinates!) // Get the position of the current fragment (screen coordinates!)
vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y); vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
// Find out which spotlight is nearest // Find out which spotlight is nearest
float d = 65000; // some high value float d = 65000; // some high value
int fi = -1; // found index int fi = -1; // found index
for (int i = 0; i < MAX_SPOTS; i++) for (int i = 0; i < MAX_SPOTS; i++)
{ {
for (int j = 0; j < MAX_SPOTS; j++) for (int j = 0; j < MAX_SPOTS; j++)
{ {
float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius; float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
if (d > dj) if (d > dj)
{ {
d = dj; d = dj;
fi = i; fi = i;
} }
} }
} }
// d now equals distance to nearest spot... // d now equals distance to nearest spot...
// allowing for the different radii of all spotlights // allowing for the different radii of all spotlights
if (fi != -1) if (fi != -1)
{ {
if (d > spots[fi].radius) alpha = 1.0; if (d > spots[fi].radius) alpha = 1.0;
else else
{ {
if (d < spots[fi].inner) alpha = 0.0; if (d < spots[fi].inner) alpha = 0.0;
else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner); else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner);
} }
} }
// Right hand side of screen is dimly lit, // Right hand side of screen is dimly lit,
// could make the threshold value user definable // could make the threshold value user definable
if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9; if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
finalColor = vec4(0, 0, 0, alpha); finalColor = vec4(0, 0, 0, alpha);
} }

View File

@ -23,15 +23,15 @@ uniform float speedX;
uniform float speedY; uniform float speedY;
void main() { void main() {
float pixelWidth = 1.0 / size.x; float pixelWidth = 1.0 / size.x;
float pixelHeight = 1.0 / size.y; float pixelHeight = 1.0 / size.y;
float aspect = pixelHeight / pixelWidth; float aspect = pixelHeight / pixelWidth;
float boxLeft = 0.0; float boxLeft = 0.0;
float boxTop = 0.0; float boxTop = 0.0;
vec2 p = fragTexCoord; vec2 p = fragTexCoord;
p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth; p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (secondes * speedX)) * ampX * pixelWidth;
p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight; p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (secondes * speedY)) * ampY * pixelHeight;
finalColor = texture(texture0, p)*colDiffuse*fragColor; finalColor = texture(texture0, p)*colDiffuse*fragColor;
} }

View File

@ -25,8 +25,7 @@
# Define required raylib variables # Define required raylib variables
PROJECT_NAME ?= game PROJECT_NAME ?= game
RAYLIB_VERSION ?= 3.0.0 RAYLIB_VERSION ?= 3.5.0
RAYLIB_API_VERSION ?= 300
RAYLIB_PATH ?= ..\.. RAYLIB_PATH ?= ..\..
# Define compiler path on Windows # Define compiler path on Windows

View File

@ -1,326 +1,122 @@
# Setup the project and settings # Setup the project and settings
project(raylib C) project(raylib C)
include(GNUInstallDirs)
include(JoinPaths)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
set(PROJECT_VERSION 3.5.0) set(PROJECT_VERSION 3.5.0)
set(API_VERSION 351) set(API_VERSION 351)
include("CMakeOptions.txt") include(GNUInstallDirs)
include(BuildType) include(JoinPaths)
configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h)
include_directories(${CMAKE_BINARY_DIR} .)
# Get the sources together # Sets build type if not set by now
file(GLOB raylib_sources *.c) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/rglfw.c) if(RAYLIB_IS_MAIN)
set(default_build_type Debug)
else()
message(WARNING "Default build type is not set (CMAKE_BUILD_TYPE)")
endif()
if(USE_EXTERNAL_GLFW STREQUAL "ON") message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
find_package(glfw3 3.2.1 REQUIRED)
elseif(USE_EXTERNAL_GLFW STREQUAL "IF_POSSIBLE") set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE)
find_package(glfw3 3.2.1 QUIET) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
if (glfw3_FOUND)
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
endif() endif()
# Explicitly check against "ON", because USE_EXTERNAL_GLFW is a tristate option # Used as public API to be included into other projects
if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MATCHES "Desktop") set(raylib_public_headers
MESSAGE(STATUS "Using raylib's GLFW") raylib.h
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) rlgl.h
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) physac.h
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) raymath.h
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE) raudio.h
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE) )
set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
add_subdirectory(external/glfw) # Sources to be compiled
set(raylib_sources
core.c
models.c
shapes.c
text.c
textures.c
utils.c
)
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>) # <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw
include_directories(BEFORE SYSTEM external/glfw/include) include(GlfwImport)
if (USE_AUDIO)
MESSAGE(STATUS "Audio Backend: miniaudio")
list(APPEND raylib_sources raudio.c)
else ()
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
endif ()
# Sets additional platform options and link libraries for each platform
# also selects the proper graphics API and version for that platform
# Produces a variable LIBS_PRIVATE that will be used later
include(LibraryConfigurations)
add_library(raylib ${raylib_sources} ${raylib_public_headers})
if (NOT BUILD_SHARED_LIBS)
MESSAGE(STATUS "Building raylib static library")
add_library(raylib_static ALIAS raylib)
else() else()
MESSAGE(STATUS "Using external GLFW") MESSAGE(STATUS "Building raylib shared library")
set(GLFW_PKG_DEPS glfw3) if (MSVC)
target_compile_definitions(raylib
PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
)
endif ()
endif() endif()
add_definitions("-DRAYLIB_CMAKE=1") set_target_properties(raylib PROPERTIES
PUBLIC_HEADER "${raylib_public_headers}"
VERSION ${PROJECT_VERSION}
SOVERSION ${API_VERSION}
)
if(USE_AUDIO) if (WITH_PIC OR BUILD_SHARED_LIBS)
MESSAGE(STATUS "Audio Backend: miniaudio") set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
set(sources ${raylib_sources}) endif ()
else()
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
set(RAYLIB_MODULE_AUDIO 0)
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/raudio.c)
set(sources ${raylib_sources})
endif()
### Config options ### target_link_libraries(raylib "${LIBS_PRIVATE}")
# Translate the config options to what raylib wants
if(${PLATFORM} MATCHES "Desktop")
set(PLATFORM_CPP "PLATFORM_DESKTOP")
if(APPLE) # Sets some compile time definitions for the pre-processor
# Need to force OpenGL 3.3 on OS X # If CUSTOMIZE_BUILD option is on you will not use config.h by default
# See: https://github.com/raysan5/raylib/issues/341 # and you will be able to select more build options
set(GRAPHICS "GRAPHICS_API_OPENGL_33") include(CompileDefinitions)
find_library(OPENGL_LIBRARY OpenGL)
set(LIBS_PRIVATE ${OPENGL_LIBRARY})
link_libraries("${LIBS_PRIVATE}")
if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
add_definitions(-DGL_SILENCE_DEPRECATION)
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
endif()
elseif(WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm)
else()
find_library(pthread NAMES pthread)
find_package(OpenGL QUIET)
if ("${OPENGL_LIBRARIES}" STREQUAL "")
set(OPENGL_LIBRARIES "GL")
endif()
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD") # Registering include directories
find_library(OSS_LIBRARY ossaudio) target_include_directories(raylib
endif() PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${OPENGL_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}
)
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY}) # Copy the header files to the build directory for convenience
endif() file(COPY ${raylib_public_headers} DESTINATION "include")
elseif(${PLATFORM} MATCHES "Web") # Includes information on how the library will be installed on the system
set(PLATFORM_CPP "PLATFORM_WEB") # when cmake --install is run
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") include(InstallConfigurations)
set(CMAKE_C_FLAGS "-s USE_GLFW=3 -s ASSERTIONS=1 --profiling")
# Change the name of the output library
elseif(${PLATFORM} MATCHES "Android")
set(PLATFORM_CPP "PLATFORM_ANDROID")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
include(AddIfFlagCompiles)
add_if_flag_compiles(-ffunction-sections CMAKE_C_FLAGS)
add_if_flag_compiles(-funwind-tables CMAKE_C_FLAGS)
add_if_flag_compiles(-fstack-protector-strong CMAKE_C_FLAGS)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_if_flag_compiles(-Wa,--noexecstack CMAKE_C_FLAGS)
add_if_flag_compiles(-no-canonical-prefixes CMAKE_C_FLAGS)
add_definitions(-DANDROID -D__ANDROID_API__=21)
include_directories(external/android/native_app_glue)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -uANativeActivity_onCreate")
find_library(OPENGL_LIBRARY OpenGL)
set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c)
elseif(${PLATFORM} MATCHES "Raspberry Pi")
set(PLATFORM_CPP "PLATFORM_RPI")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
add_definitions(-D_DEFAULT_SOURCE)
find_library(GLESV2 brcmGLESv2 HINTS /opt/vc/lib)
find_library(EGL brcmEGL HINTS /opt/vc/lib)
find_library(BCMHOST bcm_host HINTS /opt/vc/lib)
include_directories(/opt/vc/include /opt/vc/include/interface/vmcs_host/linux /opt/vc/include/interface/vcos/pthreads)
link_directories(/opt/vc/lib)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl)
elseif(${PLATFORM} MATCHES "DRM")
set(PLATFORM_CPP "PLATFORM_DRM")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
add_definitions(-D_DEFAULT_SOURCE)
add_definitions(-DEGL_NO_X11)
add_definitions(-DPLATFORM_DRM)
find_library(GLESV2 GLESv2)
find_library(EGL EGL)
find_library(DRM drm)
find_library(GBM gbm)
include_directories(/usr/include/libdrm)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl)
endif()
if (${OPENGL_VERSION})
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
if (${OPENGL_VERSION} MATCHES "3.3")
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
elseif (${OPENGL_VERSION} MATCHES "2.1")
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
elseif (${OPENGL_VERSION} MATCHES "1.1")
set(GRAPHICS "GRAPHICS_API_OPENGL_11")
elseif (${OPENGL_VERSION} MATCHES "ES 2.0")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
endif()
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
endif()
endif()
if(NOT GRAPHICS)
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
endif()
include_directories(${OPENGL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR})
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
include(LibraryPathToLinkerFlags)
library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}")
if(STATIC)
MESSAGE(STATUS "Building raylib static library")
if(${PLATFORM} MATCHES "Web")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
endif()
add_library(raylib_static STATIC ${sources})
target_compile_definitions(raylib_static
PUBLIC ${PLATFORM_CPP}
PUBLIC PLATFORM=${PLATFORM_CPP}
PUBLIC ${GRAPHICS}
PUBLIC GRAPHICS=${GRAPHICS}
)
target_link_libraries(raylib_static
PUBLIC ${LIBS_PRIVATE}
)
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS})
string (REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}")
if (${PLATFORM} MATCHES "Desktop")
target_link_libraries(raylib_static PRIVATE glfw ${GLFW_LIBRARIES} ${LIBS_PRIVATE})
endif()
if (WITH_PIC)
set_property(TARGET raylib_static PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
set_target_properties(raylib_static PROPERTIES PUBLIC_HEADER "raylib.h")
if(NOT MSVC) # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows
set_target_properties(raylib_static PROPERTIES OUTPUT_NAME raylib)
endif()
install(
TARGETS raylib_static
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
set_target_properties(raylib_static PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
add_test("pkg-config--static" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh --static)
endif(STATIC)
if(SHARED)
MESSAGE(STATUS "Building raylib shared library")
add_library(raylib SHARED ${sources})
target_compile_definitions(raylib
PUBLIC ${PLATFORM_CPP}
PUBLIC ${GRAPHICS}
)
if(MSVC)
target_compile_definitions(raylib
PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
)
endif()
set(PKG_CONFIG_LIBS_EXTRA "")
set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_MACOSX_RPATH ON)
target_link_libraries(raylib ${LIBS_PRIVATE})
if (${PLATFORM} MATCHES "Desktop")
target_link_libraries(raylib glfw)
endif()
set_target_properties(raylib PROPERTIES
PUBLIC_HEADER "raylib.h"
VERSION ${PROJECT_VERSION}
SOVERSION ${API_VERSION}
)
if (WIN32)
install(
TARGETS raylib
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
PUBLIC_HEADER DESTINATION "include"
)
else()
install(
TARGETS raylib
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
endif()
set_target_properties(raylib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
add_test("pkg-config" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh)
else(SHARED)
add_library(raylib ALIAS raylib_static)
endif(SHARED)
if (NOT DEFINED PKG_CONFIG_LIBS_EXTRA)
set(PKG_CONFIG_LIBS_EXTRA "${PKG_CONFIG_LIBS_PRIVATE}")
endif()
join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(../raylib.pc.in raylib.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
install(FILES ${PROJECT_SOURCE_DIR}/../cmake/raylib-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
# populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS}
include(PopulateConfigVariablesLocally)
populate_config_variables_locally(raylib)
# Copy the header files to the build directory
file(COPY "raylib.h" DESTINATION ".")
file(COPY "rlgl.h" DESTINATION ".")
file(COPY "physac.h" DESTINATION ".")
file(COPY "raymath.h" DESTINATION ".")
file(COPY "raudio.h" DESTINATION ".")
# Also install them
install(FILES "raylib.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "rlgl.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "physac.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "raymath.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES "raudio.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
# Print the flags for the user # Print the flags for the user
if (DEFINED CMAKE_BUILD_TYPE) if (DEFINED CMAKE_BUILD_TYPE)
message(STATUS "Generated build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Generated build type: ${CMAKE_BUILD_TYPE}")
else() else ()
message(STATUS "Generated config types: ${CMAKE_CONFIGURATION_TYPES}") message(STATUS "Generated config types: ${CMAKE_CONFIGURATION_TYPES}")
endif() endif ()
message(STATUS "Compiling with the flags:") message(STATUS "Compiling with the flags:")
message(STATUS " PLATFORM=" ${PLATFORM_CPP}) message(STATUS " PLATFORM=" ${PLATFORM_CPP})
message(STATUS " GRAPHICS=" ${GRAPHICS}) message(STATUS " GRAPHICS=" ${GRAPHICS})
# Packaging # Options if you want to create an installer using CPack
SET(CPACK_PACKAGE_NAME "raylib") include(PackConfigurations)
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to enjoy videogames programming")
SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/../README.md")
SET(CPACK_RESOURCE_FILE_WELCOME "${PROJECT_SOURCE_DIR}/../README.md")
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE")
SET(CPACK_PACKAGE_FILE_NAME "raylib-${PROJECT_VERSION}$ENV{RAYLIB_PACKAGE_SUFFIX}")
SET(CPACK_GENERATOR "ZIP;TGZ") # Remove this, if you want the NSIS installer on Windows
include(CPack)
enable_testing() enable_testing()

View File

@ -1,114 +0,0 @@
### Config options ###
include(CMakeDependentOption)
include(EnumOption)
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM" "Platform to build for.")
enum_option(OPENGL_VERSION "OFF;3.3;2.1;1.1;ES 2.0" "Force a specific OpenGL Version?")
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
option(WITH_PIC "Compile static library as position-independent code" OFF)
option(SHARED "Build raylib as a dynamic library" OFF)
option(STATIC "Build raylib as a static library" ON)
option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF)
option(USE_AUDIO "Build raylib with audio module" ON)
enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one")
if(UNIX AND NOT APPLE)
option(USE_WAYLAND "Use Wayland for window creation" OFF)
endif()
option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage" OFF)
set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option")
# core.c
option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON)
option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag" ON)
option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON)
option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" OFF)
option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON)
option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON)
option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON)
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF)
option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF)
option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF)
# rlgl.h
option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON)
# shapes.c
option(SUPPORT_FONT_TEXTURE "Draw rectangle shapes using font texture white character instead of default white texture. Allows drawing rectangles and text with a single draw call, very useful for GUI systems!" ON)
option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON)
# textures.c
option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON)
option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON)
option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON)
option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON)
option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON)
option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON)
option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON)
option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON)
option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF})
option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF})
option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF})
option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF})
option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF})
option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF})
option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF})
# text.c
option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON)
option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON)
option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON)
# models.c
option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON)
option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON)
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON)
option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON)
# raudio.c
option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON)
option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON)
option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON)
option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON)
option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON)
option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF})
# utils.c
option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON)
if(NOT (STATIC OR SHARED))
message(FATAL_ERROR "Nothing to do if both -DSHARED=OFF and -DSTATIC=OFF...")
endif()
if (DEFINED BUILD_SHARED_LIBS)
set(SHARED ${BUILD_SHARED_LIBS})
if (${BUILD_SHARED_LIBS})
set(STATIC OFF)
else()
set(STATIC ON)
endif()
endif()
if(DEFINED SHARED_RAYLIB)
set(SHARED ${SHARED_RAYLIB})
message(DEPRECATION "-DSHARED_RAYLIB is deprecated. Please use -DSHARED instead.")
endif()
if(DEFINED STATIC_RAYLIB)
set(STATIC ${STATIC_RAYLIB})
message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.")
endif()
if(${PLATFORM} MATCHES "Desktop" AND APPLE)
if(MACOS_FATLIB)
if (CMAKE_OSX_ARCHITECTURES)
message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
else()
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
endif()
endif()
endif()
# vim: ft=cmake

View File

@ -27,12 +27,6 @@
#define RAYLIB_VERSION "3.5" #define RAYLIB_VERSION "3.5"
// Edit to control what features Makefile'd raylib is compiled with
#if defined(RAYLIB_CMAKE)
// Edit CMakeOptions.txt for CMake instead
#include "cmake/config.h"
#else
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: core - Configuration Flags // Module: core - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -77,6 +71,8 @@
#define STORAGE_DATA_FILE "storage.data" // Automatic storage filename #define STORAGE_DATA_FILE "storage.data" // Automatic storage filename
#define MAX_DECOMPRESSION_SIZE 64 // Max size allocated for decompression in MB
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: rlgl - Configuration Flags // Module: rlgl - Configuration Flags
@ -215,6 +211,3 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message #define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message
#define MAX_UWP_MESSAGES 512 // Max UWP messages to process #define MAX_UWP_MESSAGES 512 // Max UWP messages to process
#endif //defined(RAYLIB_CMAKE)

View File

@ -1,89 +0,0 @@
// config.h.in
// core.c
// Camera module is included (camera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
#cmakedefine SUPPORT_CAMERA_SYSTEM 1
// Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag
#cmakedefine SUPPORT_GESTURES_SYSTEM 1
// Mouse gestures are directly mapped like touches and processed by gestures system.
#cmakedefine SUPPORT_MOUSE_GESTURES 1
// Reconfigure standard input to receive key inputs, works with SSH connection.
#cmakedefine SUPPORT_SSH_KEYBOARD_RPI 1
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
#cmakedefine SUPPORT_BUSY_WAIT_LOOP 1
// Wait for events passively (sleeping while no events) instead of polling them actively every frame
#cmakedefine SUPPORT_EVENTS_WAITING 1
// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
#cmakedefine SUPPORT_SCREEN_CAPTURE 1
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
#cmakedefine SUPPORT_GIF_RECORDING 1
// Support high DPI displays
#cmakedefine SUPPORT_HIGH_DPI 1
// Support CompressData() and DecompressData() functions
#cmakedefine SUPPORT_COMPRESSION_API 1
// rlgl.h
// Support VR simulation functionality (stereo rendering)
#cmakedefine SUPPORT_VR_SIMULATOR 1
// shapes.c
// Draw rectangle shapes using font texture white character instead of default white texture
#cmakedefine SUPPORT_FONT_TEXTURE 1
// Use QUADS instead of TRIANGLES for drawing when possible
// Some lines-based shapes could still use lines
#cmakedefine SUPPORT_QUADS_DRAW_MODE 1
// textures.c
// Selecte desired fileformats to be supported for image data loading.
#cmakedefine SUPPORT_FILEFORMAT_PNG 1
#cmakedefine SUPPORT_FILEFORMAT_DDS 1
#cmakedefine SUPPORT_FILEFORMAT_HDR 1
#cmakedefine SUPPORT_FILEFORMAT_KTX 1
#cmakedefine SUPPORT_FILEFORMAT_ASTC 1
#cmakedefine SUPPORT_FILEFORMAT_BMP 1
#cmakedefine SUPPORT_FILEFORMAT_TGA 1
#cmakedefine SUPPORT_FILEFORMAT_JPG 1
#cmakedefine SUPPORT_FILEFORMAT_GIF 1
#cmakedefine SUPPORT_FILEFORMAT_PSD 1
#cmakedefine SUPPORT_FILEFORMAT_PKM 1
#cmakedefine SUPPORT_FILEFORMAT_PVR 1
// Support image export functionality (.png, .bmp, .tga, .jpg)
#define SUPPORT_IMAGE_EXPORT 1
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()
#cmakedefine SUPPORT_IMAGE_MANIPULATION 1
// Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)
#cmakedefine SUPPORT_IMAGE_GENERATION 1
// text.c
// Default font is loaded on window initialization to be available for the user to render simple text. NOTE: If enabled, uses external module functions to load default raylib font (module: text)
#cmakedefine SUPPORT_DEFAULT_FONT 1
// Selected desired fileformats to be supported for loading.
#cmakedefine SUPPORT_FILEFORMAT_FNT 1
#cmakedefine SUPPORT_FILEFORMAT_TTF 1
// Support text management functions
// If not defined, still some functions are supported: TextLength(), TextFormat()
#cmakedefine SUPPORT_TEXT_MANIPULATION 1
// models.c
// Selected desired fileformats to be supported for loading.
#cmakedefine SUPPORT_FILEFORMAT_OBJ 1
#cmakedefine SUPPORT_FILEFORMAT_MTL 1
#cmakedefine SUPPORT_FILEFORMAT_IQM 1
#cmakedefine SUPPORT_FILEFORMAT_GLTF 1
// Support procedural mesh generation functions, uses external par_shapes.h library
// NOTE: Some generated meshes DO NOT include generated texture coordinates
#cmakedefine SUPPORT_MESH_GENERATION 1
// raudio.c
// Desired fileformats to be supported for loading.
#cmakedefine SUPPORT_FILEFORMAT_WAV 1
#cmakedefine SUPPORT_FILEFORMAT_OGG 1
#cmakedefine SUPPORT_FILEFORMAT_XM 1
#cmakedefine SUPPORT_FILEFORMAT_MOD 1
#cmakedefine SUPPORT_FILEFORMAT_FLAC 1
#cmakedefine SUPPORT_FILEFORMAT_MP3 1
// utils.c
// Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown
#cmakedefine SUPPORT_TRACELOG 1

View File

@ -150,6 +150,14 @@
#include "external/msf_gif.h" // Support GIF recording #include "external/msf_gif.h" // Support GIF recording
#endif #endif
#if defined(SUPPORT_COMPRESSION_API)
#define SINFL_IMPLEMENTATION
#include "external/sinfl.h"
#define SDEFL_IMPLEMENTATION
#include "external/sdefl.h"
#endif
#include <stdlib.h> // Required for: srand(), rand(), atexit() #include <stdlib.h> // Required for: srand(), rand(), atexit()
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()] #include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
#include <string.h> // Required for: strrchr(), strcmp(), strlen() #include <string.h> // Required for: strrchr(), strcmp(), strlen()
@ -333,12 +341,6 @@ typedef struct {
bool isKeyboard; // True if device has letter keycodes bool isKeyboard; // True if device has letter keycodes
bool isGamepad; // True if device has gamepad buttons bool isGamepad; // True if device has gamepad buttons
} InputEventWorker; } InputEventWorker;
typedef struct {
int contents[8]; // Key events FIFO contents (8 positions)
char head; // Key events FIFO head position
char tail; // Key events FIFO tail position
} KeyEventFifo;
#endif #endif
typedef struct { int x; int y; } Point; typedef struct { int x; int y; } Point;
@ -420,7 +422,7 @@ typedef struct CoreData {
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
int defaultMode; // Default keyboard mode int defaultMode; // Default keyboard mode
struct termios defaultSettings; // Default keyboard settings struct termios defaultSettings; // Default keyboard settings
KeyEventFifo lastKeyPressed; // Buffer for holding keydown events as they arrive (Needed due to multitreading of event workers) int fd; // File descriptor for the evdev keyboard
#endif #endif
} Keyboard; } Keyboard;
struct { struct {
@ -559,7 +561,8 @@ static void RestoreTerminal(void); // Restore terminal
#endif #endif
static void InitEvdevInput(void); // Evdev inputs initialization static void InitEvdevInput(void); // Evdev inputs initialization
static void EventThreadSpawn(char *device); // Identifies a input device and spawns a thread to handle it if needed static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
static void PollKeyboardEvents(void); // Process evdev keyboard events.
static void *EventThread(void *arg); // Input device events reading thread static void *EventThread(void *arg); // Input device events reading thread
static void InitGamepad(void); // Init raw gamepad input static void InitGamepad(void); // Init raw gamepad input
@ -899,6 +902,13 @@ void CloseWindow(void)
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
// Close the evdev keyboard
if (CORE.Input.Keyboard.fd != -1)
{
close(CORE.Input.Keyboard.fd);
CORE.Input.Keyboard.fd = -1;
}
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i) for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{ {
if (CORE.Input.eventWorker[i].threadId) if (CORE.Input.eventWorker[i].threadId)
@ -906,6 +916,7 @@ void CloseWindow(void)
pthread_join(CORE.Input.eventWorker[i].threadId, NULL); pthread_join(CORE.Input.eventWorker[i].threadId, NULL);
} }
} }
if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL); if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
#endif #endif
@ -1727,6 +1738,9 @@ void EnableCursor(void)
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
#endif #endif
#if defined(PLATFORM_WEB)
emscripten_exit_pointerlock();
#endif
#if defined(PLATFORM_UWP) #if defined(PLATFORM_UWP)
UWPGetMouseUnlockFunc()(); UWPGetMouseUnlockFunc()();
#endif #endif
@ -1739,6 +1753,9 @@ void DisableCursor(void)
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
#endif #endif
#if defined(PLATFORM_WEB)
emscripten_request_pointerlock("#canvas", 1);
#endif
#if defined(PLATFORM_UWP) #if defined(PLATFORM_UWP)
UWPGetMouseLockFunc()(); UWPGetMouseLockFunc()();
#endif #endif
@ -2342,7 +2359,7 @@ const char *GetFileName(const char *filePath)
const char *fileName = NULL; const char *fileName = NULL;
if (filePath != NULL) fileName = strprbrk(filePath, "\\/"); if (filePath != NULL) fileName = strprbrk(filePath, "\\/");
if (!fileName || (fileName == filePath)) return filePath; if (!fileName) return filePath;
return fileName + 1; return fileName + 1;
} }
@ -2388,9 +2405,9 @@ const char *GetDirectoryPath(const char *filePath)
static char dirPath[MAX_FILEPATH_LENGTH]; static char dirPath[MAX_FILEPATH_LENGTH];
memset(dirPath, 0, MAX_FILEPATH_LENGTH); memset(dirPath, 0, MAX_FILEPATH_LENGTH);
// In case provided path does not contains a root drive letter (C:\, D:\), // In case provided path does not contain a root drive letter (C:\, D:\) nor leading path separator (\, /),
// we add the current directory path to dirPath // we add the current directory path to dirPath
if (filePath[1] != ':') if (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/')
{ {
// For security, we set starting path to current directory, // For security, we set starting path to current directory,
// obtained path will be concated to this // obtained path will be concated to this
@ -2401,9 +2418,18 @@ const char *GetDirectoryPath(const char *filePath)
lastSlash = strprbrk(filePath, "\\/"); lastSlash = strprbrk(filePath, "\\/");
if (lastSlash) if (lastSlash)
{ {
// NOTE: Be careful, strncpy() is not safe, it does not care about '\0' if (lastSlash == filePath)
memcpy(dirPath + ((filePath[1] != ':')? 2 : 0), filePath, strlen(filePath) - (strlen(lastSlash) - 1)); {
dirPath[strlen(filePath) - strlen(lastSlash) + ((filePath[1] != ':')? 2 : 0)] = '\0'; // Add '\0' manually // The last and only slash is the leading one: path is in a root directory
dirPath[0] = filePath[0];
dirPath[1] = '\0';
}
else
{
// NOTE: Be careful, strncpy() is not safe, it does not care about '\0'
memcpy(dirPath + (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/' ? 2 : 0), filePath, strlen(filePath) - (strlen(lastSlash) - 1));
dirPath[strlen(filePath) - strlen(lastSlash) + (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/' ? 2 : 0)] = '\0'; // Add '\0' manually
}
} }
return dirPath; return dirPath;
@ -2555,7 +2581,13 @@ unsigned char *CompressData(unsigned char *data, int dataLength, int *compDataLe
unsigned char *compData = NULL; unsigned char *compData = NULL;
#if defined(SUPPORT_COMPRESSION_API) #if defined(SUPPORT_COMPRESSION_API)
compData = stbi_zlib_compress(data, dataLength, compDataLength, COMPRESSION_QUALITY_DEFLATE); // Compress data and generate a valid DEFLATE stream
struct sdefl sdefl = { 0 };
int bounds = sdefl_bound(dataLength);
compData = (unsigned char *)RL_CALLOC(bounds, 1);
*compDataLength = sdeflate(&sdefl, compData, data, dataLength, COMPRESSION_QUALITY_DEFLATE); // Compression level 8, same as stbwi
TraceLog(LOG_INFO, "SYSTEM: Data compressed: Original size: %i -> Comp. size: %i\n", dataLength, compDataLength);
#endif #endif
return compData; return compData;
@ -2567,7 +2599,13 @@ unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *
char *data = NULL; char *data = NULL;
#if defined(SUPPORT_COMPRESSION_API) #if defined(SUPPORT_COMPRESSION_API)
data = stbi_zlib_decode_malloc((char *)compData, compDataLength, dataLength); // Decompress data from a valid DEFLATE stream
data = RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1);
int length = sinflate(data, compData, compDataLength);
RL_REALLOC(data, length);
*dataLength = length;
TraceLog(LOG_INFO, "SYSTEM: Data compressed: Original size: %i -> Comp. size: %i\n", dataLength, compDataLength);
#endif #endif
return (unsigned char *)data; return (unsigned char *)data;
@ -2944,6 +2982,14 @@ int GetGamepadButtonPressed(void)
return CORE.Input.Gamepad.lastButtonPressed; return CORE.Input.Gamepad.lastButtonPressed;
} }
// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
#if defined(PLATFORM_DESKTOP)
return glfwUpdateGamepadMappings(mappings);
#endif
}
// Detect if a mouse button has been pressed once // Detect if a mouse button has been pressed once
bool IsMouseButtonPressed(int button) bool IsMouseButtonPressed(int button)
{ {
@ -4274,15 +4320,8 @@ static void PollInputEvents(void)
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
// Register previous keys states // Register previous keys states
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
// Grab a keypress from the evdev fifo if avalable PollKeyboardEvents();
if (CORE.Input.Keyboard.lastKeyPressed.head != CORE.Input.Keyboard.lastKeyPressed.tail)
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.tail]; // Read the key from the buffer
CORE.Input.Keyboard.keyPressedQueueCount++;
CORE.Input.Keyboard.lastKeyPressed.tail = (CORE.Input.Keyboard.lastKeyPressed.tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long)
}
// Register previous mouse states // Register previous mouse states
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove; CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
@ -4590,6 +4629,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
// NOTE: Before closing window, while loop must be left! // NOTE: Before closing window, while loop must be left!
} }
#if defined(SUPPORT_SCREEN_CAPTURE)
else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
{ {
#if defined(SUPPORT_GIF_RECORDING) #if defined(SUPPORT_GIF_RECORDING)
@ -4632,14 +4672,13 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
} }
} }
else else
#endif // SUPPORT_GIF_RECORDING #endif // SUPPORT_GIF_RECORDING
#if defined(SUPPORT_SCREEN_CAPTURE)
{ {
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++; screenshotCounter++;
} }
#endif // SUPPORT_SCREEN_CAPTURE
} }
#endif // SUPPORT_SCREEN_CAPTURE
else else
{ {
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
@ -5059,17 +5098,7 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
// Lock mouse pointer when click on screen // Lock mouse pointer when click on screen
if (eventType == EMSCRIPTEN_EVENT_CLICK) if (eventType == EMSCRIPTEN_EVENT_CLICK)
{ {
EmscriptenPointerlockChangeEvent plce; // TODO: Manage mouse events if required (note that GLFW JS wrapper manages it now)
emscripten_get_pointerlock_status(&plce);
int result = emscripten_request_pointerlock("#canvas", 1); // TODO: It does not work!
// result -> EMSCRIPTEN_RESULT_DEFERRED
// The requested operation cannot be completed now for web security reasons,
// and has been deferred for completion in the next event handler. --> but it never happens!
//if (!plce.isActive) emscripten_request_pointerlock(0, 1);
//else emscripten_exit_pointerlock();
} }
return 0; return 0;
@ -5352,6 +5381,9 @@ static void InitEvdevInput(void)
char path[MAX_FILEPATH_LENGTH]; char path[MAX_FILEPATH_LENGTH];
DIR *directory; DIR *directory;
struct dirent *entity; struct dirent *entity;
// Initialise keyboard file descriptor
CORE.Input.Keyboard.fd = -1;
// Reset variables // Reset variables
for (int i = 0; i < MAX_TOUCH_POINTS; ++i) for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
@ -5360,10 +5392,6 @@ static void InitEvdevInput(void)
CORE.Input.Touch.position[i].y = -1; CORE.Input.Touch.position[i].y = -1;
} }
// Reset keypress buffer
CORE.Input.Keyboard.lastKeyPressed.head = 0;
CORE.Input.Keyboard.lastKeyPressed.tail = 0;
// Reset keyboard key state // Reset keyboard key state
for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
@ -5377,7 +5405,7 @@ static void InitEvdevInput(void)
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*" if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
{ {
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name); sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
EventThreadSpawn(path); // Identify the device and spawn a thread for it ConfigureEvdevDevice(path); // Configure the device if appropriate
} }
} }
@ -5386,8 +5414,8 @@ static void InitEvdevInput(void)
else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH); else TRACELOG(LOG_WARNING, "RPI: Failed to open linux event directory: %s", DEFAULT_EVDEV_PATH);
} }
// Identifies a input device and spawns a thread to handle it if needed // Identifies a input device and configures it for use if appropriate
static void EventThreadSpawn(char *device) static void ConfigureEvdevDevice(char *device)
{ {
#define BITS_PER_LONG (8*sizeof(long)) #define BITS_PER_LONG (8*sizeof(long))
#define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1) #define NBITS(x) ((((x) - 1)/BITS_PER_LONG) + 1)
@ -5459,7 +5487,7 @@ static void EventThreadSpawn(char *device)
// Identify the device // Identify the device
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------
ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the avalable device properties ioctl(fd, EVIOCGBIT(0, sizeof(evBits)), evBits); // Read a bitfield of the available device properties
// Check for absolute input devices // Check for absolute input devices
if (TEST_BIT(evBits, EV_ABS)) if (TEST_BIT(evBits, EV_ABS))
@ -5535,15 +5563,22 @@ static void EventThreadSpawn(char *device)
// Decide what to do with the device // Decide what to do with the device
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------
if (worker->isTouch || worker->isMouse || worker->isKeyboard) if (worker->isKeyboard && CORE.Input.Keyboard.fd == -1)
{
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
// threads so that they don't drop events when the frame rate is slow.
TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);
CORE.Input.Keyboard.fd = worker->fd;
}
else if (worker->isTouch || worker->isMouse)
{ {
// Looks like an interesting device // Looks like an interesting device
TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s%s)", device, TRACELOG(LOG_INFO, "RPI: Opening input device: %s (%s%s%s%s)", device,
worker->isMouse? "mouse " : "", worker->isMouse? "mouse " : "",
worker->isMultitouch? "multitouch " : "", worker->isMultitouch? "multitouch " : "",
worker->isTouch? "touchscreen " : "", worker->isTouch? "touchscreen " : "",
worker->isGamepad? "gamepad " : "", worker->isGamepad? "gamepad " : "");
worker->isKeyboard? "keyboard " : "");
// Create a thread for this device // Create a thread for this device
int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker); int error = pthread_create(&worker->threadId, NULL, &EventThread, (void *)worker);
@ -5563,7 +5598,7 @@ static void EventThreadSpawn(char *device)
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum; if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
} }
// Find toucnscreens with lower indexes // Find touchscreens with lower indexes
for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i) for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
{ {
if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber)) if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
@ -5582,8 +5617,7 @@ static void EventThreadSpawn(char *device)
//------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------
} }
// Input device events reading thread static void PollKeyboardEvents(void)
static void *EventThread(void *arg)
{ {
// Scancode to keycode mapping for US keyboards // Scancode to keycode mapping for US keyboards
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard: // TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
@ -5605,12 +5639,62 @@ static void *EventThread(void *arg)
227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242, 227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,
243,244,245,246,247,248,0,0,0,0,0,0,0, }; 243,244,245,246,247,248,0,0,0,0,0,0,0, };
int fd = CORE.Input.Keyboard.fd;
if (fd == -1) return;
struct input_event event;
int keycode;
// Try to read data from the keyboard and only continue if successful
while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
{
// Button parsing
if (event.type == EV_KEY)
{
// Keyboard button parsing
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
{
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
// Make sure we got a valid keycode
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
{
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
if (event.value >= 1)
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
CORE.Input.Keyboard.keyPressedQueueCount++;
}
#if defined(SUPPORT_SCREEN_CAPTURE)
// Check screen capture key (raylib key: KEY_F12)
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
{
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
}
#endif
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
}
}
}
}
}
// Input device events reading thread
static void *EventThread(void *arg)
{
struct input_event event; struct input_event event;
InputEventWorker *worker = (InputEventWorker *)arg; InputEventWorker *worker = (InputEventWorker *)arg;
int touchAction = -1; int touchAction = -1;
bool gestureUpdate = false; bool gestureUpdate = false;
int keycode;
while (!CORE.Window.shouldClose) while (!CORE.Window.shouldClose)
{ {
@ -5710,39 +5794,6 @@ static void *EventThread(void *arg)
if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value; if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_RIGHT_BUTTON] = event.value;
if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value; if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_MIDDLE_BUTTON] = event.value;
// Keyboard button parsing
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
{
keycode = keymap_US[event.code & 0xFF]; // The code we get is a scancode so we look up the apropriate keycode
// Make sure we got a valid keycode
if ((keycode > 0) && (keycode < sizeof(CORE.Input.Keyboard.currentKeyState)))
{
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
if (event.value >= 1)
{
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
CORE.Input.Keyboard.keyPressedQueueCount++;
}
#if defined(SUPPORT_SCREEN_CAPTURE)
// Check screen capture key (raylib key: KEY_F12)
if (CORE.Input.Keyboard.currentKeyState[301] == 1)
{
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++;
}
#endif
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey] == 1) CORE.Window.shouldClose = true;
TRACELOGD("RPI: KEY_%s ScanCode: %4i KeyCode: %4i", event.value == 0 ? "UP":"DOWN", event.code, keycode);
}
}
} }
// Screen confinement // Screen confinement
@ -5940,6 +5991,7 @@ void UWPKeyDownEvent(int key, bool down, bool controlKey)
// Time to close the window. // Time to close the window.
CORE.Window.shouldClose = true; CORE.Window.shouldClose = true;
} }
#if defined(SUPPORT_SCREEN_CAPTURE)
else if (key == KEY_F12 && down) else if (key == KEY_F12 && down)
{ {
#if defined(SUPPORT_GIF_RECORDING) #if defined(SUPPORT_GIF_RECORDING)
@ -5973,14 +6025,13 @@ void UWPKeyDownEvent(int key, bool down, bool controlKey)
} }
} }
else else
#endif // SUPPORT_GIF_RECORDING #endif // SUPPORT_GIF_RECORDING
#if defined(SUPPORT_SCREEN_CAPTURE)
{ {
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter)); TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
screenshotCounter++; screenshotCounter++;
} }
#endif // SUPPORT_SCREEN_CAPTURE
} }
#endif // SUPPORT_SCREEN_CAPTURE
else else
{ {
CORE.Input.Keyboard.currentKeyState[key] = down; CORE.Input.Keyboard.currentKeyState[key] = down;

2944
src/external/miniaudio.h vendored

File diff suppressed because it is too large Load Diff

697
src/external/sdefl.h vendored Normal file
View File

@ -0,0 +1,697 @@
/*
# Small Deflate
`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
which implements the Deflate (RFC 1951) compressed data format specification standard.
It is mainly tuned to get as much speed and compression ratio from as little code
as needed to keep the implementation as concise as possible.
## Features
- Portable single header and source file duo written in ANSI C (ISO C90)
- Dual license with either MIT or public domain
- Small implementation
- Deflate: 525 LoC
- Inflate: 320 LoC
- Webassembly:
- Deflate ~3.7 KB (~2.2KB compressed)
- Inflate ~3.6 KB (~2.2KB compressed)
## Usage:
This file behaves differently depending on what symbols you define
before including it.
Header-File mode:
If you do not define `SDEFL_IMPLEMENTATION` before including this file, it
will operate in header only mode. In this mode it declares all used structs
and the API of the library without including the implementation of the library.
Implementation mode:
If you define `SDEFL_IMPLEMENTATION` before including this file, it will
compile the implementation . Make sure that you only include
this file implementation in *one* C or C++ file to prevent collisions.
### Benchmark
| Compressor name | Compression| Decompress.| Compr. size | Ratio |
| ------------------------| -----------| -----------| ----------- | ----- |
| sdefl 1.0 -0 | 127 MB/s | 233 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 259 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 275 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 276 MB/s | 36523781 | 36.41 |
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
| miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 |
| miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 |
| miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 |
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
| libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 |
### Compression
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| :------ | ---------: | -----------------: | ---------: | ----------: |
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620| 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
## License
```
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2020 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
```
*/
#ifndef SDEFL_H_INCLUDED
#define SDEFL_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#define SDEFL_MAX_OFF (1 << 15)
#define SDEFL_WIN_SIZ SDEFL_MAX_OFF
#define SDEFL_WIN_MSK (SDEFL_WIN_SIZ-1)
#define SDEFL_HASH_BITS 15
#define SDEFL_HASH_SIZ (1 << SDEFL_HASH_BITS)
#define SDEFL_HASH_MSK (SDEFL_HASH_SIZ-1)
#define SDEFL_MIN_MATCH 4
#define SDEFL_BLK_MAX (256*1024)
#define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX + SDEFL_MIN_MATCH)/SDEFL_MIN_MATCH)
#define SDEFL_SYM_MAX (288)
#define SDEFL_OFF_MAX (32)
#define SDEFL_PRE_MAX (19)
#define SDEFL_LVL_MIN 0
#define SDEFL_LVL_DEF 5
#define SDEFL_LVL_MAX 8
struct sdefl_freq {
unsigned lit[SDEFL_SYM_MAX];
unsigned off[SDEFL_OFF_MAX];
};
struct sdefl_code_words {
unsigned lit[SDEFL_SYM_MAX];
unsigned off[SDEFL_OFF_MAX];
};
struct sdefl_lens {
unsigned char lit[SDEFL_SYM_MAX];
unsigned char off[SDEFL_OFF_MAX];
};
struct sdefl_codes {
struct sdefl_code_words word;
struct sdefl_lens len;
};
struct sdefl_seqt {
int off, len;
};
struct sdefl {
int bits, bitcnt;
int tbl[SDEFL_HASH_SIZ];
int prv[SDEFL_WIN_SIZ];
int seq_cnt;
struct sdefl_seqt seq[SDEFL_SEQ_SIZ];
struct sdefl_freq freq;
struct sdefl_codes cod;
};
extern int sdefl_bound(int in_len);
extern int sdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
#ifdef __cplusplus
}
#endif
#endif /* SDEFL_H_INCLUDED */
#ifdef SDEFL_IMPLEMENTATION
#include <assert.h> /* assert */
#include <string.h> /* memcpy */
#include <limits.h> /* CHAR_BIT */
#define SDEFL_NIL (-1)
#define SDEFL_MAX_MATCH 258
#define SDEFL_MAX_CODE_LEN (15)
#define SDEFL_SYM_BITS (10u)
#define SDEFL_SYM_MSK ((1u << SDEFL_SYM_BITS)-1u)
#define SDEFL_LIT_LEN_CODES (14)
#define SDEFL_OFF_CODES (15)
#define SDEFL_PRE_CODES (7)
#define SDEFL_CNT_NUM(n) ((((n)+3u/4u)+3u)&~3u)
#define SDEFL_EOB (256)
#define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
static int
sdefl_ilog2(int n) {
if (!n) return 0;
#ifdef _MSC_VER
unsigned long msbp = 0;
_BitScanReverse(&msbp, (unsigned long)n);
return (int)msbp;
#elif defined(__GNUC__) || defined(__clang__)
return (int)sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl((unsigned long)n);
#else
#define lt(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
static const char tbl[256] = {
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,lt(4), lt(5), lt(5), lt(6), lt(6), lt(6), lt(6),
lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7)};
int tt, t;
if ((tt = (n >> 16))) {
return (t = (tt >> 8)) ? 24 + tbl[t] : 16 + tbl[tt];
} else {
return (t = (n >> 8)) ? 8 + tbl[t] : tbl[n];
}
#undef lt
#endif
}
static unsigned
sdefl_uload32(const void *p) {
/* hopefully will be optimized to an unaligned read */
unsigned n = 0;
memcpy(&n, p, sizeof(n));
return n;
}
static unsigned
sdefl_hash32(const void *p) {
unsigned n = sdefl_uload32(p);
return (n * 0x9E377989) >> (32 - SDEFL_HASH_BITS);
}
static void
sdefl_put(unsigned char **dst, struct sdefl *s, int code, int bitcnt) {
s->bits |= (code << s->bitcnt);
s->bitcnt += bitcnt;
while (s->bitcnt >= 8) {
unsigned char *tar = *dst;
*tar = (unsigned char)(s->bits & 0xFF);
s->bits >>= 8;
s->bitcnt -= 8;
*dst = *dst + 1;
}
}
static void
sdefl_heap_sub(unsigned A[], unsigned len, unsigned sub) {
unsigned c, p = sub;
unsigned v = A[sub];
while ((c = p << 1) <= len) {
if (c < len && A[c + 1] > A[c]) c++;
if (v >= A[c]) break;
A[p] = A[c], p = c;
}
A[p] = v;
}
static void
sdefl_heap_array(unsigned *A, unsigned len) {
unsigned sub;
for (sub = len >> 1; sub >= 1; sub--)
sdefl_heap_sub(A, len, sub);
}
static void
sdefl_heap_sort(unsigned *A, unsigned n) {
A--;
sdefl_heap_array(A, n);
while (n >= 2) {
unsigned tmp = A[n];
A[n--] = A[1];
A[1] = tmp;
sdefl_heap_sub(A, n, 1);
}
}
static unsigned
sdefl_sort_sym(unsigned sym_cnt, unsigned *freqs,
unsigned char *lens, unsigned *sym_out) {
unsigned cnts[SDEFL_CNT_NUM(SDEFL_SYM_MAX)] = {0};
unsigned cnt_num = SDEFL_CNT_NUM(sym_cnt);
unsigned used_sym = 0;
unsigned sym, i;
for (sym = 0; sym < sym_cnt; sym++)
cnts[freqs[sym] < cnt_num-1 ? freqs[sym]: cnt_num-1]++;
for (i = 1; i < cnt_num; i++) {
unsigned cnt = cnts[i];
cnts[i] = used_sym;
used_sym += cnt;
}
for (sym = 0; sym < sym_cnt; sym++) {
unsigned freq = freqs[sym];
if (freq) {
unsigned idx = freq < cnt_num-1 ? freq : cnt_num-1;
sym_out[cnts[idx]++] = sym | (freq << SDEFL_SYM_BITS);
} else lens[sym] = 0;
}
sdefl_heap_sort(sym_out + cnts[cnt_num-2], cnts[cnt_num-1] - cnts[cnt_num-2]);
return used_sym;
}
static void
sdefl_build_tree(unsigned *A, unsigned sym_cnt) {
unsigned i = 0, b = 0, e = 0;
do {
unsigned m, n, freq_shift;
if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
m = i++;
else m = b++;
if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
n = i++;
else n = b++;
freq_shift = (A[m] & ~SDEFL_SYM_MSK) + (A[n] & ~SDEFL_SYM_MSK);
A[m] = (A[m] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
A[n] = (A[n] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
A[e] = (A[e] & SDEFL_SYM_MSK) | freq_shift;
} while (sym_cnt - ++e > 1);
}
static void
sdefl_gen_len_cnt(unsigned *A, unsigned root, unsigned *len_cnt,
unsigned max_code_len) {
int n;
unsigned i;
for (i = 0; i <= max_code_len; i++)
len_cnt[i] = 0;
len_cnt[1] = 2;
A[root] &= SDEFL_SYM_MSK;
for (n = (int)root - 1; n >= 0; n--) {
unsigned p = A[n] >> SDEFL_SYM_BITS;
unsigned pdepth = A[p] >> SDEFL_SYM_BITS;
unsigned depth = pdepth + 1;
unsigned len = depth;
A[n] = (A[n] & SDEFL_SYM_MSK) | (depth << SDEFL_SYM_BITS);
if (len >= max_code_len) {
len = max_code_len;
do len--; while (!len_cnt[len]);
}
len_cnt[len]--;
len_cnt[len+1] += 2;
}
}
static void
sdefl_gen_codes(unsigned *A, unsigned char *lens, const unsigned *len_cnt,
unsigned max_code_word_len, unsigned sym_cnt) {
unsigned i, sym, len, nxt[SDEFL_MAX_CODE_LEN + 1];
for (i = 0, len = max_code_word_len; len >= 1; len--) {
unsigned cnt = len_cnt[len];
while (cnt--) lens[A[i++] & SDEFL_SYM_MSK] = (unsigned char)len;
}
nxt[0] = nxt[1] = 0;
for (len = 2; len <= max_code_word_len; len++)
nxt[len] = (nxt[len-1] + len_cnt[len-1]) << 1;
for (sym = 0; sym < sym_cnt; sym++)
A[sym] = nxt[lens[sym]]++;
}
static unsigned
sdefl_rev(unsigned c, unsigned char n) {
c = ((c & 0x5555) << 1) | ((c & 0xAAAA) >> 1);
c = ((c & 0x3333) << 2) | ((c & 0xCCCC) >> 2);
c = ((c & 0x0F0F) << 4) | ((c & 0xF0F0) >> 4);
c = ((c & 0x00FF) << 8) | ((c & 0xFF00) >> 8);
return c >> (16-n);
}
static void
sdefl_huff(unsigned char *lens, unsigned *codes, unsigned *freqs,
unsigned num_syms, unsigned max_code_len) {
unsigned c, *A = codes;
unsigned len_cnt[SDEFL_MAX_CODE_LEN + 1];
unsigned used_syms = sdefl_sort_sym(num_syms, freqs, lens, A);
if (!used_syms) return;
if (used_syms == 1) {
unsigned s = A[0] & SDEFL_SYM_MSK;
unsigned i = s ? s : 1;
codes[0] = 0, lens[0] = 1;
codes[i] = 1, lens[i] = 1;
return;
}
sdefl_build_tree(A, used_syms);
sdefl_gen_len_cnt(A, used_syms-2, len_cnt, max_code_len);
sdefl_gen_codes(A, lens, len_cnt, max_code_len, num_syms);
for (c = 0; c < num_syms; c++) {
codes[c] = sdefl_rev(codes[c], lens[c]);
}
}
struct sdefl_symcnt {
int items;
int lit;
int off;
};
static void
sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
const unsigned char *litlen, const unsigned char *offlen) {
unsigned *at = items;
unsigned run_start = 0;
unsigned total = 0;
unsigned char lens[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
for (cnt->lit = SDEFL_SYM_MAX; cnt->lit > 257; cnt->lit--)
if (litlen[cnt->lit - 1]) break;
for (cnt->off = SDEFL_OFF_MAX; cnt->off > 1; cnt->off--)
if (offlen[cnt->off - 1]) break;
total = (unsigned)(cnt->lit + cnt->off);
memcpy(lens, litlen, sizeof(unsigned char) * cnt->lit);
memcpy(lens + cnt->lit, offlen, sizeof(unsigned char) * cnt->off);
do {
unsigned len = lens[run_start];
unsigned run_end = run_start;
do run_end++; while (run_end != total && len == lens[run_end]);
if (!len) {
while ((run_end - run_start) >= 11) {
unsigned n = (run_end - run_start) - 11;
unsigned xbits = n < 0x7f ? n : 0x7f;
freqs[18]++;
*at++ = 18u | (xbits << 5u);
run_start += 11 + xbits;
}
if ((run_end - run_start) >= 3) {
unsigned n = (run_end - run_start) - 3;
unsigned xbits = n < 0x7 ? n : 0x7;
freqs[17]++;
*at++ = 17u | (xbits << 5u);
run_start += 3 + xbits;
}
} else if ((run_end - run_start) >= 4) {
freqs[len]++;
*at++ = len;
run_start++;
do {
unsigned xbits = (run_end - run_start) - 3;
xbits = xbits < 0x03 ? xbits : 0x03;
*at++ = 16 | (xbits << 5);
run_start += 3 + xbits;
freqs[16]++;
} while ((run_end - run_start) >= 3);
}
while (run_start != run_end) {
freqs[len]++;
*at++ = len;
run_start++;
}
} while (run_start != total);
cnt->items = (int)(at - items);
}
struct sdefl_match_codes {
int ls, lc;
int dc, dx;
};
static void
sdefl_match_codes(struct sdefl_match_codes *cod, int dist, int len) {
static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
static const unsigned char lslot[258+1] = {
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16,
16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18,
18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 28
};
cod->ls = lslot[len];
cod->lc = 257 + cod->ls;
cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
}
static void
sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
static const char lxn[] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
static const short lmin[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,
51,59,67,83,99,115,131,163,195,227,258};
static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
struct sdefl_match_codes cod;
sdefl_match_codes(&cod, dist, len);
sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
sdefl_put(dst, s, (int)s->cod.word.off[cod.dc], s->cod.len.off[cod.dc]);
sdefl_put(dst, s, dist - dmin[cod.dc], cod.dx);
}
static void
sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
const unsigned char *in) {
int j, i = 0, item_cnt = 0;
struct sdefl_symcnt symcnt = {0};
unsigned codes[SDEFL_PRE_MAX];
unsigned char lens[SDEFL_PRE_MAX];
unsigned freqs[SDEFL_PRE_MAX] = {0};
unsigned items[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
4,12,3,13,2,14,1,15};
/* huffman codes */
s->freq.lit[SDEFL_EOB]++;
sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
if (lens[perm[item_cnt - 1]]) break;
}
/* block header */
sdefl_put(dst, s, is_last ? 0x01 : 0x00, 1); /* block */
sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
sdefl_put(dst, s, symcnt.lit - 257, 5);
sdefl_put(dst, s, symcnt.off - 1, 5);
sdefl_put(dst, s, item_cnt - 4, 4);
for (i = 0; i < item_cnt; ++i)
sdefl_put(dst, s, lens[perm[i]], 3);
for (i = 0; i < symcnt.items; ++i) {
unsigned sym = items[i] & 0x1F;
sdefl_put(dst, s, (int)codes[sym], lens[sym]);
if (sym < 16) continue;
if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
else sdefl_put(dst, s, items[i] >> 5, 7);
}
/* block sequences */
for (i = 0; i < s->seq_cnt; ++i) {
if (s->seq[i].off >= 0)
for (j = 0; j < s->seq[i].len; ++j) {
int c = in[s->seq[i].off + j];
sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
}
else sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
}
sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
memset(&s->freq, 0, sizeof(s->freq));
s->seq_cnt = 0;
}
static void
sdefl_seq(struct sdefl *s, int off, int len) {
assert(s->seq_cnt + 2 < SDEFL_SEQ_SIZ);
s->seq[s->seq_cnt].off = off;
s->seq[s->seq_cnt].len = len;
s->seq_cnt++;
}
static void
sdefl_reg_match(struct sdefl *s, int off, int len) {
struct sdefl_match_codes cod;
sdefl_match_codes(&cod, off, len);
s->freq.lit[cod.lc]++;
s->freq.off[cod.dc]++;
}
struct sdefl_match {
int off;
int len;
};
static void
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s,
int chain_len, int max_match, const unsigned char *in, int p) {
int i = s->tbl[sdefl_hash32(&in[p])];
int limit = ((p-SDEFL_WIN_SIZ)<SDEFL_NIL)?SDEFL_NIL:(p-SDEFL_WIN_SIZ);
while (i > limit) {
if (in[i+m->len] == in[p+m->len] &&
(sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))){
int n = SDEFL_MIN_MATCH;
while (n < max_match && in[i+n] == in[p+n]) n++;
if (n > m->len) {
m->len = n, m->off = p - i;
if (n == max_match) break;
}
}
if (!(--chain_len)) break;
i = s->prv[i&SDEFL_WIN_MSK];
}
}
static int
sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
int in_len, int lvl) {
unsigned char *q = out;
static const unsigned char pref[] = {8,10,14,24,30,48,65,96,130};
int max_chain = (lvl < 8) ? (1 << (lvl + 1)): (1 << 13);
int n, i = 0, litlen = 0;
for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
s->tbl[n] = SDEFL_NIL;
}
do {int blk_end = i + SDEFL_BLK_MAX < in_len ? i + SDEFL_BLK_MAX : in_len;
while (i < blk_end) {
struct sdefl_match m = {0};
int max_match = ((in_len-i)>SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH:(in_len-i);
int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
int run = 1, inc = 1, run_inc;
if (max_match > SDEFL_MIN_MATCH) {
sdefl_fnd(&m, s, max_chain, max_match, in, i);
}
if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len < nice_match){
struct sdefl_match m2 = {0};
sdefl_fnd(&m2, s, max_chain, m.len+1, in, i+1);
m.len = (m2.len > m.len) ? 0 : m.len;
}
if (m.len >= SDEFL_MIN_MATCH) {
if (litlen) {
sdefl_seq(s, i - litlen, litlen);
litlen = 0;
}
sdefl_seq(s, -m.off, m.len);
sdefl_reg_match(s, m.off, m.len);
if (lvl < 2 && m.len >= nice_match) {
inc = m.len;
} else {
run = m.len;
}
} else {
s->freq.lit[in[i]]++;
litlen++;
}
run_inc = run * inc;
if (in_len - (i + run_inc) > SDEFL_MIN_MATCH) {
while (run-- > 0) {
unsigned h = sdefl_hash32(&in[i]);
s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
s->tbl[h] = i, i += inc;
}
} else {
i += run_inc;
}
}
if (litlen) {
sdefl_seq(s, i - litlen, litlen);
litlen = 0;
}
sdefl_flush(&q, s, blk_end == in_len, in);
} while (i < in_len);
if (s->bitcnt)
sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
return (int)(q - out);
}
extern int
sdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
s->bits = s->bitcnt = 0;
return sdefl_compr(s, (unsigned char*)out, (const unsigned char*)in, n, lvl);
}
static unsigned
sdefl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
#define SDEFL_ADLER_INIT (1)
const unsigned ADLER_MOD = 65521;
unsigned s1 = adler32 & 0xffff;
unsigned s2 = adler32 >> 16;
unsigned blk_len, i;
blk_len = in_len % 5552;
while (in_len) {
for (i = 0; i + 7 < blk_len; i += 8) {
s1 += in[0]; s2 += s1;
s1 += in[1]; s2 += s1;
s1 += in[2]; s2 += s1;
s1 += in[3]; s2 += s1;
s1 += in[4]; s2 += s1;
s1 += in[5]; s2 += s1;
s1 += in[6]; s2 += s1;
s1 += in[7]; s2 += s1;
in += 8;
}
for (; i < blk_len; ++i) {
s1 += *in++, s2 += s1;
}
s1 %= ADLER_MOD;
s2 %= ADLER_MOD;
in_len -= blk_len;
blk_len = 5552;
}
return (unsigned)(s2 << 16) + (unsigned)s1;
}
extern int
zsdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
int p = 0;
unsigned a = 0;
unsigned char *q = (unsigned char*)out;
s->bits = s->bitcnt = 0;
sdefl_put(&q, s, 0x78, 8); /* deflate, 32k window */
sdefl_put(&q, s, 0x01, 8); /* fast compression */
q += sdefl_compr(s, q, (const unsigned char*)in, n, lvl);
/* append adler checksum */
a = sdefl_adler32(SDEFL_ADLER_INIT, (const unsigned char*)in, n);
for (p = 0; p < 4; ++p) {
sdefl_put(&q, s, (a >> 24) & 0xFF, 8);
a <<= 8;
}
return (int)(q - (unsigned char*)out);
}
extern int
sdefl_bound(int len) {
int a = 128 + (len * 110) / 100;
int b = 128 + len + ((len / (31 * 1024)) + 1) * 5;
return (a > b) ? a : b;
}
#endif /* SDEFL_IMPLEMENTATION */

464
src/external/sinfl.h vendored Normal file
View File

@ -0,0 +1,464 @@
/*
# Small Deflate
`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
which implements the Deflate (RFC 1951) compressed data format specification standard.
It is mainly tuned to get as much speed and compression ratio from as little code
as needed to keep the implementation as concise as possible.
## Features
- Portable single header and source file duo written in ANSI C (ISO C90)
- Dual license with either MIT or public domain
- Small implementation
- Deflate: 525 LoC
- Inflate: 320 LoC
- Webassembly:
- Deflate ~3.7 KB (~2.2KB compressed)
- Inflate ~3.6 KB (~2.2KB compressed)
## Usage:
This file behaves differently depending on what symbols you define
before including it.
Header-File mode:
If you do not define `SINFL_IMPLEMENTATION` before including this file, it
will operate in header only mode. In this mode it declares all used structs
and the API of the library without including the implementation of the library.
Implementation mode:
If you define `SINFL_IMPLEMENTATION` before including this file, it will
compile the implementation. Make sure that you only include
this file implementation in *one* C or C++ file to prevent collisions.
### Benchmark
| Compressor name | Compression| Decompress.| Compr. size | Ratio |
| ------------------------| -----------| -----------| ----------- | ----- |
| sdefl 1.0 -0 | 127 MB/s | 233 MB/s | 40004116 | 39.88 |
| sdefl 1.0 -1 | 111 MB/s | 259 MB/s | 38940674 | 38.82 |
| sdefl 1.0 -5 | 45 MB/s | 275 MB/s | 36577183 | 36.46 |
| sdefl 1.0 -7 | 38 MB/s | 276 MB/s | 36523781 | 36.41 |
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
| miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 |
| miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 |
| miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 |
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
| libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 |
### Compression
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
| File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
| :------ | ---------: | -----------------: | ---------: | ----------: |
| dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 |
| mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
| mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
| nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
| ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
| osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
| reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
| samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
| sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
| webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
| xml | 5.345.280 | 886,620| 674,009 | 662,141 |
| x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
## License
```
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2020 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
```
*/
#ifndef SINFL_H_INCLUDED
#define SINFL_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#define SINFL_PRE_TBL_SIZE 128
#define SINFL_LIT_TBL_SIZE 1334
#define SINFL_OFF_TBL_SIZE 402
struct sinfl {
int bits, bitcnt;
unsigned lits[SINFL_LIT_TBL_SIZE];
unsigned dsts[SINFL_OFF_TBL_SIZE];
};
extern int sinflate(void *out, const void *in, int size);
extern int zsinflate(void *out, const void *in, int size);
#ifdef __cplusplus
}
#endif
#endif /* SINFL_H_INCLUDED */
#ifdef SINFL_IMPLEMENTATION
#include <string.h> /* memcpy, memset */
static int
sinfl_bsr(unsigned n) {
#ifdef _MSC_VER
_BitScanReverse(&n, n);
return n;
#elif defined(__GNUC__) || defined(__clang__)
return 31 - __builtin_clz(n);
#endif
}
static int
sinfl_get(const unsigned char **src, const unsigned char *end, struct sinfl *s,
int n) {
const unsigned char *in = *src;
int v = s->bits & ((1 << n)-1);
s->bits >>= n;
s->bitcnt = s->bitcnt - n;
s->bitcnt = s->bitcnt < 0 ? 0 : s->bitcnt;
while (s->bitcnt < 16 && in < end) {
s->bits |= (*in++) << s->bitcnt;
s->bitcnt += 8;
}
*src = in;
return v;
}
struct sinfl_gen {
int len;
int cnt;
int word;
short* sorted;
};
static int
sinfl_build_tbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
const int *cnt) {
int tbl_end = 0;
while (!(gen->cnt = cnt[gen->len])) {
++gen->len;
}
tbl_end = 1 << gen->len;
while (gen->len <= tbl_bits) {
do {unsigned bit = 0;
tbl[gen->word] = (*gen->sorted++ << 16) | gen->len;
if (gen->word == tbl_end - 1) {
for (; gen->len < tbl_bits; gen->len++) {
memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
tbl_end <<= 1;
}
return 1;
}
bit = 1 << sinfl_bsr((unsigned)(gen->word ^ (tbl_end - 1)));
gen->word &= bit - 1;
gen->word |= bit;
} while (--gen->cnt);
do {
if (++gen->len <= tbl_bits) {
memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
tbl_end <<= 1;
}
} while (!(gen->cnt = cnt[gen->len]));
}
return 0;
}
static void
sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
const int *cnt) {
int sub_bits = 0;
int sub_start = 0;
int sub_prefix = -1;
int tbl_end = 1 << tbl_bits;
while (1) {
unsigned entry;
int bit, stride, i;
/* start new subtable */
if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) {
int used = 0;
sub_prefix = gen->word & ((1 << tbl_bits)-1);
sub_start = tbl_end;
sub_bits = gen->len - tbl_bits;
used = gen->cnt;
while (used < (1 << sub_bits)) {
sub_bits++;
used = (used << 1) + cnt[tbl_bits + sub_bits];
}
tbl_end = sub_start + (1 << sub_bits);
tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf);
}
/* fill subtable */
entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf);
gen->sorted++;
i = sub_start + (gen->word >> tbl_bits);
stride = 1 << (gen->len - tbl_bits);
do {
tbl[i] = entry;
i += stride;
} while (i < tbl_end);
if (gen->word == (1 << gen->len)-1) {
return;
}
bit = 1 << sinfl_bsr(gen->word ^ ((1 << gen->len) - 1));
gen->word &= bit - 1;
gen->word |= bit;
gen->cnt--;
while (!gen->cnt) {
gen->cnt = cnt[++gen->len];
}
}
}
static void
sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
int symcnt) {
int i, used = 0;
short sort[288];
int cnt[16] = {0}, off[16]= {0};
struct sinfl_gen gen = {0};
gen.sorted = sort;
gen.len = 1;
for (i = 0; i < symcnt; ++i)
cnt[lens[i]]++;
off[1] = cnt[0];
for (i = 1; i < maxlen; ++i) {
off[i + 1] = off[i] + cnt[i];
used = (used << 1) + cnt[i];
}
used = (used << 1) + cnt[i];
for (i = 0; i < symcnt; ++i)
gen.sorted[off[lens[i]]++] = (short)i;
gen.sorted += off[0];
if (used < (1 << maxlen)){
for (i = 0; i < 1 << tbl_bits; ++i)
tbl[i] = (0 << 16u) | 1;
return;
}
if (!sinfl_build_tbl(&gen, tbl, tbl_bits, cnt)){
sinfl_build_subtbl(&gen, tbl, tbl_bits, cnt);
}
}
static int
sinfl_decode(const unsigned char **in, const unsigned char *end,
struct sinfl *s, const unsigned *tbl, int bit_len) {
int idx = s->bits & ((1 << bit_len) - 1);
unsigned key = tbl[idx];
if (key & 0x10) {
/* sub-table lookup */
int len = key & 0x0f;
sinfl_get(in, end, s, bit_len);
idx = s->bits & ((1 << len)-1);
key = tbl[((key >> 16) & 0xffff) + (unsigned)idx];
}
sinfl_get(in, end, s, key & 0x0f);
return (key >> 16) & 0x0fff;
}
static int
sinfl_decompress(unsigned char *out, const unsigned char *in, int size) {
static const unsigned char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
static const unsigned char dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
10,10,11,11,12,12,13,13,0,0};
static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,
43,51,59,67,83,99,115,131,163,195,227,258,0,0};
static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
4,4,4,5,5,5,5,0,0,0};
const unsigned char *e = in + size, *o = out;
enum sinfl_states {hdr,stored,fixed,dyn,blk};
enum sinfl_states state = hdr;
struct sinfl s = {0};
int last = 0;
sinfl_get(&in,e,&s,0); /* buffer input */
while (in < e || s.bitcnt) {
switch (state) {
case hdr: {
int type = 0; /* block header */
last = sinfl_get(&in,e,&s,1);
type = sinfl_get(&in,e,&s,2);
switch (type) {default: return (int)(out-o);
case 0x00: state = stored; break;
case 0x01: state = fixed; break;
case 0x02: state = dyn; break;}
} break;
case stored: {
int len, nlen; /* uncompressed block */
sinfl_get(&in,e,&s,s.bitcnt & 7);
len = sinfl_get(&in,e,&s,16);
nlen = sinfl_get(&in,e,&s,16);
in -= 2; s.bitcnt = 0;
if (len > (e-in) || !len)
return (int)(out-o);
memcpy(out, in, (size_t)len);
in += len, out += len;
state = hdr;
} break;
case fixed: {
/* fixed huffman codes */
int n; unsigned char lens[288+32];
for (n = 0; n <= 143; n++) lens[n] = 8;
for (n = 144; n <= 255; n++) lens[n] = 9;
for (n = 256; n <= 279; n++) lens[n] = 7;
for (n = 280; n <= 287; n++) lens[n] = 8;
for (n = 0; n < 32; n++) lens[288+n] = 5;
/* build lit/dist tables */
sinfl_build(s.lits, lens, 10, 15, 288);
sinfl_build(s.dsts, lens + 288, 8, 15, 32);
state = blk;
} break;
case dyn: {
/* dynamic huffman codes */
int n, i;
unsigned hlens[SINFL_PRE_TBL_SIZE];
unsigned char nlens[19] = {0}, lens[288+32];
int nlit = 257 + sinfl_get(&in,e,&s,5);
int ndist = 1 + sinfl_get(&in,e,&s,5);
int nlen = 4 + sinfl_get(&in,e,&s,4);
for (n = 0; n < nlen; n++)
nlens[order[n]] = (unsigned char)sinfl_get(&in,e,&s,3);
sinfl_build(hlens, nlens, 7, 7, 19);
/* decode code lengths */
for (n = 0; n < nlit + ndist;) {
int sym = sinfl_decode(&in, e, &s, hlens, 7);
switch (sym) {default: lens[n++] = (unsigned char)sym; break;
case 16: for (i=3+sinfl_get(&in,e,&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
case 17: for (i=3+sinfl_get(&in,e,&s,3);i;i--,n++) lens[n]=0; break;
case 18: for (i=11+sinfl_get(&in,e,&s,7);i;i--,n++) lens[n]=0; break;}
}
/* build lit/dist tables */
sinfl_build(s.lits, lens, 10, 15, nlit);
sinfl_build(s.dsts, lens + nlit, 8, 15, ndist);
state = blk;
} break;
case blk: {
/* decompress block */
int i, sym = sinfl_decode(&in, e, &s, s.lits, 10);
if (sym > 256) {sym -= 257; /* match symbol */
{int len = sinfl_get(&in, e, &s, lbits[sym]) + lbase[sym];
int dsym = sinfl_decode(&in, e, &s, s.dsts, 8);
int offs = sinfl_get(&in, e, &s, dbits[dsym]) + dbase[dsym];
if (offs > (int)(out-o)) {
return (int)(out-o);
} else if (offs == 1) {
/* rle match copying */
unsigned char c = *(out - offs);
unsigned long w = (c << 24) | (c << 16) | (c << 8) | c;
for (i = 0; i < len >> 2; ++i) {
memcpy(out, &w, 4);
out += 4;
}
len = len & 3;
} else if (offs >= 4) {
/* copy match */
int wcnt = len >> 2;
for (i = 0; i < wcnt; ++i) {
unsigned long w = 0;
memcpy(&w, out - offs, 4);
memcpy(out, &w, 4);
out += 4;
}
len = len & 3;
}
for (i = 0; i < len; ++i)
{*out = *(out-offs), out++;}
}
} else if (sym == 256) {
/* end of block */
if (last) return (int)(out-o);
state = hdr;
break;
/* literal */
} else *out++ = (unsigned char)sym;
} break;}
}
return (int)(out-o);
}
extern int
sinflate(void *out, const void *in, int size) {
return sinfl_decompress((unsigned char*)out, (const unsigned char*)in, size);
}
static unsigned
sinfl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
const unsigned ADLER_MOD = 65521;
unsigned s1 = adler32 & 0xffff;
unsigned s2 = adler32 >> 16;
unsigned blk_len, i;
blk_len = in_len % 5552;
while (in_len) {
for (i=0; i + 7 < blk_len; i += 8) {
s1 += in[0]; s2 += s1;
s1 += in[1]; s2 += s1;
s1 += in[2]; s2 += s1;
s1 += in[3]; s2 += s1;
s1 += in[4]; s2 += s1;
s1 += in[5]; s2 += s1;
s1 += in[6]; s2 += s1;
s1 += in[7]; s2 += s1;
in += 8;
}
for (; i < blk_len; ++i)
s1 += *in++, s2 += s1;
s1 %= ADLER_MOD; s2 %= ADLER_MOD;
in_len -= blk_len;
blk_len = 5552;
} return (unsigned)(s2 << 16) + (unsigned)s1;
}
extern int
zsinflate(void *out, const void *mem, int size) {
const unsigned char *in = (const unsigned char*)mem;
if (size >= 6) {
const unsigned char *eob = in + size - 4;
int n = sinfl_decompress((unsigned char*)out, in + 2u, size);
unsigned a = sinfl_adler32(1u, (unsigned char*)out, n);
unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0;
return a == h ? n : -1;
} else {
return -1;
}
}
#endif

View File

@ -851,6 +851,12 @@ Mesh *LoadMeshes(const char *fileName, int *meshCount)
return meshes; return meshes;
} }
// Upload mesh vertex data to GPU
void UploadMesh(Mesh *mesh)
{
rlLoadMesh(&mesh, false); // Static mesh by default
}
// Unload mesh from memory (RAM and/or VRAM) // Unload mesh from memory (RAM and/or VRAM)
void UnloadMesh(Mesh mesh) void UnloadMesh(Mesh mesh)
{ {
@ -1292,7 +1298,6 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
mesh.vertices = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float)); mesh.vertices = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float));
mesh.texcoords = (float *)RL_MALLOC(plane->ntriangles*3*2*sizeof(float)); mesh.texcoords = (float *)RL_MALLOC(plane->ntriangles*3*2*sizeof(float));
mesh.normals = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float)); mesh.normals = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float));
mesh.vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
mesh.vertexCount = plane->ntriangles*3; mesh.vertexCount = plane->ntriangles*3;
mesh.triangleCount = plane->ntriangles; mesh.triangleCount = plane->ntriangles;

File diff suppressed because it is too large Load Diff

View File

@ -1966,13 +1966,13 @@ static int SaveWAV(Wave wave, const char *fileName)
format.sampleRate = wave.sampleRate; format.sampleRate = wave.sampleRate;
format.bitsPerSample = wave.sampleSize; format.bitsPerSample = wave.sampleSize;
unsigned char *fileData = NULL; void *fileData = NULL;
size_t fileDataSize = 0; size_t fileDataSize = 0;
success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL); success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
if (success) success = (int)drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data); if (success) success = (int)drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data);
drwav_result result = drwav_uninit(&wav); drwav_result result = drwav_uninit(&wav);
if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, fileData, (unsigned int)fileDataSize); if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, (unsigned char *)fileData, (unsigned int)fileDataSize);
drwav_free(fileData, NULL); drwav_free(fileData, NULL);

View File

@ -113,7 +113,7 @@
#define RL_FREE(ptr) free(ptr) #define RL_FREE(ptr) free(ptr)
#endif #endif
// NOTE: MSC C++ compiler does not support compound literals (C99 feature) // NOTE: MSVC C++ compiler does not support compound literals (C99 feature)
// Plain structures in C++ (without constructors) can be initialized from { } initializers. // Plain structures in C++ (without constructors) can be initialized from { } initializers.
#if defined(__cplusplus) #if defined(__cplusplus)
#define CLITERAL(type) type #define CLITERAL(type) type
@ -831,7 +831,7 @@ typedef enum {
BLEND_MULTIPLIED, // Blend textures multiplying colors BLEND_MULTIPLIED, // Blend textures multiplying colors
BLEND_ADD_COLORS, // Blend textures adding colors (alternative) BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
BLEND_CUSTOM // Belnd textures using custom src/dst factors (use SetBlendModeCustom()) BLEND_CUSTOM // Belnd textures using custom src/dst factors (use rlSetBlendMode())
} BlendMode; } BlendMode;
// Gestures type // Gestures type
@ -1035,6 +1035,7 @@ RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gam
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
RLAPI int GetGamepadAxisCount(int gamepad); // Return gamepad axis count for a gamepad RLAPI int GetGamepadAxisCount(int gamepad); // Return gamepad axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
// Input-related functions: mouse // Input-related functions: mouse
RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
@ -1338,6 +1339,7 @@ RLAPI void UnloadModelKeepMeshes(Model model);
// Mesh loading/unloading functions // Mesh loading/unloading functions
RLAPI Mesh *LoadMeshes(const char *fileName, int *meshCount); // Load meshes from model file RLAPI Mesh *LoadMeshes(const char *fileName, int *meshCount); // Load meshes from model file
RLAPI void UploadMesh(Mesh *mesh); // Upload mesh vertex data to GPU (VRAM)
RLAPI void UnloadMesh(Mesh mesh); // Unload mesh from memory (RAM and/or VRAM) RLAPI void UnloadMesh(Mesh mesh); // Unload mesh from memory (RAM and/or VRAM)
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success

View File

@ -840,7 +840,7 @@ typedef struct RenderBatch {
float currentDepth; // Current depth value for next draw float currentDepth; // Current depth value for next draw
} RenderBatch; } RenderBatch;
#if defined(SUPPORT_VR_SIMULATOR) #if defined(SUPPORT_VR_SIMULATOR) && !defined(RLGL_STANDALONE)
// VR Stereo rendering configuration for simulator // VR Stereo rendering configuration for simulator
typedef struct VrStereoConfig { typedef struct VrStereoConfig {
Shader distortionShader; // VR stereo rendering distortion shader Shader distortionShader; // VR stereo rendering distortion shader
@ -1100,6 +1100,8 @@ void rlFrustum(double left, double right, double bottom, double top, double znea
// Multiply the current matrix by an orthographic matrix generated by parameters // Multiply the current matrix by an orthographic matrix generated by parameters
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
{ {
// NOTE: If left-right and top-botton values are equal it could create
// a division by zero on MatrixOrtho(), response to it is platform/compiler dependant
Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar); Matrix matOrtho = MatrixOrtho(left, right, bottom, top, znear, zfar);
*RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho); *RLGL.State.currentMatrix = MatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
@ -4788,8 +4790,8 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
// Count mipmap levels required // Count mipmap levels required
while ((width != 1) && (height != 1)) while ((width != 1) && (height != 1))
{ {
if (width != 1) width /= 2; width /= 2;
if (height != 1) height /= 2; height /= 2;
TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height); TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);

View File

@ -838,30 +838,6 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
} }
} }
// Draw one character (codepoint)
void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint)
{
// Character index position in sprite font
// NOTE: In case a codepoint is not available in the font, index returned points to '?'
int index = GetGlyphIndex(font, codepoint);
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
// Character destination rectangle on screen
// NOTE: We consider charsPadding on drawing
Rectangle dstRec = { position.x + font.chars[index].offsetX*scaleFactor - (float)font.charsPadding*scaleFactor,
position.y + font.chars[index].offsetY*scaleFactor - (float)font.charsPadding*scaleFactor,
(font.recs[index].width + 2.0f*font.charsPadding)*scaleFactor,
(font.recs[index].height + 2.0f*font.charsPadding)*scaleFactor };
// Character source rectangle from font texture atlas
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
Rectangle srcRec = { font.recs[index].x - (float)font.charsPadding, font.recs[index].y - (float)font.charsPadding,
font.recs[index].width + 2.0f*font.charsPadding, font.recs[index].height + 2.0f*font.charsPadding };
// Draw the character texture on the screen
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
}
// Draw text using Font // Draw text using Font
// NOTE: chars spacing is NOT proportional to fontSize // NOTE: chars spacing is NOT proportional to fontSize
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint) void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint)
@ -915,7 +891,7 @@ void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, flo
// Draw text using font inside rectangle limits with support for text selection // Draw text using font inside rectangle limits with support for text selection
void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint) void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
{ {
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
int textOffsetY = 0; // Offset between lines (on line break '\n') int textOffsetY = 0; // Offset between lines (on line break '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw float textOffsetX = 0.0f; // Offset X to next character to draw
@ -1043,6 +1019,30 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
} }
} }
// Draw one character (codepoint)
void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint)
{
// Character index position in sprite font
// NOTE: In case a codepoint is not available in the font, index returned points to '?'
int index = GetGlyphIndex(font, codepoint);
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
// Character destination rectangle on screen
// NOTE: We consider charsPadding on drawing
Rectangle dstRec = { position.x + font.chars[index].offsetX*scaleFactor - (float)font.charsPadding*scaleFactor,
position.y + font.chars[index].offsetY*scaleFactor - (float)font.charsPadding*scaleFactor,
(font.recs[index].width + 2.0f*font.charsPadding)*scaleFactor,
(font.recs[index].height + 2.0f*font.charsPadding)*scaleFactor };
// Character source rectangle from font texture atlas
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
Rectangle srcRec = { font.recs[index].x - (float)font.charsPadding, font.recs[index].y - (float)font.charsPadding,
font.recs[index].width + 2.0f*font.charsPadding, font.recs[index].height + 2.0f*font.charsPadding };
// Draw the character texture on the screen
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
}
// Measure string width for default font // Measure string width for default font
int MeasureText(const char *text, int fontSize) int MeasureText(const char *text, int fontSize)
{ {

View File

@ -237,7 +237,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -O2 # optimization level 2, if used, also set --memory-init-file 0 # -O2 # optimization level 2, if used, also set --memory-init-file 0
# -s USE_GLFW=3 # Use glfw3 library (context/input management) # -s USE_GLFW=3 # Use glfw3 library (context/input management)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL! # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) (67108864 = 64MB)
# -s USE_PTHREADS=1 # multithreading support # -s USE_PTHREADS=1 # multithreading support
# -s WASM=0 # disable Web Assembly, emitted by default # -s WASM=0 # disable Web Assembly, emitted by default
# -s ASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS # -s ASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS
@ -276,7 +276,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),LINUX)
# Reset everything. # Reset everything.
# Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include # Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
#INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/release/include -I$(RAYLIB_PATH)/src/external
endif endif
endif endif

View File

@ -101,6 +101,15 @@ ifeq ($(PLATFORM),PLATFORM_DRM)
PLATFORM_OS=LINUX PLATFORM_OS=LINUX
endif endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
endif
endif
# RAYLIB_PATH adjustment for different platforms. # RAYLIB_PATH adjustment for different platforms.
# If using GNU make, we can get the full path to the top of the tree. Windows? BSD? # If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
@ -388,6 +397,15 @@ OBJS = $(patsubst %.c, %.o, $(PROJECT_SOURCE_FILES))
# For Android platform we call a custom Makefile.Android # For Android platform we call a custom Makefile.Android
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(PLATFORM),PLATFORM_ANDROID)
MAKEFILE_PARAMS = -f Makefile.Android MAKEFILE_PARAMS = -f Makefile.Android
# For Linux and macOS set make and makefile
ifeq ($(PLATFORM_OS),LINUX)
MAKE = make
MAKEFILE_PARAMS = -f Makefile.Android.linux
endif
ifeq ($(PLATFORM_OS),OSX)
MAKE = make
MAKEFILE_PARAMS = -f Makefile.Android.macos
endif
export PROJECT_NAME export PROJECT_NAME
export PROJECT_SOURCE_FILES export PROJECT_SOURCE_FILES
else else

View File

@ -28,7 +28,7 @@
# Define required raylib variables # Define required raylib variables
PLATFORM ?= PLATFORM_ANDROID PLATFORM ?= PLATFORM_ANDROID
RAYLIB_PATH ?= $(HOME)/raylib_sources.ln RAYLIB_PATH ?= ../../
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version # Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
ANDROID_ARCH ?= ARM64 ANDROID_ARCH ?= ARM64
@ -48,9 +48,9 @@ endif
# no need to define JAVA_HOME , JAVA_BIN in linux environment (binaries are in $PATH) # no need to define JAVA_HOME , JAVA_BIN in linux environment (binaries are in $PATH)
#JAVA_HOME ?= C:/JavaJDK/ #JAVA_HOME ?= C:/JavaJDK/
#JAVA_BIN ?= $(JAVA_HOME)/bin/ #JAVA_BIN ?= $(JAVA_HOME)/bin/
ANDROID_HOME = /opt/android-sdk ANDROID_HOME ?= /opt/android-sdk
#ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION) #ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
ANDROID_TOOLCHAIN = /opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/ ANDROID_TOOLCHAIN ?= /opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/
# find the highest version available of build tools # find the highest version available of build tools
ANDROID_BUILD_TOOLS = $(shell ls -1d $(ANDROID_HOME)/build-tools/* | tail -n 1)/ ANDROID_BUILD_TOOLS = $(shell ls -1d $(ANDROID_HOME)/build-tools/* | tail -n 1)/
@ -94,11 +94,10 @@ APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib APP_KEYSTORE_PASS ?= raylib
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll) # Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
# attention, ne fonctionne pas avec STATIC (manque la libm quelque part) RAYLIB_LIBTYPE ?= STATIC
RAYLIB_LIBTYPE ?= SHARED
# Library path for libraylib.a/libraylib.so # Library path for libraylib.a/libraylib.so
RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src/android/ RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src/
# Shared libs must be added to APK if required # Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries # NOTE: Generated NativeLoader.java automatically load those libraries
@ -141,7 +140,7 @@ LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl
# Force linking of library module to define symbol # Force linking of library module to define symbol
LDFLAGS += -u ANativeActivity_onCreate LDFLAGS += -u ANativeActivity_onCreate
# Library paths containing required libs # Library paths containing required libs
LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME) -L$(ANDROID_TOOLCHAIN)/sysroot/usr/lib/$(ANDROID_TOOLCHAIN_LIBS) LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)
# Define any libraries to link into executable # Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname # if you want to link libraries (libname.so or libname.a), use the -lname