mirror of
https://github.com/raysan5/raylib.git
synced 2025-10-08 10:56:28 +00:00
Merge branch 'master' of https://github.com/raysan5/raylib into dr/mini_al
This commit is contained in:
195
src/CMakeLists.txt
Normal file → Executable file
195
src/CMakeLists.txt
Normal file → Executable file
@@ -1,26 +1,41 @@
|
||||
# Setup the project and settings
|
||||
project(raylib)
|
||||
project(raylib C)
|
||||
include(GNUInstallDirs)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||
|
||||
set(PROJECT_VERSION 1.9.7)
|
||||
set(API_VERSION 1)
|
||||
set(PROJECT_VERSION 2.0.0)
|
||||
set(API_VERSION 2)
|
||||
set(RAYLIB raylib) # Name of the generated library
|
||||
|
||||
include("CMakeOptions.txt")
|
||||
include(BuildType)
|
||||
configure_file(config.h.in ${CMAKE_BINARY_DIR}/cmake/config.h)
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
|
||||
include("../utils.cmake")
|
||||
include_directories(SYSTEM .)
|
||||
|
||||
# Get the sources together
|
||||
file(GLOB raylib_sources *.c)
|
||||
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/rglfw.c)
|
||||
|
||||
if(glfw3_FOUND)
|
||||
list(REMOVE_ITEM raylib_sources ${CMAKE_CURRENT_SOURCE_DIR}/rglfw.c)
|
||||
else()
|
||||
if(NOT glfw3_FOUND AND "${PLATFORM}" MATCHES "Desktop")
|
||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
|
||||
set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
|
||||
if (WITH_PIC OR SHARED)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
add_subdirectory(external/glfw)
|
||||
include_directories(external/glfw/include)
|
||||
|
||||
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw_objlib>)
|
||||
endif()
|
||||
|
||||
include(utils)
|
||||
|
||||
if(USE_AUDIO)
|
||||
file(GLOB stb_vorbis external/stb_vorbis.c)
|
||||
file(GLOB mini_al external/mini_al.c ${stb_vorbis})
|
||||
@@ -31,6 +46,8 @@ else()
|
||||
set(sources ${raylib_sources})
|
||||
endif()
|
||||
|
||||
include(AddIfFlagCompiles)
|
||||
|
||||
### Config options ###
|
||||
# Translate the config options to what raylib wants
|
||||
if(${PLATFORM} MATCHES "Desktop")
|
||||
@@ -47,11 +64,10 @@ if(${PLATFORM} MATCHES "Desktop")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
endif()
|
||||
|
||||
# Need to force OpenGL 3.3 on OS X
|
||||
# See: https://github.com/raysan5/raylib/issues/341
|
||||
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")
|
||||
set_source_files_properties(rglfw.c PROPERTIES COMPILE_FLAGS "-x objective-c")
|
||||
link_libraries("${LIBS_PRIVATE}")
|
||||
elseif(WIN32)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
@@ -61,100 +77,109 @@ elseif(${PLATFORM} MATCHES "Web")
|
||||
set(PLATFORM "PLATFORM_WEB")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
|
||||
# Need to use `emcc`
|
||||
set(CMAKE_C_COMPILER "emcc")
|
||||
set(CMAKE_CXX_COMPILER "em++")
|
||||
set(CMAKE_C_FLAGS "-s USE_GLFW=3 -s ASSERTIONS=1 --profiling")
|
||||
|
||||
# Change the name of the output library
|
||||
set(RAYLIB "libraylib.bc")
|
||||
|
||||
elseif(${PLATFORM} MATCHES "Android")
|
||||
set(PLATFORM "PLATFORM_ANDROID")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
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")
|
||||
|
||||
elseif(${PLATFORM} MATCHES "Raspberry Pi")
|
||||
set(PLATFORM "PLATFORM_RPI")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
endif()
|
||||
|
||||
if(MACOS_FATLIB)
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
|
||||
else()
|
||||
SET(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
|
||||
endif()
|
||||
endif()
|
||||
if(${SHARED})
|
||||
add_library(${RAYLIB}_shared SHARED ${sources})
|
||||
|
||||
# Which platform?
|
||||
if(${PLATFORM} MATCHES "PLATFORM_DESKTOP")
|
||||
target_compile_definitions(${RAYLIB}_shared
|
||||
PUBLIC ${PLATFORM}
|
||||
PUBLIC ${GRAPHICS}
|
||||
)
|
||||
|
||||
if(${SHARED})
|
||||
add_library(${RAYLIB}_shared SHARED ${sources})
|
||||
set_property(TARGET ${RAYLIB}_shared PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set(CMAKE_MACOSX_RPATH ON)
|
||||
|
||||
target_compile_definitions(${RAYLIB}_shared
|
||||
PUBLIC ${PLATFORM}
|
||||
PUBLIC ${GRAPHICS}
|
||||
)
|
||||
|
||||
set_property(TARGET ${RAYLIB}_shared PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set(CMAKE_MACOSX_RPATH ON)
|
||||
|
||||
target_link_libraries(${RAYLIB}_shared ${LIBS_PRIVATE})
|
||||
set_target_properties(${RAYLIB}_shared PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${API_VERSION}
|
||||
PUBLIC_HEADER "raylib.h"
|
||||
)
|
||||
if(WIN32)
|
||||
install(
|
||||
TARGETS ${RAYLIB}_shared
|
||||
RUNTIME DESTINATION lib
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
target_link_libraries(${RAYLIB}_shared ${LIBS_PRIVATE})
|
||||
if (${PLATFORM} MATCHES "Desktop")
|
||||
target_link_libraries(${RAYLIB}_shared glfw ${GLFW_LIBRARIES})
|
||||
endif()
|
||||
if (UNIX AND ${FILESYSTEM_LACKS_SYMLINKS})
|
||||
MESSAGE(WARNING "Can't version UNIX shared library on file system without symlink support")
|
||||
else()
|
||||
set_target_properties(${RAYLIB}_shared PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${API_VERSION}
|
||||
)
|
||||
else() # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows
|
||||
set_target_properties(${RAYLIB}_shared PROPERTIES OUTPUT_NAME ${RAYLIB})
|
||||
install(
|
||||
TARGETS ${RAYLIB}_shared
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
endif()
|
||||
endif(${SHARED})
|
||||
|
||||
if(${STATIC})
|
||||
add_library(${RAYLIB} STATIC ${sources})
|
||||
|
||||
target_compile_definitions(${RAYLIB}
|
||||
PUBLIC ${PLATFORM}
|
||||
PUBLIC ${GRAPHICS}
|
||||
endif()
|
||||
set_target_properties(${RAYLIB}_shared PROPERTIES
|
||||
PUBLIC_HEADER "raylib.h"
|
||||
)
|
||||
if(WIN32)
|
||||
install(
|
||||
TARGETS ${RAYLIB}_shared
|
||||
RUNTIME DESTINATION lib
|
||||
PUBLIC_HEADER DESTINATION include
|
||||
)
|
||||
|
||||
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE})
|
||||
|
||||
if (WITH_PIC)
|
||||
set_property(TARGET ${RAYLIB} PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h")
|
||||
install(TARGETS ${RAYLIB}
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
else() # Keep lib*.(a|dll) name, but avoid *.lib files overwriting each other on Windows
|
||||
set_target_properties(${RAYLIB}_shared PROPERTIES OUTPUT_NAME ${RAYLIB})
|
||||
install(
|
||||
TARGETS ${RAYLIB}_shared
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
endif(${STATIC})
|
||||
endif()
|
||||
endif(${SHARED})
|
||||
|
||||
configure_file(../raylib.pc.in raylib.pc @ONLY)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
if(${STATIC})
|
||||
if(${PLATFORM} MATCHES "PLATFORM_WEB")
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".bc")
|
||||
endif()
|
||||
|
||||
add_library(${RAYLIB} STATIC ${sources})
|
||||
|
||||
set(PKG_CONFIG_LIBS_PRIVATE ${__PKG_CONFIG_LIBS_PRIVATE})
|
||||
if (${PLATFORM} MATCHES "Desktop")
|
||||
target_link_libraries(${RAYLIB} glfw ${GLFW_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (WITH_PIC)
|
||||
set_property(TARGET ${RAYLIB} PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
set_target_properties(${RAYLIB} PROPERTIES PUBLIC_HEADER "raylib.h")
|
||||
install(TARGETS ${RAYLIB}
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
endif(${STATIC})
|
||||
|
||||
configure_file(../raylib.pc.in raylib.pc @ONLY)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/release/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
|
||||
# Copy the header files to the build directory
|
||||
file(COPY "raylib.h" DESTINATION ".")
|
||||
file(COPY "rlgl.h" DESTINATION ".")
|
||||
file(COPY "physac.h" DESTINATION ".")
|
||||
file(COPY "raymath.h" DESTINATION ".")
|
||||
file(COPY "audio.h" DESTINATION ".")
|
||||
|
||||
target_compile_definitions(${RAYLIB}
|
||||
PUBLIC ${PLATFORM}
|
||||
PUBLIC ${GRAPHICS}
|
||||
)
|
||||
|
||||
# Copy the header files to the build directory
|
||||
file(COPY "raylib.h" DESTINATION ".")
|
||||
file(COPY "rlgl.h" DESTINATION ".")
|
||||
file(COPY "physac.h" DESTINATION ".")
|
||||
file(COPY "raymath.h" DESTINATION ".")
|
||||
file(COPY "audio.h" DESTINATION ".")
|
||||
elseif(${PLATFORM} MATCHES "PLATFORM_WEB")
|
||||
# For the web.
|
||||
add_executable(${RAYLIB} ${sources})
|
||||
endif()
|
||||
|
||||
# Print the flags for the user
|
||||
message(STATUS "Compiling with the flags:")
|
||||
|
@@ -1,30 +1,36 @@
|
||||
### Config options ###
|
||||
include(CMakeDependentOption)
|
||||
|
||||
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
|
||||
option(WITH_PIC "Compile static library as position-independent code" OFF)
|
||||
option(SHARED "Build raylib as a dynamic library" OFF)
|
||||
option(STATIC "Build raylib as a static library" ON)
|
||||
option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" ON)
|
||||
option(USE_AUDIO "Build raylib with audio module" ON)
|
||||
cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" OFF "USE_AUDIO" OFF)
|
||||
set(USE_EXTERNAL_GLFW OFF CACHE STRING "Link raylib against system GLFW instead of embedded one")
|
||||
set_property(CACHE USE_EXTERNAL_GLFW PROPERTY STRINGS ON OFF IF_POSSIBLE)
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(USE_WAYLAND "Use Wayland for window creation" OFF)
|
||||
endif()
|
||||
|
||||
|
||||
set(PLATFORM "Desktop" CACHE STRING "Platform to build for.")
|
||||
set_property(CACHE PLATFORM PROPERTY STRINGS "Desktop" "Web" "Android" "Raspberry Pi")
|
||||
|
||||
set(OPENGL_VERSION "3.3" CACHE STRING "OpenGL Version to build raylib with")
|
||||
set_property(CACHE OPENGL_VERSION PROPERTY STRINGS "3.3" "2.1" "1.1" "ES 2.0")
|
||||
|
||||
# Shared library is always PIC. Static library should be PIC too if linked into a shared library
|
||||
option(WITH_PIC "Compile static library as position-independent code" OFF)
|
||||
option(SHARED "Build raylib as a dynamic library" OFF)
|
||||
option(STATIC "Build raylib as a static library" ON)
|
||||
option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" ON)
|
||||
option(USE_AUDIO "Build raylib with audio module" ON)
|
||||
if(${PLATFORM} MATCHES "Web")
|
||||
cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" ON "USE_AUDIO" OFF)
|
||||
else()
|
||||
cmake_dependent_option(USE_OPENAL_BACKEND "Link raylib with openAL instead of mini-al" OFF "USE_AUDIO" OFF)
|
||||
endif()
|
||||
|
||||
set(USE_EXTERNAL_GLFW OFF CACHE STRING "Link raylib against system GLFW instead of embedded one")
|
||||
set_property(CACHE USE_EXTERNAL_GLFW PROPERTY STRINGS ON OFF IF_POSSIBLE)
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(USE_WAYLAND "Use Wayland for window creation" OFF)
|
||||
endif()
|
||||
|
||||
|
||||
# core.c
|
||||
option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" ON)
|
||||
option(SUPPORT_CAMERA_SYSTEM "Provide camera module (camera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON)
|
||||
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_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)
|
||||
@@ -33,10 +39,9 @@ option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches a
|
||||
option(SUPPORT_VR_SIMULATOR "Support VR simulation functionality (stereo rendering)" ON)
|
||||
option(SUPPORT_DISTORTION_SHADER "Include stereo rendering distortion shader (shader_distortion.h)" ON)
|
||||
|
||||
# models.c
|
||||
option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON)
|
||||
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
|
||||
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)
|
||||
# shapes.c
|
||||
option(SUPPORT_FONT_TEXTURE "Draw rectangle shapes using font texture white character instead of default white texture. Allows drawing rectangles and text with a single draw call, very useful for GUI systems!" ON)
|
||||
option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON)
|
||||
|
||||
# textures.c
|
||||
option(SUPPORT_IMAGE_GENERATION "Support proedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON)
|
||||
@@ -53,6 +58,11 @@ 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)
|
||||
|
||||
# models.c
|
||||
option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON)
|
||||
option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON)
|
||||
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)
|
||||
|
||||
# audio.c
|
||||
option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON)
|
||||
@@ -60,9 +70,6 @@ option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON)
|
||||
option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" OFF)
|
||||
|
||||
# shapes.c
|
||||
option(USE_DEFAULT_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)
|
||||
|
||||
# utils.c
|
||||
option(SUPPORT_SAVE_PNG "Support saving image data in PNG file format" ON)
|
||||
option(SUPPORT_SAVE_BMP "Support saving image data in BMP file format" OFF)
|
||||
@@ -86,4 +93,14 @@ if(DEFINED STATIC_RAYLIB)
|
||||
message(DEPRECATION "-DSTATIC_RAYLIB is deprecated. Please use -DSTATIC instead.")
|
||||
endif()
|
||||
|
||||
if(${PLATFORM} MATCHES "Desktop" AND APPLE)
|
||||
if(MACOS_FATLIB)
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
message(FATAL_ERROR "User supplied -DCMAKE_OSX_ARCHITECTURES overrides -DMACOS_FATLIB=ON")
|
||||
else()
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;i386")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# vim: ft=cmake
|
||||
|
39
src/Makefile
39
src/Makefile
@@ -42,8 +42,8 @@
|
||||
.PHONY: all clean install uninstall
|
||||
|
||||
# Define required raylib variables
|
||||
RAYLIB_VERSION = 1.9.7
|
||||
RAYLIB_API_VERSION = 1
|
||||
RAYLIB_VERSION = 2.0.0
|
||||
RAYLIB_API_VERSION = 2
|
||||
|
||||
# See below for alternatives.
|
||||
RAYLIB_PATH = ..
|
||||
@@ -163,10 +163,11 @@ endif
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
# Android required path variables
|
||||
ANDROID_NDK = C:/android-ndk
|
||||
ANDROID_TOOLCHAIN = C:/android_toolchain_arm_api16
|
||||
ANDROID_TOOLCHAIN = C:/android_toolchain_arm64_api21
|
||||
|
||||
# Android architecture: ARM or ARM64
|
||||
ANDROID_ARCH ?= ARM
|
||||
# Android architecture: ARM64
|
||||
# Starting at 2019 using ARM64 is mandatory for published apps
|
||||
ANDROID_ARCH ?= ARM64
|
||||
endif
|
||||
|
||||
# RAYLIB_RELEASE_PATH points to provided binaries or your immediate build of raylib.
|
||||
@@ -195,9 +196,6 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/html5
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/android/armeabi-v7a
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
RAYLIB_RELEASE_PATH = $(RAYLIB_PATH)/release/libs/android/arm64-v8a
|
||||
endif
|
||||
@@ -251,12 +249,8 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
# Android toolchain (must be provided for desired architecture and compiler)
|
||||
# NOTE: gcc compiler is being deprecated in Android NDK r16
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-gcc
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-gcc
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -273,9 +267,6 @@ endif
|
||||
|
||||
# Android archiver (also depends on desired architecture)
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
|
||||
endif
|
||||
@@ -316,15 +307,15 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
# Compiler flags for arquitecture
|
||||
CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
|
||||
# Compiler flags for arquitecture (only ARM, not ARM64)
|
||||
#CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
|
||||
# Compilation functions attributes options
|
||||
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
|
||||
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIE -fPIC
|
||||
# Compiler options for the linker
|
||||
# -Werror=format-security
|
||||
CFLAGS += -Wa,--noexecstack -Wformat -no-canonical-prefixes
|
||||
# Preprocessor macro definitions
|
||||
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=16
|
||||
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=21
|
||||
endif
|
||||
|
||||
# Define required compilation flags for raylib SHARED lib
|
||||
@@ -384,11 +375,13 @@ endif
|
||||
# Define linker options
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
LDFLAGS = -Wl,-soname,libraylib.$(API_VERSION).so -Wl,--exclude-libs,libatomic.a
|
||||
LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
|
||||
LDFLAGS += -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
|
||||
# Force linking of library module to define symbol
|
||||
LDFLAGS += -u ANativeActivity_onCreate
|
||||
# Library paths containing required libs
|
||||
LDFLAGS += -L. -Lsrc -L$(RAYLIB_RELEASE_PATH)
|
||||
# Avoid unresolved symbol pointing to external main()
|
||||
LDFLAGS += -Wl,-undefined,dynamic_lookup
|
||||
|
||||
LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -latomic -lc -lm
|
||||
endif
|
||||
@@ -429,9 +422,6 @@ all: raylib
|
||||
# NOTE: Android toolchain could already be provided
|
||||
generate_android_toolchain:
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
$(ANDROID_NDK)/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=arm-linux-androideabi-4.9 --use-llvm --install-dir=$(ANDROID_TOOLCHAIN)
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
$(ANDROID_NDK)/build/tools/make-standalone-toolchain.sh --platform=android-21 --toolchain=aarch64-linux-androideabi-4.9 --use-llvm --install-dir=$(ANDROID_TOOLCHAIN)
|
||||
endif
|
||||
@@ -474,6 +464,7 @@ else
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/libraylib.$(RAYLIB_VERSION).so $(OBJS) $(LDFLAGS) $(LDLIBS)
|
||||
@echo "raylib shared library generated (libraylib.$(RAYLIB_VERSION).so)!"
|
||||
# WARNING: symbolic links creation on Windows should be done using mklink command, no ln available
|
||||
cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).so libraylib.$(RAYLIB_API_VERSION).so
|
||||
cd $(RAYLIB_RELEASE_PATH) && ln -fs libraylib.$(RAYLIB_VERSION).so libraylib.so
|
||||
endif
|
||||
|
46
src/audio.c
46
src/audio.c
@@ -24,6 +24,7 @@
|
||||
* #define SUPPORT_FILEFORMAT_XM
|
||||
* #define SUPPORT_FILEFORMAT_MOD
|
||||
* #define SUPPORT_FILEFORMAT_FLAC
|
||||
* #define SUPPORT_FILEFORMAT_MP3
|
||||
* Selected desired fileformats to be supported for loading. Some of those formats are
|
||||
* supported by default, to remove support, just comment unrequired #define in this module
|
||||
*
|
||||
@@ -73,7 +74,6 @@
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(USE_OPENAL_BACKEND)
|
||||
#define USE_MINI_AL 1 // Set to 1 to use mini_al; 0 to use OpenAL.
|
||||
#endif
|
||||
@@ -82,7 +82,8 @@
|
||||
#include "audio.h"
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
||||
#else
|
||||
#include "raylib.h"
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#include "raylib.h" // Declares module functions
|
||||
#include "utils.h" // Required for: fopen() Android mapping
|
||||
#endif
|
||||
|
||||
@@ -127,6 +128,11 @@
|
||||
#include "external/dr_flac.h" // FLAC loading functions
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_MP3)
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
#include "external/dr_mp3.h" // MP3 loading functions
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#undef bool
|
||||
#endif
|
||||
@@ -158,6 +164,7 @@
|
||||
typedef enum {
|
||||
MUSIC_AUDIO_OGG = 0,
|
||||
MUSIC_AUDIO_FLAC,
|
||||
MUSIC_AUDIO_MP3,
|
||||
MUSIC_MODULE_XM,
|
||||
MUSIC_MODULE_MOD
|
||||
} MusicContextType;
|
||||
@@ -171,6 +178,9 @@ typedef struct MusicData {
|
||||
#if defined(SUPPORT_FILEFORMAT_FLAC)
|
||||
drflac *ctxFlac; // FLAC audio context
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_MP3)
|
||||
drmp3 ctxMp3; // MP3 audio context
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_XM)
|
||||
jar_xm_context_t *ctxXm; // XM chiptune context
|
||||
#endif
|
||||
@@ -1365,6 +1375,27 @@ Music LoadMusicStream(const char *fileName)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_MP3)
|
||||
else if (IsFileExtension(fileName, ".mp3"))
|
||||
{
|
||||
drmp3_init_file(&music->ctxMp3, fileName, NULL)
|
||||
|
||||
if (music->ctxMp3 == NULL) TraceLog(LOG_WARNING, "[%s] MP3 audio file could not be opened", fileName);
|
||||
else
|
||||
{
|
||||
music->stream = InitAudioStream(music->ctxMp3.sampleRate, 16, music->ctxMp3.channels);
|
||||
//music->totalSamples = (unsigned int)music->ctxMp3.totalSampleCount/music->ctxMp3.channels; //TODO!
|
||||
music->samplesLeft = music->totalSamples;
|
||||
music->ctxType = MUSIC_AUDIO_MP3;
|
||||
music->loopCount = -1; // Infinite loop by default
|
||||
|
||||
TraceLog(LOG_DEBUG, "[%s] MP3 total samples: %i", fileName, music->totalSamples);
|
||||
TraceLog(LOG_DEBUG, "[%s] MP3 sample rate: %i", fileName, music->ctxMp3.sampleRate);
|
||||
//TraceLog(LOG_DEBUG, "[%s] MP3 bits per sample: %i", fileName, music->ctxMp3.bitsPerSample);
|
||||
TraceLog(LOG_DEBUG, "[%s] MP3 channels: %i", fileName, music->ctxMp3.channels);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_XM)
|
||||
else if (IsFileExtension(fileName, ".xm"))
|
||||
{
|
||||
@@ -1420,6 +1451,9 @@ void UnloadMusicStream(Music music)
|
||||
#if defined(SUPPORT_FILEFORMAT_FLAC)
|
||||
else if (music->ctxType == MUSIC_AUDIO_FLAC) drflac_free(music->ctxFlac);
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_MP3)
|
||||
else if (music->ctxType == MUSIC_AUDIO_MP3) drmp3_uninit(&music->ctxMp3);
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_XM)
|
||||
else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm);
|
||||
#endif
|
||||
@@ -1561,6 +1595,14 @@ void UpdateMusicStream(Music music)
|
||||
|
||||
} break;
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_MP3)
|
||||
case MUSIC_AUDIO_MP3:
|
||||
{
|
||||
// NOTE: Returns the number of samples to process
|
||||
unsigned int numSamplesMp3 = (unsigned int)drmp3_read_f32(music->ctxMp3, samplesCount*music->stream.channels, (short *)pcm);
|
||||
|
||||
} break;
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_XM)
|
||||
case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, samplesCount); break;
|
||||
#endif
|
||||
|
15
src/config.h
15
src/config.h
@@ -25,7 +25,7 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#define RAYLIB_VERSION "1.9.7-dev"
|
||||
#define RAYLIB_VERSION "2.0-dev"
|
||||
|
||||
// Edit to control what features Makefile'd raylib is compiled with
|
||||
#if defined(RAYLIB_CMAKE)
|
||||
@@ -44,6 +44,8 @@
|
||||
#define SUPPORT_MOUSE_GESTURES 1
|
||||
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
|
||||
#define SUPPORT_BUSY_WAIT_LOOP 1
|
||||
// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
|
||||
#define SUPPORT_SCREEN_CAPTURE 1
|
||||
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
|
||||
#define SUPPORT_GIF_RECORDING 1
|
||||
|
||||
@@ -57,6 +59,16 @@
|
||||
#define SUPPORT_DISTORTION_SHADER 1
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: shapes - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
// 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!
|
||||
#define SUPPORT_FONT_TEXTURE
|
||||
// Use QUADS instead of TRIANGLES for drawing when possible
|
||||
// Some lines-based shapes could still use lines
|
||||
#define SUPPORT_QUADS_DRAW_MODE
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module: textures - Configuration Flags
|
||||
//------------------------------------------------------------------------------------
|
||||
@@ -112,6 +124,7 @@
|
||||
#define SUPPORT_FILEFORMAT_XM 1
|
||||
#define SUPPORT_FILEFORMAT_MOD 1
|
||||
//#define SUPPORT_FILEFORMAT_FLAC 1
|
||||
//#define SUPPORT_FILEFORMAT_MP3 1
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
@@ -1,11 +1,30 @@
|
||||
/* config.h.in */
|
||||
|
||||
// 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
|
||||
#cmakedefine USE_OPENAL_BACKEND 1
|
||||
|
||||
// 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
|
||||
/* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used */
|
||||
#cmakedefine SUPPORT_BUSY_WAIT_LOOP 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
|
||||
|
||||
// rlgl.c
|
||||
/* Support VR simulation functionality (stereo rendering) */
|
||||
#cmakedefine SUPPORT_VR_SIMULATOR 1
|
||||
/* Include stereo rendering distortion shader (shader_distortion.h) */
|
||||
#cmakedefine SUPPORT_DISTORTION_SHADER 1
|
||||
|
||||
// shapes.c
|
||||
#cmakedefine SUPPORT_FONT_TEXTURE 1
|
||||
#cmakedefine SUPPORT_QUADS_DRAW_MODE 1
|
||||
|
||||
// textures.c
|
||||
/* Selecte desired fileformats to be supported for image data loading. */
|
||||
@@ -28,23 +47,20 @@
|
||||
/* Support proedural image generation functionality (gradient, spot, perlin-noise, cellular) */
|
||||
#cmakedefine SUPPORT_IMAGE_GENERATION 1
|
||||
|
||||
// rlgl.c
|
||||
/* Support VR simulation functionality (stereo rendering) */
|
||||
#cmakedefine SUPPORT_VR_SIMULATOR 1
|
||||
/* Include stereo rendering distortion shader (shader_distortion.h) */
|
||||
#cmakedefine SUPPORT_DISTORTION_SHADER 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
|
||||
|
||||
// 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
|
||||
/* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used */
|
||||
#cmakedefine SUPPORT_BUSY_WAIT_LOOP 1
|
||||
/* Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() */
|
||||
#cmakedefine SUPPORT_GIF_RECORDING 1
|
||||
// models.c
|
||||
/* Selected desired fileformats to be supported for loading. */
|
||||
#cmakedefine SUPPORT_FILEFORMAT_OBJ 1
|
||||
#cmakedefine SUPPORT_FILEFORMAT_MTL 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
|
||||
|
||||
// audio.c
|
||||
/* Desired fileformats to be supported for loading. */
|
||||
@@ -54,20 +70,9 @@
|
||||
#cmakedefine SUPPORT_FILEFORMAT_MOD 1
|
||||
#cmakedefine SUPPORT_FILEFORMAT_FLAC 1
|
||||
|
||||
// models.c
|
||||
/* Selected desired fileformats to be supported for loading. */
|
||||
#cmakedefine SUPPORT_FILEFORMAT_OBJ 1
|
||||
#cmakedefine SUPPORT_FILEFORMAT_MTL 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
|
||||
|
||||
// utils.c
|
||||
/* Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown */
|
||||
#cmakedefine SUPPORT_TRACELOG 1
|
||||
|
||||
/* Support saving image data as PNG fileformat. NOTE: Requires stb_image_write library */
|
||||
#cmakedefine SUPPORT_SAVE_PNG 1
|
||||
/* Support saving image data as PMP fileformat. NOTE: Requires stb_image_write library */
|
||||
|
98
src/core.c
98
src/core.c
@@ -50,6 +50,9 @@
|
||||
* #define SUPPORT_BUSY_WAIT_LOOP
|
||||
* Use busy wait loop for timing sync, if not defined, a high-resolution timer is setup and used
|
||||
*
|
||||
* #define SUPPORT_SCREEN_CAPTURE
|
||||
* Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
|
||||
*
|
||||
* #define SUPPORT_GIF_RECORDING
|
||||
* Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
|
||||
*
|
||||
@@ -81,9 +84,8 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#include "raylib.h" // Declares module functions
|
||||
|
||||
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
|
||||
#undef _POSIX_C_SOURCE
|
||||
@@ -93,8 +95,8 @@
|
||||
#define RAYMATH_IMPLEMENTATION // Define external out-of-line implementation of raymath here
|
||||
#include "raymath.h" // Required for: Vector3 and Matrix functions
|
||||
|
||||
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||
#include "utils.h" // Required for: fopen() Android mapping
|
||||
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||
#include "utils.h" // Required for: fopen() Android mapping
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
#define GESTURES_IMPLEMENTATION
|
||||
@@ -108,14 +110,14 @@
|
||||
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
#define RGIF_IMPLEMENTATION
|
||||
#include "external/rgif.h" // Support GIF recording
|
||||
#include "external/rgif.h" // Support GIF recording
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // Standard input / output lib
|
||||
#include <stdlib.h> // Required for: malloc(), free(), rand(), atexit()
|
||||
#include <stdint.h> // Required for: typedef unsigned long long int uint64_t, used by hi-res timer
|
||||
#include <time.h> // Required for: time() - Android/RPI hi-res timer (NOTE: Linux only!)
|
||||
#include <math.h> // Required for: tan() [Used in Begin3dMode() to set perspective]
|
||||
#include <math.h> // Required for: tan() [Used in BeginMode3D() to set perspective]
|
||||
#include <string.h> // Required for: strrchr(), strcmp()
|
||||
//#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
|
||||
#include <ctype.h> // Required for: tolower() [Used in IsFileExtension()]
|
||||
@@ -139,13 +141,7 @@
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
//#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
|
||||
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management
|
||||
|
||||
#if defined(__linux__)
|
||||
#define GLFW_EXPOSE_NATIVE_X11 // Linux specific definitions for getting
|
||||
#define GLFW_EXPOSE_NATIVE_GLX // native functions like glfwGetX11Window
|
||||
#include <GLFW/glfw3native.h> // which are required for hiding mouse
|
||||
#endif
|
||||
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
|
||||
// NOTE: GLFW3 already includes gl.h (OpenGL) headers
|
||||
|
||||
#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
|
||||
// NOTE: Those functions require linking with winmm library
|
||||
@@ -292,8 +288,6 @@ static bool cursorHidden = false; // Track if cursor is hidden
|
||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
|
||||
static int screenshotCounter = 0; // Screenshots counter
|
||||
|
||||
// Register mouse states
|
||||
static char previousMouseState[3] = { 0 }; // Registers previous mouse button state
|
||||
static char currentMouseState[3] = { 0 }; // Registers current mouse button state
|
||||
@@ -342,9 +336,13 @@ static double targetTime = 0.0; // Desired time for one frame, if 0
|
||||
static unsigned char configFlags = 0; // Configuration flags (bit based)
|
||||
static bool showLogo = false; // Track if showing logo at init is enabled
|
||||
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
static int screenshotCounter = 0; // Screenshots counter
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
static int gifFramesCounter = 0;
|
||||
static bool gifRecording = false;
|
||||
static int gifFramesCounter = 0; // GIF frames counter
|
||||
static bool gifRecording = false; // GIF recording state
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@@ -745,7 +743,6 @@ void SetWindowSize(int width, int height)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Get current screen width
|
||||
int GetScreenWidth(void)
|
||||
{
|
||||
@@ -885,7 +882,7 @@ void EndDrawing(void)
|
||||
}
|
||||
|
||||
// Initialize 2D mode with custom camera (2D)
|
||||
void Begin2dMode(Camera2D camera)
|
||||
void BeginMode2D(Camera2D camera)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
@@ -903,7 +900,7 @@ void Begin2dMode(Camera2D camera)
|
||||
}
|
||||
|
||||
// Ends 2D mode with custom camera
|
||||
void End2dMode(void)
|
||||
void EndMode2D(void)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
@@ -911,7 +908,7 @@ void End2dMode(void)
|
||||
}
|
||||
|
||||
// Initializes 3D mode with custom camera (3D)
|
||||
void Begin3dMode(Camera camera)
|
||||
void BeginMode3D(Camera3D camera)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
@@ -951,7 +948,7 @@ void Begin3dMode(Camera camera)
|
||||
}
|
||||
|
||||
// Ends 3D mode and returns to default 2D orthographic mode
|
||||
void End3dMode(void)
|
||||
void EndMode3D(void)
|
||||
{
|
||||
rlglDraw(); // Process internal buffers (update + draw)
|
||||
|
||||
@@ -1029,7 +1026,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
// Calculate view matrix from camera look at
|
||||
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
||||
Matrix matProj;
|
||||
Matrix matProj = MatrixIdentity();
|
||||
|
||||
if (camera.type == CAMERA_PERSPECTIVE)
|
||||
{
|
||||
@@ -1041,6 +1038,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
float aspect = (float)screenWidth/(float)screenHeight;
|
||||
double top = camera.fovy/2.0;
|
||||
double right = top*aspect;
|
||||
|
||||
// Calculate projection matrix from orthographic
|
||||
matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
|
||||
}
|
||||
@@ -1070,18 +1068,19 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
|
||||
{
|
||||
// Calculate projection matrix (from perspective instead of frustum
|
||||
Matrix matProj;
|
||||
Matrix matProj = MatrixIdentity();
|
||||
|
||||
if(camera.type == CAMERA_PERSPECTIVE)
|
||||
if (camera.type == CAMERA_PERSPECTIVE)
|
||||
{
|
||||
// Calculate projection matrix from perspective
|
||||
matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
|
||||
}
|
||||
else if(camera.type == CAMERA_ORTHOGRAPHIC)
|
||||
else if (camera.type == CAMERA_ORTHOGRAPHIC)
|
||||
{
|
||||
float aspect = (float)screenWidth/(float)screenHeight;
|
||||
double top = camera.fovy/2.0;
|
||||
double right = top*aspect;
|
||||
|
||||
// Calculate projection matrix from orthographic
|
||||
matProj = MatrixOrtho(-right, right, -top, top, 0.01, 1000.0);
|
||||
}
|
||||
@@ -1153,25 +1152,25 @@ double GetTime(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns normalized float array for a Color
|
||||
float *ColorToFloat(Color color)
|
||||
{
|
||||
static float buffer[4];
|
||||
|
||||
buffer[0] = (float)color.r/255;
|
||||
buffer[1] = (float)color.g/255;
|
||||
buffer[2] = (float)color.b/255;
|
||||
buffer[3] = (float)color.a/255;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Returns hexadecimal value for a Color
|
||||
int ColorToInt(Color color)
|
||||
{
|
||||
return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
|
||||
}
|
||||
|
||||
// Returns color normalized as float [0..1]
|
||||
Vector4 ColorNormalize(Color color)
|
||||
{
|
||||
Vector4 result;
|
||||
|
||||
result.x = (float)color.r/255.0f;
|
||||
result.y = (float)color.g/255.0f;
|
||||
result.z = (float)color.b/255.0f;
|
||||
result.w = (float)color.a/255.0f;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns HSV values for a Color
|
||||
// NOTE: Hue is returned as degrees [0..360]
|
||||
Vector3 ColorToHSV(Color color)
|
||||
@@ -1313,6 +1312,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
||||
}
|
||||
}
|
||||
}
|
||||
else result = false;
|
||||
#else
|
||||
if (strcmp(fileExt, ext) == 0) result = true;
|
||||
#endif
|
||||
@@ -1373,24 +1373,32 @@ bool ChangeDirectory(const char *dir)
|
||||
return (CHDIR(dir) == 0);
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// Check if a file has been dropped into window
|
||||
bool IsFileDropped(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
if (dropFilesCount > 0) return true;
|
||||
else return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get dropped files names
|
||||
char **GetDroppedFiles(int *count)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
*count = dropFilesCount;
|
||||
return dropFilesPath;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Clear dropped files paths buffer
|
||||
void ClearDroppedFiles(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
if (dropFilesCount > 0)
|
||||
{
|
||||
for (int i = 0; i < dropFilesCount; i++) free(dropFilesPath[i]);
|
||||
@@ -1399,8 +1407,8 @@ void ClearDroppedFiles(void)
|
||||
|
||||
dropFilesCount = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Save integer value to storage file (to defined position)
|
||||
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
|
||||
@@ -2791,10 +2799,12 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
||||
}
|
||||
else
|
||||
#endif // SUPPORT_GIF_RECORDING
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
{
|
||||
TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
|
||||
screenshotCounter++;
|
||||
}
|
||||
#endif // SUPPORT_SCREEN_CAPTURE
|
||||
}
|
||||
#endif // PLATFORM_DESKTOP
|
||||
else
|
||||
@@ -2899,7 +2909,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
||||
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||
rlClearScreenBuffers(); // Clear screen buffers (color and depth)
|
||||
|
||||
// Window size must be updated to be used on 3D mode to get new aspect ratio (Begin3dMode())
|
||||
// Window size must be updated to be used on 3D mode to get new aspect ratio (BeginMode3D())
|
||||
// NOTE: Be careful! GLFW3 will choose the closest fullscreen resolution supported by current monitor,
|
||||
// for example, if reescaling back to 800x450 (desired), it could set 720x480 (closest fullscreen supported)
|
||||
screenWidth = width;
|
||||
@@ -3456,12 +3466,14 @@ static void ProcessKeyboard(void)
|
||||
// Check exit key (same functionality as GLFW3 KeyCallback())
|
||||
if (currentKeyState[exitKey] == 1) windowShouldClose = true;
|
||||
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
// Check screen capture key (raylib key: KEY_F12)
|
||||
if (currentKeyState[301] == 1)
|
||||
{
|
||||
TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
|
||||
screenshotCounter++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Restore default keyboard input
|
||||
|
2841
src/external/dr_mp3.h
vendored
Normal file
2841
src/external/dr_mp3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23
src/external/glfw/.appveyor.yml
vendored
Normal file
23
src/external/glfw/.appveyor.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
branches:
|
||||
only:
|
||||
- ci
|
||||
- master
|
||||
skip_tags: true
|
||||
environment:
|
||||
CFLAGS: /WX
|
||||
matrix:
|
||||
- BUILD_SHARED_LIBS: ON
|
||||
- BUILD_SHARED_LIBS: OFF
|
||||
matrix:
|
||||
fast_finish: true
|
||||
build_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
|
||||
- cmake --build .
|
||||
notifications:
|
||||
- provider: Email
|
||||
to:
|
||||
- ci@glfw.org
|
||||
on_build_failure: true
|
||||
on_build_success: false
|
1
src/external/glfw/.gitattributes
vendored
Normal file
1
src/external/glfw/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.m linguist-language=Objective-C
|
84
src/external/glfw/.gitignore
vendored
Normal file
84
src/external/glfw/.gitignore
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
# External junk
|
||||
.DS_Store
|
||||
_ReSharper*
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
*.dir
|
||||
*.vcxproj*
|
||||
*.sln
|
||||
Win32
|
||||
x64
|
||||
Debug
|
||||
Release
|
||||
MinSizeRel
|
||||
RelWithDebInfo
|
||||
*.xcodeproj
|
||||
|
||||
# CMake files
|
||||
Makefile
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
cmake_install.cmake
|
||||
cmake_uninstall.cmake
|
||||
|
||||
# Generated files
|
||||
docs/Doxyfile
|
||||
docs/html
|
||||
docs/warnings.txt
|
||||
docs/doxygen_sqlite3.db
|
||||
src/glfw_config.h
|
||||
src/glfw3.pc
|
||||
src/glfw3Config.cmake
|
||||
src/glfw3ConfigVersion.cmake
|
||||
src/wayland-pointer-constraints-unstable-v1-client-protocol.h
|
||||
src/wayland-pointer-constraints-unstable-v1-protocol.c
|
||||
src/wayland-relative-pointer-unstable-v1-client-protocol.h
|
||||
src/wayland-relative-pointer-unstable-v1-protocol.c
|
||||
|
||||
# Compiled binaries
|
||||
src/libglfw.so
|
||||
src/libglfw.so.3
|
||||
src/libglfw.so.3.3
|
||||
src/libglfw.dylib
|
||||
src/libglfw.dylib
|
||||
src/libglfw.3.dylib
|
||||
src/libglfw.3.3.dylib
|
||||
src/libglfw3.a
|
||||
src/glfw3.lib
|
||||
src/glfw3.dll
|
||||
src/glfw3dll.lib
|
||||
src/libglfw3dll.a
|
||||
examples/*.app
|
||||
examples/*.exe
|
||||
examples/boing
|
||||
examples/gears
|
||||
examples/heightmap
|
||||
examples/offscreen
|
||||
examples/particles
|
||||
examples/splitview
|
||||
examples/sharing
|
||||
examples/simple
|
||||
examples/wave
|
||||
tests/*.app
|
||||
tests/*.exe
|
||||
tests/clipboard
|
||||
tests/cursor
|
||||
tests/empty
|
||||
tests/events
|
||||
tests/gamma
|
||||
tests/glfwinfo
|
||||
tests/icon
|
||||
tests/iconify
|
||||
tests/joysticks
|
||||
tests/monitors
|
||||
tests/msaa
|
||||
tests/reopen
|
||||
tests/tearing
|
||||
tests/threads
|
||||
tests/timeout
|
||||
tests/title
|
||||
tests/vulkan
|
||||
tests/windows
|
||||
|
78
src/external/glfw/.travis.yml
vendored
Normal file
78
src/external/glfw/.travis.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
language: c
|
||||
compiler: clang
|
||||
branches:
|
||||
only:
|
||||
- ci
|
||||
- master
|
||||
sudo: false
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- cmake
|
||||
- libxrandr-dev
|
||||
- libxinerama-dev
|
||||
- libxcursor-dev
|
||||
- libxi-dev
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env:
|
||||
- BUILD_SHARED_LIBS=ON
|
||||
- CFLAGS=-Werror
|
||||
- os: linux
|
||||
env:
|
||||
- BUILD_SHARED_LIBS=OFF
|
||||
- CFLAGS=-Werror
|
||||
- os: linux
|
||||
sudo: required
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libwayland-dev
|
||||
- libxkbcommon-dev
|
||||
- libegl1-mesa-dev
|
||||
env:
|
||||
- USE_WAYLAND=ON
|
||||
- BUILD_SHARED_LIBS=ON
|
||||
- CFLAGS=-Werror
|
||||
- os: linux
|
||||
sudo: required
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libwayland-dev
|
||||
- libxkbcommon-dev
|
||||
- libegl1-mesa-dev
|
||||
env:
|
||||
- USE_WAYLAND=ON
|
||||
- BUILD_SHARED_LIBS=OFF
|
||||
- CFLAGS=-Werror
|
||||
- os: osx
|
||||
env:
|
||||
- BUILD_SHARED_LIBS=ON
|
||||
- CFLAGS=-Werror
|
||||
- os: osx
|
||||
env:
|
||||
- BUILD_SHARED_LIBS=OFF
|
||||
- CFLAGS=-Werror
|
||||
script:
|
||||
- if grep -Inr '\s$' src include docs tests examples CMake *.md .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if test -n "${USE_WAYLAND}";
|
||||
then wget https://mirrors.kernel.org/ubuntu/pool/universe/e/extra-cmake-modules/extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
||||
sudo dpkg -i extra-cmake-modules_5.38.0a-0ubuntu1_amd64.deb;
|
||||
git clone git://anongit.freedesktop.org/wayland/wayland-protocols;
|
||||
pushd wayland-protocols;
|
||||
git checkout 1.12 && ./autogen.sh --prefix=/usr && make && sudo make install;
|
||||
popd;
|
||||
fi
|
||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} ..
|
||||
- cmake --build .
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- ci@glfw.org
|
||||
on_success: never
|
||||
on_failure: always
|
33
src/external/glfw/CMake/GenerateMappings.cmake
vendored
Normal file
33
src/external/glfw/CMake/GenerateMappings.cmake
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Usage:
|
||||
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
|
||||
|
||||
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
|
||||
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
|
||||
set(template_path "${CMAKE_ARGV3}")
|
||||
set(target_path "${CMAKE_ARGV4}")
|
||||
|
||||
if (NOT EXISTS "${template_path}")
|
||||
message(FATAL_ERROR "Failed to find template file ${template_path}")
|
||||
endif()
|
||||
|
||||
file(DOWNLOAD "${source_url}" "${source_path}"
|
||||
STATUS download_status
|
||||
TLS_VERIFY on)
|
||||
|
||||
list(GET download_status 0 status_code)
|
||||
list(GET download_status 1 status_message)
|
||||
|
||||
if (status_code)
|
||||
message(FATAL_ERROR "Failed to download ${source_url}: ${status_message}")
|
||||
endif()
|
||||
|
||||
file(STRINGS "${source_path}" lines)
|
||||
foreach(line ${lines})
|
||||
if ("${line}" MATCHES "^[0-9a-fA-F].*$")
|
||||
set(GLFW_GAMEPAD_MAPPINGS "${GLFW_GAMEPAD_MAPPINGS}\"${line}\",\n")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
configure_file("${template_path}" "${target_path}" @ONLY NEWLINE_STYLE UNIX)
|
||||
file(REMOVE "${source_path}")
|
||||
|
38
src/external/glfw/CMake/MacOSXBundleInfo.plist.in
vendored
Normal file
38
src/external/glfw/CMake/MacOSXBundleInfo.plist.in
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
13
src/external/glfw/CMake/amd64-mingw32msvc.cmake
vendored
Normal file
13
src/external/glfw/CMake/amd64-mingw32msvc.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross compiling from Linux to Win64
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "amd64-mingw32msvc-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "amd64-mingw32msvc-g++")
|
||||
SET(CMAKE_RC_COMPILER "amd64-mingw32msvc-windres")
|
||||
SET(CMAKE_RANLIB "amd64-mingw32msvc-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/amd64-mingw32msvc")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
13
src/external/glfw/CMake/i586-mingw32msvc.cmake
vendored
Normal file
13
src/external/glfw/CMake/i586-mingw32msvc.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross compiling from Linux to Win32
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "i586-mingw32msvc-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "i586-mingw32msvc-g++")
|
||||
SET(CMAKE_RC_COMPILER "i586-mingw32msvc-windres")
|
||||
SET(CMAKE_RANLIB "i586-mingw32msvc-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/i586-mingw32msvc")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
13
src/external/glfw/CMake/i686-pc-mingw32.cmake
vendored
Normal file
13
src/external/glfw/CMake/i686-pc-mingw32.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross compiling from Linux to Win32
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "i686-pc-mingw32-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "i686-pc-mingw32-g++")
|
||||
SET(CMAKE_RC_COMPILER "i686-pc-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "i686-pc-mingw32-ranlib")
|
||||
|
||||
#Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/opt/mingw/usr/i686-pc-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
13
src/external/glfw/CMake/i686-w64-mingw32.cmake
vendored
Normal file
13
src/external/glfw/CMake/i686-w64-mingw32.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross compiling from Linux to Win32
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++")
|
||||
SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
17
src/external/glfw/CMake/modules/FindEpollShim.cmake
vendored
Normal file
17
src/external/glfw/CMake/modules/FindEpollShim.cmake
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Find EpollShim
|
||||
# Once done, this will define
|
||||
#
|
||||
# EPOLLSHIM_FOUND - System has EpollShim
|
||||
# EPOLLSHIM_INCLUDE_DIRS - The EpollShim include directories
|
||||
# EPOLLSHIM_LIBRARIES - The libraries needed to use EpollShim
|
||||
|
||||
find_path(EPOLLSHIM_INCLUDE_DIRS NAMES sys/epoll.h sys/timerfd.h HINTS /usr/local/include/libepoll-shim)
|
||||
find_library(EPOLLSHIM_LIBRARIES NAMES epoll-shim libepoll-shim HINTS /usr/local/lib)
|
||||
|
||||
if (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
|
||||
set(EPOLLSHIM_FOUND TRUE)
|
||||
endif (EPOLLSHIM_INCLUDE_DIRS AND EPOLLSHIM_LIBRARIES)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(EPOLLSHIM DEFAULT_MSG EPOLLSHIM_LIBRARIES EPOLLSHIM_INCLUDE_DIRS)
|
||||
mark_as_advanced(EPOLLSHIM_INCLUDE_DIRS EPOLLSHIM_LIBRARIES)
|
34
src/external/glfw/CMake/modules/FindMir.cmake
vendored
Normal file
34
src/external/glfw/CMake/modules/FindMir.cmake
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# FindMir
|
||||
# -------
|
||||
# Finds the Mir library
|
||||
#
|
||||
# This will will define the following variables::
|
||||
#
|
||||
# MIR_FOUND - the system has Mir
|
||||
# MIR_INCLUDE_DIRS - the Mir include directory
|
||||
# MIR_LIBRARIES - the Mir libraries
|
||||
# MIR_DEFINITIONS - the Mir definitions
|
||||
|
||||
|
||||
find_package (PkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules (PC_MIR mirclient>=0.26.2 QUIET)
|
||||
|
||||
find_path(MIR_INCLUDE_DIR NAMES mir_toolkit/mir_client_library.h
|
||||
PATHS ${PC_MIR_INCLUDE_DIRS})
|
||||
|
||||
find_library(MIR_LIBRARY NAMES mirclient
|
||||
PATHS ${PC_MIR_LIBRARIES} ${PC_MIR_LIBRARY_DIRS})
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (MIR
|
||||
REQUIRED_VARS MIR_LIBRARY MIR_INCLUDE_DIR)
|
||||
|
||||
if (MIR_FOUND)
|
||||
set(MIR_LIBRARIES ${MIR_LIBRARY})
|
||||
set(MIR_INCLUDE_DIRS ${PC_MIR_INCLUDE_DIRS})
|
||||
set(MIR_DEFINITIONS -DHAVE_MIR=1)
|
||||
endif()
|
||||
|
||||
mark_as_advanced (MIR_LIBRARY MIR_INCLUDE_DIR)
|
||||
endif()
|
18
src/external/glfw/CMake/modules/FindOSMesa.cmake
vendored
Normal file
18
src/external/glfw/CMake/modules/FindOSMesa.cmake
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Try to find OSMesa on a Unix system
|
||||
#
|
||||
# This will define:
|
||||
#
|
||||
# OSMESA_LIBRARIES - Link these to use OSMesa
|
||||
# OSMESA_INCLUDE_DIR - Include directory for OSMesa
|
||||
#
|
||||
# Copyright (c) 2014 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||
|
||||
if (NOT WIN32)
|
||||
|
||||
find_package (PkgConfig)
|
||||
pkg_check_modules (PKG_OSMESA QUIET osmesa)
|
||||
|
||||
set (OSMESA_INCLUDE_DIR ${PKG_OSMESA_INCLUDE_DIRS})
|
||||
set (OSMESA_LIBRARIES ${PKG_OSMESA_LIBRARIES})
|
||||
|
||||
endif ()
|
46
src/external/glfw/CMake/modules/FindVulkan.cmake
vendored
Normal file
46
src/external/glfw/CMake/modules/FindVulkan.cmake
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# Find Vulkan
|
||||
#
|
||||
# VULKAN_INCLUDE_DIR
|
||||
# VULKAN_LIBRARY
|
||||
# VULKAN_FOUND
|
||||
|
||||
if (WIN32)
|
||||
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||
"$ENV{VULKAN_SDK}/Include"
|
||||
"$ENV{VK_SDK_PATH}/Include")
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Lib"
|
||||
"$ENV{VULKAN_SDK}/Bin"
|
||||
"$ENV{VK_SDK_PATH}/Bin")
|
||||
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Lib"
|
||||
"$ENV{VULKAN_SDK}/Bin"
|
||||
"$ENV{VK_SDK_PATH}/Bin")
|
||||
else()
|
||||
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Lib32"
|
||||
"$ENV{VULKAN_SDK}/Bin32"
|
||||
"$ENV{VK_SDK_PATH}/Bin32")
|
||||
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Lib32"
|
||||
"$ENV{VULKAN_SDK}/Bin32"
|
||||
"$ENV{VK_SDK_PATH}/Bin32")
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
find_library(VULKAN_LIBRARY vulkan.1 HINTS
|
||||
"$ENV{VULKAN_SDK}/macOS/lib")
|
||||
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||
"$ENV{VULKAN_SDK}/macOS/include")
|
||||
else()
|
||||
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||
"$ENV{VULKAN_SDK}/include")
|
||||
find_library(VULKAN_LIBRARY NAMES vulkan HINTS
|
||||
"$ENV{VULKAN_SDK}/lib")
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY VULKAN_STATIC_LIBRARY)
|
||||
|
26
src/external/glfw/CMake/modules/FindWaylandProtocols.cmake
vendored
Normal file
26
src/external/glfw/CMake/modules/FindWaylandProtocols.cmake
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(WaylandProtocols QUIET wayland-protocols>=${WaylandProtocols_FIND_VERSION})
|
||||
|
||||
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols
|
||||
OUTPUT_VARIABLE WaylandProtocols_PKGDATADIR
|
||||
RESULT_VARIABLE _pkgconfig_failed)
|
||||
if (_pkgconfig_failed)
|
||||
message(FATAL_ERROR "Missing wayland-protocols pkgdatadir")
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "[\r\n]" "" WaylandProtocols_PKGDATADIR "${WaylandProtocols_PKGDATADIR}")
|
||||
|
||||
find_package_handle_standard_args(WaylandProtocols
|
||||
FOUND_VAR
|
||||
WaylandProtocols_FOUND
|
||||
REQUIRED_VARS
|
||||
WaylandProtocols_PKGDATADIR
|
||||
VERSION_VAR
|
||||
WaylandProtocols_VERSION
|
||||
HANDLE_COMPONENTS
|
||||
)
|
||||
|
||||
set(WAYLAND_PROTOCOLS_FOUND ${WaylandProtocols_FOUND})
|
||||
set(WAYLAND_PROTOCOLS_PKGDATADIR ${WaylandProtocols_PKGDATADIR})
|
||||
set(WAYLAND_PROTOCOLS_VERSION ${WaylandProtocols_VERSION})
|
34
src/external/glfw/CMake/modules/FindXKBCommon.cmake
vendored
Normal file
34
src/external/glfw/CMake/modules/FindXKBCommon.cmake
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# - Try to find XKBCommon
|
||||
# Once done, this will define
|
||||
#
|
||||
# XKBCOMMON_FOUND - System has XKBCommon
|
||||
# XKBCOMMON_INCLUDE_DIRS - The XKBCommon include directories
|
||||
# XKBCOMMON_LIBRARIES - The libraries needed to use XKBCommon
|
||||
# XKBCOMMON_DEFINITIONS - Compiler switches required for using XKBCommon
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon)
|
||||
set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER})
|
||||
|
||||
find_path(XKBCOMMON_INCLUDE_DIR
|
||||
NAMES xkbcommon/xkbcommon.h
|
||||
HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(XKBCOMMON_LIBRARY
|
||||
NAMES xkbcommon
|
||||
HINTS ${PC_XKBCOMMON_LIBRARY} ${PC_XKBCOMMON_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
set(XKBCOMMON_LIBRARIES ${XKBCOMMON_LIBRARY})
|
||||
set(XKBCOMMON_LIBRARY_DIRS ${XKBCOMMON_LIBRARY_DIRS})
|
||||
set(XKBCOMMON_INCLUDE_DIRS ${XKBCOMMON_INCLUDE_DIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(XKBCommon DEFAULT_MSG
|
||||
XKBCOMMON_LIBRARY
|
||||
XKBCOMMON_INCLUDE_DIR
|
||||
)
|
||||
|
||||
mark_as_advanced(XKBCOMMON_LIBRARY XKBCOMMON_INCLUDE_DIR)
|
||||
|
13
src/external/glfw/CMake/x86_64-w64-mingw32.cmake
vendored
Normal file
13
src/external/glfw/CMake/x86_64-w64-mingw32.cmake
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Define the environment for cross compiling from Linux to Win32
|
||||
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc")
|
||||
SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++")
|
||||
SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres")
|
||||
SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib")
|
||||
|
||||
# Configure the behaviour of the find commands
|
||||
SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32")
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
402
src/external/glfw/CMakeLists.txt
vendored
Normal file
402
src/external/glfw/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(GLFW C)
|
||||
|
||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS "3.1")
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
|
||||
set(GLFW_VERSION_MAJOR "3")
|
||||
set(GLFW_VERSION_MINOR "3")
|
||||
set(GLFW_VERSION_PATCH "0")
|
||||
set(GLFW_VERSION_EXTRA "")
|
||||
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
|
||||
set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}")
|
||||
set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64")
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
|
||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
|
||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
||||
option(GLFW_INSTALL "Generate installation target" ON)
|
||||
option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF)
|
||||
|
||||
if (UNIX)
|
||||
option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
||||
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON)
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(_GLFW_BUILD_DLL 1)
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS AND UNIX)
|
||||
# On Unix-like systems, shared libraries can use the soname system.
|
||||
set(GLFW_LIB_NAME glfw)
|
||||
else()
|
||||
set(GLFW_LIB_NAME glfw3)
|
||||
endif()
|
||||
|
||||
if (GLFW_VULKAN_STATIC)
|
||||
set(_GLFW_VULKAN_STATIC 1)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(Vulkan)
|
||||
|
||||
if (GLFW_BUILD_DOCS)
|
||||
set(DOXYGEN_SKIP_DOT TRUE)
|
||||
find_package(Doxygen)
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Set compiler specific flags
|
||||
#--------------------------------------------------------------------
|
||||
if (MSVC)
|
||||
if (MSVC90)
|
||||
# Workaround for VS 2008 not shipping with the DirectX 9 SDK
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||
if (NOT DINPUT_H_FOUND)
|
||||
message(FATAL_ERROR "DirectX 9 SDK not found")
|
||||
endif()
|
||||
# Workaround for VS 2008 not shipping with stdint.h
|
||||
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
|
||||
endif()
|
||||
|
||||
if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
|
||||
foreach (flag CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
|
||||
if (${flag} MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if (${flag} MATCHES "/MDd")
|
||||
string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
# Workaround for legacy MinGW not providing XInput and DirectInput
|
||||
include(CheckIncludeFile)
|
||||
|
||||
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||
check_include_file(xinput.h XINPUT_H_FOUND)
|
||||
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
|
||||
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw")
|
||||
endif()
|
||||
|
||||
# Enable link-time exploit mitigation features enabled by default on MSVC
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
# Compatibility with data execution prevention (DEP)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat")
|
||||
check_c_compiler_flag("" _GLFW_HAS_DEP)
|
||||
if (_GLFW_HAS_DEP)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--nxcompat ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
# Compatibility with address space layout randomization (ASLR)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wl,--dynamicbase")
|
||||
check_c_compiler_flag("" _GLFW_HAS_ASLR)
|
||||
if (_GLFW_HAS_ASLR)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--dynamicbase ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
# Compatibility with 64-bit address space layout randomization (ASLR)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wl,--high-entropy-va")
|
||||
check_c_compiler_flag("" _GLFW_HAS_64ASLR)
|
||||
if (_GLFW_HAS_64ASLR)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Detect and select backend APIs
|
||||
#--------------------------------------------------------------------
|
||||
if (GLFW_USE_WAYLAND)
|
||||
set(_GLFW_WAYLAND 1)
|
||||
message(STATUS "Using Wayland for window creation")
|
||||
elseif (GLFW_USE_MIR)
|
||||
set(_GLFW_MIR 1)
|
||||
message(STATUS "Using Mir for window creation")
|
||||
elseif (GLFW_USE_OSMESA)
|
||||
set(_GLFW_OSMESA 1)
|
||||
message(STATUS "Using OSMesa for headless context creation")
|
||||
elseif (WIN32)
|
||||
set(_GLFW_WIN32 1)
|
||||
message(STATUS "Using Win32 for window creation")
|
||||
elseif (APPLE)
|
||||
set(_GLFW_COCOA 1)
|
||||
message(STATUS "Using Cocoa for window creation")
|
||||
elseif (UNIX)
|
||||
set(_GLFW_X11 1)
|
||||
message(STATUS "Using X11 for window creation")
|
||||
else()
|
||||
message(FATAL_ERROR "No supported platform was detected")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Add Vulkan static library if requested
|
||||
#--------------------------------------------------------------------
|
||||
if (GLFW_VULKAN_STATIC)
|
||||
if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
|
||||
list(APPEND glfw_LIBRARIES "${VULKAN_STATIC_LIBRARY}")
|
||||
if (BUILD_SHARED_LIBS)
|
||||
message(WARNING "Linking Vulkan loader static library into GLFW")
|
||||
endif()
|
||||
else()
|
||||
if (BUILD_SHARED_LIBS OR GLFW_BUILD_EXAMPLES OR GLFW_BUILD_TESTS)
|
||||
message(FATAL_ERROR "Vulkan loader static library not found")
|
||||
else()
|
||||
message(WARNING "Vulkan loader static library not found")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Find and add Unix math and time libraries
|
||||
#--------------------------------------------------------------------
|
||||
if (UNIX AND NOT APPLE)
|
||||
find_library(RT_LIBRARY rt)
|
||||
mark_as_advanced(RT_LIBRARY)
|
||||
if (RT_LIBRARY)
|
||||
list(APPEND glfw_LIBRARIES "${RT_LIBRARY}")
|
||||
list(APPEND glfw_PKG_LIBS "-lrt")
|
||||
endif()
|
||||
|
||||
find_library(MATH_LIBRARY m)
|
||||
mark_as_advanced(MATH_LIBRARY)
|
||||
if (MATH_LIBRARY)
|
||||
list(APPEND glfw_LIBRARIES "${MATH_LIBRARY}")
|
||||
list(APPEND glfw_PKG_LIBS "-lm")
|
||||
endif()
|
||||
|
||||
if (CMAKE_DL_LIBS)
|
||||
list(APPEND glfw_LIBRARIES "${CMAKE_DL_LIBS}")
|
||||
list(APPEND glfw_PKG_LIBS "-l${CMAKE_DL_LIBS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use Win32 for window creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_WIN32)
|
||||
|
||||
list(APPEND glfw_PKG_LIBS "-lgdi32")
|
||||
|
||||
if (GLFW_USE_HYBRID_HPG)
|
||||
set(_GLFW_USE_HYBRID_HPG 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use X11 for window creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_X11)
|
||||
|
||||
find_package(X11 REQUIRED)
|
||||
|
||||
list(APPEND glfw_PKG_DEPS "x11")
|
||||
|
||||
# Set up library and include paths
|
||||
list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
|
||||
list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
# Check for XRandR (modern resolution switching and gamma control)
|
||||
if (NOT X11_Xrandr_FOUND)
|
||||
message(FATAL_ERROR "The RandR headers were not found")
|
||||
endif()
|
||||
|
||||
# Check for Xinerama (legacy multi-monitor support)
|
||||
if (NOT X11_Xinerama_FOUND)
|
||||
message(FATAL_ERROR "The Xinerama headers were not found")
|
||||
endif()
|
||||
|
||||
# Check for Xkb (X keyboard extension)
|
||||
if (NOT X11_Xkb_FOUND)
|
||||
message(FATAL_ERROR "The X keyboard extension headers were not found")
|
||||
endif()
|
||||
|
||||
# Check for Xcursor (cursor creation from RGBA images)
|
||||
if (NOT X11_Xcursor_FOUND)
|
||||
message(FATAL_ERROR "The Xcursor headers were not found")
|
||||
endif()
|
||||
|
||||
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
|
||||
"${X11_Xinerama_INCLUDE_PATH}"
|
||||
"${X11_Xkb_INCLUDE_PATH}"
|
||||
"${X11_Xcursor_INCLUDE_PATH}")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use Wayland for window creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_WAYLAND)
|
||||
find_package(ECM REQUIRED NO_MODULE)
|
||||
list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
|
||||
|
||||
find_package(Wayland REQUIRED Client Cursor Egl)
|
||||
find_package(WaylandScanner REQUIRED)
|
||||
find_package(WaylandProtocols 1.12 REQUIRED)
|
||||
|
||||
list(APPEND glfw_PKG_DEPS "wayland-egl")
|
||||
|
||||
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
|
||||
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
find_package(XKBCommon REQUIRED)
|
||||
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
||||
|
||||
include(CheckIncludeFiles)
|
||||
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
|
||||
|
||||
if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
|
||||
find_package(EpollShim)
|
||||
if (EPOLLSHIM_FOUND)
|
||||
list(APPEND glfw_INCLUDE_DIRS "${EPOLLSHIM_INCLUDE_DIRS}")
|
||||
list(APPEND glfw_LIBRARIES "${EPOLLSHIM_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use Mir for window creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_MIR)
|
||||
find_package(Mir REQUIRED)
|
||||
list(APPEND glfw_PKG_DEPS "mirclient")
|
||||
|
||||
list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIRS}")
|
||||
list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
find_package(XKBCommon REQUIRED)
|
||||
list(APPEND glfw_PKG_DEPS "xkbcommon")
|
||||
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
|
||||
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use OSMesa for offscreen context creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_OSMESA)
|
||||
find_package(OSMesa REQUIRED)
|
||||
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use Cocoa for window creation and NSOpenGL for context creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_COCOA)
|
||||
|
||||
list(APPEND glfw_LIBRARIES
|
||||
"-framework Cocoa"
|
||||
"-framework IOKit"
|
||||
"-framework CoreFoundation"
|
||||
"-framework CoreVideo")
|
||||
|
||||
set(glfw_PKG_DEPS "")
|
||||
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Export GLFW library dependencies
|
||||
#--------------------------------------------------------------------
|
||||
foreach(arg ${glfw_PKG_DEPS})
|
||||
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} ${arg}")
|
||||
endforeach()
|
||||
foreach(arg ${glfw_PKG_LIBS})
|
||||
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}")
|
||||
endforeach()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Create generated files
|
||||
#--------------------------------------------------------------------
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3")
|
||||
|
||||
configure_package_config_file(src/glfw3Config.cmake.in
|
||||
src/glfw3Config.cmake
|
||||
INSTALL_DESTINATION "${GLFW_CONFIG_PATH}"
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
|
||||
write_basic_package_version_file(src/glfw3ConfigVersion.cmake
|
||||
VERSION ${GLFW_VERSION_FULL}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
|
||||
|
||||
configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Add subdirectories
|
||||
#--------------------------------------------------------------------
|
||||
add_subdirectory(src)
|
||||
|
||||
if (GLFW_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if (GLFW_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if (DOXYGEN_FOUND AND GLFW_BUILD_DOCS)
|
||||
add_subdirectory(docs)
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Install files other than the library
|
||||
# The library is installed by src/CMakeLists.txt
|
||||
#--------------------------------------------------------------------
|
||||
if (GLFW_INSTALL)
|
||||
install(DIRECTORY include/GLFW DESTINATION include
|
||||
FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h)
|
||||
|
||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake"
|
||||
"${GLFW_BINARY_DIR}/src/glfw3ConfigVersion.cmake"
|
||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||
|
||||
install(EXPORT glfwTargets FILE glfw3Targets.cmake
|
||||
EXPORT_LINK_INTERFACE_LIBRARIES
|
||||
DESTINATION "${GLFW_CONFIG_PATH}")
|
||||
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
|
||||
DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
|
||||
|
||||
# Only generate this target if no higher-level project already has
|
||||
if (NOT TARGET uninstall)
|
||||
configure_file(cmake_uninstall.cmake.in
|
||||
cmake_uninstall.cmake IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
"${CMAKE_COMMAND}" -P
|
||||
"${GLFW_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
set_target_properties(uninstall PROPERTIES FOLDER "GLFW3")
|
||||
endif()
|
||||
endif()
|
||||
|
29
src/external/glfw/cmake_uninstall.cmake.in
vendored
Normal file
29
src/external/glfw/cmake_uninstall.cmake.in
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
|
||||
foreach (file ${files})
|
||||
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
||||
if (EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval)
|
||||
if (NOT "${rm_retval}" STREQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
||||
endif()
|
||||
elseif (IS_SYMLINK "$ENV{DESTDIR}${file}")
|
||||
EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval)
|
||||
if (NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing symlink \"$ENV{DESTDIR}${file}\"")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
|
230
src/external/glfw/deps/getopt.c
vendored
Normal file
230
src/external/glfw/deps/getopt.c
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
const int no_argument = 0;
|
||||
const int required_argument = 1;
|
||||
const int optional_argument = 2;
|
||||
|
||||
char* optarg;
|
||||
int optopt;
|
||||
/* The variable optind [...] shall be initialized to 1 by the system. */
|
||||
int optind = 1;
|
||||
int opterr;
|
||||
|
||||
static char* optcursor = NULL;
|
||||
|
||||
/* Implemented based on [1] and [2] for optional arguments.
|
||||
optopt is handled FreeBSD-style, per [3].
|
||||
Other GNU and FreeBSD extensions are purely accidental.
|
||||
|
||||
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
|
||||
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
|
||||
*/
|
||||
int getopt(int argc, char* const argv[], const char* optstring) {
|
||||
int optchar = -1;
|
||||
const char* optdecl = NULL;
|
||||
|
||||
optarg = NULL;
|
||||
opterr = 0;
|
||||
optopt = 0;
|
||||
|
||||
/* Unspecified, but we need it to avoid overrunning the argv bounds. */
|
||||
if (optind >= argc)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
|
||||
shall return -1 without changing optind. */
|
||||
if (argv[optind] == NULL)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called *argv[optind] is not the character '-',
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (*argv[optind] != '-')
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "-",
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (strcmp(argv[optind], "-") == 0)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "--",
|
||||
getopt() shall return -1 after incrementing optind. */
|
||||
if (strcmp(argv[optind], "--") == 0) {
|
||||
++optind;
|
||||
goto no_more_optchars;
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *optcursor == '\0')
|
||||
optcursor = argv[optind] + 1;
|
||||
|
||||
optchar = *optcursor;
|
||||
|
||||
/* FreeBSD: The variable optopt saves the last known option character
|
||||
returned by getopt(). */
|
||||
optopt = optchar;
|
||||
|
||||
/* The getopt() function shall return the next option character (if one is
|
||||
found) from argv that matches a character in optstring, if there is
|
||||
one that matches. */
|
||||
optdecl = strchr(optstring, optchar);
|
||||
if (optdecl) {
|
||||
/* [I]f a character is followed by a colon, the option takes an
|
||||
argument. */
|
||||
if (optdecl[1] == ':') {
|
||||
optarg = ++optcursor;
|
||||
if (*optarg == '\0') {
|
||||
/* GNU extension: Two colons mean an option takes an
|
||||
optional arg; if there is text in the current argv-element
|
||||
(i.e., in the same word as the option name itself, for example,
|
||||
"-oarg"), then it is returned in optarg, otherwise optarg is set
|
||||
to zero. */
|
||||
if (optdecl[2] != ':') {
|
||||
/* If the option was the last character in the string pointed to by
|
||||
an element of argv, then optarg shall contain the next element
|
||||
of argv, and optind shall be incremented by 2. If the resulting
|
||||
value of optind is greater than argc, this indicates a missing
|
||||
option-argument, and getopt() shall return an error indication.
|
||||
|
||||
Otherwise, optarg shall point to the string following the
|
||||
option character in that element of argv, and optind shall be
|
||||
incremented by 1.
|
||||
*/
|
||||
if (++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
} else {
|
||||
/* If it detects a missing option-argument, it shall return the
|
||||
colon character ( ':' ) if the first character of optstring
|
||||
was a colon, or a question-mark character ( '?' ) otherwise.
|
||||
*/
|
||||
optarg = NULL;
|
||||
optchar = (optstring[0] == ':') ? ':' : '?';
|
||||
}
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
optcursor = NULL;
|
||||
}
|
||||
} else {
|
||||
/* If getopt() encounters an option character that is not contained in
|
||||
optstring, it shall return the question-mark ( '?' ) character. */
|
||||
optchar = '?';
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *++optcursor == '\0')
|
||||
++optind;
|
||||
|
||||
return optchar;
|
||||
|
||||
no_more_optchars:
|
||||
optcursor = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Implementation based on [1].
|
||||
|
||||
[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
*/
|
||||
int getopt_long(int argc, char* const argv[], const char* optstring,
|
||||
const struct option* longopts, int* longindex) {
|
||||
const struct option* o = longopts;
|
||||
const struct option* match = NULL;
|
||||
int num_matches = 0;
|
||||
size_t argument_name_length = 0;
|
||||
const char* current_argument = NULL;
|
||||
int retval = -1;
|
||||
|
||||
optarg = NULL;
|
||||
optopt = 0;
|
||||
|
||||
if (optind >= argc)
|
||||
return -1;
|
||||
|
||||
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
|
||||
return getopt(argc, argv, optstring);
|
||||
|
||||
/* It's an option; starts with -- and is longer than two chars. */
|
||||
current_argument = argv[optind] + 2;
|
||||
argument_name_length = strcspn(current_argument, "=");
|
||||
for (; o->name; ++o) {
|
||||
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
|
||||
match = o;
|
||||
++num_matches;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_matches == 1) {
|
||||
/* If longindex is not NULL, it points to a variable which is set to the
|
||||
index of the long option relative to longopts. */
|
||||
if (longindex)
|
||||
*longindex = (int) (match - longopts);
|
||||
|
||||
/* If flag is NULL, then getopt_long() shall return val.
|
||||
Otherwise, getopt_long() returns 0, and flag shall point to a variable
|
||||
which shall be set to val if the option is found, but left unchanged if
|
||||
the option is not found. */
|
||||
if (match->flag)
|
||||
*(match->flag) = match->val;
|
||||
|
||||
retval = match->flag ? 0 : match->val;
|
||||
|
||||
if (match->has_arg != no_argument) {
|
||||
optarg = strchr(argv[optind], '=');
|
||||
if (optarg != NULL)
|
||||
++optarg;
|
||||
|
||||
if (match->has_arg == required_argument) {
|
||||
/* Only scan the next argv for required arguments. Behavior is not
|
||||
specified, but has been observed with Ubuntu and Mac OSX. */
|
||||
if (optarg == NULL && ++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
}
|
||||
|
||||
if (optarg == NULL)
|
||||
retval = ':';
|
||||
}
|
||||
} else if (strchr(argv[optind], '=')) {
|
||||
/* An argument was provided to a non-argument option.
|
||||
I haven't seen this specified explicitly, but both GNU and BSD-based
|
||||
implementations show this behavior.
|
||||
*/
|
||||
retval = '?';
|
||||
}
|
||||
} else {
|
||||
/* Unknown option or ambiguous match. */
|
||||
retval = '?';
|
||||
}
|
||||
|
||||
++optind;
|
||||
return retval;
|
||||
}
|
57
src/external/glfw/deps/getopt.h
vendored
Normal file
57
src/external/glfw/deps/getopt.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GETOPT_PORT_H
|
||||
#define INCLUDED_GETOPT_PORT_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const int no_argument;
|
||||
extern const int required_argument;
|
||||
extern const int optional_argument;
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
struct option {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
int getopt(int argc, char* const argv[], const char* optstring);
|
||||
|
||||
int getopt_long(int argc, char* const argv[],
|
||||
const char* optstring, const struct option* longopts, int* longindex);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // INCLUDED_GETOPT_PORT_H
|
1678
src/external/glfw/deps/glad.c
vendored
Normal file
1678
src/external/glfw/deps/glad.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3680
src/external/glfw/deps/glad/glad.h
vendored
Normal file
3680
src/external/glfw/deps/glad/glad.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
574
src/external/glfw/deps/linmath.h
vendored
Normal file
574
src/external/glfw/deps/linmath.h
vendored
Normal file
@@ -0,0 +1,574 @@
|
||||
#ifndef LINMATH_H
|
||||
#define LINMATH_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#define LINMATH_H_DEFINE_VEC(n) \
|
||||
typedef float vec##n[n]; \
|
||||
static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = a[i] + b[i]; \
|
||||
} \
|
||||
static inline void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = a[i] - b[i]; \
|
||||
} \
|
||||
static inline void vec##n##_scale(vec##n r, vec##n const v, float const s) \
|
||||
{ \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
r[i] = v[i] * s; \
|
||||
} \
|
||||
static inline float vec##n##_mul_inner(vec##n const a, vec##n const b) \
|
||||
{ \
|
||||
float p = 0.; \
|
||||
int i; \
|
||||
for(i=0; i<n; ++i) \
|
||||
p += b[i]*a[i]; \
|
||||
return p; \
|
||||
} \
|
||||
static inline float vec##n##_len(vec##n const v) \
|
||||
{ \
|
||||
return (float) sqrt(vec##n##_mul_inner(v,v)); \
|
||||
} \
|
||||
static inline void vec##n##_norm(vec##n r, vec##n const v) \
|
||||
{ \
|
||||
float k = 1.f / vec##n##_len(v); \
|
||||
vec##n##_scale(r, v, k); \
|
||||
}
|
||||
|
||||
LINMATH_H_DEFINE_VEC(2)
|
||||
LINMATH_H_DEFINE_VEC(3)
|
||||
LINMATH_H_DEFINE_VEC(4)
|
||||
|
||||
static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
|
||||
{
|
||||
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||
}
|
||||
|
||||
static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
|
||||
{
|
||||
float p = 2.f*vec3_mul_inner(v, n);
|
||||
int i;
|
||||
for(i=0;i<3;++i)
|
||||
r[i] = v[i] - p*n[i];
|
||||
}
|
||||
|
||||
static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
|
||||
{
|
||||
r[0] = a[1]*b[2] - a[2]*b[1];
|
||||
r[1] = a[2]*b[0] - a[0]*b[2];
|
||||
r[2] = a[0]*b[1] - a[1]*b[0];
|
||||
r[3] = 1.f;
|
||||
}
|
||||
|
||||
static inline void vec4_reflect(vec4 r, vec4 v, vec4 n)
|
||||
{
|
||||
float p = 2.f*vec4_mul_inner(v, n);
|
||||
int i;
|
||||
for(i=0;i<4;++i)
|
||||
r[i] = v[i] - p*n[i];
|
||||
}
|
||||
|
||||
typedef vec4 mat4x4[4];
|
||||
static inline void mat4x4_identity(mat4x4 M)
|
||||
{
|
||||
int i, j;
|
||||
for(i=0; i<4; ++i)
|
||||
for(j=0; j<4; ++j)
|
||||
M[i][j] = i==j ? 1.f : 0.f;
|
||||
}
|
||||
static inline void mat4x4_dup(mat4x4 M, mat4x4 N)
|
||||
{
|
||||
int i, j;
|
||||
for(i=0; i<4; ++i)
|
||||
for(j=0; j<4; ++j)
|
||||
M[i][j] = N[i][j];
|
||||
}
|
||||
static inline void mat4x4_row(vec4 r, mat4x4 M, int i)
|
||||
{
|
||||
int k;
|
||||
for(k=0; k<4; ++k)
|
||||
r[k] = M[k][i];
|
||||
}
|
||||
static inline void mat4x4_col(vec4 r, mat4x4 M, int i)
|
||||
{
|
||||
int k;
|
||||
for(k=0; k<4; ++k)
|
||||
r[k] = M[i][k];
|
||||
}
|
||||
static inline void mat4x4_transpose(mat4x4 M, mat4x4 N)
|
||||
{
|
||||
int i, j;
|
||||
for(j=0; j<4; ++j)
|
||||
for(i=0; i<4; ++i)
|
||||
M[i][j] = N[j][i];
|
||||
}
|
||||
static inline void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_add(M[i], a[i], b[i]);
|
||||
}
|
||||
static inline void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_sub(M[i], a[i], b[i]);
|
||||
}
|
||||
static inline void mat4x4_scale(mat4x4 M, mat4x4 a, float k)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
vec4_scale(M[i], a[i], k);
|
||||
}
|
||||
static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z)
|
||||
{
|
||||
int i;
|
||||
vec4_scale(M[0], a[0], x);
|
||||
vec4_scale(M[1], a[1], y);
|
||||
vec4_scale(M[2], a[2], z);
|
||||
for(i = 0; i < 4; ++i) {
|
||||
M[3][i] = a[3][i];
|
||||
}
|
||||
}
|
||||
static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
|
||||
{
|
||||
mat4x4 temp;
|
||||
int k, r, c;
|
||||
for(c=0; c<4; ++c) for(r=0; r<4; ++r) {
|
||||
temp[c][r] = 0.f;
|
||||
for(k=0; k<4; ++k)
|
||||
temp[c][r] += a[k][r] * b[c][k];
|
||||
}
|
||||
mat4x4_dup(M, temp);
|
||||
}
|
||||
static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v)
|
||||
{
|
||||
int i, j;
|
||||
for(j=0; j<4; ++j) {
|
||||
r[j] = 0.f;
|
||||
for(i=0; i<4; ++i)
|
||||
r[j] += M[i][j] * v[i];
|
||||
}
|
||||
}
|
||||
static inline void mat4x4_translate(mat4x4 T, float x, float y, float z)
|
||||
{
|
||||
mat4x4_identity(T);
|
||||
T[3][0] = x;
|
||||
T[3][1] = y;
|
||||
T[3][2] = z;
|
||||
}
|
||||
static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
|
||||
{
|
||||
vec4 t = {x, y, z, 0};
|
||||
vec4 r;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
mat4x4_row(r, M, i);
|
||||
M[3][i] += vec4_mul_inner(r, t);
|
||||
}
|
||||
}
|
||||
static inline void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b)
|
||||
{
|
||||
int i, j;
|
||||
for(i=0; i<4; ++i) for(j=0; j<4; ++j)
|
||||
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
|
||||
}
|
||||
static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
vec3 u = {x, y, z};
|
||||
|
||||
if(vec3_len(u) > 1e-4) {
|
||||
mat4x4 T, C, S = {{0}};
|
||||
|
||||
vec3_norm(u, u);
|
||||
mat4x4_from_vec3_mul_outer(T, u, u);
|
||||
|
||||
S[1][2] = u[0];
|
||||
S[2][1] = -u[0];
|
||||
S[2][0] = u[1];
|
||||
S[0][2] = -u[1];
|
||||
S[0][1] = u[2];
|
||||
S[1][0] = -u[2];
|
||||
|
||||
mat4x4_scale(S, S, s);
|
||||
|
||||
mat4x4_identity(C);
|
||||
mat4x4_sub(C, C, T);
|
||||
|
||||
mat4x4_scale(C, C, c);
|
||||
|
||||
mat4x4_add(T, T, C);
|
||||
mat4x4_add(T, T, S);
|
||||
|
||||
T[3][3] = 1.;
|
||||
mat4x4_mul(R, M, T);
|
||||
} else {
|
||||
mat4x4_dup(R, M);
|
||||
}
|
||||
}
|
||||
static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
mat4x4 R = {
|
||||
{1.f, 0.f, 0.f, 0.f},
|
||||
{0.f, c, s, 0.f},
|
||||
{0.f, -s, c, 0.f},
|
||||
{0.f, 0.f, 0.f, 1.f}
|
||||
};
|
||||
mat4x4_mul(Q, M, R);
|
||||
}
|
||||
static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
mat4x4 R = {
|
||||
{ c, 0.f, s, 0.f},
|
||||
{ 0.f, 1.f, 0.f, 0.f},
|
||||
{ -s, 0.f, c, 0.f},
|
||||
{ 0.f, 0.f, 0.f, 1.f}
|
||||
};
|
||||
mat4x4_mul(Q, M, R);
|
||||
}
|
||||
static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
|
||||
{
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
mat4x4 R = {
|
||||
{ c, s, 0.f, 0.f},
|
||||
{ -s, c, 0.f, 0.f},
|
||||
{ 0.f, 0.f, 1.f, 0.f},
|
||||
{ 0.f, 0.f, 0.f, 1.f}
|
||||
};
|
||||
mat4x4_mul(Q, M, R);
|
||||
}
|
||||
static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
||||
{
|
||||
float idet;
|
||||
float s[6];
|
||||
float c[6];
|
||||
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
||||
s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2];
|
||||
s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3];
|
||||
s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2];
|
||||
s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3];
|
||||
s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3];
|
||||
|
||||
c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1];
|
||||
c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2];
|
||||
c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3];
|
||||
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
|
||||
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
|
||||
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
||||
|
||||
/* Assumes it is invertible */
|
||||
idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
|
||||
|
||||
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
|
||||
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
|
||||
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
|
||||
T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
|
||||
|
||||
T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
|
||||
T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
|
||||
T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
|
||||
T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
|
||||
|
||||
T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
|
||||
T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
|
||||
T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
|
||||
T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
|
||||
|
||||
T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
|
||||
T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
|
||||
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
|
||||
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
|
||||
}
|
||||
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
|
||||
{
|
||||
float s = 1.;
|
||||
vec3 h;
|
||||
|
||||
mat4x4_dup(R, M);
|
||||
vec3_norm(R[2], R[2]);
|
||||
|
||||
s = vec3_mul_inner(R[1], R[2]);
|
||||
vec3_scale(h, R[2], s);
|
||||
vec3_sub(R[1], R[1], h);
|
||||
vec3_norm(R[2], R[2]);
|
||||
|
||||
s = vec3_mul_inner(R[1], R[2]);
|
||||
vec3_scale(h, R[2], s);
|
||||
vec3_sub(R[1], R[1], h);
|
||||
vec3_norm(R[1], R[1]);
|
||||
|
||||
s = vec3_mul_inner(R[0], R[1]);
|
||||
vec3_scale(h, R[1], s);
|
||||
vec3_sub(R[0], R[0], h);
|
||||
vec3_norm(R[0], R[0]);
|
||||
}
|
||||
|
||||
static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
||||
{
|
||||
M[0][0] = 2.f*n/(r-l);
|
||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||
|
||||
M[1][1] = 2.f*n/(t-b);
|
||||
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
||||
|
||||
M[2][0] = (r+l)/(r-l);
|
||||
M[2][1] = (t+b)/(t-b);
|
||||
M[2][2] = -(f+n)/(f-n);
|
||||
M[2][3] = -1.f;
|
||||
|
||||
M[3][2] = -2.f*(f*n)/(f-n);
|
||||
M[3][0] = M[3][1] = M[3][3] = 0.f;
|
||||
}
|
||||
static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
|
||||
{
|
||||
M[0][0] = 2.f/(r-l);
|
||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||
|
||||
M[1][1] = 2.f/(t-b);
|
||||
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
||||
|
||||
M[2][2] = -2.f/(f-n);
|
||||
M[2][0] = M[2][1] = M[2][3] = 0.f;
|
||||
|
||||
M[3][0] = -(r+l)/(r-l);
|
||||
M[3][1] = -(t+b)/(t-b);
|
||||
M[3][2] = -(f+n)/(f-n);
|
||||
M[3][3] = 1.f;
|
||||
}
|
||||
static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
|
||||
{
|
||||
/* NOTE: Degrees are an unhandy unit to work with.
|
||||
* linmath.h uses radians for everything! */
|
||||
float const a = 1.f / (float) tan(y_fov / 2.f);
|
||||
|
||||
m[0][0] = a / aspect;
|
||||
m[0][1] = 0.f;
|
||||
m[0][2] = 0.f;
|
||||
m[0][3] = 0.f;
|
||||
|
||||
m[1][0] = 0.f;
|
||||
m[1][1] = a;
|
||||
m[1][2] = 0.f;
|
||||
m[1][3] = 0.f;
|
||||
|
||||
m[2][0] = 0.f;
|
||||
m[2][1] = 0.f;
|
||||
m[2][2] = -((f + n) / (f - n));
|
||||
m[2][3] = -1.f;
|
||||
|
||||
m[3][0] = 0.f;
|
||||
m[3][1] = 0.f;
|
||||
m[3][2] = -((2.f * f * n) / (f - n));
|
||||
m[3][3] = 0.f;
|
||||
}
|
||||
static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
|
||||
{
|
||||
/* Adapted from Android's OpenGL Matrix.java. */
|
||||
/* See the OpenGL GLUT documentation for gluLookAt for a description */
|
||||
/* of the algorithm. We implement it in a straightforward way: */
|
||||
|
||||
/* TODO: The negation of of can be spared by swapping the order of
|
||||
* operands in the following cross products in the right way. */
|
||||
vec3 f;
|
||||
vec3 s;
|
||||
vec3 t;
|
||||
|
||||
vec3_sub(f, center, eye);
|
||||
vec3_norm(f, f);
|
||||
|
||||
vec3_mul_cross(s, f, up);
|
||||
vec3_norm(s, s);
|
||||
|
||||
vec3_mul_cross(t, s, f);
|
||||
|
||||
m[0][0] = s[0];
|
||||
m[0][1] = t[0];
|
||||
m[0][2] = -f[0];
|
||||
m[0][3] = 0.f;
|
||||
|
||||
m[1][0] = s[1];
|
||||
m[1][1] = t[1];
|
||||
m[1][2] = -f[1];
|
||||
m[1][3] = 0.f;
|
||||
|
||||
m[2][0] = s[2];
|
||||
m[2][1] = t[2];
|
||||
m[2][2] = -f[2];
|
||||
m[2][3] = 0.f;
|
||||
|
||||
m[3][0] = 0.f;
|
||||
m[3][1] = 0.f;
|
||||
m[3][2] = 0.f;
|
||||
m[3][3] = 1.f;
|
||||
|
||||
mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
|
||||
}
|
||||
|
||||
typedef float quat[4];
|
||||
static inline void quat_identity(quat q)
|
||||
{
|
||||
q[0] = q[1] = q[2] = 0.f;
|
||||
q[3] = 1.f;
|
||||
}
|
||||
static inline void quat_add(quat r, quat a, quat b)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
r[i] = a[i] + b[i];
|
||||
}
|
||||
static inline void quat_sub(quat r, quat a, quat b)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
r[i] = a[i] - b[i];
|
||||
}
|
||||
static inline void quat_mul(quat r, quat p, quat q)
|
||||
{
|
||||
vec3 w;
|
||||
vec3_mul_cross(r, p, q);
|
||||
vec3_scale(w, p, q[3]);
|
||||
vec3_add(r, r, w);
|
||||
vec3_scale(w, q, p[3]);
|
||||
vec3_add(r, r, w);
|
||||
r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
|
||||
}
|
||||
static inline void quat_scale(quat r, quat v, float s)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
r[i] = v[i] * s;
|
||||
}
|
||||
static inline float quat_inner_product(quat a, quat b)
|
||||
{
|
||||
float p = 0.f;
|
||||
int i;
|
||||
for(i=0; i<4; ++i)
|
||||
p += b[i]*a[i];
|
||||
return p;
|
||||
}
|
||||
static inline void quat_conj(quat r, quat q)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<3; ++i)
|
||||
r[i] = -q[i];
|
||||
r[3] = q[3];
|
||||
}
|
||||
static inline void quat_rotate(quat r, float angle, vec3 axis) {
|
||||
int i;
|
||||
vec3 v;
|
||||
vec3_scale(v, axis, sinf(angle / 2));
|
||||
for(i=0; i<3; ++i)
|
||||
r[i] = v[i];
|
||||
r[3] = cosf(angle / 2);
|
||||
}
|
||||
#define quat_norm vec4_norm
|
||||
static inline void quat_mul_vec3(vec3 r, quat q, vec3 v)
|
||||
{
|
||||
/*
|
||||
* Method by Fabian 'ryg' Giessen (of Farbrausch)
|
||||
t = 2 * cross(q.xyz, v)
|
||||
v' = v + q.w * t + cross(q.xyz, t)
|
||||
*/
|
||||
vec3 t = {q[0], q[1], q[2]};
|
||||
vec3 u = {q[0], q[1], q[2]};
|
||||
|
||||
vec3_mul_cross(t, t, v);
|
||||
vec3_scale(t, t, 2);
|
||||
|
||||
vec3_mul_cross(u, u, t);
|
||||
vec3_scale(t, t, q[3]);
|
||||
|
||||
vec3_add(r, v, t);
|
||||
vec3_add(r, r, u);
|
||||
}
|
||||
static inline void mat4x4_from_quat(mat4x4 M, quat q)
|
||||
{
|
||||
float a = q[3];
|
||||
float b = q[0];
|
||||
float c = q[1];
|
||||
float d = q[2];
|
||||
float a2 = a*a;
|
||||
float b2 = b*b;
|
||||
float c2 = c*c;
|
||||
float d2 = d*d;
|
||||
|
||||
M[0][0] = a2 + b2 - c2 - d2;
|
||||
M[0][1] = 2.f*(b*c + a*d);
|
||||
M[0][2] = 2.f*(b*d - a*c);
|
||||
M[0][3] = 0.f;
|
||||
|
||||
M[1][0] = 2*(b*c - a*d);
|
||||
M[1][1] = a2 - b2 + c2 - d2;
|
||||
M[1][2] = 2.f*(c*d + a*b);
|
||||
M[1][3] = 0.f;
|
||||
|
||||
M[2][0] = 2.f*(b*d + a*c);
|
||||
M[2][1] = 2.f*(c*d - a*b);
|
||||
M[2][2] = a2 - b2 - c2 + d2;
|
||||
M[2][3] = 0.f;
|
||||
|
||||
M[3][0] = M[3][1] = M[3][2] = 0.f;
|
||||
M[3][3] = 1.f;
|
||||
}
|
||||
|
||||
static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q)
|
||||
{
|
||||
/* XXX: The way this is written only works for othogonal matrices. */
|
||||
/* TODO: Take care of non-orthogonal case. */
|
||||
quat_mul_vec3(R[0], q, M[0]);
|
||||
quat_mul_vec3(R[1], q, M[1]);
|
||||
quat_mul_vec3(R[2], q, M[2]);
|
||||
|
||||
R[3][0] = R[3][1] = R[3][2] = 0.f;
|
||||
R[3][3] = 1.f;
|
||||
}
|
||||
static inline void quat_from_mat4x4(quat q, mat4x4 M)
|
||||
{
|
||||
float r=0.f;
|
||||
int i;
|
||||
|
||||
int perm[] = { 0, 1, 2, 0, 1 };
|
||||
int *p = perm;
|
||||
|
||||
for(i = 0; i<3; i++) {
|
||||
float m = M[i][i];
|
||||
if( m < r )
|
||||
continue;
|
||||
m = r;
|
||||
p = &perm[i];
|
||||
}
|
||||
|
||||
r = (float) sqrt(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] );
|
||||
|
||||
if(r < 1e-6) {
|
||||
q[0] = 1.f;
|
||||
q[1] = q[2] = q[3] = 0.f;
|
||||
return;
|
||||
}
|
||||
|
||||
q[0] = r/2.f;
|
||||
q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r);
|
||||
q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r);
|
||||
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
|
||||
}
|
||||
|
||||
#endif
|
23717
src/external/glfw/deps/nuklear.h
vendored
Normal file
23717
src/external/glfw/deps/nuklear.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
381
src/external/glfw/deps/nuklear_glfw_gl2.h
vendored
Normal file
381
src/external/glfw/deps/nuklear_glfw_gl2.h
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Nuklear - v1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2017 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GLFW_GL2_H_
|
||||
#define NK_GLFW_GL2_H_
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{
|
||||
NK_GLFW3_DEFAULT = 0,
|
||||
NK_GLFW3_INSTALL_CALLBACKS
|
||||
};
|
||||
NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GLFW_GL2_IMPLEMENTATION
|
||||
|
||||
#ifndef NK_GLFW_TEXT_MAX
|
||||
#define NK_GLFW_TEXT_MAX 256
|
||||
#endif
|
||||
#ifndef NK_GLFW_DOUBLE_CLICK_LO
|
||||
#define NK_GLFW_DOUBLE_CLICK_LO 0.02
|
||||
#endif
|
||||
#ifndef NK_GLFW_DOUBLE_CLICK_HI
|
||||
#define NK_GLFW_DOUBLE_CLICK_HI 0.2
|
||||
#endif
|
||||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
GLuint font_tex;
|
||||
};
|
||||
|
||||
struct nk_glfw_vertex {
|
||||
float position[2];
|
||||
float uv[2];
|
||||
nk_byte col[4];
|
||||
};
|
||||
|
||||
static struct nk_glfw {
|
||||
GLFWwindow *win;
|
||||
int width, height;
|
||||
int display_width, display_height;
|
||||
struct nk_glfw_device ogl;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
struct nk_vec2 fb_scale;
|
||||
unsigned int text[NK_GLFW_TEXT_MAX];
|
||||
int text_len;
|
||||
struct nk_vec2 scroll;
|
||||
double last_button_click;
|
||||
int is_double_click_down;
|
||||
struct nk_vec2 double_click_pos;
|
||||
} glfw;
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_device_upload_atlas(const void *image, int width, int height)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
glGenTextures(1, &dev->font_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, dev->font_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
/* setup global state */
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* setup viewport/project */
|
||||
glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
{
|
||||
GLsizei vs = sizeof(struct nk_glfw_vertex);
|
||||
size_t vp = offsetof(struct nk_glfw_vertex, position);
|
||||
size_t vt = offsetof(struct nk_glfw_vertex, uv);
|
||||
size_t vc = offsetof(struct nk_glfw_vertex, col);
|
||||
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
const struct nk_draw_command *cmd;
|
||||
const nk_draw_index *offset = NULL;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
|
||||
/* fill convert configuration */
|
||||
struct nk_convert_config config;
|
||||
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
NK_MEMSET(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
|
||||
/* convert shapes into vertexes */
|
||||
nk_buffer_init_default(&vbuf);
|
||||
nk_buffer_init_default(&ebuf);
|
||||
nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
/* setup vertex buffer pointer */
|
||||
{const void *vertices = nk_buffer_memory_const(&vbuf);
|
||||
glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
|
||||
glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
|
||||
nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor(
|
||||
(GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
|
||||
(GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
|
||||
(GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
|
||||
(GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
nk_clear(&glfw.ctx);
|
||||
nk_buffer_free(&vbuf);
|
||||
nk_buffer_free(&ebuf);
|
||||
}
|
||||
|
||||
/* default OpenGL state */
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
|
||||
{
|
||||
(void)win;
|
||||
if (glfw.text_len < NK_GLFW_TEXT_MAX)
|
||||
glfw.text[glfw.text_len++] = codepoint;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
||||
{
|
||||
(void)win; (void)xoff;
|
||||
glfw.scroll.x += (float)xoff;
|
||||
glfw.scroll.y += (float)yoff;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
||||
glfwGetCursorPos(window, &x, &y);
|
||||
if (action == GLFW_PRESS) {
|
||||
double dt = glfwGetTime() - glfw.last_button_click;
|
||||
if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI) {
|
||||
glfw.is_double_click_down = nk_true;
|
||||
glfw.double_click_pos = nk_vec2((float)x, (float)y);
|
||||
}
|
||||
glfw.last_button_click = glfwGetTime();
|
||||
} else glfw.is_double_click_down = nk_false;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
const char *text = glfwGetClipboardString(glfw.win);
|
||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
char *str = 0;
|
||||
(void)usr;
|
||||
if (!len) return;
|
||||
str = (char*)malloc((size_t)len+1);
|
||||
if (!str) return;
|
||||
NK_MEMCPY(str, text, (size_t)len);
|
||||
str[len] = '\0';
|
||||
glfwSetClipboardString(glfw.win, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
|
||||
{
|
||||
glfw.win = win;
|
||||
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
||||
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
||||
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
||||
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
||||
}
|
||||
nk_init_default(&glfw.ctx, 0);
|
||||
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
|
||||
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
|
||||
glfw.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
nk_buffer_init_default(&glfw.ogl.cmds);
|
||||
|
||||
glfw.is_double_click_down = nk_false;
|
||||
glfw.double_click_pos = nk_vec2(0, 0);
|
||||
|
||||
return &glfw.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&glfw.atlas);
|
||||
nk_font_atlas_begin(&glfw.atlas);
|
||||
*atlas = &glfw.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_end(void)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
|
||||
if (glfw.atlas.default_font)
|
||||
nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_new_frame(void)
|
||||
{
|
||||
int i;
|
||||
double x, y;
|
||||
struct nk_context *ctx = &glfw.ctx;
|
||||
struct GLFWwindow *win = glfw.win;
|
||||
|
||||
glfwGetWindowSize(win, &glfw.width, &glfw.height);
|
||||
glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
|
||||
glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width;
|
||||
glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height;
|
||||
|
||||
nk_input_begin(ctx);
|
||||
for (i = 0; i < glfw.text_len; ++i)
|
||||
nk_input_unicode(ctx, glfw.text[i]);
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
else if (ctx->input.mouse.ungrab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
|
||||
nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
|
||||
|
||||
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
||||
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
|
||||
} else {
|
||||
nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_COPY, 0);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, 0);
|
||||
nk_input_key(ctx, NK_KEY_CUT, 0);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, 0);
|
||||
}
|
||||
|
||||
glfwGetCursorPos(win, &x, &y);
|
||||
nk_input_motion(ctx, (int)x, (int)y);
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
glfwSetCursorPos(glfw.win, (double)ctx->input.mouse.prev.x, (double)ctx->input.mouse.prev.y);
|
||||
ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
|
||||
ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
|
||||
}
|
||||
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_DOUBLE, (int)glfw.double_click_pos.x, (int)glfw.double_click_pos.y, glfw.is_double_click_down);
|
||||
nk_input_scroll(ctx, glfw.scroll);
|
||||
nk_input_end(&glfw.ctx);
|
||||
glfw.text_len = 0;
|
||||
glfw.scroll = nk_vec2(0,0);
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_glfw3_shutdown(void)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
nk_font_atlas_clear(&glfw.atlas);
|
||||
nk_free(&glfw.ctx);
|
||||
glDeleteTextures(1, &dev->font_tex);
|
||||
nk_buffer_free(&dev->cmds);
|
||||
NK_MEMSET(&glfw, 0, sizeof(glfw));
|
||||
}
|
||||
|
||||
#endif
|
1048
src/external/glfw/deps/stb_image_write.h
vendored
Normal file
1048
src/external/glfw/deps/stb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
594
src/external/glfw/deps/tinycthread.c
vendored
Normal file
594
src/external/glfw/deps/tinycthread.c
vendored
Normal file
@@ -0,0 +1,594 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||
Copyright (c) 2012 Marcus Geelnard
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
/* 2013-01-06 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* Added casts from time_t to DWORD to avoid warnings on VC++.
|
||||
* Fixed time retrieval on POSIX systems.
|
||||
*/
|
||||
|
||||
#include "tinycthread.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Platform specific includes */
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#elif defined(_TTHREAD_WIN32_)
|
||||
#include <process.h>
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
/* Standard, good-to-have defines */
|
||||
#ifndef NULL
|
||||
#define NULL (void*)0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
int mtx_init(mtx_t *mtx, int type)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
mtx->mAlreadyLocked = FALSE;
|
||||
mtx->mRecursive = type & mtx_recursive;
|
||||
InitializeCriticalSection(&mtx->mHandle);
|
||||
return thrd_success;
|
||||
#else
|
||||
int ret;
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
if (type & mtx_recursive)
|
||||
{
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
}
|
||||
ret = pthread_mutex_init(mtx, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return ret == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mtx_destroy(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
DeleteCriticalSection(&mtx->mHandle);
|
||||
#else
|
||||
pthread_mutex_destroy(mtx);
|
||||
#endif
|
||||
}
|
||||
|
||||
int mtx_lock(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
EnterCriticalSection(&mtx->mHandle);
|
||||
if (!mtx->mRecursive)
|
||||
{
|
||||
while(mtx->mAlreadyLocked) Sleep(1000); /* Simulate deadlock... */
|
||||
mtx->mAlreadyLocked = TRUE;
|
||||
}
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
|
||||
{
|
||||
/* FIXME! */
|
||||
(void)mtx;
|
||||
(void)ts;
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
int mtx_trylock(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
int ret = TryEnterCriticalSection(&mtx->mHandle) ? thrd_success : thrd_busy;
|
||||
if ((!mtx->mRecursive) && (ret == thrd_success) && mtx->mAlreadyLocked)
|
||||
{
|
||||
LeaveCriticalSection(&mtx->mHandle);
|
||||
ret = thrd_busy;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
|
||||
#endif
|
||||
}
|
||||
|
||||
int mtx_unlock(mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
mtx->mAlreadyLocked = FALSE;
|
||||
LeaveCriticalSection(&mtx->mHandle);
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
#define _CONDITION_EVENT_ONE 0
|
||||
#define _CONDITION_EVENT_ALL 1
|
||||
#endif
|
||||
|
||||
int cnd_init(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
cond->mWaitersCount = 0;
|
||||
|
||||
/* Init critical section */
|
||||
InitializeCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* Init events */
|
||||
cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL)
|
||||
{
|
||||
cond->mEvents[_CONDITION_EVENT_ALL] = NULL;
|
||||
return thrd_error;
|
||||
}
|
||||
cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL)
|
||||
{
|
||||
CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
|
||||
cond->mEvents[_CONDITION_EVENT_ONE] = NULL;
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cnd_destroy(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL)
|
||||
{
|
||||
CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]);
|
||||
}
|
||||
if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL)
|
||||
{
|
||||
CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
|
||||
}
|
||||
DeleteCriticalSection(&cond->mWaitersCountLock);
|
||||
#else
|
||||
pthread_cond_destroy(cond);
|
||||
#endif
|
||||
}
|
||||
|
||||
int cnd_signal(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
int haveWaiters;
|
||||
|
||||
/* Are there any waiters? */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
haveWaiters = (cond->mWaitersCount > 0);
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* If we have any waiting threads, send them a signal */
|
||||
if(haveWaiters)
|
||||
{
|
||||
if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cnd_broadcast(cnd_t *cond)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
int haveWaiters;
|
||||
|
||||
/* Are there any waiters? */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
haveWaiters = (cond->mWaitersCount > 0);
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* If we have any waiting threads, send them a signal */
|
||||
if(haveWaiters)
|
||||
{
|
||||
if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
#else
|
||||
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout)
|
||||
{
|
||||
int result, lastWaiter;
|
||||
|
||||
/* Increment number of waiters */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
++ cond->mWaitersCount;
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* Release the mutex while waiting for the condition (will decrease
|
||||
the number of waiters when done)... */
|
||||
mtx_unlock(mtx);
|
||||
|
||||
/* Wait for either event to become signaled due to cnd_signal() or
|
||||
cnd_broadcast() being called */
|
||||
result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout);
|
||||
if (result == WAIT_TIMEOUT)
|
||||
{
|
||||
return thrd_timeout;
|
||||
}
|
||||
else if (result == (int)WAIT_FAILED)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
/* Check if we are the last waiter */
|
||||
EnterCriticalSection(&cond->mWaitersCountLock);
|
||||
-- cond->mWaitersCount;
|
||||
lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
|
||||
(cond->mWaitersCount == 0);
|
||||
LeaveCriticalSection(&cond->mWaitersCountLock);
|
||||
|
||||
/* If we are the last waiter to be notified to stop waiting, reset the event */
|
||||
if (lastWaiter)
|
||||
{
|
||||
if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-acquire the mutex */
|
||||
mtx_lock(mtx);
|
||||
|
||||
return thrd_success;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cnd_wait(cnd_t *cond, mtx_t *mtx)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return _cnd_timedwait_win32(cond, mtx, INFINITE);
|
||||
#else
|
||||
return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
struct timespec now;
|
||||
if (clock_gettime(CLOCK_REALTIME, &now) == 0)
|
||||
{
|
||||
DWORD delta = (DWORD) ((ts->tv_sec - now.tv_sec) * 1000 +
|
||||
(ts->tv_nsec - now.tv_nsec + 500000) / 1000000);
|
||||
return _cnd_timedwait_win32(cond, mtx, delta);
|
||||
}
|
||||
else
|
||||
return thrd_error;
|
||||
#else
|
||||
int ret;
|
||||
ret = pthread_cond_timedwait(cond, mtx, ts);
|
||||
if (ret == ETIMEDOUT)
|
||||
{
|
||||
return thrd_timeout;
|
||||
}
|
||||
return ret == 0 ? thrd_success : thrd_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** Information to pass to the new thread (what to run). */
|
||||
typedef struct {
|
||||
thrd_start_t mFunction; /**< Pointer to the function to be executed. */
|
||||
void * mArg; /**< Function argument for the thread function. */
|
||||
} _thread_start_info;
|
||||
|
||||
/* Thread wrapper function. */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
static unsigned WINAPI _thrd_wrapper_function(void * aArg)
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
static void * _thrd_wrapper_function(void * aArg)
|
||||
#endif
|
||||
{
|
||||
thrd_start_t fun;
|
||||
void *arg;
|
||||
int res;
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
void *pres;
|
||||
#endif
|
||||
|
||||
/* Get thread startup information */
|
||||
_thread_start_info *ti = (_thread_start_info *) aArg;
|
||||
fun = ti->mFunction;
|
||||
arg = ti->mArg;
|
||||
|
||||
/* The thread is responsible for freeing the startup information */
|
||||
free((void *)ti);
|
||||
|
||||
/* Call the actual client thread function */
|
||||
res = fun(arg);
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return res;
|
||||
#else
|
||||
pres = malloc(sizeof(int));
|
||||
if (pres != NULL)
|
||||
{
|
||||
*(int*)pres = res;
|
||||
}
|
||||
return pres;
|
||||
#endif
|
||||
}
|
||||
|
||||
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
|
||||
{
|
||||
/* Fill out the thread startup information (passed to the thread wrapper,
|
||||
which will eventually free it) */
|
||||
_thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info));
|
||||
if (ti == NULL)
|
||||
{
|
||||
return thrd_nomem;
|
||||
}
|
||||
ti->mFunction = func;
|
||||
ti->mArg = arg;
|
||||
|
||||
/* Create the thread */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
*thr = (HANDLE)_beginthreadex(NULL, 0, _thrd_wrapper_function, (void *)ti, 0, NULL);
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0)
|
||||
{
|
||||
*thr = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Did we fail to create the thread? */
|
||||
if(!*thr)
|
||||
{
|
||||
free(ti);
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
thrd_t thrd_current(void)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return GetCurrentThread();
|
||||
#else
|
||||
return pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
int thrd_detach(thrd_t thr)
|
||||
{
|
||||
/* FIXME! */
|
||||
(void)thr;
|
||||
return thrd_error;
|
||||
}
|
||||
|
||||
int thrd_equal(thrd_t thr0, thrd_t thr1)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return thr0 == thr1;
|
||||
#else
|
||||
return pthread_equal(thr0, thr1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void thrd_exit(int res)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
ExitThread(res);
|
||||
#else
|
||||
void *pres = malloc(sizeof(int));
|
||||
if (pres != NULL)
|
||||
{
|
||||
*(int*)pres = res;
|
||||
}
|
||||
pthread_exit(pres);
|
||||
#endif
|
||||
}
|
||||
|
||||
int thrd_join(thrd_t thr, int *res)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
if (res != NULL)
|
||||
{
|
||||
DWORD dwRes;
|
||||
GetExitCodeThread(thr, &dwRes);
|
||||
*res = dwRes;
|
||||
}
|
||||
#elif defined(_TTHREAD_POSIX_)
|
||||
void *pres;
|
||||
int ires = 0;
|
||||
if (pthread_join(thr, &pres) != 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
if (pres != NULL)
|
||||
{
|
||||
ires = *(int*)pres;
|
||||
free(pres);
|
||||
}
|
||||
if (res != NULL)
|
||||
{
|
||||
*res = ires;
|
||||
}
|
||||
#endif
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
|
||||
{
|
||||
struct timespec now;
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
DWORD delta;
|
||||
#else
|
||||
long delta;
|
||||
#endif
|
||||
|
||||
/* Get the current time */
|
||||
if (clock_gettime(CLOCK_REALTIME, &now) != 0)
|
||||
return -2; // FIXME: Some specific error code?
|
||||
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
/* Delta in milliseconds */
|
||||
delta = (DWORD) ((time_point->tv_sec - now.tv_sec) * 1000 +
|
||||
(time_point->tv_nsec - now.tv_nsec + 500000) / 1000000);
|
||||
if (delta > 0)
|
||||
{
|
||||
Sleep(delta);
|
||||
}
|
||||
#else
|
||||
/* Delta in microseconds */
|
||||
delta = (time_point->tv_sec - now.tv_sec) * 1000000L +
|
||||
(time_point->tv_nsec - now.tv_nsec + 500L) / 1000L;
|
||||
|
||||
/* On some systems, the usleep argument must be < 1000000 */
|
||||
while (delta > 999999L)
|
||||
{
|
||||
usleep(999999);
|
||||
delta -= 999999L;
|
||||
}
|
||||
if (delta > 0L)
|
||||
{
|
||||
usleep((useconds_t)delta);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We don't support waking up prematurely (yet) */
|
||||
if (remaining)
|
||||
{
|
||||
remaining->tv_sec = 0;
|
||||
remaining->tv_nsec = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void thrd_yield(void)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
Sleep(0);
|
||||
#else
|
||||
sched_yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
int tss_create(tss_t *key, tss_dtor_t dtor)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
/* FIXME: The destructor function is not supported yet... */
|
||||
if (dtor != NULL)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
*key = TlsAlloc();
|
||||
if (*key == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#else
|
||||
if (pthread_key_create(key, dtor) != 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#endif
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
void tss_delete(tss_t key)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
TlsFree(key);
|
||||
#else
|
||||
pthread_key_delete(key);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *tss_get(tss_t key)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
return TlsGetValue(key);
|
||||
#else
|
||||
return pthread_getspecific(key);
|
||||
#endif
|
||||
}
|
||||
|
||||
int tss_set(tss_t key, void *val)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
if (TlsSetValue(key, val) == 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#else
|
||||
if (pthread_setspecific(key, val) != 0)
|
||||
{
|
||||
return thrd_error;
|
||||
}
|
||||
#endif
|
||||
return thrd_success;
|
||||
}
|
||||
|
||||
#if defined(_TTHREAD_EMULATE_CLOCK_GETTIME_)
|
||||
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||
{
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
ts->tv_sec = (time_t)tb.time;
|
||||
ts->tv_nsec = 1000000L * (long)tb.millitm;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
ts->tv_sec = (time_t)tv.tv_sec;
|
||||
ts->tv_nsec = 1000L * (long)tv.tv_usec;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif // _TTHREAD_EMULATE_CLOCK_GETTIME_
|
||||
|
443
src/external/glfw/deps/tinycthread.h
vendored
Normal file
443
src/external/glfw/deps/tinycthread.h
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
|
||||
Copyright (c) 2012 Marcus Geelnard
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#ifndef _TINYCTHREAD_H_
|
||||
#define _TINYCTHREAD_H_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @mainpage TinyCThread API Reference
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
* TinyCThread is a minimal, portable implementation of basic threading
|
||||
* classes for C.
|
||||
*
|
||||
* They closely mimic the functionality and naming of the C11 standard, and
|
||||
* should be easily replaceable with the corresponding standard variants.
|
||||
*
|
||||
* @section port_sec Portability
|
||||
* The Win32 variant uses the native Win32 API for implementing the thread
|
||||
* classes, while for other systems, the POSIX threads API (pthread) is used.
|
||||
*
|
||||
* @section misc_sec Miscellaneous
|
||||
* The following special keywords are available: #_Thread_local.
|
||||
*
|
||||
* For more detailed information, browse the different sections of this
|
||||
* documentation. A good place to start is:
|
||||
* tinycthread.h.
|
||||
*/
|
||||
|
||||
/* Which platform are we on? */
|
||||
#if !defined(_TTHREAD_PLATFORM_DEFINED_)
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
|
||||
#define _TTHREAD_WIN32_
|
||||
#else
|
||||
#define _TTHREAD_POSIX_
|
||||
#endif
|
||||
#define _TTHREAD_PLATFORM_DEFINED_
|
||||
#endif
|
||||
|
||||
/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#undef _FEATURES_H
|
||||
#if !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#endif
|
||||
#if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
|
||||
#undef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Generic includes */
|
||||
#include <time.h>
|
||||
|
||||
/* Platform specific includes */
|
||||
#if defined(_TTHREAD_POSIX_)
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#elif defined(_TTHREAD_WIN32_)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define __UNDEF_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#ifdef __UNDEF_LEAN_AND_MEAN
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#undef __UNDEF_LEAN_AND_MEAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Workaround for missing TIME_UTC: If time.h doesn't provide TIME_UTC,
|
||||
it's quite likely that libc does not support it either. Hence, fall back to
|
||||
the only other supported time specifier: CLOCK_REALTIME (and if that fails,
|
||||
we're probably emulating clock_gettime anyway, so anything goes). */
|
||||
#ifndef TIME_UTC
|
||||
#ifdef CLOCK_REALTIME
|
||||
#define TIME_UTC CLOCK_REALTIME
|
||||
#else
|
||||
#define TIME_UTC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Workaround for missing clock_gettime (most Windows compilers, afaik) */
|
||||
#if defined(_TTHREAD_WIN32_) || defined(__APPLE_CC__)
|
||||
#define _TTHREAD_EMULATE_CLOCK_GETTIME_
|
||||
/* Emulate struct timespec */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
struct _ttherad_timespec {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
#define timespec _ttherad_timespec
|
||||
#endif
|
||||
|
||||
/* Emulate clockid_t */
|
||||
typedef int _tthread_clockid_t;
|
||||
#define clockid_t _tthread_clockid_t
|
||||
|
||||
/* Emulate clock_gettime */
|
||||
int _tthread_clock_gettime(clockid_t clk_id, struct timespec *ts);
|
||||
#define clock_gettime _tthread_clock_gettime
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/** TinyCThread version (major number). */
|
||||
#define TINYCTHREAD_VERSION_MAJOR 1
|
||||
/** TinyCThread version (minor number). */
|
||||
#define TINYCTHREAD_VERSION_MINOR 1
|
||||
/** TinyCThread version (full version). */
|
||||
#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
|
||||
|
||||
/**
|
||||
* @def _Thread_local
|
||||
* Thread local storage keyword.
|
||||
* A variable that is declared with the @c _Thread_local keyword makes the
|
||||
* value of the variable local to each thread (known as thread-local storage,
|
||||
* or TLS). Example usage:
|
||||
* @code
|
||||
* // This variable is local to each thread.
|
||||
* _Thread_local int variable;
|
||||
* @endcode
|
||||
* @note The @c _Thread_local keyword is a macro that maps to the corresponding
|
||||
* compiler directive (e.g. @c __declspec(thread)).
|
||||
* @note This directive is currently not supported on Mac OS X (it will give
|
||||
* a compiler error), since compile-time TLS is not supported in the Mac OS X
|
||||
* executable format. Also, some older versions of MinGW (before GCC 4.x) do
|
||||
* not support this directive.
|
||||
* @hideinitializer
|
||||
*/
|
||||
|
||||
/* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
|
||||
#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
|
||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
|
||||
#define _Thread_local __thread
|
||||
#else
|
||||
#define _Thread_local __declspec(thread)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Macros */
|
||||
#define TSS_DTOR_ITERATIONS 0
|
||||
|
||||
/* Function return values */
|
||||
#define thrd_error 0 /**< The requested operation failed */
|
||||
#define thrd_success 1 /**< The requested operation succeeded */
|
||||
#define thrd_timeout 2 /**< The time specified in the call was reached without acquiring the requested resource */
|
||||
#define thrd_busy 3 /**< The requested operation failed because a tesource requested by a test and return function is already in use */
|
||||
#define thrd_nomem 4 /**< The requested operation failed because it was unable to allocate memory */
|
||||
|
||||
/* Mutex types */
|
||||
#define mtx_plain 1
|
||||
#define mtx_timed 2
|
||||
#define mtx_try 4
|
||||
#define mtx_recursive 8
|
||||
|
||||
/* Mutex */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef struct {
|
||||
CRITICAL_SECTION mHandle; /* Critical section handle */
|
||||
int mAlreadyLocked; /* TRUE if the mutex is already locked */
|
||||
int mRecursive; /* TRUE if the mutex is recursive */
|
||||
} mtx_t;
|
||||
#else
|
||||
typedef pthread_mutex_t mtx_t;
|
||||
#endif
|
||||
|
||||
/** Create a mutex object.
|
||||
* @param mtx A mutex object.
|
||||
* @param type Bit-mask that must have one of the following six values:
|
||||
* @li @c mtx_plain for a simple non-recursive mutex
|
||||
* @li @c mtx_timed for a non-recursive mutex that supports timeout
|
||||
* @li @c mtx_try for a non-recursive mutex that supports test and return
|
||||
* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive)
|
||||
* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive)
|
||||
* @li @c mtx_try | @c mtx_recursive (same as @c mtx_try, but recursive)
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int mtx_init(mtx_t *mtx, int type);
|
||||
|
||||
/** Release any resources used by the given mutex.
|
||||
* @param mtx A mutex object.
|
||||
*/
|
||||
void mtx_destroy(mtx_t *mtx);
|
||||
|
||||
/** Lock the given mutex.
|
||||
* Blocks until the given mutex can be locked. If the mutex is non-recursive, and
|
||||
* the calling thread already has a lock on the mutex, this call will block
|
||||
* forever.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int mtx_lock(mtx_t *mtx);
|
||||
|
||||
/** NOT YET IMPLEMENTED.
|
||||
*/
|
||||
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
|
||||
|
||||
/** Try to lock the given mutex.
|
||||
* The specified mutex shall support either test and return or timeout. If the
|
||||
* mutex is already locked, the function returns without blocking.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_busy if the resource
|
||||
* requested is already in use, or @ref thrd_error if the request could not be
|
||||
* honored.
|
||||
*/
|
||||
int mtx_trylock(mtx_t *mtx);
|
||||
|
||||
/** Unlock the given mutex.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int mtx_unlock(mtx_t *mtx);
|
||||
|
||||
/* Condition variable */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef struct {
|
||||
HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */
|
||||
unsigned int mWaitersCount; /* Count of the number of waiters. */
|
||||
CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
|
||||
} cnd_t;
|
||||
#else
|
||||
typedef pthread_cond_t cnd_t;
|
||||
#endif
|
||||
|
||||
/** Create a condition variable object.
|
||||
* @param cond A condition variable object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_init(cnd_t *cond);
|
||||
|
||||
/** Release any resources used by the given condition variable.
|
||||
* @param cond A condition variable object.
|
||||
*/
|
||||
void cnd_destroy(cnd_t *cond);
|
||||
|
||||
/** Signal a condition variable.
|
||||
* Unblocks one of the threads that are blocked on the given condition variable
|
||||
* at the time of the call. If no threads are blocked on the condition variable
|
||||
* at the time of the call, the function does nothing and return success.
|
||||
* @param cond A condition variable object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_signal(cnd_t *cond);
|
||||
|
||||
/** Broadcast a condition variable.
|
||||
* Unblocks all of the threads that are blocked on the given condition variable
|
||||
* at the time of the call. If no threads are blocked on the condition variable
|
||||
* at the time of the call, the function does nothing and return success.
|
||||
* @param cond A condition variable object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_broadcast(cnd_t *cond);
|
||||
|
||||
/** Wait for a condition variable to become signaled.
|
||||
* The function atomically unlocks the given mutex and endeavors to block until
|
||||
* the given condition variable is signaled by a call to cnd_signal or to
|
||||
* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex
|
||||
* before it returns.
|
||||
* @param cond A condition variable object.
|
||||
* @param mtx A mutex object.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int cnd_wait(cnd_t *cond, mtx_t *mtx);
|
||||
|
||||
/** Wait for a condition variable to become signaled.
|
||||
* The function atomically unlocks the given mutex and endeavors to block until
|
||||
* the given condition variable is signaled by a call to cnd_signal or to
|
||||
* cnd_broadcast, or until after the specified time. When the calling thread
|
||||
* becomes unblocked it locks the mutex before it returns.
|
||||
* @param cond A condition variable object.
|
||||
* @param mtx A mutex object.
|
||||
* @param xt A point in time at which the request will time out (absolute time).
|
||||
* @return @ref thrd_success upon success, or @ref thrd_timeout if the time
|
||||
* specified in the call was reached without acquiring the requested resource, or
|
||||
* @ref thrd_error if the request could not be honored.
|
||||
*/
|
||||
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
|
||||
|
||||
/* Thread */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef HANDLE thrd_t;
|
||||
#else
|
||||
typedef pthread_t thrd_t;
|
||||
#endif
|
||||
|
||||
/** Thread start function.
|
||||
* Any thread that is started with the @ref thrd_create() function must be
|
||||
* started through a function of this type.
|
||||
* @param arg The thread argument (the @c arg argument of the corresponding
|
||||
* @ref thrd_create() call).
|
||||
* @return The thread return value, which can be obtained by another thread
|
||||
* by using the @ref thrd_join() function.
|
||||
*/
|
||||
typedef int (*thrd_start_t)(void *arg);
|
||||
|
||||
/** Create a new thread.
|
||||
* @param thr Identifier of the newly created thread.
|
||||
* @param func A function pointer to the function that will be executed in
|
||||
* the new thread.
|
||||
* @param arg An argument to the thread function.
|
||||
* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could
|
||||
* be allocated for the thread requested, or @ref thrd_error if the request
|
||||
* could not be honored.
|
||||
* @note A thread’s identifier may be reused for a different thread once the
|
||||
* original thread has exited and either been detached or joined to another
|
||||
* thread.
|
||||
*/
|
||||
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
|
||||
|
||||
/** Identify the calling thread.
|
||||
* @return The identifier of the calling thread.
|
||||
*/
|
||||
thrd_t thrd_current(void);
|
||||
|
||||
/** NOT YET IMPLEMENTED.
|
||||
*/
|
||||
int thrd_detach(thrd_t thr);
|
||||
|
||||
/** Compare two thread identifiers.
|
||||
* The function determines if two thread identifiers refer to the same thread.
|
||||
* @return Zero if the two thread identifiers refer to different threads.
|
||||
* Otherwise a nonzero value is returned.
|
||||
*/
|
||||
int thrd_equal(thrd_t thr0, thrd_t thr1);
|
||||
|
||||
/** Terminate execution of the calling thread.
|
||||
* @param res Result code of the calling thread.
|
||||
*/
|
||||
void thrd_exit(int res);
|
||||
|
||||
/** Wait for a thread to terminate.
|
||||
* The function joins the given thread with the current thread by blocking
|
||||
* until the other thread has terminated.
|
||||
* @param thr The thread to join with.
|
||||
* @param res If this pointer is not NULL, the function will store the result
|
||||
* code of the given thread in the integer pointed to by @c res.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int thrd_join(thrd_t thr, int *res);
|
||||
|
||||
/** Put the calling thread to sleep.
|
||||
* Suspend execution of the calling thread.
|
||||
* @param time_point A point in time at which the thread will resume (absolute time).
|
||||
* @param remaining If non-NULL, this parameter will hold the remaining time until
|
||||
* time_point upon return. This will typically be zero, but if
|
||||
* the thread was woken up by a signal that is not ignored before
|
||||
* time_point was reached @c remaining will hold a positive
|
||||
* time.
|
||||
* @return 0 (zero) on successful sleep, or -1 if an interrupt occurred.
|
||||
*/
|
||||
int thrd_sleep(const struct timespec *time_point, struct timespec *remaining);
|
||||
|
||||
/** Yield execution to another thread.
|
||||
* Permit other threads to run, even if the current thread would ordinarily
|
||||
* continue to run.
|
||||
*/
|
||||
void thrd_yield(void);
|
||||
|
||||
/* Thread local storage */
|
||||
#if defined(_TTHREAD_WIN32_)
|
||||
typedef DWORD tss_t;
|
||||
#else
|
||||
typedef pthread_key_t tss_t;
|
||||
#endif
|
||||
|
||||
/** Destructor function for a thread-specific storage.
|
||||
* @param val The value of the destructed thread-specific storage.
|
||||
*/
|
||||
typedef void (*tss_dtor_t)(void *val);
|
||||
|
||||
/** Create a thread-specific storage.
|
||||
* @param key The unique key identifier that will be set if the function is
|
||||
* successful.
|
||||
* @param dtor Destructor function. This can be NULL.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
* @note The destructor function is not supported under Windows. If @c dtor is
|
||||
* not NULL when calling this function under Windows, the function will fail
|
||||
* and return @ref thrd_error.
|
||||
*/
|
||||
int tss_create(tss_t *key, tss_dtor_t dtor);
|
||||
|
||||
/** Delete a thread-specific storage.
|
||||
* The function releases any resources used by the given thread-specific
|
||||
* storage.
|
||||
* @param key The key that shall be deleted.
|
||||
*/
|
||||
void tss_delete(tss_t key);
|
||||
|
||||
/** Get the value for a thread-specific storage.
|
||||
* @param key The thread-specific storage identifier.
|
||||
* @return The value for the current thread held in the given thread-specific
|
||||
* storage.
|
||||
*/
|
||||
void *tss_get(tss_t key);
|
||||
|
||||
/** Set the value for a thread-specific storage.
|
||||
* @param key The thread-specific storage identifier.
|
||||
* @param val The value of the thread-specific storage to set for the current
|
||||
* thread.
|
||||
* @return @ref thrd_success on success, or @ref thrd_error if the request could
|
||||
* not be honored.
|
||||
*/
|
||||
int tss_set(tss_t key, void *val);
|
||||
|
||||
|
||||
#endif /* _TINYTHREAD_H_ */
|
||||
|
212
src/external/glfw/deps/vulkan/vk_platform.h
vendored
212
src/external/glfw/deps/vulkan/vk_platform.h
vendored
@@ -1,120 +1,92 @@
|
||||
//
|
||||
// File: vk_platform.h
|
||||
//
|
||||
/*
|
||||
** Copyright (c) 2014-2015 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VK_PLATFORM_H_
|
||||
#define VK_PLATFORM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Platform-specific directives and type declarations
|
||||
***************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Platform-specific calling convention macros.
|
||||
*
|
||||
* Platforms should define these so that Vulkan clients call Vulkan commands
|
||||
* with the same calling conventions that the Vulkan implementation expects.
|
||||
*
|
||||
* VKAPI_ATTR - Placed before the return type in function declarations.
|
||||
* Useful for C++11 and GCC/Clang-style function attribute syntax.
|
||||
* VKAPI_CALL - Placed after the return type in function declarations.
|
||||
* Useful for MSVC-style calling convention syntax.
|
||||
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
|
||||
*
|
||||
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
|
||||
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
// On Windows, Vulkan commands use the stdcall convention
|
||||
#define VKAPI_ATTR
|
||||
#define VKAPI_CALL __stdcall
|
||||
#define VKAPI_PTR VKAPI_CALL
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
|
||||
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
||||
// calling convention, i.e. float parameters are passed in registers. This
|
||||
// is true even if the rest of the application passes floats on the stack,
|
||||
// as it does by default when compiling for the armeabi-v7a NDK ABI.
|
||||
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
|
||||
#define VKAPI_CALL
|
||||
#define VKAPI_PTR VKAPI_ATTR
|
||||
#else
|
||||
// On other platforms, use the default calling convention
|
||||
#define VKAPI_ATTR
|
||||
#define VKAPI_CALL
|
||||
#define VKAPI_PTR
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined(VK_NO_STDINT_H)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
typedef signed __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif // !defined(VK_NO_STDINT_H)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
// Platform-specific headers required by platform window system extensions.
|
||||
// These are enabled prior to #including "vulkan.h". The same enable then
|
||||
// controls inclusion of the extension interfaces in vulkan.h.
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
#include <android/native_window.h>
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_MIR_KHR
|
||||
#include <mir_toolkit/client_types.h>
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
#include <xcb/xcb.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
//
|
||||
// File: vk_platform.h
|
||||
//
|
||||
/*
|
||||
** Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VK_PLATFORM_H_
|
||||
#define VK_PLATFORM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
***************************************************************************************************
|
||||
* Platform-specific directives and type declarations
|
||||
***************************************************************************************************
|
||||
*/
|
||||
|
||||
/* Platform-specific calling convention macros.
|
||||
*
|
||||
* Platforms should define these so that Vulkan clients call Vulkan commands
|
||||
* with the same calling conventions that the Vulkan implementation expects.
|
||||
*
|
||||
* VKAPI_ATTR - Placed before the return type in function declarations.
|
||||
* Useful for C++11 and GCC/Clang-style function attribute syntax.
|
||||
* VKAPI_CALL - Placed after the return type in function declarations.
|
||||
* Useful for MSVC-style calling convention syntax.
|
||||
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
|
||||
*
|
||||
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
|
||||
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
// On Windows, Vulkan commands use the stdcall convention
|
||||
#define VKAPI_ATTR
|
||||
#define VKAPI_CALL __stdcall
|
||||
#define VKAPI_PTR VKAPI_CALL
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
|
||||
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
||||
// calling convention, i.e. float parameters are passed in registers. This
|
||||
// is true even if the rest of the application passes floats on the stack,
|
||||
// as it does by default when compiling for the armeabi-v7a NDK ABI.
|
||||
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
|
||||
#define VKAPI_CALL
|
||||
#define VKAPI_PTR VKAPI_ATTR
|
||||
#else
|
||||
// On other platforms, use the default calling convention
|
||||
#define VKAPI_ATTR
|
||||
#define VKAPI_CALL
|
||||
#define VKAPI_PTR
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if !defined(VK_NO_STDINT_H)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
typedef signed __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif // !defined(VK_NO_STDINT_H)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
4842
src/external/glfw/deps/vulkan/vulkan.h
vendored
4842
src/external/glfw/deps/vulkan/vulkan.h
vendored
File diff suppressed because it is too large
Load Diff
7334
src/external/glfw/deps/vulkan/vulkan_core.h
vendored
Normal file
7334
src/external/glfw/deps/vulkan/vulkan_core.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
src/external/glfw/include/GLFW/glfw3.h
vendored
6
src/external/glfw/include/GLFW/glfw3.h
vendored
@@ -4697,7 +4697,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid);
|
||||
* This function may be called from the joystick callback, even for a joystick
|
||||
* that is being disconnected.
|
||||
*
|
||||
* @param[in] joystick The joystick whose pointer to set.
|
||||
* @param[in] jid The joystick whose pointer to set.
|
||||
* @param[in] pointer The new value.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
@@ -4722,7 +4722,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
|
||||
* This function may be called from the joystick callback, even for a joystick
|
||||
* that is being disconnected.
|
||||
*
|
||||
* @param[in] joystick The joystick whose pointer to return.
|
||||
* @param[in] jid The joystick whose pointer to return.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
@@ -4874,7 +4874,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
|
||||
*
|
||||
* Not all devices have all the buttons or axes provided by @ref
|
||||
* GLFWgamepadstate. Unavailable buttons and axes will always report
|
||||
* `GLFW_RELEASE` and 1.0 respectively.
|
||||
* `GLFW_RELEASE` and 0.0 respectively.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @param[out] state The gamepad input state of the joystick.
|
||||
|
38
src/external/glfw/src/CMakeLists.txt
vendored
38
src/external/glfw/src/CMakeLists.txt
vendored
@@ -23,20 +23,12 @@ elseif (_GLFW_X11)
|
||||
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
|
||||
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
|
||||
egl_context.c osmesa_context.c)
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
|
||||
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
|
||||
else()
|
||||
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
|
||||
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
|
||||
endif()
|
||||
elseif (_GLFW_WAYLAND)
|
||||
set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h
|
||||
set(glfw_HEADERS ${common_HEADERS} wl_platform.h
|
||||
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
|
||||
osmesa_context.h)
|
||||
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
|
||||
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
|
||||
posix_time.c posix_thread.c xkb_unicode.c
|
||||
egl_context.c osmesa_context.c)
|
||||
|
||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||
@@ -73,6 +65,16 @@ elseif (_GLFW_OSMESA)
|
||||
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
|
||||
endif()
|
||||
|
||||
if (_GLFW_X11 OR _GLFW_WAYLAND)
|
||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
|
||||
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
|
||||
else()
|
||||
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
|
||||
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# For some reason, CMake doesn't know about .m
|
||||
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
||||
@@ -90,7 +92,9 @@ if (${CMAKE_C_COMPILER_ID} STREQUAL GNU OR ${CMAKE_C_COMPILER_ID} STREQUAL Clang
|
||||
COMPILE_FLAGS -Wdeclaration-after-statement)
|
||||
endif()
|
||||
|
||||
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
||||
add_library(glfw_objlib OBJECT ${glfw_SOURCES} ${glfw_HEADERS})
|
||||
add_library(glfw $<TARGET_OBJECTS:glfw_objlib>)
|
||||
|
||||
set_target_properties(glfw PROPERTIES
|
||||
OUTPUT_NAME ${GLFW_LIB_NAME}
|
||||
VERSION ${GLFW_VERSION}
|
||||
@@ -98,11 +102,11 @@ set_target_properties(glfw PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
FOLDER "GLFW3")
|
||||
|
||||
target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H)
|
||||
target_include_directories(glfw PUBLIC
|
||||
target_compile_definitions(glfw_objlib PRIVATE _GLFW_USE_CONFIG_H)
|
||||
target_include_directories(glfw_objlib PUBLIC
|
||||
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
|
||||
target_include_directories(glfw PRIVATE
|
||||
target_include_directories(glfw_objlib PRIVATE
|
||||
"${GLFW_SOURCE_DIR}/src"
|
||||
"${GLFW_BINARY_DIR}/src"
|
||||
${glfw_INCLUDE_DIRS})
|
||||
@@ -111,11 +115,11 @@ target_include_directories(glfw PRIVATE
|
||||
# the inclusion of stddef.h (by glfw3.h), which is itself included before
|
||||
# win32_platform.h. We define them here until a saner solution can be found
|
||||
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
|
||||
target_compile_definitions(glfw PRIVATE
|
||||
target_compile_definitions(glfw_objlib PRIVATE
|
||||
"$<$<BOOL:${MINGW}>:UNICODE;WINVER=0x0501>")
|
||||
|
||||
# Enable a reasonable set of warnings (no, -Wextra is not reasonable)
|
||||
target_compile_options(glfw PRIVATE
|
||||
target_compile_options(glfw_objlib PRIVATE
|
||||
"$<$<C_COMPILER_ID:Clang>:-Wall>"
|
||||
"$<$<C_COMPILER_ID:GNU>:-Wall>")
|
||||
|
||||
@@ -133,7 +137,7 @@ if (BUILD_SHARED_LIBS)
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
# Add -fno-common to work around a bug in Apple's GCC
|
||||
target_compile_options(glfw PRIVATE "-fno-common")
|
||||
target_compile_options(glfw_objlib PRIVATE "-fno-common")
|
||||
|
||||
set_target_properties(glfw PROPERTIES
|
||||
INSTALL_NAME_DIR "lib${LIB_SUFFIX}")
|
||||
|
56
src/external/glfw/src/cocoa_window.m
vendored
56
src/external/glfw/src/cocoa_window.m
vendored
@@ -128,6 +128,32 @@ static void updateCursorImage(_GLFWwindow* window)
|
||||
hideCursor(window);
|
||||
}
|
||||
|
||||
// Apply chosen cursor mode to a focused window
|
||||
//
|
||||
static void updateCursorMode(_GLFWwindow* window)
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfw.ns.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.ns.restoreCursorPosX,
|
||||
&_glfw.ns.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
}
|
||||
else if (_glfw.ns.disabledCursorWindow == window)
|
||||
{
|
||||
_glfw.ns.disabledCursorWindow = NULL;
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.ns.restoreCursorPosX,
|
||||
_glfw.ns.restoreCursorPosY);
|
||||
}
|
||||
|
||||
if (cursorInClientArea(window))
|
||||
updateCursorImage(window);
|
||||
}
|
||||
|
||||
// Transforms the specified y-coordinate between the CG display and NS screen
|
||||
// coordinate systems
|
||||
//
|
||||
@@ -321,7 +347,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
centerCursor(window);
|
||||
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
_glfwPlatformSetCursorMode(window, window->cursorMode);
|
||||
updateCursorMode(window);
|
||||
}
|
||||
|
||||
- (void)windowDidResignKey:(NSNotification *)notification
|
||||
@@ -582,6 +608,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
window->ns.xscale = xscale;
|
||||
window->ns.yscale = yscale;
|
||||
_glfwInputWindowContentScale(window, xscale, yscale);
|
||||
|
||||
if (window->ns.layer)
|
||||
[window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,7 +901,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
- (void)loadMainMenu
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 100800
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
|
||||
owner:NSApp
|
||||
topLevelObjects:&nibObjects];
|
||||
@@ -1635,26 +1664,8 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
_glfw.ns.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.ns.restoreCursorPosX,
|
||||
&_glfw.ns.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
}
|
||||
else if (_glfw.ns.disabledCursorWindow == window)
|
||||
{
|
||||
_glfw.ns.disabledCursorWindow = NULL;
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.ns.restoreCursorPosX,
|
||||
_glfw.ns.restoreCursorPosY);
|
||||
}
|
||||
|
||||
if (cursorInClientArea(window))
|
||||
updateCursorImage(window);
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
updateCursorMode(window);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||
@@ -1871,6 +1882,7 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
|
||||
[window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]];
|
||||
[window->ns.view setWantsLayer:YES];
|
||||
|
||||
memset(&sci, 0, sizeof(sci));
|
||||
|
56
src/external/glfw/src/init.c
vendored
56
src/external/glfw/src/init.c
vendored
@@ -57,37 +57,6 @@ static _GLFWinitconfig _glfwInitHints =
|
||||
}
|
||||
};
|
||||
|
||||
// Returns a generic string representation of the specified error
|
||||
//
|
||||
static const char* getErrorString(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case GLFW_NOT_INITIALIZED:
|
||||
return "The GLFW library is not initialized";
|
||||
case GLFW_NO_CURRENT_CONTEXT:
|
||||
return "There is no current context";
|
||||
case GLFW_INVALID_ENUM:
|
||||
return "Invalid argument for enum parameter";
|
||||
case GLFW_INVALID_VALUE:
|
||||
return "Invalid value for parameter";
|
||||
case GLFW_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
case GLFW_API_UNAVAILABLE:
|
||||
return "The requested API is unavailable";
|
||||
case GLFW_VERSION_UNAVAILABLE:
|
||||
return "The requested API version is unavailable";
|
||||
case GLFW_PLATFORM_ERROR:
|
||||
return "An undocumented platform-specific error occurred";
|
||||
case GLFW_FORMAT_UNAVAILABLE:
|
||||
return "The requested format is unavailable";
|
||||
case GLFW_NO_WINDOW_CONTEXT:
|
||||
return "The specified window has no context";
|
||||
default:
|
||||
return "ERROR: UNKNOWN GLFW ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
// Terminate the library
|
||||
//
|
||||
static void terminate(void)
|
||||
@@ -173,7 +142,30 @@ void _glfwInputError(int code, const char* format, ...)
|
||||
description[sizeof(description) - 1] = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(description, getErrorString(code));
|
||||
{
|
||||
if (code == GLFW_NOT_INITIALIZED)
|
||||
strcpy(description, "The GLFW library is not initialized");
|
||||
else if (code == GLFW_NO_CURRENT_CONTEXT)
|
||||
strcpy(description, "There is no current context");
|
||||
else if (code == GLFW_INVALID_ENUM)
|
||||
strcpy(description, "Invalid argument for enum parameter");
|
||||
else if (code == GLFW_INVALID_VALUE)
|
||||
strcpy(description, "Invalid value for parameter");
|
||||
else if (code == GLFW_OUT_OF_MEMORY)
|
||||
strcpy(description, "Out of memory");
|
||||
else if (code == GLFW_API_UNAVAILABLE)
|
||||
strcpy(description, "The requested API is unavailable");
|
||||
else if (code == GLFW_VERSION_UNAVAILABLE)
|
||||
strcpy(description, "The requested API version is unavailable");
|
||||
else if (code == GLFW_PLATFORM_ERROR)
|
||||
strcpy(description, "A platform-specific error occurred");
|
||||
else if (code == GLFW_FORMAT_UNAVAILABLE)
|
||||
strcpy(description, "The requested format is unavailable");
|
||||
else if (code == GLFW_NO_WINDOW_CONTEXT)
|
||||
strcpy(description, "The specified window has no context");
|
||||
else
|
||||
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
|
||||
}
|
||||
|
||||
if (_glfw.initialized)
|
||||
{
|
||||
|
4
src/external/glfw/src/input.c
vendored
4
src/external/glfw/src/input.c
vendored
@@ -509,9 +509,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&window->virtualCursorPosX,
|
||||
&window->virtualCursorPosY);
|
||||
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
_glfwPlatformSetCursorMode(window, value);
|
||||
_glfwPlatformSetCursorMode(window, value);
|
||||
}
|
||||
else if (mode == GLFW_STICKY_KEYS)
|
||||
{
|
||||
|
2
src/external/glfw/src/internal.h
vendored
2
src/external/glfw/src/internal.h
vendored
@@ -128,7 +128,7 @@ typedef enum VkStructureType
|
||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
|
||||
VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000,
|
||||
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
|
||||
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000053000,
|
||||
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
|
||||
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||
} VkStructureType;
|
||||
|
||||
|
2
src/external/glfw/src/nsgl_context.m
vendored
2
src/external/glfw/src/nsgl_context.m
vendored
@@ -175,7 +175,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
// Info.plist for unbundled applications
|
||||
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
||||
// a straightforward wrapper of its CGL counterpart
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 100800
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
|
||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||
}
|
||||
|
2
src/external/glfw/src/win32_platform.h
vendored
2
src/external/glfw/src/win32_platform.h
vendored
@@ -120,6 +120,8 @@ typedef struct
|
||||
HRGN hRgnBlur;
|
||||
BOOL fTransitionOnMaximized;
|
||||
} DWM_BLURBEHIND;
|
||||
#else
|
||||
#include <dwmapi.h>
|
||||
#endif /*Windows Vista*/
|
||||
|
||||
#ifndef DPI_ENUMS_DECLARED
|
||||
|
130
src/external/glfw/src/win32_window.c
vendored
130
src/external/glfw/src/win32_window.c
vendored
@@ -235,26 +235,6 @@ static void centerCursor(_GLFWwindow* window)
|
||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||
}
|
||||
|
||||
// Returns whether the cursor is in the client area of the specified window
|
||||
//
|
||||
static GLFWbool cursorInClientArea(_GLFWwindow* window)
|
||||
{
|
||||
RECT area;
|
||||
POINT pos;
|
||||
|
||||
if (!GetCursorPos(&pos))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (WindowFromPoint(pos) != window->win32.handle)
|
||||
return GLFW_FALSE;
|
||||
|
||||
GetClientRect(window->win32.handle, &area);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &area.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &area.right);
|
||||
|
||||
return PtInRect(&area, pos);
|
||||
}
|
||||
|
||||
// Updates the cursor image according to its cursor mode
|
||||
//
|
||||
static void updateCursorImage(_GLFWwindow* window)
|
||||
@@ -286,6 +266,67 @@ static void updateClipRect(_GLFWwindow* window)
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
|
||||
// Apply disabled cursor mode to a focused window
|
||||
//
|
||||
static void disableCursor(_GLFWwindow* window)
|
||||
{
|
||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
|
||||
|
||||
_glfw.win32.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.win32.restoreCursorPosX,
|
||||
&_glfw.win32.restoreCursorPosY);
|
||||
updateCursorImage(window);
|
||||
centerCursor(window);
|
||||
updateClipRect(window);
|
||||
|
||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to register raw input device");
|
||||
}
|
||||
}
|
||||
|
||||
// Exit disabled cursor mode for the specified window
|
||||
//
|
||||
static void enableCursor(_GLFWwindow* window)
|
||||
{
|
||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
||||
|
||||
_glfw.win32.disabledCursorWindow = NULL;
|
||||
updateClipRect(NULL);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.win32.restoreCursorPosX,
|
||||
_glfw.win32.restoreCursorPosY);
|
||||
updateCursorImage(window);
|
||||
|
||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to remove raw input device");
|
||||
}
|
||||
}
|
||||
|
||||
// Returns whether the cursor is in the client area of the specified window
|
||||
//
|
||||
static GLFWbool cursorInClientArea(_GLFWwindow* window)
|
||||
{
|
||||
RECT area;
|
||||
POINT pos;
|
||||
|
||||
if (!GetCursorPos(&pos))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (WindowFromPoint(pos) != window->win32.handle)
|
||||
return GLFW_FALSE;
|
||||
|
||||
GetClientRect(window->win32.handle, &area);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &area.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &area.right);
|
||||
|
||||
return PtInRect(&area, pos);
|
||||
}
|
||||
|
||||
// Update native window styles to match attributes
|
||||
//
|
||||
static void updateWindowStyles(const _GLFWwindow* window)
|
||||
@@ -575,7 +616,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (lParam == 0 && window->win32.frameAction)
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||
disableCursor(window);
|
||||
|
||||
window->win32.frameAction = GLFW_FALSE;
|
||||
}
|
||||
@@ -593,7 +634,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
break;
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||
disableCursor(window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -601,7 +642,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case WM_KILLFOCUS:
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
||||
enableCursor(window);
|
||||
|
||||
if (window->monitor && window->autoIconify)
|
||||
_glfwPlatformIconifyWindow(window);
|
||||
@@ -857,10 +898,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
case WM_ENTERSIZEMOVE:
|
||||
case WM_ENTERMENULOOP:
|
||||
{
|
||||
// HACK: Postpone cursor disabling while the user is moving or
|
||||
// resizing the window or using the menu
|
||||
// HACK: Enable the cursor while the user is moving or
|
||||
// resizing the window or using the window menu
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
||||
enableCursor(window);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -871,7 +912,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
// HACK: Disable the cursor once the user is done moving or
|
||||
// resizing the window or using the menu
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||
disableCursor(window);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1772,39 +1813,12 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
|
||||
|
||||
_glfw.win32.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.win32.restoreCursorPosX,
|
||||
&_glfw.win32.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
updateClipRect(window);
|
||||
|
||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to register raw input device");
|
||||
}
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
disableCursor(window);
|
||||
}
|
||||
else if (_glfw.win32.disabledCursorWindow == window)
|
||||
{
|
||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
||||
|
||||
_glfw.win32.disabledCursorWindow = NULL;
|
||||
updateClipRect(NULL);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.win32.restoreCursorPosX,
|
||||
_glfw.win32.restoreCursorPosY);
|
||||
|
||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to remove raw input device");
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorInClientArea(window))
|
||||
enableCursor(window);
|
||||
else if (cursorInClientArea(window))
|
||||
updateCursorImage(window);
|
||||
}
|
||||
|
||||
|
4
src/external/glfw/src/wl_init.c
vendored
4
src/external/glfw/src/wl_init.c
vendored
@@ -1046,8 +1046,10 @@ int _glfwPlatformInit(void)
|
||||
// Sync so we got all initial output events
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
|
||||
#ifdef __linux__
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
@@ -1073,7 +1075,9 @@ int _glfwPlatformInit(void)
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
_glfwTerminateJoysticksLinux();
|
||||
#endif
|
||||
_glfwTerminateEGL();
|
||||
if (_glfw.wl.egl.handle)
|
||||
{
|
||||
|
4
src/external/glfw/src/wl_platform.h
vendored
4
src/external/glfw/src/wl_platform.h
vendored
@@ -47,7 +47,11 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
|
||||
#include "posix_thread.h"
|
||||
#include "posix_time.h"
|
||||
#ifdef __linux__
|
||||
#include "linux_joystick.h"
|
||||
#else
|
||||
#include "null_joystick.h"
|
||||
#endif
|
||||
#include "xkb_unicode.h"
|
||||
#include "egl_context.h"
|
||||
#include "osmesa_context.h"
|
||||
|
42
src/external/glfw/src/x11_init.c
vendored
42
src/external/glfw/src/x11_init.c
vendored
@@ -479,7 +479,11 @@ static GLFWbool initExtensions(void)
|
||||
&_glfw.x11.vidmode.errorBase);
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so");
|
||||
#else
|
||||
_glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
|
||||
#endif
|
||||
if (_glfw.x11.xi.handle)
|
||||
{
|
||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||
@@ -505,7 +509,11 @@ static GLFWbool initExtensions(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so");
|
||||
#else
|
||||
_glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
|
||||
#endif
|
||||
if (_glfw.x11.randr.handle)
|
||||
{
|
||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
||||
@@ -593,7 +601,11 @@ static GLFWbool initExtensions(void)
|
||||
RROutputChangeNotifyMask);
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so");
|
||||
#else
|
||||
_glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
|
||||
#endif
|
||||
if (_glfw.x11.xcursor.handle)
|
||||
{
|
||||
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
|
||||
@@ -604,7 +616,11 @@ static GLFWbool initExtensions(void)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so");
|
||||
#else
|
||||
_glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
|
||||
#endif
|
||||
if (_glfw.x11.xinerama.handle)
|
||||
{
|
||||
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
|
||||
@@ -644,14 +660,22 @@ static GLFWbool initExtensions(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so");
|
||||
#else
|
||||
_glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
|
||||
#endif
|
||||
if (_glfw.x11.x11xcb.handle)
|
||||
{
|
||||
_glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
|
||||
_glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so");
|
||||
#else
|
||||
_glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
|
||||
#endif
|
||||
if (_glfw.x11.xrender.handle)
|
||||
{
|
||||
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
|
||||
@@ -1024,6 +1048,24 @@ void _glfwPlatformTerminate(void)
|
||||
_glfw.x11.xinerama.handle = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.x11.xrender.handle)
|
||||
{
|
||||
_glfw_dlclose(_glfw.x11.xrender.handle);
|
||||
_glfw.x11.xrender.handle = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.x11.vidmode.handle)
|
||||
{
|
||||
_glfw_dlclose(_glfw.x11.vidmode.handle);
|
||||
_glfw.x11.vidmode.handle = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.x11.xi.handle)
|
||||
{
|
||||
_glfw_dlclose(_glfw.x11.xi.handle);
|
||||
_glfw.x11.xi.handle = NULL;
|
||||
}
|
||||
|
||||
// NOTE: These need to be unloaded after XCloseDisplay, as they register
|
||||
// cleanup callbacks that get called by that function
|
||||
_glfwTerminateEGL();
|
||||
|
110
src/external/glfw/src/x11_window.c
vendored
110
src/external/glfw/src/x11_window.c
vendored
@@ -571,6 +571,61 @@ static void updateCursorImage(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply disabled cursor mode to a focused window
|
||||
//
|
||||
static void disableCursor(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
XIEventMask em;
|
||||
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
|
||||
|
||||
em.deviceid = XIAllMasterDevices;
|
||||
em.mask_len = sizeof(mask);
|
||||
em.mask = mask;
|
||||
XISetMask(mask, XI_RawMotion);
|
||||
|
||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||
}
|
||||
|
||||
_glfw.x11.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.x11.restoreCursorPosX,
|
||||
&_glfw.x11.restoreCursorPosY);
|
||||
updateCursorImage(window);
|
||||
centerCursor(window);
|
||||
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
window->x11.handle,
|
||||
_glfw.x11.hiddenCursorHandle,
|
||||
CurrentTime);
|
||||
}
|
||||
|
||||
// Exit disabled cursor mode for the specified window
|
||||
//
|
||||
static void enableCursor(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
XIEventMask em;
|
||||
unsigned char mask[] = { 0 };
|
||||
|
||||
em.deviceid = XIAllMasterDevices;
|
||||
em.mask_len = sizeof(mask);
|
||||
em.mask = mask;
|
||||
|
||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||
}
|
||||
|
||||
_glfw.x11.disabledCursorWindow = NULL;
|
||||
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.x11.restoreCursorPosX,
|
||||
_glfw.x11.restoreCursorPosY);
|
||||
updateCursorImage(window);
|
||||
}
|
||||
|
||||
// Create the X11 window (and its colormap)
|
||||
//
|
||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
@@ -1432,7 +1487,7 @@ static void processEvent(XEvent *event)
|
||||
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
|
||||
// ignore the defined cursor for hidden cursor mode
|
||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_HIDDEN);
|
||||
updateCursorImage(window);
|
||||
|
||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||
return;
|
||||
@@ -1725,7 +1780,7 @@ static void processEvent(XEvent *event)
|
||||
case FocusIn:
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||
disableCursor(window);
|
||||
|
||||
if (event->xfocus.mode == NotifyGrab ||
|
||||
event->xfocus.mode == NotifyUngrab)
|
||||
@@ -1745,7 +1800,7 @@ static void processEvent(XEvent *event)
|
||||
case FocusOut:
|
||||
{
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
||||
enableCursor(window);
|
||||
|
||||
if (event->xfocus.mode == NotifyGrab ||
|
||||
event->xfocus.mode == NotifyUngrab)
|
||||
@@ -2708,53 +2763,14 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
XIEventMask em;
|
||||
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
|
||||
|
||||
em.deviceid = XIAllMasterDevices;
|
||||
em.mask_len = sizeof(mask);
|
||||
em.mask = mask;
|
||||
XISetMask(mask, XI_RawMotion);
|
||||
|
||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||
}
|
||||
|
||||
_glfw.x11.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.x11.restoreCursorPosX,
|
||||
&_glfw.x11.restoreCursorPosY);
|
||||
centerCursor(window);
|
||||
XGrabPointer(_glfw.x11.display, window->x11.handle, True,
|
||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
window->x11.handle,
|
||||
_glfw.x11.hiddenCursorHandle,
|
||||
CurrentTime);
|
||||
if (_glfwPlatformWindowFocused(window))
|
||||
disableCursor(window);
|
||||
}
|
||||
else if (_glfw.x11.disabledCursorWindow == window)
|
||||
{
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
XIEventMask em;
|
||||
unsigned char mask[] = { 0 };
|
||||
enableCursor(window);
|
||||
else
|
||||
updateCursorImage(window);
|
||||
|
||||
em.deviceid = XIAllMasterDevices;
|
||||
em.mask_len = sizeof(mask);
|
||||
em.mask = mask;
|
||||
|
||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||
}
|
||||
|
||||
_glfw.x11.disabledCursorWindow = NULL;
|
||||
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
_glfw.x11.restoreCursorPosX,
|
||||
_glfw.x11.restoreCursorPosY);
|
||||
}
|
||||
|
||||
updateCursorImage(window);
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
|
95
src/models.c
95
src/models.c
@@ -36,9 +36,8 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#include "raylib.h" // Declares module functions
|
||||
|
||||
#include "utils.h" // Required for: fopen() Android mapping
|
||||
|
||||
@@ -2119,16 +2118,98 @@ BoundingBox MeshBoundingBox(Mesh mesh)
|
||||
return box;
|
||||
}
|
||||
|
||||
// Compute mesh tangents
|
||||
// Compute mesh tangents
|
||||
// NOTE: To calculate mesh tangents and binormals we need mesh vertex positions and texture coordinates
|
||||
// Implementation base don: https://answers.unity.com/questions/7789/calculating-tangents-vector4.html
|
||||
void MeshTangents(Mesh *mesh)
|
||||
{
|
||||
// TODO: Compute mesh tangents
|
||||
if (mesh->tangents == NULL) mesh->tangents = (float *)malloc(mesh->vertexCount*4*sizeof(float));
|
||||
else TraceLog(LOG_WARNING, "Mesh tangents already exist");
|
||||
|
||||
Vector3 *tan1 = (Vector3 *)malloc(mesh->vertexCount*sizeof(Vector3));
|
||||
Vector3 *tan2 = (Vector3 *)malloc(mesh->vertexCount*sizeof(Vector3));
|
||||
|
||||
for (int i = 0; i < mesh->vertexCount; i += 3)
|
||||
{
|
||||
// Get triangle vertices
|
||||
Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] };
|
||||
Vector3 v2 = { mesh->vertices[(i + 1)*3 + 0], mesh->vertices[(i + 1)*3 + 1], mesh->vertices[(i + 1)*3 + 2] };
|
||||
Vector3 v3 = { mesh->vertices[(i + 2)*3 + 0], mesh->vertices[(i + 2)*3 + 1], mesh->vertices[(i + 2)*3 + 2] };
|
||||
|
||||
// Get triangle texcoords
|
||||
Vector2 uv1 = { mesh->texcoords[(i + 0)*2 + 0], mesh->texcoords[(i + 0)*2 + 1] };
|
||||
Vector2 uv2 = { mesh->texcoords[(i + 1)*2 + 0], mesh->texcoords[(i + 1)*2 + 1] };
|
||||
Vector2 uv3 = { mesh->texcoords[(i + 2)*2 + 0], mesh->texcoords[(i + 2)*2 + 1] };
|
||||
|
||||
float x1 = v2.x - v1.x;
|
||||
float y1 = v2.y - v1.y;
|
||||
float z1 = v2.z - v1.z;
|
||||
float x2 = v3.x - v1.x;
|
||||
float y2 = v3.y - v1.y;
|
||||
float z2 = v3.z - v1.z;
|
||||
|
||||
float s1 = uv2.x - uv1.x;
|
||||
float t1 = uv2.y - uv1.y;
|
||||
float s2 = uv3.x - uv1.x;
|
||||
float t2 = uv3.y - uv1.y;
|
||||
|
||||
float div = s1*t2 - s2*t1;
|
||||
float r = (div == 0.0f) ? 0.0f : 1.0f/div;
|
||||
|
||||
Vector3 sdir = { (t2*x1 - t1*x2)*r, (t2*y1 - t1*y2)*r, (t2*z1 - t1*z2)*r };
|
||||
Vector3 tdir = { (s1*x2 - s2*x1)*r, (s1*y2 - s2*y1)*r, (s1*z2 - s2*z1)*r };
|
||||
|
||||
tan1[i + 0] = sdir;
|
||||
tan1[i + 1] = sdir;
|
||||
tan1[i + 2] = sdir;
|
||||
|
||||
tan2[i + 0] = tdir;
|
||||
tan2[i + 1] = tdir;
|
||||
tan2[i + 2] = tdir;
|
||||
}
|
||||
|
||||
// Compute tangents considering normals
|
||||
for (int i = 0; i < mesh->vertexCount; ++i)
|
||||
{
|
||||
Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
|
||||
Vector3 tangent = tan1[i];
|
||||
|
||||
// TODO: Review, not sure if tangent computation is right, just used reference proposed maths...
|
||||
#if defined(COMPUTE_TANGENTS_METHOD_01)
|
||||
Vector3 tmp = Vector3Subtract(tangent, Vector3Multiply(normal, Vector3DotProduct(normal, tangent)));
|
||||
tmp = Vector3Normalize(tmp);
|
||||
mesh->tangents[i*4 + 0] = tmp.x;
|
||||
mesh->tangents[i*4 + 1] = tmp.y;
|
||||
mesh->tangents[i*4 + 2] = tmp.z;
|
||||
mesh->tangents[i*4 + 3] = 1.0f;
|
||||
#else
|
||||
Vector3OrthoNormalize(&normal, &tangent);
|
||||
mesh->tangents[i*4 + 0] = tangent.x;
|
||||
mesh->tangents[i*4 + 1] = tangent.y;
|
||||
mesh->tangents[i*4 + 2] = tangent.z;
|
||||
mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, tangent), tan2[i]) < 0.0f) ? -1.0f : 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
free(tan1);
|
||||
free(tan2);
|
||||
|
||||
TraceLog(LOG_INFO, "Tangents computed for mesh");
|
||||
}
|
||||
|
||||
// Compute mesh binormals
|
||||
// Compute mesh binormals (aka bitangent)
|
||||
void MeshBinormals(Mesh *mesh)
|
||||
{
|
||||
// TODO: Compute mesh binormals
|
||||
for (int i = 0; i < mesh->vertexCount; i++)
|
||||
{
|
||||
Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
|
||||
Vector3 tangent = { mesh->tangents[i*4 + 0], mesh->tangents[i*4 + 1], mesh->tangents[i*4 + 2] };
|
||||
float tangentW = mesh->tangents[i*4 + 3];
|
||||
|
||||
Vector3 binormal = Vector3Multiply(Vector3CrossProduct(normal, tangent), tangentW);
|
||||
|
||||
// TODO: Register computed binormal in mesh->binormal ?
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
86
src/raylib.h
86
src/raylib.h
@@ -6,7 +6,7 @@
|
||||
* - Written in plain C code (C99) in PascalCase/camelCase notation
|
||||
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2 - choose at compile)
|
||||
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
|
||||
* - Powerful fonts module with SpriteFonts support (XNA fonts, AngelCode fonts, TTF)
|
||||
* - Powerful fonts module with Fonts support (XNA fonts, AngelCode fonts, TTF)
|
||||
* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
|
||||
* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
|
||||
* - Flexible Materials system, supporting classic maps and PBR maps
|
||||
@@ -190,7 +190,7 @@
|
||||
#define MOUSE_MIDDLE_BUTTON 2
|
||||
|
||||
// Touch points registered
|
||||
#define MAX_TOUCH_POINTS 2
|
||||
#define MAX_TOUCH_POINTS 2
|
||||
|
||||
// Gamepad Number
|
||||
#define GAMEPAD_PLAYER1 0
|
||||
@@ -349,10 +349,10 @@ typedef struct Color {
|
||||
|
||||
// Rectangle type
|
||||
typedef struct Rectangle {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
float height;
|
||||
} Rectangle;
|
||||
|
||||
// Image type, bpp always RGBA (32bit)
|
||||
@@ -382,7 +382,7 @@ typedef struct RenderTexture2D {
|
||||
Texture2D depth; // Depth buffer attachment texture
|
||||
} RenderTexture2D;
|
||||
|
||||
// SpriteFont character info
|
||||
// Font character info
|
||||
typedef struct CharInfo {
|
||||
int value; // Character value (Unicode)
|
||||
Rectangle rec; // Character rectangle in sprite font
|
||||
@@ -391,22 +391,26 @@ typedef struct CharInfo {
|
||||
int advanceX; // Character advance position X
|
||||
} CharInfo;
|
||||
|
||||
// SpriteFont type, includes texture and charSet array data
|
||||
typedef struct SpriteFont {
|
||||
// Font type, includes texture and charSet array data
|
||||
typedef struct Font {
|
||||
Texture2D texture; // Font texture
|
||||
int baseSize; // Base size (default chars height)
|
||||
int charsCount; // Number of characters
|
||||
CharInfo *chars; // Characters info data
|
||||
} SpriteFont;
|
||||
} Font;
|
||||
|
||||
#define SpriteFont Font // SpriteFont type fallback, defaults to Font
|
||||
|
||||
// Camera type, defines a camera position/orientation in 3d space
|
||||
typedef struct Camera {
|
||||
typedef struct Camera3D {
|
||||
Vector3 position; // Camera position
|
||||
Vector3 target; // Camera target it looks-at
|
||||
Vector3 up; // Camera up vector (rotation over its axis)
|
||||
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||
int type; // Camera type, defines projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
|
||||
} Camera;
|
||||
} Camera3D;
|
||||
|
||||
#define Camera Camera3D // Camera type fallback, defaults to Camera3D
|
||||
|
||||
// Camera2D type, defines a 2d camera
|
||||
typedef struct Camera2D {
|
||||
@@ -726,15 +730,15 @@ RLAPI void DisableCursor(void); // Disables cu
|
||||
RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
|
||||
RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
|
||||
RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
|
||||
RLAPI void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera (2D)
|
||||
RLAPI void End2dMode(void); // Ends 2D mode with custom camera
|
||||
RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode with custom camera (3D)
|
||||
RLAPI void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
|
||||
RLAPI void BeginMode2D(Camera2D camera); // Initialize 2D mode with custom camera (2D)
|
||||
RLAPI void EndMode2D(void); // Ends 2D mode with custom camera
|
||||
RLAPI void BeginMode3D(Camera3D camera); // Initializes 3D mode with custom camera (3D)
|
||||
RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode
|
||||
RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
|
||||
RLAPI void EndTextureMode(void); // Ends drawing to render texture
|
||||
|
||||
// Screen-space-related functions
|
||||
RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
|
||||
RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
|
||||
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
|
||||
RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
|
||||
|
||||
@@ -745,8 +749,8 @@ RLAPI float GetFrameTime(void); // Returns tim
|
||||
RLAPI double GetTime(void); // Returns elapsed time in seconds since InitWindow()
|
||||
|
||||
// Color-related functions
|
||||
RLAPI float *ColorToFloat(Color color); // Returns normalized float array for a Color
|
||||
RLAPI int ColorToInt(Color color); // Returns hexadecimal value for a Color
|
||||
RLAPI Vector4 ColorNormalize(Color color); // Returns color normalized as float [0..1]
|
||||
RLAPI Vector3 ColorToHSV(Color color); // Returns HSV values for a Color
|
||||
RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
|
||||
RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
|
||||
@@ -837,9 +841,7 @@ RLAPI void UpdateCamera(Camera *camera); // Update came
|
||||
RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
|
||||
RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
|
||||
RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
|
||||
RLAPI void SetCameraMoveControls(int frontKey, int backKey,
|
||||
int rightKey, int leftKey,
|
||||
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
|
||||
RLAPI void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic Shapes Drawing Functions (Module: shapes)
|
||||
@@ -901,7 +903,6 @@ RLAPI int GetPixelDataSize(int width, int height, int format);
|
||||
RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
|
||||
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
|
||||
|
||||
|
||||
// Image manipulation functions
|
||||
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
|
||||
RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
@@ -916,12 +917,11 @@ RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight);
|
||||
RLAPI void ImageMipmaps(Image *image); // Generate all mipmap levels for a provided image
|
||||
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
|
||||
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
|
||||
RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
|
||||
RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font)
|
||||
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
|
||||
RLAPI void ImageDrawRectangle(Image *dst, Vector2 position, Rectangle rec, Color color); // Draw rectangle within an image
|
||||
RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
|
||||
RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text,
|
||||
float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
|
||||
RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color); // Draw text (custom sprite font) within an image (destination)
|
||||
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
|
||||
RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
|
||||
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
|
||||
@@ -950,31 +950,30 @@ RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint);
|
||||
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
|
||||
RLAPI void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
|
||||
RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
|
||||
float rotation, Color tint);
|
||||
RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Font Loading and Text Drawing Functions (Module: text)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// SpriteFont loading/unloading functions
|
||||
RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
|
||||
RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM)
|
||||
RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters
|
||||
RLAPI void UnloadSpriteFont(SpriteFont font); // Unload SpriteFont from GPU memory (VRAM)
|
||||
// Font loading/unloading functions
|
||||
RLAPI Font GetDefaultFont(void); // Get the default Font
|
||||
RLAPI Font LoadFont(const char *fileName); // Load Font from file into GPU memory (VRAM)
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load Font from file with extended parameters
|
||||
RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
|
||||
|
||||
// Text drawing functions
|
||||
RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
|
||||
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
|
||||
RLAPI void DrawTextEx(SpriteFont font, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
|
||||
float fontSize, int spacing, Color tint);
|
||||
RLAPI void DrawTextEx(Font font, const char* text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using Font and additional parameters
|
||||
|
||||
// Text misc. functions
|
||||
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
|
||||
RLAPI Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
|
||||
RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
|
||||
RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string
|
||||
RLAPI int GetGlyphIndex(SpriteFont font, int character); // Returns index position for a unicode character on sprite font
|
||||
RLAPI int GetGlyphIndex(Font font, int character); // Returns index position for a unicode character on sprite font
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic 3d Shapes Drawing Functions (Module: models)
|
||||
@@ -1035,23 +1034,19 @@ RLAPI void UnloadMaterial(Material material);
|
||||
|
||||
// Model drawing functions
|
||||
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis,
|
||||
float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis,
|
||||
float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec,
|
||||
Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
|
||||
|
||||
// Collision detection functions
|
||||
RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
|
||||
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
|
||||
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
|
||||
RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
|
||||
RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius,
|
||||
Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
|
||||
RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
|
||||
RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
|
||||
RLAPI RayHitInfo GetCollisionRayModel(Ray ray, Model *model); // Get collision info between ray and model
|
||||
RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||
@@ -1152,8 +1147,7 @@ RLAPI float GetMusicTimeLength(Music music); // Get mus
|
||||
RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
|
||||
|
||||
// AudioStream management functions
|
||||
RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize,
|
||||
unsigned int channels); // Init audio stream (to stream raw audio pcm data)
|
||||
RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data)
|
||||
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
|
||||
RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory
|
||||
RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
|
@@ -1,22 +1,22 @@
|
||||
GLFW_ICON ICON "raylib.ico"
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 1,8,0,0
|
||||
PRODUCTVERSION 1,8,0,0
|
||||
FILEVERSION 2,0,0,0
|
||||
PRODUCTVERSION 2,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
//BLOCK "080904E4" // English UK
|
||||
BLOCK "040904E4" // English US
|
||||
BEGIN
|
||||
//VALUE "CompanyName", "My Company Name"
|
||||
VALUE "CompanyName", "raylib technologies"
|
||||
VALUE "FileDescription", "Created using raylib (www.raylib.com)"
|
||||
VALUE "FileVersion", "1.8.0"
|
||||
VALUE "InternalName", "raylib"
|
||||
VALUE "LegalCopyright", "(c) 2017 Ramon Santamaria - @raysan5"
|
||||
VALUE "FileVersion", "2.0.0"
|
||||
VALUE "InternalName", "raylib app"
|
||||
VALUE "LegalCopyright", "(c) 2018 Ramon Santamaria - @raysan5"
|
||||
//VALUE "OriginalFilename", "raylib_app.exe"
|
||||
VALUE "ProductName", "raylib game"
|
||||
VALUE "ProductVersion", "1.8.0"
|
||||
VALUE "ProductVersion", "2.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Binary file not shown.
@@ -372,6 +372,17 @@ RMDEF Vector3 Vector3Normalize(Vector3 v)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Orthonormalize provided vectors
|
||||
// Makes vectors normalized and orthogonal to each other
|
||||
// Gram-Schmidt function implementation
|
||||
RMDEF void Vector3OrthoNormalize(Vector3 *v1, Vector3 *v2)
|
||||
{
|
||||
*v1 = Vector3Normalize(*v1);
|
||||
Vector3 vn = Vector3CrossProduct(*v1, *v2);
|
||||
vn = Vector3Normalize(vn);
|
||||
*v2 = Vector3CrossProduct(vn, *v1);
|
||||
}
|
||||
|
||||
// Transforms a Vector3 by a given Matrix
|
||||
RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
|
||||
{
|
||||
|
116
src/rlgl.c
116
src/rlgl.c
@@ -85,18 +85,18 @@
|
||||
#define WINGDIAPI __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h> // OpenGL 1.1 library
|
||||
#include <GL/gl.h> // OpenGL 1.1 library
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
#define GRAPHICS_API_OPENGL_33
|
||||
#define GRAPHICS_API_OPENGL_33 // OpenGL 2.1 uses mostly OpenGL 3.3 Core functionality
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
|
||||
#include <OpenGL/gl3ext.h>
|
||||
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
|
||||
#include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX
|
||||
#else
|
||||
#define GLAD_IMPLEMENTATION
|
||||
#if defined(RLGL_STANDALONE)
|
||||
@@ -108,17 +108,17 @@
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#include <EGL/egl.h> // EGL library
|
||||
#include <GLES2/gl2.h> // OpenGL ES 2.0 library
|
||||
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
|
||||
#include <EGL/egl.h> // EGL library
|
||||
#include <GLES2/gl2.h> // OpenGL ES 2.0 library
|
||||
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
|
||||
#endif
|
||||
|
||||
#if defined(RLGL_STANDALONE)
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
|
||||
#endif
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11) && defined(SUPPORT_DISTORTION_SHADER)
|
||||
#include "shader_distortion.h" // Distortion shader to be embedded
|
||||
#include "shader_distortion.h" // Distortion shader to be embedded
|
||||
#endif
|
||||
|
||||
|
||||
@@ -307,17 +307,17 @@ static bool vrStereoRender = false; // VR stereo rendering enabled/disabled
|
||||
|
||||
// Extension supported flag: Anisotropic filtering
|
||||
static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support
|
||||
static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supported (minimum is 2.0f)
|
||||
static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supported (minimum is 2.0f)
|
||||
|
||||
// Extension supported flag: Clamp mirror wrap mode
|
||||
static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported
|
||||
static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: VAO functionality is exposed through extensions (OES)
|
||||
static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
|
||||
static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
|
||||
static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
|
||||
//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted
|
||||
//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted
|
||||
#endif
|
||||
|
||||
static bool debugMarkerSupported = false;
|
||||
@@ -658,13 +658,11 @@ void rlEnd(void)
|
||||
// Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits)
|
||||
currentDepth += (1.0f/20000.0f);
|
||||
|
||||
// TODO: Verify internal buffers limits
|
||||
// NOTE: Before launching draw, verify no matrix are left in the stack!
|
||||
// NOTE: Probably a lines/triangles margin should be left, rlEnd could be called
|
||||
// after an undetermined number of triangles buffered (check shapes::DrawPoly())
|
||||
// Verify internal buffers limits
|
||||
// NOTE: This check is combined with usage of rlCheckBufferLimit()
|
||||
if ((lines.vCounter/2 >= MAX_LINES_BATCH - 2) ||
|
||||
(triangles.vCounter/3 >= MAX_TRIANGLES_BATCH - 16) ||
|
||||
(quads.vCounter/4 >= MAX_QUADS_BATCH - 2)) rlglDraw();
|
||||
(triangles.vCounter/3 >= MAX_TRIANGLES_BATCH - 3) ||
|
||||
(quads.vCounter/4 >= MAX_QUADS_BATCH - 4)) rlglDraw();
|
||||
}
|
||||
|
||||
// Define one vertex (position)
|
||||
@@ -1313,6 +1311,22 @@ int rlGetVersion(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check internal buffer overflow for a given number of vertex
|
||||
bool rlCheckBufferLimit(int type, int vCount)
|
||||
{
|
||||
bool overflow = false;
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
switch (type)
|
||||
{
|
||||
case RL_LINES: overflow = ((lines.vCounter + vCount)/2 >= MAX_LINES_BATCH); break;
|
||||
case RL_TRIANGLES: overflow = ((triangles.vCounter + vCount)/3 >= MAX_TRIANGLES_BATCH); break;
|
||||
case RL_QUADS: overflow = ((quads.vCounter + vCount)/4 >= MAX_QUADS_BATCH); break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
return overflow;
|
||||
}
|
||||
|
||||
// Set debug marker
|
||||
void rlSetDebugMarker(const char *text)
|
||||
{
|
||||
@@ -1325,7 +1339,7 @@ void rlSetDebugMarker(const char *text)
|
||||
// NOTE: External loader function could be passed as a pointer
|
||||
void rlLoadExtensions(void *loader)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33)
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
|
||||
#if !defined(__APPLE__)
|
||||
if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
|
||||
@@ -1456,7 +1470,11 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
|
||||
}
|
||||
else if (format == UNCOMPRESSED_GRAY_ALPHA)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA };
|
||||
#elif defined(GRAPHICS_API_OPENGL_33)
|
||||
GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
|
||||
#endif
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
#endif
|
||||
@@ -1648,37 +1666,40 @@ void rlGenerateMipmaps(Texture2D *texture)
|
||||
if ((texIsPOT) || (texNPOTSupported))
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
// Compute required mipmaps
|
||||
void *data = rlReadTexturePixels(*texture);
|
||||
|
||||
// NOTE: data size is reallocated to fit mipmaps data
|
||||
// NOTE: CPU mipmap generation only supports RGBA 32bit data
|
||||
int mipmapCount = GenerateMipmaps(data, texture->width, texture->height);
|
||||
|
||||
int size = texture->width*texture->height*4; // RGBA 32bit only
|
||||
int offset = size;
|
||||
|
||||
int mipWidth = texture->width/2;
|
||||
int mipHeight = texture->height/2;
|
||||
|
||||
// Load the mipmaps
|
||||
for (int level = 1; level < mipmapCount; level++)
|
||||
// WARNING: Manual mipmap generation only works for RGBA 32bit textures!
|
||||
if (texture->format == UNCOMPRESSED_R8G8B8A8)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data + offset);
|
||||
// Retrieve texture data from VRAM
|
||||
void *data = rlReadTexturePixels(*texture);
|
||||
|
||||
// NOTE: data size is reallocated to fit mipmaps data
|
||||
// NOTE: CPU mipmap generation only supports RGBA 32bit data
|
||||
int mipmapCount = GenerateMipmaps(data, texture->width, texture->height);
|
||||
|
||||
size = mipWidth*mipHeight*4;
|
||||
offset += size;
|
||||
int size = texture->width*texture->height*4;
|
||||
int offset = size;
|
||||
|
||||
mipWidth /= 2;
|
||||
mipHeight /= 2;
|
||||
int mipWidth = texture->width/2;
|
||||
int mipHeight = texture->height/2;
|
||||
|
||||
// Load the mipmaps
|
||||
for (int level = 1; level < mipmapCount; level++)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data + offset);
|
||||
|
||||
size = mipWidth*mipHeight*4;
|
||||
offset += size;
|
||||
|
||||
mipWidth /= 2;
|
||||
mipHeight /= 2;
|
||||
}
|
||||
|
||||
texture->mipmaps = mipmapCount + 1;
|
||||
free(data); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
|
||||
|
||||
TraceLog(LOG_WARNING, "[TEX ID %i] Mipmaps [%i] generated manually on CPU side", texture->id, texture->mipmaps);
|
||||
}
|
||||
|
||||
TraceLog(LOG_WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", texture->id);
|
||||
|
||||
// NOTE: Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
|
||||
free(data);
|
||||
|
||||
texture->mipmaps = mipmapCount + 1;
|
||||
else TraceLog(LOG_WARNING, "[TEX ID %i] Mipmaps could not be generated for texture format", texture->id);
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
@@ -1947,7 +1968,7 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||
if (material.shader.locs[LOC_MATRIX_PROJECTION] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_PROJECTION], projection);
|
||||
|
||||
// At this point the modelview matrix just contains the view matrix (camera)
|
||||
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
||||
// That's because BeginMode3D() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
||||
Matrix matView = modelview; // View matrix (camera)
|
||||
Matrix matProjection = projection; // Projection matrix (perspective)
|
||||
|
||||
@@ -4058,6 +4079,7 @@ static void GetGlFormats(int format, int *glInternalFormat, int *glFormat, int *
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
// Mipmaps data is generated after image data
|
||||
// NOTE: Only works with RGBA (4 bytes) data!
|
||||
static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
|
||||
{
|
||||
int mipmapCount = 1; // Required mipmap levels count (including base level)
|
||||
|
@@ -424,6 +424,7 @@ void rlglClose(void); // De-inititialize rlgl (buffers
|
||||
void rlglDraw(void); // Update and Draw default buffers (lines, triangles, quads)
|
||||
|
||||
int rlGetVersion(void); // Returns current OpenGL version
|
||||
bool rlCheckBufferLimit(int type, int vCount); // Check internal buffer overflow for a given number of vertex
|
||||
void rlSetDebugMarker(const char *text); // Set debug marker for analysis
|
||||
void rlLoadExtensions(void *loader); // Load OpenGL extensions
|
||||
Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
|
||||
|
377
src/shapes.c
377
src/shapes.c
@@ -4,10 +4,13 @@
|
||||
*
|
||||
* CONFIGURATION:
|
||||
*
|
||||
* #define USE_DEFAULT_FONT_TEXTURE
|
||||
* #define 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!
|
||||
*
|
||||
* #define SUPPORT_QUADS_DRAW_MODE
|
||||
* Use QUADS instead of TRIANGLES for drawing when possible.
|
||||
* Some lines-based shapes could still use lines
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
@@ -30,13 +33,12 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#include "raylib.h" // Declares module functions
|
||||
|
||||
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
|
||||
|
||||
#include <stdlib.h> // Required for: abs()
|
||||
#include <stdlib.h> // Required for: abs(), fabs()
|
||||
#include <math.h> // Required for: sinf(), cosf(), sqrtf()
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@@ -171,6 +173,8 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
|
||||
// NOTE: Gradient goes from center (color1) to border (color2)
|
||||
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
|
||||
{
|
||||
if (rlCheckBufferLimit(RL_TRIANGLES, 3*36)) rlglDraw();
|
||||
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
@@ -187,43 +191,46 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
|
||||
// Draw a color-filled circle (Vector version)
|
||||
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
|
||||
void DrawCircleV(Vector2 center, float radius, Color color)
|
||||
{
|
||||
if (rlGetVersion() == OPENGL_11)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
|
||||
{
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
{
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
if (rlCheckBufferLimit(RL_QUADS, 4*(36/2))) rlglDraw();
|
||||
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
for (int i = 0; i < 360; i += 20)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(i + 20))*radius, center.y + cosf(DEG2RAD*(i + 20))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
rlBegin(RL_QUADS);
|
||||
for (int i = 0; i < 360; i += 20)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(i + 20))*radius, center.y + cosf(DEG2RAD*(i + 20))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
|
||||
rlDisableTexture();
|
||||
}
|
||||
rlDisableTexture();
|
||||
#else
|
||||
if (rlCheckBufferLimit(RL_TRIANGLES, 3*(36/2))) rlglDraw();
|
||||
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw circle outline
|
||||
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
||||
{
|
||||
if (rlCheckBufferLimit(RL_LINES, 2*36)) rlglDraw();
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
@@ -249,72 +256,69 @@ void DrawRectangle(int posX, int posY, int width, int height, Color color)
|
||||
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
|
||||
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
||||
{
|
||||
if (rlGetVersion() == OPENGL_11)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
#if defined(SUPPORT_FONT_TEXTURE)
|
||||
// Draw rectangle using font texture white character
|
||||
rlEnableTexture(GetDefaultFont().texture.id);
|
||||
|
||||
rlVertex2i(position.x, position.y);
|
||||
rlVertex2i(position.x, position.y + size.y);
|
||||
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f);
|
||||
|
||||
rlVertex2i(position.x, position.y);
|
||||
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||
rlVertex2i(position.x + size.x, position.y);
|
||||
rlEnd();
|
||||
}
|
||||
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
|
||||
{
|
||||
#if defined(USE_DEFAULT_FONT_TEXTURE)
|
||||
// Draw rectangle using font texture white character
|
||||
rlEnableTexture(GetDefaultFont().texture.id);
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f);
|
||||
|
||||
// NOTE: Default raylib font character 95 is a white square
|
||||
rlTexCoord2f((float)GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(float)GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x, position.y);
|
||||
|
||||
rlTexCoord2f((float)GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(float)(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f((float)(GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(float)(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x + size.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f((float)(GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(float)GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x + size.x, position.y);
|
||||
rlEnd();
|
||||
// NOTE: Default raylib font character 95 is a white square
|
||||
rlTexCoord2f((float)GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(float)GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x, position.y);
|
||||
|
||||
rlDisableTexture();
|
||||
rlTexCoord2f((float)GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(float)(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f((float)(GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(float)(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x + size.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f((float)(GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(float)GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlVertex2f(position.x + size.x, position.y);
|
||||
rlEnd();
|
||||
|
||||
rlDisableTexture();
|
||||
#else
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f);
|
||||
|
||||
rlTexCoord2f(0.0f, 0.0f);
|
||||
rlVertex2f(position.x, position.y);
|
||||
|
||||
rlTexCoord2f(0.0f, 1.0f);
|
||||
rlVertex2f(position.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f(1.0f, 1.0f);
|
||||
rlVertex2f(position.x + size.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f(1.0f, 0.0f);
|
||||
rlVertex2f(position.x + size.x, position.y);
|
||||
rlEnd();
|
||||
|
||||
rlDisableTexture();
|
||||
#endif // SUPPORT_FONT_TEXTURE
|
||||
#else
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
rlBegin(RL_TRIANGLES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f);
|
||||
rlVertex2i(position.x, position.y);
|
||||
rlVertex2i(position.x, position.y + size.y);
|
||||
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f(0.0f, 0.0f);
|
||||
rlVertex2f(position.x, position.y);
|
||||
|
||||
rlTexCoord2f(0.0f, 1.0f);
|
||||
rlVertex2f(position.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f(1.0f, 1.0f);
|
||||
rlVertex2f(position.x + size.x, position.y + size.y);
|
||||
|
||||
rlTexCoord2f(1.0f, 0.0f);
|
||||
rlVertex2f(position.x + size.x, position.y);
|
||||
rlEnd();
|
||||
|
||||
rlDisableTexture();
|
||||
#endif
|
||||
}
|
||||
rlVertex2i(position.x, position.y);
|
||||
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||
rlVertex2i(position.x + size.x, position.y);
|
||||
rlEnd();
|
||||
#endif // SUPPORT_QUADS_DRAW_MODE
|
||||
}
|
||||
|
||||
// Draw a color-filled rectangle
|
||||
@@ -328,7 +332,7 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
|
||||
rlEnableTexture(GetTextureDefault().id);
|
||||
|
||||
rlPushMatrix();
|
||||
rlTranslatef((float)rec.x, (float)rec.y, 0);
|
||||
rlTranslatef(rec.x, rec.y, 0);
|
||||
rlRotatef(rotation, 0, 0, 1);
|
||||
rlTranslatef(-origin.x, -origin.y, 0);
|
||||
|
||||
@@ -337,9 +341,9 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
||||
|
||||
rlVertex2f(0.0f, 0.0f);
|
||||
rlVertex2f(0.0f, (float)rec.height);
|
||||
rlVertex2f((float)rec.width, (float)rec.height);
|
||||
rlVertex2f((float)rec.width, 0.0f);
|
||||
rlVertex2f(0.0f, rec.height);
|
||||
rlVertex2f(rec.width, rec.height);
|
||||
rlVertex2f(rec.width, 0.0f);
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
|
||||
@@ -364,7 +368,7 @@ void DrawRectangleGradientH(int posX, int posY, int width, int height, Color col
|
||||
// NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise
|
||||
void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4)
|
||||
{
|
||||
#if defined(USE_DEFAULT_FONT_TEXTURE)
|
||||
#if defined(SUPPORT_FONT_TEXTURE)
|
||||
// Draw rectangle using font texture white character
|
||||
rlEnableTexture(GetDefaultFont().texture.id);
|
||||
|
||||
@@ -373,23 +377,23 @@ void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3,
|
||||
|
||||
// NOTE: Default raylib font character 95 is a white square
|
||||
rlColor4ub(col1.r, col1.g, col1.b, col1.a);
|
||||
rlTexCoord2f((float)GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(float)GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlTexCoord2f(GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlVertex2f(rec.x, rec.y);
|
||||
|
||||
rlColor4ub(col2.r, col2.g, col2.b, col2.a);
|
||||
rlTexCoord2f((float)GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(float)(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlTexCoord2f(GetDefaultFont().chars[95].rec.x/GetDefaultFont().texture.width,
|
||||
(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlVertex2f(rec.x, rec.y + rec.height);
|
||||
|
||||
rlColor4ub(col3.r, col3.g, col3.b, col3.a);
|
||||
rlTexCoord2f((float)(GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(float)(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlTexCoord2f((GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(GetDefaultFont().chars[95].rec.y + GetDefaultFont().chars[95].rec.height)/GetDefaultFont().texture.height);
|
||||
rlVertex2f(rec.x + rec.width, rec.y + rec.height);
|
||||
|
||||
rlColor4ub(col4.r, col4.g, col4.b, col4.a);
|
||||
rlTexCoord2f((float)(GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
(float)GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlTexCoord2f((GetDefaultFont().chars[95].rec.x + GetDefaultFont().chars[95].rec.width)/GetDefaultFont().texture.width,
|
||||
GetDefaultFont().chars[95].rec.y/GetDefaultFont().texture.height);
|
||||
rlVertex2f(rec.x + rec.width, rec.y);
|
||||
rlEnd();
|
||||
|
||||
@@ -425,30 +429,27 @@ void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3,
|
||||
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
|
||||
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
|
||||
{
|
||||
if (rlGetVersion() == OPENGL_11)
|
||||
{
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2i(posX + 1, posY + 1);
|
||||
rlVertex2i(posX + width, posY + 1);
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
DrawRectangle(posX, posY, width, 1, color);
|
||||
DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color);
|
||||
DrawRectangle(posX, posY + height - 1, width, 1, color);
|
||||
DrawRectangle(posX, posY + 1, 1, height - 2, color);
|
||||
#else
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2i(posX + 1, posY + 1);
|
||||
rlVertex2i(posX + width, posY + 1);
|
||||
|
||||
rlVertex2i(posX + width, posY + 1);
|
||||
rlVertex2i(posX + width, posY + height);
|
||||
rlVertex2i(posX + width, posY + 1);
|
||||
rlVertex2i(posX + width, posY + height);
|
||||
|
||||
rlVertex2i(posX + width, posY + height);
|
||||
rlVertex2i(posX + 1, posY + height);
|
||||
rlVertex2i(posX + width, posY + height);
|
||||
rlVertex2i(posX + 1, posY + height);
|
||||
|
||||
rlVertex2i(posX + 1, posY + height);
|
||||
rlVertex2i(posX + 1, posY + 1);
|
||||
rlEnd();
|
||||
}
|
||||
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
|
||||
{
|
||||
DrawRectangle(posX, posY, width, 1, color);
|
||||
DrawRectangle(posX + width - 1, posY + 1, 1, height - 2, color);
|
||||
DrawRectangle(posX, posY + height - 1, width, 1, color);
|
||||
DrawRectangle(posX, posY + 1, 1, height - 2, color);
|
||||
}
|
||||
rlVertex2i(posX + 1, posY + height);
|
||||
rlVertex2i(posX + 1, posY + 1);
|
||||
rlEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw rectangle outline with extended parameters
|
||||
@@ -469,31 +470,29 @@ void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color)
|
||||
// Draw a triangle
|
||||
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
||||
{
|
||||
if (rlGetVersion() == OPENGL_11)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(v1.x, v1.y);
|
||||
rlVertex2f(v2.x, v2.y);
|
||||
rlVertex2f(v3.x, v3.y);
|
||||
rlEnd();
|
||||
}
|
||||
else if ((rlGetVersion() == OPENGL_21) || (rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
|
||||
{
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(v1.x, v1.y);
|
||||
rlVertex2f(v2.x, v2.y);
|
||||
rlVertex2f(v2.x, v2.y);
|
||||
rlVertex2f(v3.x, v3.y);
|
||||
rlEnd();
|
||||
|
||||
rlDisableTexture();
|
||||
}
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(v1.x, v1.y);
|
||||
rlVertex2f(v2.x, v2.y);
|
||||
rlVertex2f(v2.x, v2.y);
|
||||
rlVertex2f(v3.x, v3.y);
|
||||
rlEnd();
|
||||
|
||||
rlDisableTexture();
|
||||
#else
|
||||
rlBegin(RL_TRIANGLES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(v1.x, v1.y);
|
||||
rlVertex2f(v2.x, v2.y);
|
||||
rlVertex2f(v3.x, v3.y);
|
||||
rlEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw a triangle using lines
|
||||
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
||||
{
|
||||
rlBegin(RL_LINES);
|
||||
@@ -513,11 +512,29 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
||||
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color)
|
||||
{
|
||||
if (sides < 3) sides = 3;
|
||||
|
||||
if (rlCheckBufferLimit(RL_QUADS, 4*(360/sides))) rlglDraw();
|
||||
|
||||
rlPushMatrix();
|
||||
rlTranslatef(center.x, center.y, 0.0);
|
||||
rlRotatef(rotation, 0, 0, 1);
|
||||
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
for (int i = 0; i < 360; i += 360/sides)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2f(0, 0);
|
||||
rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius);
|
||||
rlVertex2f(sinf(DEG2RAD*(i + 360/sides))*radius, cosf(DEG2RAD*(i + 360/sides))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
rlDisableTexture();
|
||||
#else
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i = 0; i < 360; i += 360/sides)
|
||||
{
|
||||
@@ -528,38 +545,58 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
||||
rlVertex2f(sinf(DEG2RAD*(i + 360/sides))*radius, cosf(DEG2RAD*(i + 360/sides))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
#endif
|
||||
rlPopMatrix();
|
||||
}
|
||||
|
||||
// Draw a closed polygon defined by points
|
||||
// NOTE: Array num elements MUST be passed as parameter to function
|
||||
void DrawPolyEx(Vector2 *points, int numPoints, Color color)
|
||||
void DrawPolyEx(Vector2 *points, int pointsCount, Color color)
|
||||
{
|
||||
if (numPoints >= 3)
|
||||
if (pointsCount >= 3)
|
||||
{
|
||||
if (rlCheckBufferLimit(RL_QUADS, pointsCount)) rlglDraw();
|
||||
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
rlEnableTexture(GetTextureDefault().id); // Default white texture
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
for (int i = 1; i < pointsCount - 1; i++)
|
||||
{
|
||||
rlVertex2f(points[0].x, points[0].y);
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i + 1].x, points[i + 1].y);
|
||||
}
|
||||
rlEnd();
|
||||
rlDisableTexture();
|
||||
#else
|
||||
rlBegin(RL_TRIANGLES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
for (int i = 1; i < numPoints - 1; i++)
|
||||
for (int i = 1; i < pointsCount - 1; i++)
|
||||
{
|
||||
rlVertex2f(points[0].x, points[0].y);
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i + 1].x, points[i + 1].y);
|
||||
}
|
||||
rlEnd();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Draw polygon lines
|
||||
// NOTE: Array num elements MUST be passed as parameter to function
|
||||
void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
|
||||
// Draw polygon using lines
|
||||
void DrawPolyExLines(Vector2 *points, int pointsCount, Color color)
|
||||
{
|
||||
if (numPoints >= 2)
|
||||
if (pointsCount >= 2)
|
||||
{
|
||||
if (rlCheckBufferLimit(RL_LINES, pointsCount)) rlglDraw();
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
for (int i = 0; i < numPoints - 1; i++)
|
||||
for (int i = 0; i < pointsCount - 1; i++)
|
||||
{
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i + 1].x, points[i + 1].y);
|
||||
@@ -611,8 +648,8 @@ bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
|
||||
{
|
||||
bool collision = false;
|
||||
|
||||
int dx = abs((rec1.x + rec1.width/2) - (rec2.x + rec2.width/2));
|
||||
int dy = abs((rec1.y + rec1.height/2) - (rec2.y + rec2.height/2));
|
||||
float dx = fabsf((rec1.x + rec1.width/2) - (rec2.x + rec2.width/2));
|
||||
float dy = fabsf((rec1.y + rec1.height/2) - (rec2.y + rec2.height/2));
|
||||
|
||||
if ((dx <= (rec1.width/2 + rec2.width/2)) && ((dy <= (rec1.height/2 + rec2.height/2)))) collision = true;
|
||||
|
||||
@@ -644,14 +681,14 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
|
||||
float dx = fabsf(center.x - recCenterX);
|
||||
float dy = fabsf(center.y - recCenterY);
|
||||
|
||||
if (dx > ((float)rec.width/2.0f + radius)) { return false; }
|
||||
if (dy > ((float)rec.height/2.0f + radius)) { return false; }
|
||||
if (dx > (rec.width/2.0f + radius)) { return false; }
|
||||
if (dy > (rec.height/2.0f + radius)) { return false; }
|
||||
|
||||
if (dx <= ((float)rec.width/2.0f)) { return true; }
|
||||
if (dy <= ((float)rec.height/2.0f)) { return true; }
|
||||
if (dx <= (rec.width/2.0f)) { return true; }
|
||||
if (dy <= (rec.height/2.0f)) { return true; }
|
||||
|
||||
float cornerDistanceSq = (dx - (float)rec.width/2.0f)*(dx - (float)rec.width/2.0f) +
|
||||
(dy - (float)rec.height/2.0f)*(dy - (float)rec.height/2.0f);
|
||||
float cornerDistanceSq = (dx - rec.width/2.0f)*(dx - rec.width/2.0f) +
|
||||
(dy - rec.height/2.0f)*(dy - rec.height/2.0f);
|
||||
|
||||
return (cornerDistanceSq <= (radius*radius));
|
||||
}
|
||||
@@ -663,8 +700,8 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
|
||||
|
||||
if (CheckCollisionRecs(rec1, rec2))
|
||||
{
|
||||
int dxx = abs(rec1.x - rec2.x);
|
||||
int dyy = abs(rec1.y - rec2.y);
|
||||
float dxx = fabsf(rec1.x - rec2.x);
|
||||
float dyy = fabsf(rec1.y - rec2.y);
|
||||
|
||||
if (rec1.x <= rec2.x)
|
||||
{
|
||||
|
100
src/text.c
100
src/text.c
@@ -1,6 +1,6 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.text - Basic functions to load SpriteFonts and draw Text
|
||||
* raylib.text - Basic functions to load Fonts and draw Text
|
||||
*
|
||||
* CONFIGURATION:
|
||||
*
|
||||
@@ -36,9 +36,8 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#include "raylib.h" // Declares module functions
|
||||
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
#include <string.h> // Required for: strlen()
|
||||
@@ -73,7 +72,7 @@
|
||||
// Global variables
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
static SpriteFont defaultFont; // Default font provided by raylib
|
||||
static Font defaultFont; // Default font provided by raylib
|
||||
// NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
|
||||
#endif
|
||||
|
||||
@@ -85,12 +84,12 @@ static SpriteFont defaultFont; // Default font provided by raylib
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
|
||||
static Font LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
|
||||
#if defined(SUPPORT_FILEFORMAT_FNT)
|
||||
static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_TTF)
|
||||
static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data
|
||||
static Font LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
@@ -114,7 +113,7 @@ extern void LoadDefaultFont(void)
|
||||
defaultFont.charsCount = 224; // Number of chars included in our default font
|
||||
|
||||
// Default font is directly defined here (data generated from a sprite font image)
|
||||
// This way, we reconstruct SpriteFont without creating large global variables
|
||||
// This way, we reconstruct Font without creating large global variables
|
||||
// This data is automatically allocated to Stack and automatically deallocated at the end of this function
|
||||
int defaultFontData[512] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
|
||||
@@ -261,28 +260,28 @@ extern void UnloadDefaultFont(void)
|
||||
#endif // SUPPORT_DEFAULT_FONT
|
||||
|
||||
// Get the default font, useful to be used with extended parameters
|
||||
SpriteFont GetDefaultFont()
|
||||
Font GetDefaultFont()
|
||||
{
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
return defaultFont;
|
||||
#else
|
||||
SpriteFont font = { 0 };
|
||||
Font font = { 0 };
|
||||
return font;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Load SpriteFont from file into GPU memory (VRAM)
|
||||
SpriteFont LoadSpriteFont(const char *fileName)
|
||||
// Load Font from file into GPU memory (VRAM)
|
||||
Font LoadFont(const char *fileName)
|
||||
{
|
||||
// Default hardcoded values for ttf file loading
|
||||
#define DEFAULT_TTF_FONTSIZE 32 // Font first character (32 - space)
|
||||
#define DEFAULT_TTF_NUMCHARS 95 // ASCII 32..126 is 95 glyphs
|
||||
#define DEFAULT_FIRST_CHAR 32 // Expected first char for image spritefont
|
||||
|
||||
SpriteFont spriteFont = { 0 };
|
||||
Font spriteFont = { 0 };
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_TTF)
|
||||
if (IsFileExtension(fileName, ".ttf")) spriteFont = LoadSpriteFontEx(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL);
|
||||
if (IsFileExtension(fileName, ".ttf")) spriteFont = LoadFontEx(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL);
|
||||
else
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_FNT)
|
||||
@@ -297,7 +296,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
|
||||
if (spriteFont.texture.id == 0)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName);
|
||||
TraceLog(LOG_WARNING, "[%s] Font could not be loaded, using default font", fileName);
|
||||
spriteFont = GetDefaultFont();
|
||||
}
|
||||
else SetTextureFilter(spriteFont.texture, FILTER_POINT); // By default we set point filter (best performance)
|
||||
@@ -305,12 +304,12 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
return spriteFont;
|
||||
}
|
||||
|
||||
// Load SpriteFont from TTF font file with generation parameters
|
||||
// Load Font from TTF font file with generation parameters
|
||||
// NOTE: You can pass an array with desired characters, those characters should be available in the font
|
||||
// if array is NULL, default char set is selected 32..126
|
||||
SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars)
|
||||
Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars)
|
||||
{
|
||||
SpriteFont spriteFont = { 0 };
|
||||
Font spriteFont = { 0 };
|
||||
int totalChars = 95; // Default charset [32..126]
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_TTF)
|
||||
@@ -330,15 +329,15 @@ SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount,
|
||||
|
||||
if (spriteFont.texture.id == 0)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "[%s] SpriteFont could not be generated, using default font", fileName);
|
||||
TraceLog(LOG_WARNING, "[%s] Font could not be generated, using default font", fileName);
|
||||
spriteFont = GetDefaultFont();
|
||||
}
|
||||
|
||||
return spriteFont;
|
||||
}
|
||||
|
||||
// Unload SpriteFont from GPU memory (VRAM)
|
||||
void UnloadSpriteFont(SpriteFont font)
|
||||
// Unload Font from GPU memory (VRAM)
|
||||
void UnloadFont(Font font)
|
||||
{
|
||||
// NOTE: Make sure spriteFont is not default font (fallback)
|
||||
if (font.texture.id != GetDefaultFont().texture.id)
|
||||
@@ -364,13 +363,13 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
|
||||
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||
int spacing = fontSize/defaultFontSize;
|
||||
|
||||
DrawTextEx(GetDefaultFont(), text, position, (float)fontSize, spacing, color);
|
||||
DrawTextEx(GetDefaultFont(), text, position, (float)fontSize, (float)spacing, color);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw text using SpriteFont
|
||||
// Draw text using Font
|
||||
// NOTE: chars spacing is NOT proportional to fontSize
|
||||
void DrawTextEx(SpriteFont font, const char *text, Vector2 position, float fontSize, int spacing, Color tint)
|
||||
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint)
|
||||
{
|
||||
int length = strlen(text);
|
||||
int textOffsetX = 0; // Offset between characters
|
||||
@@ -476,14 +475,14 @@ int MeasureText(const char *text, int fontSize)
|
||||
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||
int spacing = fontSize/defaultFontSize;
|
||||
|
||||
vec = MeasureTextEx(GetDefaultFont(), text, (float)fontSize, spacing);
|
||||
vec = MeasureTextEx(GetDefaultFont(), text, (float)fontSize, (float)spacing);
|
||||
}
|
||||
|
||||
return (int)vec.x;
|
||||
}
|
||||
|
||||
// Measure string size for SpriteFont
|
||||
Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing)
|
||||
// Measure string size for Font
|
||||
Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing)
|
||||
{
|
||||
int len = strlen(text);
|
||||
int tempLen = 0; // Used to count longer text line num chars
|
||||
@@ -527,7 +526,7 @@ Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spa
|
||||
}
|
||||
|
||||
// Returns index position for a unicode character on spritefont
|
||||
int GetGlyphIndex(SpriteFont font, int character)
|
||||
int GetGlyphIndex(Font font, int character)
|
||||
{
|
||||
#define UNORDERED_CHARSET
|
||||
#if defined(UNORDERED_CHARSET)
|
||||
@@ -575,7 +574,7 @@ void DrawFPS(int posX, int posY)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Load an Image font file (XNA style)
|
||||
static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
||||
static Font LoadImageFont(Image image, Color key, int firstChar)
|
||||
{
|
||||
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
|
||||
|
||||
@@ -648,7 +647,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
||||
xPosToRead = charSpacing;
|
||||
}
|
||||
|
||||
TraceLog(LOG_DEBUG, "SpriteFont data parsed correctly from image");
|
||||
TraceLog(LOG_DEBUG, "Font data parsed correctly from image");
|
||||
|
||||
// NOTE: We need to remove key color borders from image to avoid weird
|
||||
// artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
|
||||
@@ -660,7 +659,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
||||
free(pixels); // Free pixels array memory
|
||||
|
||||
// Create spritefont with all data parsed from image
|
||||
SpriteFont spriteFont = { 0 };
|
||||
Font spriteFont = { 0 };
|
||||
|
||||
spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
||||
spriteFont.charsCount = index;
|
||||
@@ -684,18 +683,18 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
||||
|
||||
spriteFont.baseSize = spriteFont.chars[0].rec.height;
|
||||
|
||||
TraceLog(LOG_INFO, "Image file loaded correctly as SpriteFont");
|
||||
TraceLog(LOG_INFO, "Image file loaded correctly as Font");
|
||||
|
||||
return spriteFont;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_FNT)
|
||||
// Load a BMFont file (AngelCode font file)
|
||||
static SpriteFont LoadBMFont(const char *fileName)
|
||||
static Font LoadBMFont(const char *fileName)
|
||||
{
|
||||
#define MAX_BUFFER_SIZE 256
|
||||
|
||||
SpriteFont font = { 0 };
|
||||
Font font = { 0 };
|
||||
font.texture.id = 0;
|
||||
|
||||
char buffer[MAX_BUFFER_SIZE];
|
||||
@@ -764,22 +763,23 @@ static SpriteFont LoadBMFont(const char *fileName)
|
||||
{
|
||||
Image imCopy = ImageCopy(imFont);
|
||||
|
||||
for (int i = 0; i < imCopy.width*imCopy.height; i++) ((unsigned char *)imCopy.data)[i] = 0xff; // WHITE pixel
|
||||
for (int i = 0; i < imCopy.width*imCopy.height; i++) ((unsigned char *)imCopy.data)[i] = 0xff;
|
||||
|
||||
ImageAlphaMask(&imCopy, imFont);
|
||||
font.texture = LoadTextureFromImage(imCopy);
|
||||
UnloadImage(imCopy);
|
||||
}
|
||||
else font.texture = LoadTextureFromImage(imFont);
|
||||
|
||||
UnloadImage(imFont);
|
||||
free(texPath);
|
||||
|
||||
|
||||
// Fill font characters info data
|
||||
font.baseSize = fontSize;
|
||||
font.charsCount = charsCount;
|
||||
font.chars = (CharInfo *)malloc(charsCount*sizeof(CharInfo));
|
||||
|
||||
UnloadImage(imFont);
|
||||
|
||||
free(texPath);
|
||||
|
||||
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
|
||||
|
||||
for (int i = 0; i < charsCount; i++)
|
||||
@@ -800,10 +800,10 @@ static SpriteFont LoadBMFont(const char *fileName)
|
||||
|
||||
if (font.texture.id == 0)
|
||||
{
|
||||
UnloadSpriteFont(font);
|
||||
UnloadFont(font);
|
||||
font = GetDefaultFont();
|
||||
}
|
||||
else TraceLog(LOG_INFO, "[%s] SpriteFont loaded successfully", fileName);
|
||||
else TraceLog(LOG_INFO, "[%s] Font loaded successfully", fileName);
|
||||
|
||||
return font;
|
||||
}
|
||||
@@ -812,7 +812,7 @@ static SpriteFont LoadBMFont(const char *fileName)
|
||||
#if defined(SUPPORT_FILEFORMAT_TTF)
|
||||
// Generate a sprite font from TTF file data (font size required)
|
||||
// TODO: Review texture packing method and generation (use oversampling)
|
||||
static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars)
|
||||
static Font LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars)
|
||||
{
|
||||
#define MAX_TTF_SIZE 16 // Maximum ttf file size in MB
|
||||
|
||||
@@ -830,7 +830,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in
|
||||
unsigned char *dataBitmap = (unsigned char *)malloc(textureSize*textureSize*sizeof(unsigned char)); // One channel bitmap returned!
|
||||
stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*charsCount);
|
||||
|
||||
SpriteFont font = { 0 };
|
||||
Font font = { 0 };
|
||||
|
||||
FILE *ttfFile = fopen(fileName, "rb");
|
||||
|
||||
@@ -871,7 +871,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in
|
||||
|
||||
for (int i = 0, k = 0; i < textureSize*textureSize; i++, k += 2)
|
||||
{
|
||||
dataGrayAlpha[k] = 255;
|
||||
dataGrayAlpha[k] = 0xff;
|
||||
dataGrayAlpha[k + 1] = dataBitmap[i];
|
||||
}
|
||||
|
||||
@@ -884,13 +884,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in
|
||||
image.mipmaps = 1;
|
||||
image.format = UNCOMPRESSED_GRAY_ALPHA;
|
||||
image.data = dataGrayAlpha;
|
||||
font.texture = LoadTextureFromImage(image); // Load image into texture
|
||||
UnloadImage(image); // Unloads image data (dataGrayAlpha)
|
||||
|
||||
font.texture = LoadTextureFromImage(image);
|
||||
|
||||
//SavePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2);
|
||||
|
||||
UnloadImage(image); // Unloads dataGrayAlpha
|
||||
|
||||
|
||||
// Fill font characters info data
|
||||
font.baseSize = fontSize;
|
||||
font.charsCount = charsCount;
|
||||
font.chars = (CharInfo *)malloc(font.charsCount*sizeof(CharInfo));
|
||||
|
119
src/textures.c
119
src/textures.c
@@ -52,9 +52,9 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
#include "config.h"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "config.h" // Defines module configuration flags
|
||||
#include "raylib.h" // Declares module functions
|
||||
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
#include <string.h> // Required for: strcmp(), strrchr(), strncmp()
|
||||
@@ -568,6 +568,7 @@ void ExportImage(const char *fileName, Image image)
|
||||
// NOTE: Getting Color array as RGBA unsigned char values
|
||||
unsigned char *imgData = (unsigned char *)GetImageData(image);
|
||||
SavePNG(fileName, imgData, image.width, image.height, 4);
|
||||
// FIXME ^ this fails on PLATFORM_WEB, what should we do?
|
||||
free(imgData);
|
||||
}
|
||||
|
||||
@@ -713,7 +714,7 @@ void ImageFormat(Image *image, int newFormat)
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*3; i += 3, k++)
|
||||
for (int i = 0, k = 0; i < image->width*image->height*3; i += 3, k++)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
@@ -766,7 +767,7 @@ void ImageFormat(Image *image, int newFormat)
|
||||
{
|
||||
image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*3; i += 3, k++)
|
||||
for (int i = 0, k = 0; i < image->width*image->height*4; i += 4, k++)
|
||||
{
|
||||
((unsigned char *)image->data)[i] = pixels[k].r;
|
||||
((unsigned char *)image->data)[i + 1] = pixels[k].g;
|
||||
@@ -787,7 +788,7 @@ void ImageFormat(Image *image, int newFormat)
|
||||
{
|
||||
image->data = (float *)malloc(image->width*image->height*3*sizeof(float));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*3; i += 3, k++)
|
||||
for (int i = 0, k = 0; i < image->width*image->height*3; i += 3, k++)
|
||||
{
|
||||
((float *)image->data)[i] = (float)pixels[k].r/255.0f;
|
||||
((float *)image->data)[i + 1] = (float)pixels[k].g/255.0f;
|
||||
@@ -798,7 +799,7 @@ void ImageFormat(Image *image, int newFormat)
|
||||
{
|
||||
image->data = (float *)malloc(image->width*image->height*4*sizeof(float));
|
||||
|
||||
for (int i = 0; i < image->width*image->height*4; i += 4, k++)
|
||||
for (int i = 0, k = 0; i < image->width*image->height*4; i += 4, k++)
|
||||
{
|
||||
((float *)image->data)[i] = (float)pixels[k].r/255.0f;
|
||||
((float *)image->data)[i + 1] = (float)pixels[k].g/255.0f;
|
||||
@@ -977,13 +978,13 @@ void ImageCrop(Image *image, Rectangle crop)
|
||||
{
|
||||
// Start the cropping process
|
||||
Color *pixels = GetImageData(*image); // Get data as Color pixels array
|
||||
Color *cropPixels = (Color *)malloc(crop.width*crop.height*sizeof(Color));
|
||||
Color *cropPixels = (Color *)malloc((int)crop.width*(int)crop.height*sizeof(Color));
|
||||
|
||||
for (int j = crop.y; j < (crop.y + crop.height); j++)
|
||||
for (int j = (int)crop.y; j < (int)(crop.y + crop.height); j++)
|
||||
{
|
||||
for (int i = crop.x; i < (crop.x + crop.width); i++)
|
||||
for (int i = (int)crop.x; i < (int)(crop.x + crop.width); i++)
|
||||
{
|
||||
cropPixels[(j - crop.y)*crop.width + (i - crop.x)] = pixels[j*image->width + i];
|
||||
cropPixels[(j - (int)crop.y)*(int)crop.width + (i - (int)crop.x)] = pixels[j*image->width + i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -993,7 +994,7 @@ void ImageCrop(Image *image, Rectangle crop)
|
||||
|
||||
UnloadImage(*image);
|
||||
|
||||
*image = LoadImageEx(cropPixels, crop.width, crop.height);
|
||||
*image = LoadImageEx(cropPixels, (int)crop.width, (int)crop.height);
|
||||
|
||||
free(cropPixels);
|
||||
|
||||
@@ -1312,44 +1313,38 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
|
||||
|
||||
UnloadImage(srcCopy); // Source copy not required any more...
|
||||
|
||||
Color srcCol, dstCol;
|
||||
|
||||
Vector4 fsrc, fdst, fout; // float based versions of pixel data
|
||||
|
||||
// Blit pixels, copy source image into destination
|
||||
// TODO: Probably out-of-bounds blitting could be considered here instead of so much cropping...
|
||||
for (int j = dstRec.y; j < (dstRec.y + dstRec.height); j++)
|
||||
for (int j = (int)dstRec.y; j < (int)(dstRec.y + dstRec.height); j++)
|
||||
{
|
||||
for (int i = dstRec.x; i < (dstRec.x + dstRec.width); i++)
|
||||
for (int i = (int)dstRec.x; i < (int)(dstRec.x + dstRec.width); i++)
|
||||
{
|
||||
// Alpha blending implementation
|
||||
dstCol = dstPixels[j*dst->width + i];
|
||||
srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
|
||||
// Alpha blending (https://en.wikipedia.org/wiki/Alpha_compositing)
|
||||
|
||||
/*
|
||||
// Pre-multiply alpha
|
||||
Vector3 dstColf = { (float)dstCol.r/255.0f, (float)dstCol.g/255.0f, (float)dstCol.b/255.0f };
|
||||
dstColf = Vector3Multiply(dstColf, (float)dstCol.a/255.0f);
|
||||
Vector3 srcColf = { (float)srcCol.r/255.0f, (float)srcCol.g/255.0f, (float)srcCol.b/255.0f };
|
||||
srcColf = Vector3Multiply(srcColf, (float)srcCol.a/255.0f);
|
||||
|
||||
dstColf = Vector3Add(dstColf, srcColf);
|
||||
|
||||
if (dstColf.x > 1.0f) dstColf.x = 1.0f;
|
||||
if (dstColf.y > 1.0f) dstColf.y = 1.0f;
|
||||
if (dstColf.z > 1.0f) dstColf.z = 1.0f;
|
||||
|
||||
dstCol.r = (unsigned char)(dstColf.x*255.0f);
|
||||
dstCol.g = (unsigned char)(dstColf.y*255.0f);
|
||||
dstCol.b = (unsigned char)(dstColf.z*255.0f);
|
||||
dstCol.a = srcCol.a;
|
||||
*/
|
||||
fdst = ColorNormalize(dstPixels[j*(int)dst->width + i]);
|
||||
fsrc = ColorNormalize(srcPixels[(j - (int)dstRec.y)*(int)dstRec.width + (i - (int)dstRec.x)]);
|
||||
|
||||
dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
|
||||
dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
|
||||
dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
|
||||
//dstCol.a = ((srcCol.a*(srcCol.a - dstCol.a)) >> 8) + dstCol.a;
|
||||
dstCol.a = srcCol.a;
|
||||
fout.w = fsrc.w + fdst.w*(1.0f - fsrc.w);
|
||||
|
||||
if (fout.w <= 0.0f)
|
||||
{
|
||||
fout.x = 0.0f;
|
||||
fout.y = 0.0f;
|
||||
fout.z = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fout.x = (fsrc.x*fsrc.w + fdst.x*fdst.w*(1 - fsrc.w))/fout.w;
|
||||
fout.y = (fsrc.y*fsrc.w + fdst.y*fdst.w*(1 - fsrc.w))/fout.w;
|
||||
fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w;
|
||||
}
|
||||
|
||||
dstPixels[j*dst->width + i] = dstCol;
|
||||
dstPixels[j*(int)dst->width + i] = (Color){ (unsigned char)(fout.x*255.0f),
|
||||
(unsigned char)(fout.y*255.0f),
|
||||
(unsigned char)(fout.z*255.0f),
|
||||
(unsigned char)(fout.w*255.0f) };
|
||||
|
||||
// TODO: Support other blending options
|
||||
}
|
||||
@@ -1357,7 +1352,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
|
||||
|
||||
UnloadImage(*dst); // NOTE: Only dst->data is unloaded
|
||||
|
||||
*dst = LoadImageEx(dstPixels, dst->width, dst->height);
|
||||
*dst = LoadImageEx(dstPixels, (int)dst->width, (int)dst->height);
|
||||
ImageFormat(dst, dst->format);
|
||||
|
||||
free(srcPixels);
|
||||
@@ -1369,15 +1364,15 @@ Image ImageText(const char *text, int fontSize, Color color)
|
||||
{
|
||||
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||
int spacing = fontSize/defaultFontSize;
|
||||
int spacing = (float)fontSize/defaultFontSize;
|
||||
|
||||
Image imText = ImageTextEx(GetDefaultFont(), text, (float)fontSize, spacing, color);
|
||||
Image imText = ImageTextEx(GetDefaultFont(), text, (float)fontSize, (float)spacing, color);
|
||||
|
||||
return imText;
|
||||
}
|
||||
|
||||
// Create an image from text (custom sprite font)
|
||||
Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint)
|
||||
Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint)
|
||||
{
|
||||
int length = strlen(text);
|
||||
int posX = 0;
|
||||
@@ -1391,7 +1386,7 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
|
||||
|
||||
// NOTE: glGetTexImage() not available in OpenGL ES
|
||||
// TODO: This is horrible, retrieving font texture from GPU!!!
|
||||
// Define ImageFont struct? or include Image spritefont in SpriteFont struct?
|
||||
// Define ImageFont struct? or include Image spritefont in Font struct?
|
||||
Image imFont = GetTextureData(font.texture);
|
||||
|
||||
ImageColorTint(&imFont, tint); // Apply color tint to font
|
||||
@@ -1457,7 +1452,7 @@ void ImageDrawRectangle(Image *dst, Vector2 position, Rectangle rec, Color color
|
||||
{
|
||||
Image imRec = GenImageColor(rec.width, rec.height, color);
|
||||
|
||||
Rectangle dstRec = { (int)position.x, (int)position.y, imRec.width, imRec.height };
|
||||
Rectangle dstRec = { position.x, position.y, imRec.width, imRec.height };
|
||||
|
||||
ImageDraw(dst, imRec, rec, dstRec);
|
||||
|
||||
@@ -1468,16 +1463,16 @@ void ImageDrawRectangle(Image *dst, Vector2 position, Rectangle rec, Color color
|
||||
void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color)
|
||||
{
|
||||
// NOTE: For default font, sapcing is set to desired font size / default font size (10)
|
||||
ImageDrawTextEx(dst, position, GetDefaultFont(), text, (float)fontSize, fontSize/10, color);
|
||||
ImageDrawTextEx(dst, position, GetDefaultFont(), text, (float)fontSize, (float)fontSize/10, color);
|
||||
}
|
||||
|
||||
// Draw text (custom sprite font) within an image (destination)
|
||||
void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color)
|
||||
void ImageDrawTextEx(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color)
|
||||
{
|
||||
Image imText = ImageTextEx(font, text, fontSize, spacing, color);
|
||||
|
||||
Rectangle srcRec = { 0, 0, imText.width, imText.height };
|
||||
Rectangle dstRec = { (int)position.x, (int)position.y, imText.width, imText.height };
|
||||
Rectangle dstRec = { position.x, position.y, imText.width, imText.height };
|
||||
|
||||
ImageDraw(dst, imText, srcRec, dstRec);
|
||||
|
||||
@@ -2026,7 +2021,7 @@ void DrawTextureV(Texture2D texture, Vector2 position, Color tint)
|
||||
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
|
||||
{
|
||||
Rectangle sourceRec = { 0, 0, texture.width, texture.height };
|
||||
Rectangle destRec = { (int)position.x, (int)position.y, texture.width*scale, texture.height*scale };
|
||||
Rectangle destRec = { position.x, position.y, texture.width*scale, texture.height*scale };
|
||||
Vector2 origin = { 0, 0 };
|
||||
|
||||
DrawTexturePro(texture, sourceRec, destRec, origin, rotation, tint);
|
||||
@@ -2035,7 +2030,7 @@ void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float sc
|
||||
// Draw a part of a texture (defined by a rectangle)
|
||||
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
|
||||
{
|
||||
Rectangle destRec = { (int)position.x, (int)position.y, abs(sourceRec.width), abs(sourceRec.height) };
|
||||
Rectangle destRec = { position.x, position.y, sourceRec.width, fabsf(sourceRec.height) };
|
||||
Vector2 origin = { 0, 0 };
|
||||
|
||||
DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);
|
||||
@@ -2054,7 +2049,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
|
||||
rlEnableTexture(texture.id);
|
||||
|
||||
rlPushMatrix();
|
||||
rlTranslatef((float)destRec.x, (float)destRec.y, 0);
|
||||
rlTranslatef(destRec.x, destRec.y, 0);
|
||||
rlRotatef(rotation, 0, 0, 1);
|
||||
rlTranslatef(-origin.x, -origin.y, 0);
|
||||
|
||||
@@ -2063,20 +2058,20 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
||||
|
||||
// Bottom-left corner for texture and quad
|
||||
rlTexCoord2f((float)sourceRec.x/texture.width, (float)sourceRec.y/texture.height);
|
||||
rlTexCoord2f(sourceRec.x/texture.width, sourceRec.y/texture.height);
|
||||
rlVertex2f(0.0f, 0.0f);
|
||||
|
||||
// Bottom-right corner for texture and quad
|
||||
rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
|
||||
rlVertex2f(0.0f, (float)destRec.height);
|
||||
rlTexCoord2f(sourceRec.x/texture.width, (sourceRec.y + sourceRec.height)/texture.height);
|
||||
rlVertex2f(0.0f, destRec.height);
|
||||
|
||||
// Top-right corner for texture and quad
|
||||
rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
|
||||
rlVertex2f((float)destRec.width, (float)destRec.height);
|
||||
rlTexCoord2f((sourceRec.x + sourceRec.width)/texture.width, (sourceRec.y + sourceRec.height)/texture.height);
|
||||
rlVertex2f(destRec.width, destRec.height);
|
||||
|
||||
// Top-left corner for texture and quad
|
||||
rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height);
|
||||
rlVertex2f((float)destRec.width, 0.0f);
|
||||
rlTexCoord2f((sourceRec.x + sourceRec.width)/texture.width, sourceRec.y/texture.height);
|
||||
rlVertex2f(destRec.width, 0.0f);
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
|
||||
@@ -2680,7 +2675,7 @@ static Image LoadASTC(const char *fileName)
|
||||
fread(image.data, dataSize, 1, astcFile);
|
||||
|
||||
if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA;
|
||||
else if (bpp == 2) image.format = COMPRESSED_ASTC_4x4_RGBA;
|
||||
else if (bpp == 2) image.format = COMPRESSED_ASTC_8x8_RGBA;
|
||||
}
|
||||
else TraceLog(LOG_WARNING, "[%s] ASTC block size configuration not supported", fileName);
|
||||
}
|
||||
|
16
src/utils.c
16
src/utils.c
@@ -57,6 +57,12 @@
|
||||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
||||
#include <string.h> // Required for: strlen(), strrchr(), strcmp()
|
||||
|
||||
/* This should be in <stdio.h>, but Travis doesn't find it... */
|
||||
FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int),
|
||||
int (*writefn)(void *, const char *, int),
|
||||
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
|
||||
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "external/stb_image_write.h" // Required for: stbi_write_bmp(), stbi_write_png()
|
||||
@@ -137,31 +143,27 @@ void TraceLog(int msgType, const char *text, ...)
|
||||
va_end(args);
|
||||
|
||||
if (msgType == LOG_ERROR) exit(1); // If LOG_ERROR message, exit program
|
||||
|
||||
|
||||
#endif // SUPPORT_TRACELOG
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_SAVE_BMP)
|
||||
// Creates a BMP image file from an array of pixel data
|
||||
void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(SUPPORT_SAVE_BMP) && (defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI))
|
||||
stbi_write_bmp(fileName, width, height, compSize, imgData);
|
||||
TraceLog(LOG_INFO, "BMP Image saved: %s", fileName);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_SAVE_PNG)
|
||||
// Creates a PNG image file from an array of pixel data
|
||||
void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(SUPPORT_SAVE_PNG) && (defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI))
|
||||
stbi_write_png(fileName, width, height, compSize, imgData, width*compSize);
|
||||
TraceLog(LOG_INFO, "PNG Image saved: %s", fileName);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Keep track of memory allocated
|
||||
// NOTE: mallocType defines the type of data allocated
|
||||
|
@@ -58,14 +58,12 @@ extern "C" { // Prevents name mangling of functions
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(SUPPORT_SAVE_BMP)
|
||||
void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize);
|
||||
#endif
|
||||
#if defined(SUPPORT_SAVE_PNG)
|
||||
void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void InitAssetManager(AAssetManager *manager); // Initialize asset manager from android app
|
||||
|
Reference in New Issue
Block a user