commit
be6b094ce9
93
.github/workflows/cmake.yml
vendored
Normal file
93
.github/workflows/cmake.yml
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
name: CMake Builds
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
name: Windows Build
|
||||
# The CMake configure and build commands are platform agnostic and should work equally
|
||||
# well on Windows or Mac. You can convert this to a matrix build if you need
|
||||
# cross-platform coverage.
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{github.workspace}}/build
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: powershell
|
||||
working-directory: ${{github.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $env:GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE -DPLATFORM=Desktop
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: powershell
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $env:BUILD_TYPE
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: powershell
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: ctest -C $env:BUILD_TYPE
|
||||
|
||||
build_linux:
|
||||
name: Linux Build
|
||||
# The CMake configure and build commands are platform agnostic and should work equally
|
||||
# well on Windows or Mac. You can convert this to a matrix build if you need
|
||||
# cross-platform coverage.
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Create Build Environment
|
||||
# Some projects don't allow in-source building, so create a separate build directory
|
||||
# We'll use this as our working directory for all subsequent commands
|
||||
run: cmake -E make_directory ${{github.workspace}}/build
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install gcc-multilib
|
||||
sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{github.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPLATFORM=Desktop
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
# Execute tests defined by the CMake configuration.
|
||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
run: ctest -C $BUILD_TYPE
|
||||
|
|
@ -2,9 +2,11 @@ cmake_minimum_required(VERSION 3.0)
|
|||
project(raylib)
|
||||
|
||||
# Directory for easier includes
|
||||
# Anywhere you see include(...) you can check <root>/cmake for that file
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
# 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}")
|
||||
set(RAYLIB_IS_MAIN TRUE)
|
||||
else()
|
||||
|
|
@ -17,7 +19,7 @@ include(CompilerFlags)
|
|||
# Registers build options that are exposed to cmake
|
||||
include(CMakeOptions.txt)
|
||||
|
||||
# Checks a few environment and compiler configurations
|
||||
# Enforces a few environment and compiler configurations
|
||||
include(BuildOptions)
|
||||
|
||||
# Main sources directory (the second parameter sets the output directory name to raylib)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN})
|
||||
option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF)
|
||||
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
|
||||
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
|
||||
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
|
||||
|
||||
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
|
||||
option(WITH_PIC "Compile static library as position-independent code" OFF)
|
||||
option(SHARED "Build raylib as a dynamic library" OFF)
|
||||
option(STATIC "Build raylib as a static library" ON)
|
||||
option(BUILD_SHARED_LIBS "Build raylib as a shared library" OFF)
|
||||
option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF)
|
||||
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")
|
||||
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")
|
||||
|
||||
# core.c
|
||||
option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON)
|
||||
option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag" ON)
|
||||
option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON)
|
||||
option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" OFF)
|
||||
option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON)
|
||||
option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON)
|
||||
option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON)
|
||||
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF)
|
||||
option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF)
|
||||
option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF)
|
||||
option(SUPPORT_DATA_STORAGE "Support for persistent data storage" 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)
|
||||
cmake_dependent_option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" OFF CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_HIGH_DPI "Support high DPI displays" OFF CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_DATA_STORAGE "Support for persistent data storage" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON)
|
||||
|
||||
# rlgl.h
|
||||
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
|
||||
option(SUPPORT_FONT_TEXTURE "Draw rectangle shapes using font texture white character instead of default white texture. Allows drawing rectangles and text with a single draw call, very useful for GUI systems!" ON)
|
||||
option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON)
|
||||
cmake_dependent_option(SUPPORT_FONT_TEXTURE "Draw rectangle shapes using font texture white character instead of default white texture. Allows drawing rectangles and text with a single draw call, very useful for GUI systems!" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON CUSTOMIZE_BUILD ON)
|
||||
|
||||
# textures.c
|
||||
option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON)
|
||||
option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON)
|
||||
option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON)
|
||||
option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON)
|
||||
option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON)
|
||||
option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON)
|
||||
option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON)
|
||||
option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON)
|
||||
option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF})
|
||||
option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF})
|
||||
option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF})
|
||||
option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF})
|
||||
option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF})
|
||||
option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF})
|
||||
option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF})
|
||||
cmake_dependent_option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
|
||||
# text.c
|
||||
option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON)
|
||||
option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON)
|
||||
option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON CUSTOMIZE_BUILD ON)
|
||||
|
||||
# models.c
|
||||
option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON)
|
||||
option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON)
|
||||
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
|
||||
option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON)
|
||||
option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON)
|
||||
cmake_dependent_option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON CUSTOMIZE_BUILD ON)
|
||||
|
||||
# raudio.c
|
||||
option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF})
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON CUSTOMIZE_BUILD ON)
|
||||
cmake_dependent_option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF} CUSTOMIZE_BUILD OFF)
|
||||
|
||||
# utils.c
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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(MACOS_FATLIB)
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
|
|
|
|||
109
cmake/CompileDefinitions.cmake
Normal file
109
cmake/CompileDefinitions.cmake
Normal 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 ()
|
||||
|
||||
|
|
@ -1,28 +1,52 @@
|
|||
include(AddIfFlagCompiles)
|
||||
|
||||
# Makes +/- operations on void pointers be considered an error
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
|
||||
add_if_flag_compiles(-Werror=pointer-arith CMAKE_C_FLAGS)
|
||||
|
||||
# Generates error whenever a function is used before being declared
|
||||
# https://gcc.gnu.org/onlinedocs/gcc-4.0.1/gcc/Warning-Options.html
|
||||
add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
|
||||
# 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)
|
||||
|
||||
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)
|
||||
# MSAN and ASAN both work on memory - ASAN does more things
|
||||
MESSAGE(WARNING "Compiling with both AddressSanitizer and MemorySanitizer is not recommended")
|
||||
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_C_COMPILER_ID STREQUAL "GNU")
|
||||
|
|
@ -31,3 +55,25 @@ if(CMAKE_VERSION VERSION_LESS "3.1")
|
|||
else()
|
||||
set (CMAKE_C_STANDARD 99)
|
||||
endif()
|
||||
|
||||
if(${PLATFORM} MATCHES "Android")
|
||||
|
||||
# If enabled will remove dead code during the linking process
|
||||
# https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html
|
||||
add_if_flag_compiles(-ffunction-sections CMAKE_C_FLAGS)
|
||||
|
||||
# If enabled will generate some exception data (usually disabled for C programs)
|
||||
# https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Code-Gen-Options.html
|
||||
add_if_flag_compiles(-funwind-tables CMAKE_C_FLAGS)
|
||||
|
||||
# If enabled adds stack protection guards around functions that allocate memory
|
||||
# https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_cjh1548250046139.htm
|
||||
add_if_flag_compiles(-fstack-protector-strong CMAKE_C_FLAGS)
|
||||
|
||||
# Marks that the library will not be compiled with an executable stack
|
||||
add_if_flag_compiles(-Wa,--noexecstack CMAKE_C_FLAGS)
|
||||
|
||||
# Do not expand symbolic links or resolve paths like "/./" or "/../", etc.
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
|
||||
add_if_flag_compiles(-no-canonical-prefixes CMAKE_C_FLAGS)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -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_EXAMPLES 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(WAS_SHARED ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
|
||||
|
||||
add_subdirectory(external/glfw)
|
||||
|
||||
set(BUILD_SHARED_LIBS ${WAS_SHARED} CACHE BOOL " " FORCE)
|
||||
unset(WAS_SHARED)
|
||||
|
||||
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>)
|
||||
include_directories(BEFORE SYSTEM external/glfw/include)
|
||||
else()
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ install(
|
|||
)
|
||||
|
||||
# PKG_CONFIG_LIBS_PRIVATE is used in raylib.pc.in
|
||||
if (STATIC)
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
include(LibraryPathToLinkerFlags)
|
||||
library_path_to_linker_flags(__PKG_CONFIG_LIBS_PRIVATE "${LIBS_PRIVATE}")
|
||||
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE} ${GLFW_PKG_LIBS})
|
||||
string(REPLACE ";" " " PKG_CONFIG_LIBS_PRIVATE "${PKG_CONFIG_LIBS_PRIVATE}")
|
||||
elseif (SHARED)
|
||||
elseif (BUILD_SHARED_LIBS)
|
||||
set(PKG_CONFIG_LIBS_EXTRA "")
|
||||
endif ()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
|
||||
### 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")
|
||||
if (${PLATFORM} MATCHES "Desktop")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP")
|
||||
|
||||
if(APPLE)
|
||||
if (APPLE)
|
||||
# Need to force OpenGL 3.3 on OS X
|
||||
# See: https://github.com/raysan5/raylib/issues/341
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
||||
|
|
@ -16,40 +11,35 @@ if(${PLATFORM} MATCHES "Desktop")
|
|||
if (NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
|
||||
add_definitions(-DGL_SILENCE_DEPRECATION)
|
||||
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
endif ()
|
||||
elseif (WIN32)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
set(LIBS_PRIVATE ${LIBS_PRIVATE} winmm)
|
||||
else()
|
||||
else ()
|
||||
find_library(pthread NAMES pthread)
|
||||
find_package(OpenGL QUIET)
|
||||
if ("${OPENGL_LIBRARIES}" STREQUAL "")
|
||||
set(OPENGL_LIBRARIES "GL")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
|
||||
find_library(OSS_LIBRARY ossaudio)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
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(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")
|
||||
|
||||
elseif(${PLATFORM} MATCHES "Android")
|
||||
elseif (${PLATFORM} MATCHES "Android")
|
||||
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
include(AddIfFlagCompiles)
|
||||
add_if_flag_compiles(-ffunction-sections CMAKE_C_FLAGS)
|
||||
add_if_flag_compiles(-funwind-tables CMAKE_C_FLAGS)
|
||||
add_if_flag_compiles(-fstack-protector-strong CMAKE_C_FLAGS)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
add_if_flag_compiles(-Wa,--noexecstack CMAKE_C_FLAGS)
|
||||
add_if_flag_compiles(-no-canonical-prefixes CMAKE_C_FLAGS)
|
||||
|
||||
add_definitions(-DANDROID -D__ANDROID_API__=21)
|
||||
include_directories(external/android/native_app_glue)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -uANativeActivity_onCreate")
|
||||
|
|
@ -57,7 +47,7 @@ elseif(${PLATFORM} MATCHES "Android")
|
|||
find_library(OPENGL_LIBRARY OpenGL)
|
||||
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(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
|
||||
|
|
@ -70,7 +60,7 @@ elseif(${PLATFORM} MATCHES "Raspberry Pi")
|
|||
link_directories(/opt/vc/lib)
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${BCMHOST} pthread rt m dl)
|
||||
|
||||
elseif(${PLATFORM} MATCHES "DRM")
|
||||
elseif (${PLATFORM} MATCHES "DRM")
|
||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
|
||||
|
|
@ -86,7 +76,7 @@ elseif(${PLATFORM} MATCHES "DRM")
|
|||
include_directories(/usr/include/libdrm)
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} pthread m dl)
|
||||
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if (${OPENGL_VERSION})
|
||||
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
||||
|
|
@ -98,12 +88,18 @@ if (${OPENGL_VERSION})
|
|||
set(GRAPHICS "GRAPHICS_API_OPENGL_11")
|
||||
elseif (${OPENGL_VERSION} MATCHES "ES 2.0")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
endif()
|
||||
endif ()
|
||||
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
||||
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
|
||||
endif()
|
||||
endif()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if(NOT GRAPHICS)
|
||||
if (NOT GRAPHICS)
|
||||
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 ()
|
||||
|
|
@ -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
|
||||
|
|
@ -1,33 +1,29 @@
|
|||
# Setup the project and settings
|
||||
project(examples)
|
||||
|
||||
# Get the sources together
|
||||
set(example_dirs audio core models others shaders shapes text textures)
|
||||
# Directories that contain examples
|
||||
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)
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
|
||||
check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC)
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
|
||||
check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS)
|
||||
if(HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
|
||||
|
||||
if (HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
|
||||
set(example_dirs ${example_dirs} physac)
|
||||
endif()
|
||||
|
||||
set(example_sources)
|
||||
set(example_resources)
|
||||
foreach(example_dir ${example_dirs})
|
||||
# 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()
|
||||
endif ()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
CHECK_INCLUDE_FILE("stdatomic.h" HAVE_STDATOMIC_H)
|
||||
|
|
@ -35,19 +31,39 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
|||
find_package(Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT AND HAVE_STDATOMIC_H)
|
||||
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)
|
||||
endif()
|
||||
if(CMAKE_THREAD_LIBS_INIT)
|
||||
endif ()
|
||||
if (CMAKE_THREAD_LIBS_INIT)
|
||||
link_libraries("${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif()
|
||||
else()
|
||||
endif ()
|
||||
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 ()
|
||||
|
||||
# Collect all source files and resource files
|
||||
# into a CMake variable
|
||||
set(example_sources)
|
||||
set(example_resources)
|
||||
foreach (example_dir ${example_dirs})
|
||||
# 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(NOT CMAKE_USE_PTHREADS_INIT OR NOT HAVE_STDATOMIC_H)
|
||||
# Items requiring pthreads
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_loading_thread.c)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
|
||||
if(${PLATFORM} MATCHES "Android")
|
||||
if (${PLATFORM} MATCHES "Android")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_picking.c)
|
||||
|
|
@ -78,7 +94,7 @@ if(${PLATFORM} MATCHES "Android")
|
|||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
|
||||
|
||||
elseif(${PLATFORM} MATCHES "Web")
|
||||
elseif (${PLATFORM} MATCHES "Web")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
|
||||
# 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")
|
||||
|
|
@ -89,16 +105,16 @@ elseif(${PLATFORM} MATCHES "Web")
|
|||
# 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()
|
||||
endif ()
|
||||
|
||||
include_directories(BEFORE SYSTEM others/external/include)
|
||||
|
||||
if (NOT TARGET raylib)
|
||||
find_package(raylib 2.0 REQUIRED)
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
# Do each example
|
||||
foreach(example_source ${example_sources})
|
||||
foreach (example_source ${example_sources})
|
||||
# Create the basename for the example
|
||||
get_filename_component(example_name ${example_source} NAME)
|
||||
string(REPLACE ".c" "" example_name ${example_name})
|
||||
|
|
@ -111,12 +127,12 @@ foreach(example_source ${example_sources})
|
|||
string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
|
||||
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
|
||||
string(APPEND resources_dir "@resources")
|
||||
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# Copy all of the resource files to the destination
|
||||
file(COPY ${example_resources} DESTINATION "resources/")
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ int main(void)
|
|||
model.materials[0].maps[MAP_DIFFUSE].texture = texture; // Set map diffuse texture
|
||||
|
||||
// Get map image data to be used for collision detection
|
||||
Color *mapPixels = GetImageData(imMap);
|
||||
Color *mapPixels = LoadImageColors(imMap);
|
||||
UnloadImage(imMap); // Unload image from RAM
|
||||
|
||||
Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position
|
||||
|
|
@ -113,7 +113,7 @@ int main(void)
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
free(mapPixels); // Unload color array
|
||||
UnloadImageColors(mapPixels); // Unload color array
|
||||
|
||||
UnloadTexture(cubicmap); // Unload cubicmap texture
|
||||
UnloadTexture(texture); // Unload map texture
|
||||
|
|
|
|||
115
examples/models/models_gltf_animation.c
Normal file
115
examples/models/models_gltf_animation.c
Normal 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;
|
||||
}
|
||||
87
examples/models/models_gltf_model.c
Normal file
87
examples/models/models_gltf_model.c
Normal 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;
|
||||
}
|
||||
BIN
examples/models/resources/gltf/Avocado.glb
Normal file
BIN
examples/models/resources/gltf/Avocado.glb
Normal file
Binary file not shown.
11
examples/models/resources/gltf/LICENSE
Normal file
11
examples/models/resources/gltf/LICENSE
Normal 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/
|
||||
BIN
examples/models/resources/gltf/rigged_figure.glb
Normal file
BIN
examples/models/resources/gltf/rigged_figure.glb
Normal file
Binary file not shown.
|
|
@ -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.
|
||||
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread)
|
||||
* This example has been created using raylib 1.5 (www.raylib.com)
|
||||
* 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 /
|
||||
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
|
||||
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
|
||||
*
|
||||
* Copyright (c) 2016-2018 Victor Fisac
|
||||
* Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#define PHYSAC_NO_THREADS
|
||||
#include "physac.h"
|
||||
|
||||
int main(void)
|
||||
|
|
@ -29,12 +24,11 @@ int main(void)
|
|||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics demo");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics demo");
|
||||
|
||||
// Physac logo drawing position
|
||||
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
|
||||
int logoY = 15;
|
||||
bool needsReset = false;
|
||||
|
||||
// Initialize physics and default physics bodies
|
||||
InitPhysics();
|
||||
|
|
@ -55,25 +49,17 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Delay initialization of variables due to physics reset async
|
||||
RunPhysicsStep();
|
||||
UpdatePhysics(); // Update physics system
|
||||
|
||||
if (needsReset)
|
||||
if (IsKeyPressed('R')) // Reset physics system
|
||||
{
|
||||
ResetPhysics();
|
||||
|
||||
floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2, screenHeight }, 500, 100, 10);
|
||||
floor->enabled = false;
|
||||
|
||||
circle = CreatePhysicsBodyCircle((Vector2){ screenWidth/2, screenHeight/2 }, 45, 10);
|
||||
circle->enabled = false;
|
||||
|
||||
needsReset = false;
|
||||
}
|
||||
|
||||
// Reset physics input
|
||||
if (IsKeyPressed('R'))
|
||||
{
|
||||
ResetPhysics();
|
||||
needsReset = true;
|
||||
}
|
||||
|
||||
// Physics body creation inputs
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread)
|
||||
* This example has been created using raylib 1.5 (www.raylib.com)
|
||||
* 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 /
|
||||
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
|
||||
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
|
||||
*
|
||||
* Copyright (c) 2016-2018 Victor Fisac
|
||||
* Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#define PHYSAC_NO_THREADS
|
||||
#include "physac.h"
|
||||
|
||||
int main(void)
|
||||
|
|
@ -29,7 +24,7 @@ int main(void)
|
|||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics friction");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics friction");
|
||||
|
||||
// Physac logo drawing position
|
||||
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
|
||||
|
|
@ -73,9 +68,9 @@ int main(void)
|
|||
{
|
||||
// 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
|
||||
bodyA->position = (Vector2){ 35, screenHeight*0.6f };
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread)
|
||||
* This example has been created using raylib 1.5 (www.raylib.com)
|
||||
* 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 /
|
||||
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
|
||||
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
|
||||
*
|
||||
* Copyright (c) 2016-2018 Victor Fisac
|
||||
* Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#define PHYSAC_NO_THREADS
|
||||
#include "physac.h"
|
||||
|
||||
#define VELOCITY 0.5f
|
||||
|
|
@ -31,7 +26,7 @@ int main(void)
|
|||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics movement");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics movement");
|
||||
|
||||
// Physac logo drawing position
|
||||
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
|
||||
|
|
@ -66,7 +61,7 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
RunPhysicsStep();
|
||||
UpdatePhysics(); // Update physics system
|
||||
|
||||
if (IsKeyPressed('R')) // Reset physics input
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread)
|
||||
* This example has been created using raylib 1.5 (www.raylib.com)
|
||||
* 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 /
|
||||
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
|
||||
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
|
||||
*
|
||||
* Copyright (c) 2016-2018 Victor Fisac
|
||||
* Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#define PHYSAC_NO_THREADS
|
||||
#include "physac.h"
|
||||
|
||||
int main(void)
|
||||
|
|
@ -29,7 +24,7 @@ int main(void)
|
|||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Physics restitution");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics restitution");
|
||||
|
||||
// Physac logo drawing position
|
||||
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
|
||||
|
|
@ -62,7 +57,7 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
RunPhysicsStep();
|
||||
UpdatePhysics(); // Update physics system
|
||||
|
||||
if (IsKeyPressed('R')) // Reset physics input
|
||||
{
|
||||
|
|
@ -124,6 +119,7 @@ int main(void)
|
|||
DestroyPhysicsBody(circleB);
|
||||
DestroyPhysicsBody(circleC);
|
||||
DestroyPhysicsBody(floor);
|
||||
|
||||
ClosePhysics(); // Unitialize physics
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread)
|
||||
* This example has been created using raylib 1.5 (www.raylib.com)
|
||||
* 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 /
|
||||
* -lraylib -lpthread -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm /
|
||||
* -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
|
||||
*
|
||||
* Copyright (c) 2016-2018 Victor Fisac
|
||||
* Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#define PHYSAC_NO_THREADS
|
||||
#include "physac.h"
|
||||
|
||||
int main(void)
|
||||
|
|
@ -29,12 +24,11 @@ int main(void)
|
|||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "Physac [raylib] - Body shatter");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics shatter");
|
||||
|
||||
// Physac logo drawing position
|
||||
int logoX = screenWidth - MeasureText("Physac", 30) - 10;
|
||||
int logoY = 15;
|
||||
bool needsReset = false;
|
||||
|
||||
// Initialize physics and default physics bodies
|
||||
InitPhysics();
|
||||
|
|
@ -49,31 +43,23 @@ int main(void)
|
|||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
RunPhysicsStep();
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Delay initialization of variables due to physics reset asynchronous
|
||||
if (needsReset)
|
||||
{
|
||||
// Create random polygon physics body to shatter
|
||||
CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
|
||||
needsReset = false;
|
||||
}
|
||||
UpdatePhysics(); // Update physics system
|
||||
|
||||
if (IsKeyPressed('R')) // Reset physics input
|
||||
{
|
||||
ResetPhysics();
|
||||
needsReset = true;
|
||||
|
||||
CreatePhysicsBodyPolygon((Vector2){ screenWidth/2, screenHeight/2 }, GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
|
||||
}
|
||||
|
||||
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();
|
||||
for (int i = count - 1; i >= 0; i--)
|
||||
{
|
||||
PhysicsBody currentBody = GetPhysicsBody(i);
|
||||
|
||||
if (currentBody != NULL) PhysicsShatter(currentBody, GetMousePosition(), 10/currentBody->inverseMass);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ void main()
|
|||
vec4 texelColor1 = texture(texture1, fragTexCoord);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -25,8 +25,7 @@
|
|||
|
||||
# Define required raylib variables
|
||||
PROJECT_NAME ?= game
|
||||
RAYLIB_VERSION ?= 3.0.0
|
||||
RAYLIB_API_VERSION ?= 300
|
||||
RAYLIB_VERSION ?= 3.5.0
|
||||
RAYLIB_PATH ?= ..\..
|
||||
|
||||
# Define compiler path on Windows
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ include(JoinPaths)
|
|||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
if(RAYLIB_IS_MAIN)
|
||||
set(default_build_type Debug)
|
||||
else()
|
||||
message(WARNING "Default build type is not set (CMAKE_BUILD_TYPE)")
|
||||
endif()
|
||||
|
||||
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")
|
||||
endif()
|
||||
|
||||
# Get the sources together
|
||||
# Used as public API to be included into other projects
|
||||
set(raylib_public_headers
|
||||
raylib.h
|
||||
rlgl.h
|
||||
|
|
@ -27,6 +29,7 @@ set(raylib_public_headers
|
|||
raudio.h
|
||||
)
|
||||
|
||||
# Sources to be compiled
|
||||
set(raylib_sources
|
||||
core.c
|
||||
models.c
|
||||
|
|
@ -36,7 +39,7 @@ set(raylib_sources
|
|||
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)
|
||||
|
||||
|
||||
|
|
@ -47,56 +50,42 @@ else ()
|
|||
MESSAGE(STATUS "Audio Backend: None (-DUSE_AUDIO=OFF)")
|
||||
endif ()
|
||||
|
||||
# Sets additional platform options and link libraries for each platform
|
||||
# also selects the proper graphics API and version for that platform
|
||||
# Produces a variable LIBS_PRIVATE that will be used later
|
||||
include(LibraryConfigurations)
|
||||
|
||||
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")
|
||||
|
||||
add_library(raylib STATIC ${raylib_sources} ${raylib_public_headers})
|
||||
add_library(raylib_static ALIAS raylib)
|
||||
|
||||
add_test("pkg-config--static" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh --static)
|
||||
endif (STATIC)
|
||||
|
||||
|
||||
if (SHARED)
|
||||
else()
|
||||
MESSAGE(STATUS "Building raylib shared library")
|
||||
add_library(raylib SHARED ${raylib_sources} ${raylib_public_headers})
|
||||
|
||||
if (MSVC)
|
||||
target_compile_definitions(raylib
|
||||
PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
|
||||
INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
|
||||
)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
add_test("pkg-config" ${PROJECT_SOURCE_DIR}/../cmake/test-pkgconfig.sh)
|
||||
endif ()
|
||||
|
||||
# Setting target properties
|
||||
set_target_properties(raylib PROPERTIES
|
||||
PUBLIC_HEADER "${raylib_public_headers}"
|
||||
VERSION ${PROJECT_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)
|
||||
endif ()
|
||||
|
||||
# Linking libraries
|
||||
target_link_libraries(raylib "${LIBS_PRIVATE}")
|
||||
if (${PLATFORM} MATCHES "Desktop")
|
||||
target_link_libraries(raylib glfw)
|
||||
endif ()
|
||||
|
||||
# Adding compile definitions
|
||||
target_compile_definitions(raylib
|
||||
PUBLIC "${PLATFORM_CPP}"
|
||||
PUBLIC "${GRAPHICS}"
|
||||
)
|
||||
# Sets some compile time definitions for the pre-processor
|
||||
# If CUSTOMIZE_BUILD option is on you will not use config.h by default
|
||||
# and you will be able to select more build options
|
||||
include(CompileDefinitions)
|
||||
|
||||
# Registering include directories
|
||||
target_include_directories(raylib
|
||||
|
|
@ -105,7 +94,6 @@ target_include_directories(raylib
|
|||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR} # For cmake/config.h
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${OPENAL_INCLUDE_DIR}
|
||||
)
|
||||
|
|
@ -113,6 +101,8 @@ target_include_directories(raylib
|
|||
# Copy the header files to the build directory for convenience
|
||||
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)
|
||||
|
||||
# Print the flags for the user
|
||||
|
|
@ -126,6 +116,7 @@ message(STATUS "Compiling with the flags:")
|
|||
message(STATUS " PLATFORM=" ${PLATFORM_CPP})
|
||||
message(STATUS " GRAPHICS=" ${GRAPHICS})
|
||||
|
||||
# Options if you want to create an installer using CPack
|
||||
include(PackConfigurations)
|
||||
|
||||
enable_testing()
|
||||
|
|
|
|||
|
|
@ -27,12 +27,6 @@
|
|||
|
||||
#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
|
||||
//------------------------------------------------------------------------------------
|
||||
|
|
@ -217,6 +211,3 @@
|
|||
//------------------------------------------------------------------------------------
|
||||
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message
|
||||
#define MAX_UWP_MESSAGES 512 // Max UWP messages to process
|
||||
|
||||
|
||||
#endif //defined(RAYLIB_CMAKE)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
98
src/core.c
98
src/core.c
|
|
@ -189,13 +189,13 @@
|
|||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
|
||||
// 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
|
||||
|
||||
// Support retrieving native window handlers
|
||||
#if defined(_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)
|
||||
// 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_WAYLAND
|
||||
//#define GLFW_EXPOSE_NATIVE_MIR
|
||||
#include <GLFW/glfw3native.h> // Required for: glfwGetX11Window()
|
||||
#include "GLFW/glfw3native.h" // Required for: glfwGetX11Window()
|
||||
#elif defined(__APPLE__)
|
||||
#include <unistd.h> // Required for: usleep()
|
||||
|
||||
//#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
|
||||
|
||||
|
|
@ -263,7 +263,7 @@
|
|||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#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 <emscripten/emscripten.h> // Emscripten library - LLVM to JavaScript compiler
|
||||
|
|
@ -1738,6 +1738,9 @@ void EnableCursor(void)
|
|||
#if defined(PLATFORM_DESKTOP)
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
#endif
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_exit_pointerlock();
|
||||
#endif
|
||||
#if defined(PLATFORM_UWP)
|
||||
UWPGetMouseUnlockFunc()();
|
||||
#endif
|
||||
|
|
@ -1750,6 +1753,9 @@ void DisableCursor(void)
|
|||
#if defined(PLATFORM_DESKTOP)
|
||||
glfwSetInputMode(CORE.Window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
#endif
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_request_pointerlock("#canvas", 1);
|
||||
#endif
|
||||
#if defined(PLATFORM_UWP)
|
||||
UWPGetMouseLockFunc()();
|
||||
#endif
|
||||
|
|
@ -2854,9 +2860,7 @@ bool IsGamepadAvailable(int gamepad)
|
|||
{
|
||||
bool result = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad]) result = true;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2865,13 +2869,10 @@ bool IsGamepadAvailable(int gamepad)
|
|||
bool IsGamepadName(int gamepad, const char *name)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
const char *currentName = NULL;
|
||||
|
||||
if (CORE.Input.Gamepad.ready[gamepad]) currentName = GetGamepadName(gamepad);
|
||||
if ((name != NULL) && (currentName != NULL)) result = (strcmp(name, currentName) == 0);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2899,6 +2900,7 @@ int GetGamepadAxisCount(int gamepad)
|
|||
if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount);
|
||||
CORE.Input.Gamepad.axisCount = axisCount;
|
||||
#endif
|
||||
|
||||
return CORE.Input.Gamepad.axisCount;
|
||||
}
|
||||
|
||||
|
|
@ -2907,11 +2909,8 @@ float GetGamepadAxisMovement(int gamepad, int axis)
|
|||
{
|
||||
float value = 0;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
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.2f))) value = CORE.Input.Gamepad.axisState[gamepad][axis];
|
||||
#endif
|
||||
(fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]) > 0.1f)) value = CORE.Input.Gamepad.axisState[gamepad][axis]; // 0.1f = GAMEPAD_AXIS_MINIMUM_DRIFT/DELTA
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
@ -2921,11 +2920,9 @@ bool IsGamepadButtonPressed(int gamepad, int button)
|
|||
{
|
||||
bool pressed = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
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.currentState[gamepad][button] == 1)) pressed = true;
|
||||
#endif
|
||||
(CORE.Input.Gamepad.previousState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentState[gamepad][button] == 1)) pressed = true;
|
||||
else pressed = false;
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
|
@ -2935,10 +2932,8 @@ bool IsGamepadButtonDown(int gamepad, int button)
|
|||
{
|
||||
bool result = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(CORE.Input.Gamepad.currentState[gamepad][button] == 1)) result = true;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2948,11 +2943,9 @@ bool IsGamepadButtonReleased(int gamepad, int button)
|
|||
{
|
||||
bool released = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
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.currentState[gamepad][button] == 0)) released = true;
|
||||
#endif
|
||||
(CORE.Input.Gamepad.previousState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentState[gamepad][button] == 0)) released = true;
|
||||
else released = false;
|
||||
|
||||
return released;
|
||||
}
|
||||
|
|
@ -2962,10 +2955,8 @@ bool IsGamepadButtonUp(int gamepad, int button)
|
|||
{
|
||||
bool result = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(CORE.Input.Gamepad.currentState[gamepad][button] == 0)) result = true;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2976,6 +2967,18 @@ int GetGamepadButtonPressed(void)
|
|||
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
|
||||
bool IsMouseButtonPressed(int button)
|
||||
{
|
||||
|
|
@ -3275,7 +3278,11 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
|
||||
#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
|
||||
// with forward compatibility to older OpenGL versions.
|
||||
|
|
@ -4228,7 +4235,8 @@ static void Wait(float ms)
|
|||
// Get gamepad button generic to all platforms
|
||||
static int GetGamepadButton(int button)
|
||||
{
|
||||
int btn = GAMEPAD_BUTTON_UNKNOWN;
|
||||
int btn = -1;
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
switch (button)
|
||||
{
|
||||
|
|
@ -4317,6 +4325,16 @@ static void PollInputEvents(void)
|
|||
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[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
|
||||
|
||||
#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!
|
||||
}
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
|
||||
{
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
|
|
@ -4658,13 +4677,12 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||
}
|
||||
else
|
||||
#endif // SUPPORT_GIF_RECORDING
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
{
|
||||
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||
screenshotCounter++;
|
||||
}
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
}
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
else
|
||||
{
|
||||
// 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
|
||||
if (eventType == EMSCRIPTEN_EVENT_CLICK)
|
||||
{
|
||||
EmscriptenPointerlockChangeEvent plce;
|
||||
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();
|
||||
// TODO: Manage mouse events if required (note that GLFW JS wrapper manages it now)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -5896,7 +5904,7 @@ static void *GamepadThread(void *arg)
|
|||
// Process gamepad events by type
|
||||
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)
|
||||
{
|
||||
|
|
@ -5909,7 +5917,7 @@ static void *GamepadThread(void *arg)
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
|
@ -5987,6 +5995,7 @@ void UWPKeyDownEvent(int key, bool down, bool controlKey)
|
|||
// Time to close the window.
|
||||
CORE.Window.shouldClose = true;
|
||||
}
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
else if (key == KEY_F12 && down)
|
||||
{
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
|
|
@ -6021,13 +6030,12 @@ void UWPKeyDownEvent(int key, bool down, bool controlKey)
|
|||
}
|
||||
else
|
||||
#endif // SUPPORT_GIF_RECORDING
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
{
|
||||
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||
screenshotCounter++;
|
||||
}
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
}
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
else
|
||||
{
|
||||
CORE.Input.Keyboard.currentKeyState[key] = down;
|
||||
|
|
|
|||
689
src/models.c
689
src/models.c
|
|
@ -114,9 +114,11 @@ static Model LoadOBJ(const char *fileName); // Load OBJ mesh data
|
|||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_IQM)
|
||||
static Model LoadIQM(const char *fileName); // Load IQM mesh data
|
||||
static ModelAnimation *LoadIQMModelAnimations(const char *fileName, int *animCount); // Load IQM animation data
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_GLTF)
|
||||
static Model LoadGLTF(const char *fileName); // Load GLTF mesh data
|
||||
static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount); // Load GLTF animation data
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -849,6 +851,12 @@ Mesh *LoadMeshes(const char *fileName, int *meshCount)
|
|||
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)
|
||||
void UnloadMesh(Mesh mesh)
|
||||
{
|
||||
|
|
@ -1008,210 +1016,14 @@ void SetModelMeshMaterial(Model *model, int meshId, int materialId)
|
|||
// Load model animations from file
|
||||
ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
|
||||
{
|
||||
#define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number
|
||||
#define IQM_VERSION 2 // only IQM version 2 supported
|
||||
ModelAnimation *animations = NULL;
|
||||
|
||||
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);
|
||||
#if defined(SUPPORT_FILEFORMAT_IQM)
|
||||
if (IsFileExtension(fileName, ".iqm")) animations = LoadIQMModelAnimations(fileName, animCount);
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_GLTF)
|
||||
if (IsFileExtension(fileName, ".gltf;.glb")) animations = LoadGLTFModelAnimations(fileName, animCount);
|
||||
#endif
|
||||
|
||||
return animations;
|
||||
}
|
||||
|
|
@ -3548,6 +3360,218 @@ static Model LoadIQM(const char *fileName)
|
|||
|
||||
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
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_GLTF)
|
||||
|
|
@ -3757,7 +3781,8 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
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
|
||||
model.meshCount = primitivesCount;
|
||||
|
|
@ -3765,8 +3790,64 @@ static Model LoadGLTF(const char *fileName)
|
|||
model.materialCount = (int)data->materials_count + 1;
|
||||
model.materials = RL_MALLOC(model.materialCount*sizeof(Material));
|
||||
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++)
|
||||
{
|
||||
|
|
@ -3848,16 +3929,22 @@ static Model LoadGLTF(const char *fileName)
|
|||
{
|
||||
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -3874,6 +3961,45 @@ static Model LoadGLTF(const char *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;
|
||||
|
|
@ -3908,8 +4034,11 @@ static Model LoadGLTF(const char *fileName)
|
|||
model.meshMaterial[primitiveIndex] = model.materialCount - 1;;
|
||||
}
|
||||
|
||||
// if(data->meshes[i].)
|
||||
|
||||
primitiveIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cgltf_free(data);
|
||||
|
|
@ -3920,4 +4049,146 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
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
|
||||
|
|
|
|||
1045
src/physac.h
1045
src/physac.h
File diff suppressed because it is too large
Load Diff
10
src/raylib.h
10
src/raylib.h
|
|
@ -113,7 +113,7 @@
|
|||
#define RL_FREE(ptr) free(ptr)
|
||||
#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.
|
||||
#if defined(__cplusplus)
|
||||
#define CLITERAL(type) type
|
||||
|
|
@ -674,9 +674,9 @@ typedef enum {
|
|||
GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
|
||||
|
||||
// These are buttons in the center of the gamepad
|
||||
GAMEPAD_BUTTON_MIDDLE_LEFT, //PS3 Select
|
||||
GAMEPAD_BUTTON_MIDDLE, //PS Button/XBOX Button
|
||||
GAMEPAD_BUTTON_MIDDLE_RIGHT, //PS3 Start
|
||||
GAMEPAD_BUTTON_MIDDLE_LEFT, // PS3 Select
|
||||
GAMEPAD_BUTTON_MIDDLE, // PS Button/XBOX Button
|
||||
GAMEPAD_BUTTON_MIDDLE_RIGHT, // PS3 Start
|
||||
|
||||
// These are the joystick press in buttons
|
||||
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 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 int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
|
||||
|
||||
// Input-related functions: mouse
|
||||
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
|
||||
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 bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
|
||||
|
||||
|
|
|
|||
|
|
@ -840,7 +840,7 @@ typedef struct RenderBatch {
|
|||
float currentDepth; // Current depth value for next draw
|
||||
} RenderBatch;
|
||||
|
||||
#if defined(SUPPORT_VR_SIMULATOR)
|
||||
#if defined(SUPPORT_VR_SIMULATOR) && !defined(RLGL_STANDALONE)
|
||||
// VR Stereo rendering configuration for simulator
|
||||
typedef struct VrStereoConfig {
|
||||
Shader distortionShader; // VR stereo rendering distortion shader
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
|
|||
# -O2 # optimization level 2, if used, also set --memory-init-file 0
|
||||
# -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 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 WASM=0 # disable Web Assembly, emitted by default
|
||||
# -s ASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user