Merge pull request #2 from raysan5/master

Merge raysan5/master
This commit is contained in:
Kirottu 2021-02-01 13:00:12 +02:00 committed by GitHub
commit be6b094ce9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 2094 additions and 1615 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

View File

@ -2,9 +2,11 @@ cmake_minimum_required(VERSION 3.0)
project(raylib) project(raylib)
# Directory for easier includes # 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 as a dependency. # 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()
@ -17,7 +19,7 @@ include(CompilerFlags)
# Registers build options that are exposed to cmake # Registers build options that are exposed to cmake
include(CMakeOptions.txt) include(CMakeOptions.txt)
# Checks a few environment and compiler configurations # Enforces a few environment and compiler configurations
include(BuildOptions) include(BuildOptions)
# Main sources directory (the second parameter sets the output directory name to raylib) # Main sources directory (the second parameter sets the output directory name to raylib)

View File

@ -8,16 +8,16 @@ enum_option(OPENGL_VERSION "OFF;3.3;2.1;1.1;ES 2.0" "Force a specific OpenGL Ver
# Configuration options # Configuration options
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN}) 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_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" 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) 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 # 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(WITH_PIC "Compile static library as position-independent code" OFF)
option(SHARED "Build raylib as a dynamic library" OFF) option(BUILD_SHARED_LIBS "Build raylib as a shared 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(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF)
option(USE_AUDIO "Build raylib with audio module" ON) 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") enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one")
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
@ -28,61 +28,62 @@ option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage"
set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option") set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option")
# core.c # core.c
option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON) cmake_dependent_option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag" 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)
option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON) cmake_dependent_option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" OFF) cmake_dependent_option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" OFF CUSTOMIZE_BUILD 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) 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)
option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON) cmake_dependent_option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON) cmake_dependent_option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF) cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF CUSTOMIZE_BUILD OFF)
option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" 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)
option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF) cmake_dependent_option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF CUSTOMIZE_BUILD OFF)
option(SUPPORT_DATA_STORAGE "Support for persistent data storage" ON) 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 # rlgl.h
option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON) cmake_dependent_option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON CUSTOMIZE_BUILD ON)
# shapes.c # 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) 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)
option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" 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 # textures.c
option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON) cmake_dependent_option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON) cmake_dependent_option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON CUSTOMIZE_BUILD 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) 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)
option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF} CUSTOMIZE_BUILD OFF)
option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF} CUSTOMIZE_BUILD OFF)
option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF} CUSTOMIZE_BUILD OFF)
option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF} CUSTOMIZE_BUILD OFF)
option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF)
option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF)
option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF)
# text.c # text.c
option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON) cmake_dependent_option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON CUSTOMIZE_BUILD ON)
# models.c # 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) 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)
option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON CUSTOMIZE_BUILD ON)
# raudio.c # raudio.c
option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON) cmake_dependent_option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON CUSTOMIZE_BUILD ON)
option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF}) cmake_dependent_option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF} CUSTOMIZE_BUILD OFF)
# utils.c # utils.c
option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON) cmake_dependent_option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON CUSTOMIZE_BUILD ON)

View File

@ -1,24 +1,3 @@
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(${PLATFORM} MATCHES "Desktop" AND APPLE)
if(MACOS_FATLIB) if(MACOS_FATLIB)
if (CMAKE_OSX_ARCHITECTURES) if (CMAKE_OSX_ARCHITECTURES)

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 ()

View File

@ -1,28 +1,52 @@
include(AddIfFlagCompiles) 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) 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) add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
# src/external/jar_xm.h does shady stuff
# Allows some casting of pointers without generating a warning
add_if_flag_compiles(-fno-strict-aliasing CMAKE_C_FLAGS) 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) 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") MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
endif() endif()
add_definitions("-DRAYLIB_CMAKE=1") 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_VERSION VERSION_LESS "3.1")
if(CMAKE_C_COMPILER_ID STREQUAL "GNU") if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
@ -31,3 +55,25 @@ if(CMAKE_VERSION VERSION_LESS "3.1")
else() else()
set (CMAKE_C_STANDARD 99) set (CMAKE_C_STANDARD 99)
endif() 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()

View File

@ -16,11 +16,16 @@ if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MAT
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE) set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
set(GLFW_USE_WAYLAND ${USE_WAYLAND} 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) add_subdirectory(external/glfw)
set(BUILD_SHARED_LIBS ${WAS_SHARED} CACHE BOOL " " FORCE)
unset(WAS_SHARED)
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>) list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>)
include_directories(BEFORE SYSTEM external/glfw/include) include_directories(BEFORE SYSTEM external/glfw/include)
else() else()

View File

@ -7,12 +7,12 @@ install(
) )
# PKG_CONFIG_LIBS_PRIVATE is used in raylib.pc.in # PKG_CONFIG_LIBS_PRIVATE is used in raylib.pc.in
if (STATIC) if (NOT BUILD_SHARED_LIBS)
include(LibraryPathToLinkerFlags) include(LibraryPathToLinkerFlags)
library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}") library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}")
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS}) set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS})
string(REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}") string(REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}")
elseif (SHARED) elseif (BUILD_SHARED_LIBS)
set(PKG_CONFIG_LIBS_EXTRA "") set(PKG_CONFIG_LIBS_EXTRA "")
endif () endif ()

View File

@ -1,12 +1,7 @@
if (${PLATFORM} MATCHES "Desktop")
### Config options ###
# Translate the config options to what raylib wants
configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h)
if(${PLATFORM} MATCHES "Desktop")
set(PLATFORM_CPP "PLATFORM_DESKTOP") set(PLATFORM_CPP "PLATFORM_DESKTOP")
if(APPLE) if (APPLE)
# Need to force OpenGL 3.3 on OS X # Need to force OpenGL 3.3 on OS X
# See: https://github.com/raysan5/raylib/issues/341 # See: https://github.com/raysan5/raylib/issues/341
set(GRAPHICS "GRAPHICS_API_OPENGL_33") set(GRAPHICS "GRAPHICS_API_OPENGL_33")
@ -16,40 +11,35 @@ if(${PLATFORM} MATCHES "Desktop")
if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0") if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
add_definitions(-DGL_SILENCE_DEPRECATION) add_definitions(-DGL_SILENCE_DEPRECATION)
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!") MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
endif() endif ()
elseif(WIN32) elseif (WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm) set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm)
else() else ()
find_library(pthread NAMES pthread) find_library(pthread NAMES pthread)
find_package(OpenGL QUIET) find_package(OpenGL QUIET)
if ("${OPENGL_LIBRARIES}" STREQUAL "") if ("${OPENGL_LIBRARIES}" STREQUAL "")
set(OPENGL_LIBRARIES "GL") set(OPENGL_LIBRARIES "GL")
endif() endif ()
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD") if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
find_library(OSS_LIBRARY ossaudio) find_library(OSS_LIBRARY ossaudio)
endif() endif ()
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY}) set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
endif() endif ()
elseif(${PLATFORM} MATCHES "Web") elseif (${PLATFORM} MATCHES "Web")
set(PLATFORM_CPP "PLATFORM_WEB") set(PLATFORM_CPP "PLATFORM_WEB")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
set(CMAKE_C_FLAGS "-s USE_GLFW=3 -s ASSERTIONS=1 --profiling") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 --profiling")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
elseif(${PLATFORM} MATCHES "Android") elseif (${PLATFORM} MATCHES "Android")
set(PLATFORM_CPP "PLATFORM_ANDROID") set(PLATFORM_CPP "PLATFORM_ANDROID")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") 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) 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) add_definitions(-DANDROID -D__ANDROID_API__=21)
include_directories(external/android/native_app_glue) 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") 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")
@ -57,7 +47,7 @@ elseif(${PLATFORM} MATCHES "Android")
find_library(OPENGL_LIBRARY OpenGL) find_library(OPENGL_LIBRARY OpenGL)
set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c) set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c)
elseif(${PLATFORM} MATCHES "Raspberry Pi") elseif (${PLATFORM} MATCHES "Raspberry Pi")
set(PLATFORM_CPP "PLATFORM_RPI") set(PLATFORM_CPP "PLATFORM_RPI")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
@ -70,7 +60,7 @@ elseif(${PLATFORM} MATCHES "Raspberry Pi")
link_directories(/opt/vc/lib) link_directories(/opt/vc/lib)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl) set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl)
elseif(${PLATFORM} MATCHES "DRM") elseif (${PLATFORM} MATCHES "DRM")
set(PLATFORM_CPP "PLATFORM_DRM") set(PLATFORM_CPP "PLATFORM_DRM")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
@ -86,7 +76,7 @@ elseif(${PLATFORM} MATCHES "DRM")
include_directories(/usr/include/libdrm) include_directories(/usr/include/libdrm)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl) set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl)
endif() endif ()
if (${OPENGL_VERSION}) if (${OPENGL_VERSION})
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}") set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
@ -98,12 +88,18 @@ if (${OPENGL_VERSION})
set(GRAPHICS "GRAPHICS_API_OPENGL_11") set(GRAPHICS "GRAPHICS_API_OPENGL_11")
elseif (${OPENGL_VERSION} MATCHES "ES 2.0") elseif (${OPENGL_VERSION} MATCHES "ES 2.0")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
endif() endif ()
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}") if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail") message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
endif() endif ()
endif() endif ()
if(NOT GRAPHICS) if (NOT GRAPHICS)
set(GRAPHICS "GRAPHICS_API_OPENGL_33") set(GRAPHICS "GRAPHICS_API_OPENGL_33")
endif() endif ()
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
if (${PLATFORM} MATCHES "Desktop")
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
endif ()

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,122 +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()
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})
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c) # Any any resources
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_material_pbr.c) file(GLOB resources ${example_dir}/resources/*)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_cubicmap.c) list(APPEND example_resources ${resources})
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_skybox.c) endforeach ()
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(NOT CMAKE_USE_PTHREADS_INIT OR NOT HAVE_STDATOMIC_H)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c) # Items requiring pthreads
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_loading_thread.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c) endif ()
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") if (${PLATFORM} MATCHES "Android")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy") list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_picking.c)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html") list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_vr_simulator.c)
set(CMAKE_EXECUTABLE_SUFFIX ".html") 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)
# Remove the -rdynamic flag because otherwise emscripten list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
# does not generate HTML+JS+WASM files, only a non-working list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_material_pbr.c)
# and fat HTML list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_cubicmap.c)
string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}") 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)
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")
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
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_EXECUTABLE_SUFFIX ".html")
# Remove the -rdynamic flag because otherwise emscripten
# does not generate HTML+JS+WASM files, only a non-working
# and fat HTML
string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}")
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 # 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 # Setup the example
add_executable(${example_name} ${example_source}) add_executable(${example_name} ${example_source})
target_link_libraries(${example_name} raylib) target_link_libraries(${example_name} raylib)
string(REGEX MATCH ".*/.*/" resources_dir ${example_source}) string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
string(APPEND resources_dir "resources") string(APPEND resources_dir "resources")
if(${PLATFORM} MATCHES "Web" AND EXISTS ${resources_dir}) if (${PLATFORM} MATCHES "Web" AND EXISTS ${resources_dir})
# The local resources path needs to be mapped to /resources virtual path # The local resources path needs to be mapped to /resources virtual path
string(APPEND resources_dir "@resources") string(APPEND resources_dir "@resources")
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}") set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}")
endif() endif ()
endforeach() 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

@ -35,7 +35,7 @@ int main(void)
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
// Get map image data to be used for collision detection // Get map image data to be used for collision detection
Color *mapPixels = GetImageData(imMap); Color *mapPixels = LoadImageColors(imMap);
UnloadImage(imMap); // Unload image from RAM UnloadImage(imMap); // Unload image from RAM
Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position
@ -113,13 +113,13 @@ int main(void)
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
free(mapPixels); // Unload color array UnloadImageColors(mapPixels); // Unload color array
UnloadTexture(cubicmap); // Unload cubicmap texture UnloadTexture(cubicmap); // Unload cubicmap texture
UnloadTexture(texture); // Unload map texture UnloadTexture(texture); // Unload map texture
UnloadModel(model); // Unload map model UnloadModel(model); // Unload map model
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;

View File

@ -0,0 +1,115 @@
/*******************************************************************************************
*
* raylib [models] example - Load 3d gltf model with animations and play them
*
* This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Hristo Stamenov (@object71) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 Hristo Stamenov (@object71) and Ramon Santamaria (@raysan5)
*
********************************************************************************************
*
* To export a model from blender, make sure it is not posed, the vertices need to be in the
* same position as they would be in edit mode.
* and that the scale of your models is set to 0. Scaling can be done from the export menu.
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h>
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation");
// Define the camera to look into our 3d world
Camera camera = { 0 };
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type
Model model = LoadModel("resources/gltf/rigged_figure.glb"); // Load the animated model mesh and
// basic data
// Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
// SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
// Load animation data
int animsCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/gltf/rigged_figure.glb", &animsCount);
int animFrameCounter = 0;
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera);
// Play animation when spacebar is held down
if (IsKeyDown(KEY_SPACE))
{
animFrameCounter++;
UpdateModelAnimation(model, anims[0], animFrameCounter);
if (animFrameCounter >= anims[0].frameCount) animFrameCounter = 0;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
for (int i = 0; i < model.boneCount; i++)
{
DrawSphere(anims[0].framePoses[animFrameCounter][i].translation, 0.01f, RED);
}
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON);
DrawText("(cc4) Rigged Figure by @Cesium", screenWidth - 200, screenHeight - 20, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// UnloadTexture(texture); // Unload texture
// Unload model animations data
for (int i = 0; i < animsCount; i++) UnloadModelAnimation(anims[i]);
RL_FREE(anims);
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -0,0 +1,87 @@
/*******************************************************************************************
*
* raylib [models] example - Load 3d gltf model
*
* This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Hristo Stamenov (@object71) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 Hristo Stamenov (@object71) and Ramon Santamaria (@raysan5)
*
********************************************************************************************
*
* To export a model from blender, make sure it is not posed, the vertices need to be in the
* same position as they would be in edit mode.
* and that the scale of your models is set to 0. Scaling can be done from the export menu.
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h>
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation");
// Define the camera to look into our 3d world
Camera camera = { 0 };
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type
Model model = LoadModel("resources/gltf/Avocado.glb"); // Load the animated model mesh and
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera);
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModelEx(model, position, (Vector3){ 0.0f, 1.0f, 0.0f }, 180.0f, (Vector3){ 15.0f, 15.0f, 15.0f }, WHITE);
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
DrawText("(cc0) Avocado by @Microsoft", screenWidth - 200, screenHeight - 20, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,11 @@
Rigged Figure model has been created by Cesium (https://cesium.com/cesiumjs/),
and licensed as Creative Commons Attribution 4.0 International License.
Check for details: http://creativecommons.org/licenses/by/4.0/
Avocado model is provided by Microsoft
and licensed as CC0 Universal Public Domain
Check for details: https://creativecommons.org/publicdomain/zero/1.0/
GLTF sample models for testing are taken from: https://github.com/KhronosGroup/glTF-Sample-Models/

Binary file not shown.

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)
{
// 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 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

@ -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;
@ -416,7 +416,7 @@ void main()
// 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

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

@ -19,7 +19,7 @@ void main()
vec4 texelColor1 = texture(texture1, fragTexCoord); vec4 texelColor1 = texture(texture1, fragTexCoord);
float x = fract(fragTexCoord.s); float x = fract(fragTexCoord.s);
float out = smoothstep(0.4, 0.6, x); float outVal = smoothstep(0.4, 0.6, x);
finalColor = mix(texelColor0, texelColor1, out); finalColor = mix(texelColor0, texelColor1, outVal);
} }

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;
@ -417,7 +417,7 @@ void main()
// 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

@ -10,6 +10,8 @@ include(JoinPaths)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
if(RAYLIB_IS_MAIN) if(RAYLIB_IS_MAIN)
set(default_build_type Debug) set(default_build_type Debug)
else()
message(WARNING "Default build type is not set (CMAKE_BUILD_TYPE)")
endif() endif()
message(STATUS "Setting build type to '${default_build_type}' as none was specified.") message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
@ -18,7 +20,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif() endif()
# Get the sources together # Used as public API to be included into other projects
set(raylib_public_headers set(raylib_public_headers
raylib.h raylib.h
rlgl.h rlgl.h
@ -27,6 +29,7 @@ set(raylib_public_headers
raudio.h raudio.h
) )
# Sources to be compiled
set(raylib_sources set(raylib_sources
core.c core.c
models.c models.c
@ -36,7 +39,7 @@ set(raylib_sources
utils.c utils.c
) )
# cmake/GlfwImport.cmake handles the details around the inclusion of glfw # <root>/cmake/GlfwImport.cmake handles the details around the inclusion of glfw
include(GlfwImport) include(GlfwImport)
@ -47,56 +50,42 @@ else ()
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)") MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
endif () 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) include(LibraryConfigurations)
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY}) add_library(raylib ${raylib_sources} ${raylib_public_headers})
if (STATIC) if (NOT BUILD_SHARED_LIBS)
MESSAGE(STATUS "Building raylib static library") MESSAGE(STATUS "Building raylib static library")
add_library(raylib STATIC ${raylib_sources} ${raylib_public_headers})
add_library(raylib_static ALIAS raylib) add_library(raylib_static ALIAS raylib)
else()
add_test("pkg-config--static" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh --static)
endif (STATIC)
if (SHARED)
MESSAGE(STATUS "Building raylib shared library") MESSAGE(STATUS "Building raylib shared library")
add_library(raylib SHARED ${raylib_sources} ${raylib_public_headers})
if (MSVC) if (MSVC)
target_compile_definitions(raylib target_compile_definitions(raylib
PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED> PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED> INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
) )
endif () endif ()
endif()
add_test("pkg-config" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh)
endif ()
# Setting target properties
set_target_properties(raylib PROPERTIES set_target_properties(raylib PROPERTIES
PUBLIC_HEADER "${raylib_public_headers}" PUBLIC_HEADER "${raylib_public_headers}"
VERSION ${PROJECT_VERSION} VERSION ${PROJECT_VERSION}
SOVERSION ${API_VERSION} SOVERSION ${API_VERSION}
) )
if (WITH_PIC OR SHARED) if (WITH_PIC OR BUILD_SHARED_LIBS)
set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
endif () endif ()
# Linking libraries
target_link_libraries(raylib "${LIBS_PRIVATE}") target_link_libraries(raylib "${LIBS_PRIVATE}")
if (${PLATFORM} MATCHES "Desktop")
target_link_libraries(raylib glfw)
endif ()
# Adding compile definitions # Sets some compile time definitions for the pre-processor
target_compile_definitions(raylib # If CUSTOMIZE_BUILD option is on you will not use config.h by default
PUBLIC "${PLATFORM_CPP}" # and you will be able to select more build options
PUBLIC "${GRAPHICS}" include(CompileDefinitions)
)
# Registering include directories # Registering include directories
target_include_directories(raylib target_include_directories(raylib
@ -105,7 +94,6 @@ target_include_directories(raylib
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
PRIVATE PRIVATE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_BINARY_DIR} # For cmake/config.h
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR}
) )
@ -113,6 +101,8 @@ target_include_directories(raylib
# Copy the header files to the build directory for convenience # Copy the header files to the build directory for convenience
file(COPY ${raylib_public_headers} DESTINATION "include") file(COPY ${raylib_public_headers} DESTINATION "include")
# Includes information on how the library will be installed on the system
# when cmake --install is run
include(InstallConfigurations) include(InstallConfigurations)
# Print the flags for the user # Print the flags for the user
@ -126,6 +116,7 @@ message(STATUS "Compiling with the flags:")
message(STATUS " PLATFORM=" ${PLATFORM_CPP}) message(STATUS " PLATFORM=" ${PLATFORM_CPP})
message(STATUS " GRAPHICS=" ${GRAPHICS}) message(STATUS " GRAPHICS=" ${GRAPHICS})
# Options if you want to create an installer using CPack
include(PackConfigurations) include(PackConfigurations)
enable_testing() enable_testing()

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 cmake/RaylibOptions.cmake for CMake instead
#include "cmake/config.h"
#else
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: core - Configuration Flags // Module: core - Configuration Flags
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -217,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,91 +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
// Support for persistent data storage
#cmakedefine SUPPORT_DATA_STORAGE 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

@ -189,13 +189,13 @@
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3 #define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
// NOTE: Already provided by rlgl implementation (on glad.h) // NOTE: Already provided by rlgl implementation (on glad.h)
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management #include "GLFW/glfw3.h" // GLFW3 library: Windows, OpenGL context and Input management
// NOTE: GLFW3 already includes gl.h (OpenGL) headers // NOTE: GLFW3 already includes gl.h (OpenGL) headers
// Support retrieving native window handlers // Support retrieving native window handlers
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h> // WARNING: It requires customization to avoid windows.h inclusion! #include "GLFW/glfw3native.h" // WARNING: It requires customization to avoid windows.h inclusion!
#if !defined(SUPPORT_BUSY_WAIT_LOOP) #if !defined(SUPPORT_BUSY_WAIT_LOOP)
// NOTE: Those functions require linking with winmm library // NOTE: Those functions require linking with winmm library
@ -209,12 +209,12 @@
//#define GLFW_EXPOSE_NATIVE_X11 // WARNING: Exposing Xlib.h > X.h results in dup symbols for Font type //#define GLFW_EXPOSE_NATIVE_X11 // WARNING: Exposing Xlib.h > X.h results in dup symbols for Font type
//#define GLFW_EXPOSE_NATIVE_WAYLAND //#define GLFW_EXPOSE_NATIVE_WAYLAND
//#define GLFW_EXPOSE_NATIVE_MIR //#define GLFW_EXPOSE_NATIVE_MIR
#include <GLFW/glfw3native.h> // Required for: glfwGetX11Window() #include "GLFW/glfw3native.h" // Required for: glfwGetX11Window()
#elif defined(__APPLE__) #elif defined(__APPLE__)
#include <unistd.h> // Required for: usleep() #include <unistd.h> // Required for: usleep()
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
#include <GLFW/glfw3native.h> // Required for: glfwGetCocoaWindow() #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow()
#endif #endif
#endif #endif
@ -263,7 +263,7 @@
#if defined(PLATFORM_WEB) #if defined(PLATFORM_WEB)
#define GLFW_INCLUDE_ES2 // GLFW3: Enable OpenGL ES 2.0 (translated to WebGL) #define GLFW_INCLUDE_ES2 // GLFW3: Enable OpenGL ES 2.0 (translated to WebGL)
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management #include "GLFW/glfw3.h" // GLFW3 library: Windows, OpenGL context and Input management
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX #include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
#include <emscripten/emscripten.h> // Emscripten library - LLVM to JavaScript compiler #include <emscripten/emscripten.h> // Emscripten library - LLVM to JavaScript compiler
@ -1738,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
@ -1750,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
@ -2854,9 +2860,7 @@ bool IsGamepadAvailable(int gamepad)
{ {
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true; if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
#endif
return result; return result;
} }
@ -2865,13 +2869,10 @@ bool IsGamepadAvailable(int gamepad)
bool IsGamepadName(int gamepad, const char *name) bool IsGamepadName(int gamepad, const char *name)
{ {
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID)
const char *currentName = NULL; const char *currentName = NULL;
if (CORE.Input.Gamepad.ready[gamepad]) currentName = GetGamepadName(gamepad); if (CORE.Input.Gamepad.ready[gamepad]) currentName = GetGamepadName(gamepad);
if ((name != NULL) && (currentName != NULL)) result = (strcmp(name, currentName) == 0); if ((name != NULL) && (currentName != NULL)) result = (strcmp(name, currentName) == 0);
#endif
return result; return result;
} }
@ -2899,6 +2900,7 @@ int GetGamepadAxisCount(int gamepad)
if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount); if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount);
CORE.Input.Gamepad.axisCount = axisCount; CORE.Input.Gamepad.axisCount = axisCount;
#endif #endif
return CORE.Input.Gamepad.axisCount; return CORE.Input.Gamepad.axisCount;
} }
@ -2907,11 +2909,8 @@ float GetGamepadAxisMovement(int gamepad, int axis)
{ {
float value = 0; float value = 0;
#if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS) && if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS) &&
((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER) || (fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]) > 0.1f)) value = CORE.Input.Gamepad.axisState[gamepad][axis]; // 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA
(fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]) >= 0.2f))) value = CORE.Input.Gamepad.axisState[gamepad][axis];
#endif
return value; return value;
} }
@ -2921,11 +2920,9 @@ bool IsGamepadButtonPressed(int gamepad, int button)
{ {
bool pressed = false; bool pressed = false;
#if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(CORE.Input.Gamepad.currentState[gamepad][button] != CORE.Input.Gamepad.previousState[gamepad][button]) && (CORE.Input.Gamepad.previousState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentState[gamepad][button] == 1)) pressed = true;
(CORE.Input.Gamepad.currentState[gamepad][button] == 1)) pressed = true; else pressed = false;
#endif
return pressed; return pressed;
} }
@ -2935,10 +2932,8 @@ bool IsGamepadButtonDown(int gamepad, int button)
{ {
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(CORE.Input.Gamepad.currentState[gamepad][button] == 1)) result = true; (CORE.Input.Gamepad.currentState[gamepad][button] == 1)) result = true;
#endif
return result; return result;
} }
@ -2948,11 +2943,9 @@ bool IsGamepadButtonReleased(int gamepad, int button)
{ {
bool released = false; bool released = false;
#if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(CORE.Input.Gamepad.currentState[gamepad][button] != CORE.Input.Gamepad.previousState[gamepad][button]) && (CORE.Input.Gamepad.previousState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentState[gamepad][button] == 0)) released = true;
(CORE.Input.Gamepad.currentState[gamepad][button] == 0)) released = true; else released = false;
#endif
return released; return released;
} }
@ -2962,10 +2955,8 @@ bool IsGamepadButtonUp(int gamepad, int button)
{ {
bool result = false; bool result = false;
#if !defined(PLATFORM_ANDROID)
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
(CORE.Input.Gamepad.currentState[gamepad][button] == 0)) result = true; (CORE.Input.Gamepad.currentState[gamepad][button] == 0)) result = true;
#endif
return result; return result;
} }
@ -2976,6 +2967,18 @@ int GetGamepadButtonPressed(void)
return CORE.Input.Gamepad.lastButtonPressed; return CORE.Input.Gamepad.lastButtonPressed;
} }
// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
int result = 0;
#if defined(PLATFORM_DESKTOP)
result = glfwUpdateGamepadMappings(mappings);
#endif
return result;
}
// 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)
{ {
@ -3275,7 +3278,11 @@ static bool InitGraphicsDevice(int width, int height)
else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
#endif #endif
if (CORE.Window.flags & FLAG_MSAA_4X_HINT) glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0 if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
{
TRACELOG(LOG_INFO, "DISPLAY: Trying to enable MSAA x4");
glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0
}
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version // NOTE: When asking for an OpenGL context version, most drivers provide highest supported version
// with forward compatibility to older OpenGL versions. // with forward compatibility to older OpenGL versions.
@ -4228,7 +4235,8 @@ static void Wait(float ms)
// Get gamepad button generic to all platforms // Get gamepad button generic to all platforms
static int GetGamepadButton(int button) static int GetGamepadButton(int button)
{ {
int btn = GAMEPAD_BUTTON_UNKNOWN; int btn = -1;
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
switch (button) switch (button)
{ {
@ -4317,6 +4325,16 @@ static void PollInputEvents(void)
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
CORE.Input.Mouse.currentButtonState[i] = CORE.Input.Mouse.currentButtonStateEvdev[i]; CORE.Input.Mouse.currentButtonState[i] = CORE.Input.Mouse.currentButtonStateEvdev[i];
} }
// Register gamepads buttons events
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (CORE.Input.Gamepad.ready[i]) // Check if gamepad is available
{
// Register previous gamepad states
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousState[i][k] = CORE.Input.Gamepad.currentState[i][k];
}
}
#endif #endif
#if defined(PLATFORM_UWP) #if defined(PLATFORM_UWP)
@ -4615,6 +4633,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)
@ -4658,13 +4677,12 @@ 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
@ -5084,17 +5102,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;
@ -5896,7 +5904,7 @@ static void *GamepadThread(void *arg)
// Process gamepad events by type // Process gamepad events by type
if (gamepadEvent.type == JS_EVENT_BUTTON) if (gamepadEvent.type == JS_EVENT_BUTTON)
{ {
TRACELOGD("RPI: Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value); //TRACELOG(LOG_WARNING, "RPI: Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)
{ {
@ -5909,7 +5917,7 @@ static void *GamepadThread(void *arg)
} }
else if (gamepadEvent.type == JS_EVENT_AXIS) else if (gamepadEvent.type == JS_EVENT_AXIS)
{ {
TRACELOGD("RPI: Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value); //TRACELOG(LOG_WARNING, "RPI: Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
if (gamepadEvent.number < MAX_GAMEPAD_AXIS) if (gamepadEvent.number < MAX_GAMEPAD_AXIS)
{ {
@ -5987,6 +5995,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)
@ -6021,13 +6030,12 @@ 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;

View File

@ -114,9 +114,11 @@ static Model LoadOBJ(const char *fileName); // Load OBJ mesh data
#endif #endif
#if defined(SUPPORT_FILEFORMAT_IQM) #if defined(SUPPORT_FILEFORMAT_IQM)
static Model LoadIQM(const char *fileName); // Load IQM mesh data static Model LoadIQM(const char *fileName); // Load IQM mesh data
static ModelAnimation *LoadIQMModelAnimations(const char *fileName, int *animCount); // Load IQM animation data
#endif #endif
#if defined(SUPPORT_FILEFORMAT_GLTF) #if defined(SUPPORT_FILEFORMAT_GLTF)
static Model LoadGLTF(const char *fileName); // Load GLTF mesh data static Model LoadGLTF(const char *fileName); // Load GLTF mesh data
static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount); // Load GLTF animation data
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -849,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)
{ {
@ -1008,210 +1016,14 @@ void SetModelMeshMaterial(Model *model, int meshId, int materialId)
// Load model animations from file // Load model animations from file
ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount) ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
{ {
#define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number ModelAnimation *animations = NULL;
#define IQM_VERSION 2 // only IQM version 2 supported
unsigned int fileSize = 0; #if defined(SUPPORT_FILEFORMAT_IQM)
unsigned char *fileData = LoadFileData(fileName, &fileSize); if (IsFileExtension(fileName, ".iqm")) animations = LoadIQMModelAnimations(fileName, animCount);
unsigned char *fileDataPtr = fileData; #endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
typedef struct IQMHeader { if (IsFileExtension(fileName, ".gltf;.glb")) animations = LoadGLTFModelAnimations(fileName, animCount);
char magic[16]; #endif
unsigned int version;
unsigned int filesize;
unsigned int flags;
unsigned int num_text, ofs_text;
unsigned int num_meshes, ofs_meshes;
unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
unsigned int num_triangles, ofs_triangles, ofs_adjacency;
unsigned int num_joints, ofs_joints;
unsigned int num_poses, ofs_poses;
unsigned int num_anims, ofs_anims;
unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds;
unsigned int num_comment, ofs_comment;
unsigned int num_extensions, ofs_extensions;
} IQMHeader;
typedef struct IQMPose {
int parent;
unsigned int mask;
float channeloffset[10];
float channelscale[10];
} IQMPose;
typedef struct IQMAnim {
unsigned int name;
unsigned int first_frame, num_frames;
float framerate;
unsigned int flags;
} IQMAnim;
// In case file can not be read, return an empty model
if (fileDataPtr == NULL) return NULL;
// Read IQM header
IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
if (memcmp(iqmHeader->magic, IQM_MAGIC, sizeof(IQM_MAGIC)) != 0)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file is not a valid model", fileName);
return NULL;
}
if (iqmHeader->version != IQM_VERSION)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqmHeader->version);
return NULL;
}
// Get bones data
IQMPose *poses = RL_MALLOC(iqmHeader->num_poses*sizeof(IQMPose));
//fseek(iqmFile, iqmHeader->ofs_poses, SEEK_SET);
//fread(poses, iqmHeader->num_poses*sizeof(IQMPose), 1, iqmFile);
memcpy(poses, fileDataPtr + iqmHeader->ofs_poses, iqmHeader->num_poses*sizeof(IQMPose));
// Get animations data
*animCount = iqmHeader->num_anims;
IQMAnim *anim = RL_MALLOC(iqmHeader->num_anims*sizeof(IQMAnim));
//fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET);
//fread(anim, iqmHeader->num_anims*sizeof(IQMAnim), 1, iqmFile);
memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim));
ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation));
// frameposes
unsigned short *framedata = RL_MALLOC(iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short));
//fseek(iqmFile, iqmHeader->ofs_frames, SEEK_SET);
//fread(framedata, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short), 1, iqmFile);
memcpy(framedata, fileDataPtr + iqmHeader->ofs_frames, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short));
for (unsigned int a = 0; a < iqmHeader->num_anims; a++)
{
animations[a].frameCount = anim[a].num_frames;
animations[a].boneCount = iqmHeader->num_poses;
animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo));
animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
//animations[a].framerate = anim.framerate; // TODO: Use framerate?
for (unsigned int j = 0; j < iqmHeader->num_poses; j++)
{
strcpy(animations[a].bones[j].name, "ANIMJOINTNAME");
animations[a].bones[j].parent = poses[j].parent;
}
for (unsigned int j = 0; j < anim[a].num_frames; j++) animations[a].framePoses[j] = RL_MALLOC(iqmHeader->num_poses*sizeof(Transform));
int dcounter = anim[a].first_frame*iqmHeader->num_framechannels;
for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
{
for (unsigned int i = 0; i < iqmHeader->num_poses; i++)
{
animations[a].framePoses[frame][i].translation.x = poses[i].channeloffset[0];
if (poses[i].mask & 0x01)
{
animations[a].framePoses[frame][i].translation.x += framedata[dcounter]*poses[i].channelscale[0];
dcounter++;
}
animations[a].framePoses[frame][i].translation.y = poses[i].channeloffset[1];
if (poses[i].mask & 0x02)
{
animations[a].framePoses[frame][i].translation.y += framedata[dcounter]*poses[i].channelscale[1];
dcounter++;
}
animations[a].framePoses[frame][i].translation.z = poses[i].channeloffset[2];
if (poses[i].mask & 0x04)
{
animations[a].framePoses[frame][i].translation.z += framedata[dcounter]*poses[i].channelscale[2];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.x = poses[i].channeloffset[3];
if (poses[i].mask & 0x08)
{
animations[a].framePoses[frame][i].rotation.x += framedata[dcounter]*poses[i].channelscale[3];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.y = poses[i].channeloffset[4];
if (poses[i].mask & 0x10)
{
animations[a].framePoses[frame][i].rotation.y += framedata[dcounter]*poses[i].channelscale[4];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.z = poses[i].channeloffset[5];
if (poses[i].mask & 0x20)
{
animations[a].framePoses[frame][i].rotation.z += framedata[dcounter]*poses[i].channelscale[5];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.w = poses[i].channeloffset[6];
if (poses[i].mask & 0x40)
{
animations[a].framePoses[frame][i].rotation.w += framedata[dcounter]*poses[i].channelscale[6];
dcounter++;
}
animations[a].framePoses[frame][i].scale.x = poses[i].channeloffset[7];
if (poses[i].mask & 0x80)
{
animations[a].framePoses[frame][i].scale.x += framedata[dcounter]*poses[i].channelscale[7];
dcounter++;
}
animations[a].framePoses[frame][i].scale.y = poses[i].channeloffset[8];
if (poses[i].mask & 0x100)
{
animations[a].framePoses[frame][i].scale.y += framedata[dcounter]*poses[i].channelscale[8];
dcounter++;
}
animations[a].framePoses[frame][i].scale.z = poses[i].channeloffset[9];
if (poses[i].mask & 0x200)
{
animations[a].framePoses[frame][i].scale.z += framedata[dcounter]*poses[i].channelscale[9];
dcounter++;
}
animations[a].framePoses[frame][i].rotation = QuaternionNormalize(animations[a].framePoses[frame][i].rotation);
}
}
// Build frameposes
for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
{
for (int i = 0; i < animations[a].boneCount; i++)
{
if (animations[a].bones[i].parent >= 0)
{
animations[a].framePoses[frame][i].rotation = QuaternionMultiply(animations[a].framePoses[frame][animations[a].bones[i].parent].rotation, animations[a].framePoses[frame][i].rotation);
animations[a].framePoses[frame][i].translation = Vector3RotateByQuaternion(animations[a].framePoses[frame][i].translation, animations[a].framePoses[frame][animations[a].bones[i].parent].rotation);
animations[a].framePoses[frame][i].translation = Vector3Add(animations[a].framePoses[frame][i].translation, animations[a].framePoses[frame][animations[a].bones[i].parent].translation);
animations[a].framePoses[frame][i].scale = Vector3Multiply(animations[a].framePoses[frame][i].scale, animations[a].framePoses[frame][animations[a].bones[i].parent].scale);
}
}
}
}
RL_FREE(fileData);
RL_FREE(framedata);
RL_FREE(poses);
RL_FREE(anim);
return animations; return animations;
} }
@ -3548,6 +3360,218 @@ static Model LoadIQM(const char *fileName)
return model; return model;
} }
// Load IQM animation data
static ModelAnimation* LoadIQMModelAnimations(const char* fileName, int* animCount)
{
#define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number
#define IQM_VERSION 2 // only IQM version 2 supported
unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize);
unsigned char *fileDataPtr = fileData;
typedef struct IQMHeader {
char magic[16];
unsigned int version;
unsigned int filesize;
unsigned int flags;
unsigned int num_text, ofs_text;
unsigned int num_meshes, ofs_meshes;
unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
unsigned int num_triangles, ofs_triangles, ofs_adjacency;
unsigned int num_joints, ofs_joints;
unsigned int num_poses, ofs_poses;
unsigned int num_anims, ofs_anims;
unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds;
unsigned int num_comment, ofs_comment;
unsigned int num_extensions, ofs_extensions;
} IQMHeader;
typedef struct IQMPose {
int parent;
unsigned int mask;
float channeloffset[10];
float channelscale[10];
} IQMPose;
typedef struct IQMAnim {
unsigned int name;
unsigned int first_frame, num_frames;
float framerate;
unsigned int flags;
} IQMAnim;
// In case file can not be read, return an empty model
if (fileDataPtr == NULL) return NULL;
// Read IQM header
IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
if (memcmp(iqmHeader->magic, IQM_MAGIC, sizeof(IQM_MAGIC)) != 0)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file is not a valid model", fileName);
return NULL;
}
if (iqmHeader->version != IQM_VERSION)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqmHeader->version);
return NULL;
}
// Get bones data
IQMPose *poses = RL_MALLOC(iqmHeader->num_poses*sizeof(IQMPose));
//fseek(iqmFile, iqmHeader->ofs_poses, SEEK_SET);
//fread(poses, iqmHeader->num_poses*sizeof(IQMPose), 1, iqmFile);
memcpy(poses, fileDataPtr + iqmHeader->ofs_poses, iqmHeader->num_poses*sizeof(IQMPose));
// Get animations data
*animCount = iqmHeader->num_anims;
IQMAnim *anim = RL_MALLOC(iqmHeader->num_anims*sizeof(IQMAnim));
//fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET);
//fread(anim, iqmHeader->num_anims*sizeof(IQMAnim), 1, iqmFile);
memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim));
ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation));
// frameposes
unsigned short *framedata = RL_MALLOC(iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short));
//fseek(iqmFile, iqmHeader->ofs_frames, SEEK_SET);
//fread(framedata, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short), 1, iqmFile);
memcpy(framedata, fileDataPtr + iqmHeader->ofs_frames, iqmHeader->num_frames*iqmHeader->num_framechannels*sizeof(unsigned short));
for (unsigned int a = 0; a < iqmHeader->num_anims; a++)
{
animations[a].frameCount = anim[a].num_frames;
animations[a].boneCount = iqmHeader->num_poses;
animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo));
animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
//animations[a].framerate = anim.framerate; // TODO: Use framerate?
for (unsigned int j = 0; j < iqmHeader->num_poses; j++)
{
strcpy(animations[a].bones[j].name, "ANIMJOINTNAME");
animations[a].bones[j].parent = poses[j].parent;
}
for (unsigned int j = 0; j < anim[a].num_frames; j++) animations[a].framePoses[j] = RL_MALLOC(iqmHeader->num_poses*sizeof(Transform));
int dcounter = anim[a].first_frame*iqmHeader->num_framechannels;
for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
{
for (unsigned int i = 0; i < iqmHeader->num_poses; i++)
{
animations[a].framePoses[frame][i].translation.x = poses[i].channeloffset[0];
if (poses[i].mask & 0x01)
{
animations[a].framePoses[frame][i].translation.x += framedata[dcounter]*poses[i].channelscale[0];
dcounter++;
}
animations[a].framePoses[frame][i].translation.y = poses[i].channeloffset[1];
if (poses[i].mask & 0x02)
{
animations[a].framePoses[frame][i].translation.y += framedata[dcounter]*poses[i].channelscale[1];
dcounter++;
}
animations[a].framePoses[frame][i].translation.z = poses[i].channeloffset[2];
if (poses[i].mask & 0x04)
{
animations[a].framePoses[frame][i].translation.z += framedata[dcounter]*poses[i].channelscale[2];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.x = poses[i].channeloffset[3];
if (poses[i].mask & 0x08)
{
animations[a].framePoses[frame][i].rotation.x += framedata[dcounter]*poses[i].channelscale[3];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.y = poses[i].channeloffset[4];
if (poses[i].mask & 0x10)
{
animations[a].framePoses[frame][i].rotation.y += framedata[dcounter]*poses[i].channelscale[4];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.z = poses[i].channeloffset[5];
if (poses[i].mask & 0x20)
{
animations[a].framePoses[frame][i].rotation.z += framedata[dcounter]*poses[i].channelscale[5];
dcounter++;
}
animations[a].framePoses[frame][i].rotation.w = poses[i].channeloffset[6];
if (poses[i].mask & 0x40)
{
animations[a].framePoses[frame][i].rotation.w += framedata[dcounter]*poses[i].channelscale[6];
dcounter++;
}
animations[a].framePoses[frame][i].scale.x = poses[i].channeloffset[7];
if (poses[i].mask & 0x80)
{
animations[a].framePoses[frame][i].scale.x += framedata[dcounter]*poses[i].channelscale[7];
dcounter++;
}
animations[a].framePoses[frame][i].scale.y = poses[i].channeloffset[8];
if (poses[i].mask & 0x100)
{
animations[a].framePoses[frame][i].scale.y += framedata[dcounter]*poses[i].channelscale[8];
dcounter++;
}
animations[a].framePoses[frame][i].scale.z = poses[i].channeloffset[9];
if (poses[i].mask & 0x200)
{
animations[a].framePoses[frame][i].scale.z += framedata[dcounter]*poses[i].channelscale[9];
dcounter++;
}
animations[a].framePoses[frame][i].rotation = QuaternionNormalize(animations[a].framePoses[frame][i].rotation);
}
}
// Build frameposes
for (unsigned int frame = 0; frame < anim[a].num_frames; frame++)
{
for (int i = 0; i < animations[a].boneCount; i++)
{
if (animations[a].bones[i].parent >= 0)
{
animations[a].framePoses[frame][i].rotation = QuaternionMultiply(animations[a].framePoses[frame][animations[a].bones[i].parent].rotation, animations[a].framePoses[frame][i].rotation);
animations[a].framePoses[frame][i].translation = Vector3RotateByQuaternion(animations[a].framePoses[frame][i].translation, animations[a].framePoses[frame][animations[a].bones[i].parent].rotation);
animations[a].framePoses[frame][i].translation = Vector3Add(animations[a].framePoses[frame][i].translation, animations[a].framePoses[frame][animations[a].bones[i].parent].translation);
animations[a].framePoses[frame][i].scale = Vector3Multiply(animations[a].framePoses[frame][i].scale, animations[a].framePoses[frame][animations[a].bones[i].parent].scale);
}
}
}
}
RL_FREE(fileData);
RL_FREE(framedata);
RL_FREE(poses);
RL_FREE(anim);
return animations;
}
#endif #endif
#if defined(SUPPORT_FILEFORMAT_GLTF) #if defined(SUPPORT_FILEFORMAT_GLTF)
@ -3757,7 +3781,8 @@ static Model LoadGLTF(const char *fileName)
int primitivesCount = 0; int primitivesCount = 0;
for (unsigned int i = 0; i < data->meshes_count; i++) primitivesCount += (int)data->meshes[i].primitives_count; for (unsigned int i = 0; i < data->meshes_count; i++)
primitivesCount += (int)data->meshes[i].primitives_count;
// Process glTF data and map to model // Process glTF data and map to model
model.meshCount = primitivesCount; model.meshCount = primitivesCount;
@ -3765,8 +3790,64 @@ static Model LoadGLTF(const char *fileName)
model.materialCount = (int)data->materials_count + 1; model.materialCount = (int)data->materials_count + 1;
model.materials = RL_MALLOC(model.materialCount*sizeof(Material)); model.materials = RL_MALLOC(model.materialCount*sizeof(Material));
model.meshMaterial = RL_MALLOC(model.meshCount*sizeof(int)); model.meshMaterial = RL_MALLOC(model.meshCount*sizeof(int));
model.boneCount = data->nodes_count;
model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo));
model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform));
for (int i = 0; i < model.meshCount; i++) model.meshes[i].vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int)); for (int i = 0; i < model.meshCount; i++)
model.meshes[i].vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
for (unsigned int j = 0; j < data->nodes_count; j++)
{
strcpy(model.bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
model.bones[j].parent = j != 0 ? data->nodes[j].parent - data->nodes : 0;
}
for (unsigned int i = 0; i < data->nodes_count; i++)
{
if(data->nodes[i].has_translation)
{
memcpy(&model.bindPose[i].translation, data->nodes[i].translation, 3 * sizeof(float));
}
else
{
model.bindPose[i].translation = Vector3Zero();
}
if(data->nodes[i].has_rotation)
{
memcpy(&model.bindPose[i].rotation, data->nodes[i].rotation, 4 * sizeof(float));
}
else
{
model.bindPose[i].rotation = QuaternionIdentity();
}
model.bindPose[i].rotation = QuaternionNormalize(model.bindPose[i].rotation);
if(data->nodes[i].has_scale)
{
memcpy(&model.bindPose[i].scale, data->nodes[i].scale, 3 * sizeof(float));
}
else
{
model.bindPose[i].scale = Vector3One();
}
}
for (int i = 0; i < model.boneCount; i++)
{
Transform* currentTransform = model.bindPose + i;
BoneInfo* currentBone = model.bones + i;
Transform* parentTransform = model.bindPose + currentBone->parent;
if (currentBone->parent >= 0)
{
currentTransform->rotation = QuaternionMultiply(parentTransform->rotation, currentTransform->rotation);
currentTransform->translation = Vector3RotateByQuaternion(currentTransform->translation, parentTransform->rotation);
currentTransform->translation = Vector3Add(currentTransform->translation, parentTransform->translation);
currentTransform->scale = Vector3Multiply(parentTransform->scale, parentTransform->scale);
}
}
for (int i = 0; i < model.materialCount - 1; i++) for (int i = 0; i < model.materialCount - 1; i++)
{ {
@ -3848,16 +3929,22 @@ static Model LoadGLTF(const char *fileName)
{ {
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].vertexCount = (int)acc->count; model.meshes[primitiveIndex].vertexCount = (int)acc->count;
model.meshes[primitiveIndex].vertices = RL_MALLOC(model.meshes[primitiveIndex].vertexCount*3*sizeof(float)); int bufferSize = model.meshes[primitiveIndex].vertexCount * 3 * sizeof(float);
model.meshes[primitiveIndex].vertices = RL_MALLOC(bufferSize);
model.meshes[primitiveIndex].animVertices = RL_MALLOC(bufferSize);
LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].vertices) LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].vertices);
memcpy(model.meshes[primitiveIndex].animVertices, model.meshes[primitiveIndex].vertices, bufferSize);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal) else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal)
{ {
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].normals = RL_MALLOC(acc->count*3*sizeof(float)); int bufferSize = acc->count*3*sizeof(float);
model.meshes[primitiveIndex].normals = RL_MALLOC(bufferSize);
model.meshes[primitiveIndex].animNormals = RL_MALLOC(bufferSize);
LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].normals) LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].normals);
memcpy(model.meshes[primitiveIndex].animNormals, model.meshes[primitiveIndex].normals, bufferSize);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord)
{ {
@ -3874,6 +3961,45 @@ static Model LoadGLTF(const char *fileName)
TRACELOG(LOG_WARNING, "MODEL: [%s] glTF texture coordinates must be float", fileName); TRACELOG(LOG_WARNING, "MODEL: [%s] glTF texture coordinates must be float", fileName);
} }
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_joints)
{
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
if(acc->component_type == cgltf_component_type_r_16u)
{
model.meshes[primitiveIndex].boneIds = RL_MALLOC(sizeof(int) * acc->count * 4);
short* bones = RL_MALLOC(sizeof(short) * acc->count * 4);
LOAD_ACCESSOR(short, 4, acc, bones);
for(int a = 0; a < acc->count * 4; a ++)
{
cgltf_node* skinJoint = data->skins->joints[bones[a]];
for(int k = 0; k < data->nodes_count; k++)
{
if(&(data->nodes[k]) == skinJoint)
{
model.meshes[primitiveIndex].boneIds[a] = k;
break;
}
}
}
RL_FREE(bones);
}
else
{
// TODO: Support other size of bone index?
TRACELOG(LOG_WARNING, "MODEL: [%s] glTF bones in unexpected format", fileName);
}
}
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights)
{
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].boneWeights = RL_MALLOC(acc->count*4*sizeof(float));
LOAD_ACCESSOR(float, 4, acc, model.meshes[primitiveIndex].boneWeights)
}
} }
cgltf_accessor *acc = data->meshes[i].primitives[p].indices; cgltf_accessor *acc = data->meshes[i].primitives[p].indices;
@ -3908,8 +4034,11 @@ static Model LoadGLTF(const char *fileName)
model.meshMaterial[primitiveIndex] = model.materialCount - 1;; model.meshMaterial[primitiveIndex] = model.materialCount - 1;;
} }
// if(data->meshes[i].)
primitiveIndex++; primitiveIndex++;
} }
} }
cgltf_free(data); cgltf_free(data);
@ -3920,4 +4049,146 @@ static Model LoadGLTF(const char *fileName)
return model; return model;
} }
// LoadGLTF loads in animation data from given filename
static ModelAnimation* LoadGLTFModelAnimations(const char *fileName, int *animCount)
{
/***********************************************************************************
Function implemented by Hristo Stamenov (@object71)
Features:
- Supports .gltf and .glb files
Some restrictions (not exhaustive):
- ...
*************************************************************************************/
// glTF file loading
unsigned int dataSize = 0;
unsigned char *fileData = LoadFileData(fileName, &dataSize);
ModelAnimation *animations = NULL;
if (fileData == NULL) return animations;
// glTF data loading
cgltf_options options = { 0 };
cgltf_data *data = NULL;
cgltf_result result = cgltf_parse(&options, fileData, dataSize, &data);
if (result == cgltf_result_success)
{
TRACELOG(LOG_INFO, "MODEL: [%s] glTF animations (%s) count: %i", fileName, (data->file_type == 2)? "glb" :
"gltf", data->animations_count);
animations = RL_MALLOC(data->animations_count*sizeof(ModelAnimation));
for (unsigned int a = 0; a < data->animations_count; a++)
{
cgltf_animation *animation = data->animations + a;
ModelAnimation *output = animations + a;
output->frameCount = animation->channels->sampler->input->count;
output->boneCount = data->nodes_count;
output->bones = RL_MALLOC(output->boneCount*sizeof(BoneInfo));
output->framePoses = RL_MALLOC(output->frameCount*sizeof(Transform *));
for (unsigned int j = 0; j < data->nodes_count; j++)
{
strcpy(output->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
output->bones[j].parent = j != 0 ? (int)(data->nodes[j].parent - data->nodes) : 0;
}
for (unsigned int j = 0; j < output->frameCount; j++)
output->framePoses[j] = RL_MALLOC(output->frameCount*data->nodes_count*sizeof(Transform));
for (unsigned int frame = 0; frame < output->frameCount; frame++)
{
for (unsigned int i = 0; i < data->nodes_count; i++)
{
output->framePoses[frame][i].translation = Vector3Zero();
output->framePoses[frame][i].rotation = QuaternionIdentity();
output->framePoses[frame][i].rotation = QuaternionNormalize(output->framePoses[frame][i].rotation);
output->framePoses[frame][i].scale = Vector3One();
}
}
for(int channelId = 0; channelId < animation->channels_count; channelId++)
{
cgltf_animation_channel* channel = animation->channels + channelId;
cgltf_animation_sampler* sampler = channel->sampler;
int boneId = channel->target_node - data->nodes;
for(int frame = 0; frame < output->frameCount; frame++)
{
if(channel->target_path == cgltf_animation_path_type_translation) {
Vector3 translation;
if(cgltf_accessor_read_float(sampler->output, frame, (float*)&translation, 3))
{
output->framePoses[frame][boneId].translation = translation;
}
else if (output->frameCount == 2)
{
memcpy(&translation, frame == 0 ? &(sampler->output->min) : &(sampler->output->max), 3 * sizeof(float));
output->framePoses[frame][boneId].translation = translation;
}
}
if(channel->target_path == cgltf_animation_path_type_rotation) {
Quaternion rotation;
if(cgltf_accessor_read_float(sampler->output, frame, (float*)&rotation, 4))
{
output->framePoses[frame][boneId].rotation = rotation;
output->framePoses[frame][boneId].rotation = QuaternionNormalize(output->framePoses[frame][boneId].rotation);
}
else if (output->frameCount == 2)
{
memcpy(&rotation, frame == 0 ? &(sampler->output->min) : &(sampler->output->max), 4 * sizeof(float));
output->framePoses[frame][boneId].rotation = rotation;
output->framePoses[frame][boneId].rotation = QuaternionNormalize(output->framePoses[frame][boneId].rotation);
}
}
if(channel->target_path == cgltf_animation_path_type_scale) {
Vector3 scale;
if(cgltf_accessor_read_float(sampler->output, frame, (float*)&scale, 4))
{
output->framePoses[frame][boneId].scale = scale;
}
else if (output->frameCount == 2)
{
memcpy(&scale, frame == 0 ? &(sampler->output->min) : &(sampler->output->max), 3 * sizeof(float));
output->framePoses[frame][boneId].scale = scale;
}
}
}
}
// Build frameposes
for (unsigned int frame = 0; frame < output->frameCount; frame++)
{
for (int i = 0; i < output->boneCount; i++)
{
if (output->bones[i].parent >= 0)
{
output->framePoses[frame][i].rotation = QuaternionMultiply(output->framePoses[frame][output->bones[i].parent].rotation, output->framePoses[frame][i].rotation);
output->framePoses[frame][i].translation = Vector3RotateByQuaternion(output->framePoses[frame][i].translation, output->framePoses[frame][output->bones[i].parent].rotation);
output->framePoses[frame][i].translation = Vector3Add(output->framePoses[frame][i].translation, output->framePoses[frame][output->bones[i].parent].translation);
output->framePoses[frame][i].scale = Vector3Multiply(output->framePoses[frame][i].scale, output->framePoses[frame][output->bones[i].parent].scale);
}
}
}
}
cgltf_free(data);
}
else TRACELOG(LOG_WARNING, ": [%s] Failed to load glTF data", fileName);
RL_FREE(fileData);
return animations;
}
#endif #endif

File diff suppressed because it is too large Load Diff

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
@ -674,9 +674,9 @@ typedef enum {
GAMEPAD_BUTTON_RIGHT_TRIGGER_2, GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
// These are buttons in the center of the gamepad // These are buttons in the center of the gamepad
GAMEPAD_BUTTON_MIDDLE_LEFT, //PS3 Select GAMEPAD_BUTTON_MIDDLE_LEFT, // PS3 Select
GAMEPAD_BUTTON_MIDDLE, //PS Button/XBOX Button GAMEPAD_BUTTON_MIDDLE, // PS Button/XBOX Button
GAMEPAD_BUTTON_MIDDLE_RIGHT, //PS3 Start GAMEPAD_BUTTON_MIDDLE_RIGHT, // PS3 Start
// These are the joystick press in buttons // These are the joystick press in buttons
GAMEPAD_BUTTON_LEFT_THUMB, GAMEPAD_BUTTON_LEFT_THUMB,
@ -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

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