convert submodules to normal folders for now
161
raylib/examples/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Setup the project and settings
|
||||
project(examples)
|
||||
|
||||
# Directories that contain examples
|
||||
set(example_dirs
|
||||
audio
|
||||
core
|
||||
models
|
||||
others
|
||||
shaders
|
||||
shapes
|
||||
text
|
||||
textures
|
||||
)
|
||||
|
||||
# Next few lines will check for existence of symbols or header files
|
||||
# They are needed for the physac example and threads examples
|
||||
set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=199309L)
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
|
||||
check_symbol_exists(QueryPerformanceCounter windows.h HAVE_QPC)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS)
|
||||
|
||||
if (HAVE_QPC OR HAVE_CLOCK_MONOTONIC)
|
||||
set(example_dirs ${example_dirs} physac)
|
||||
endif ()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
CHECK_INCLUDE_FILE("stdatomic.h" HAVE_STDATOMIC_H)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
find_package(Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT AND HAVE_STDATOMIC_H)
|
||||
add_if_flag_compiles("-std=c11" CMAKE_C_FLAGS)
|
||||
if (THREADS_HAVE_PTHREAD_ARG)
|
||||
add_if_flag_compiles("-pthread" CMAKE_C_FLAGS)
|
||||
endif ()
|
||||
if (CMAKE_THREAD_LIBS_INIT)
|
||||
link_libraries("${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (APPLE AND NOT CMAKE_SYSTEM STRLESS "Darwin-18.0.0")
|
||||
add_definitions(-DGL_SILENCE_DEPRECATION)
|
||||
MESSAGE(AUTHOR_WARNING "OpenGL is deprecated starting with macOS 10.14 (Mojave)!")
|
||||
endif ()
|
||||
|
||||
# Collect all source files and resource files
|
||||
# into a CMake variable
|
||||
set(example_sources)
|
||||
set(example_resources)
|
||||
foreach (example_dir ${example_dirs})
|
||||
# Get the .c files
|
||||
file(GLOB sources ${example_dir}/*.c)
|
||||
list(APPEND example_sources ${sources})
|
||||
|
||||
# Any any resources
|
||||
file(GLOB resources ${example_dir}/resources/*)
|
||||
list(APPEND example_resources ${resources})
|
||||
endforeach ()
|
||||
|
||||
if(NOT CMAKE_USE_PTHREADS_INIT OR NOT HAVE_STDATOMIC_H)
|
||||
# Items requiring pthreads
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_loading_thread.c)
|
||||
endif ()
|
||||
|
||||
if (${PLATFORM} MATCHES "Android")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/standard_lighting.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_picking.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_vr_simulator.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_camera_free.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_3d_camera_first_person.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_world_screen.c)
|
||||
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_cubicmap.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_skybox.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_generation.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_heightmap.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_billboard.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_solar_system.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_rlgl_full_solar_system.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_solar_system.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_obj_viewer.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_animation.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_first_person_maze.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_magicavoxel_loading.c)
|
||||
|
||||
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
|
||||
|
||||
elseif (${PLATFORM} MATCHES "Web")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os")
|
||||
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1 -s ASYNCIFY -s ALLOW_MEMORY_GROWTH=1 --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||
|
||||
# Remove the -rdynamic flag because otherwise emscripten
|
||||
# does not generate HTML+JS+WASM files, only a non-working
|
||||
# and fat HTML
|
||||
string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}")
|
||||
|
||||
elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||
|
||||
elseif (NOT SUPPORT_GESTURES_SYSTEM)
|
||||
# Items requiring gestures system
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_mouse_painting.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_basic_screen_manager.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_input_gestures_web.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_input_gestures.c)
|
||||
|
||||
endif ()
|
||||
|
||||
# The rlgl_standalone example only targets desktop, without shared libraries.
|
||||
if (BUILD_SHARED_LIBS OR NOT ${PLATFORM} MATCHES "Desktop")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
|
||||
endif()
|
||||
|
||||
include_directories(BEFORE SYSTEM others/external/include)
|
||||
|
||||
if (NOT TARGET raylib)
|
||||
find_package(raylib 2.0 REQUIRED)
|
||||
endif ()
|
||||
|
||||
# Do each example
|
||||
foreach (example_source ${example_sources})
|
||||
# Create the basename for the example
|
||||
get_filename_component(example_name ${example_source} NAME)
|
||||
string(REPLACE ".c" "" example_name ${example_name})
|
||||
|
||||
# Setup the example
|
||||
add_executable(${example_name} ${example_source})
|
||||
|
||||
target_link_libraries(${example_name} raylib)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(${example_name} m)
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
|
||||
string(APPEND resources_dir "resources")
|
||||
|
||||
if (${PLATFORM} MATCHES "Web" AND EXISTS ${resources_dir})
|
||||
# The local resources path needs to be mapped to /resources virtual path
|
||||
string(APPEND resources_dir "@resources")
|
||||
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}")
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
# Copy all of the resource files to the destination
|
||||
file(COPY ${example_resources} DESTINATION "resources/")
|
||||
720
raylib/examples/Makefile
Normal file
|
|
@ -0,0 +1,720 @@
|
|||
#**************************************************************************************************
|
||||
#
|
||||
# raylib makefile for multiple platforms
|
||||
#
|
||||
# This file supports building raylib examples for the following platforms:
|
||||
#
|
||||
# > PLATFORM_DESKTOP
|
||||
# - Defaults to PLATFORM_DESKTOP_GLFW
|
||||
# > PLATFORM_DESKTOP_GFLW (GLFW backend):
|
||||
# - Windows (Win32, Win64)
|
||||
# - Linux (X11/Wayland desktop mode)
|
||||
# - macOS/OSX (x64, arm64)
|
||||
# - FreeBSD, OpenBSD, NetBSD, DragonFly (X11 desktop)
|
||||
# > PLATFORM_DESKTOP_SDL (SDL backend):
|
||||
# - Windows (Win32, Win64)
|
||||
# - Linux (X11/Wayland desktop mode)
|
||||
# - Others (not tested)
|
||||
# > PLATFORM_DESKTOP_RGFW (RGFW backend):
|
||||
# - Windows (Win32, Win64)
|
||||
# - Linux (X11 desktop mode)
|
||||
# - macOS/OSX (x64, arm64 (not tested))
|
||||
# - Others (not tested)
|
||||
# > PLATFORM_WEB:
|
||||
# - HTML5 (WebAssembly)
|
||||
# > PLATFORM_DRM:
|
||||
# - Raspberry Pi 0-5 (DRM/KMS)
|
||||
# - Linux DRM subsystem (KMS mode)
|
||||
# > PLATFORM_ANDROID:
|
||||
# - Android (ARM, ARM64)
|
||||
#
|
||||
# Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
# Define required environment variables
|
||||
#------------------------------------------------------------------------------------------------
|
||||
# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW))
|
||||
TARGET_PLATFORM := $(PLATFORM)
|
||||
override PLATFORM = PLATFORM_DESKTOP
|
||||
else
|
||||
ifeq ($(PLATFORM), PLATFORM_DESKTOP)
|
||||
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
|
||||
else
|
||||
TARGET_PLATFORM = $(PLATFORM)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define required raylib variables
|
||||
PROJECT_NAME ?= raylib_examples
|
||||
RAYLIB_VERSION ?= 5.5.0
|
||||
RAYLIB_PATH ?= ..
|
||||
|
||||
# Define raylib source code path
|
||||
RAYLIB_SRC_PATH ?= ../src
|
||||
|
||||
# Locations of raylib.h and libraylib.a/libraylib.so
|
||||
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
||||
DESTDIR ?= /usr/local
|
||||
RAYLIB_INCLUDE_PATH ?= $(DESTDIR)/include
|
||||
RAYLIB_LIB_PATH ?= $(DESTDIR)/lib
|
||||
|
||||
# Library type compilation: STATIC (.a) or SHARED (.so/.dll)
|
||||
RAYLIB_LIBTYPE ?= STATIC
|
||||
|
||||
# Build mode for project: DEBUG or RELEASE
|
||||
BUILD_MODE ?= RELEASE
|
||||
|
||||
# Use external GLFW library instead of rglfw module
|
||||
USE_EXTERNAL_GLFW ?= FALSE
|
||||
|
||||
# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally
|
||||
# WARNING: Library is not included in raylib, it MUST be configured by users
|
||||
SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
|
||||
SDL_LIBRARY_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/lib
|
||||
SDL_LIBRARIES ?= -lSDL2 -lSDL2main
|
||||
|
||||
|
||||
# Use Wayland display server protocol on Linux desktop (by default it uses X11 windowing system)
|
||||
# NOTE: This variable is only used for PLATFORM_OS: LINUX
|
||||
USE_WAYLAND_DISPLAY ?= FALSE
|
||||
|
||||
# PLATFORM_WEB: Default properties
|
||||
BUILD_WEB_ASYNCIFY ?= TRUE
|
||||
BUILD_WEB_SHELL ?= $(RAYLIB_PATH)/src/minshell.html
|
||||
BUILD_WEB_HEAP_SIZE ?= 134217728
|
||||
BUILD_WEB_RESOURCES ?= TRUE
|
||||
BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources
|
||||
|
||||
# Determine PLATFORM_OS when required
|
||||
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB))
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
|
||||
# ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS = WINDOWS
|
||||
else
|
||||
UNAMEOS = $(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS = LINUX
|
||||
endif
|
||||
ifeq ($(UNAMEOS),FreeBSD)
|
||||
PLATFORM_OS = BSD
|
||||
endif
|
||||
ifeq ($(UNAMEOS),OpenBSD)
|
||||
PLATFORM_OS = BSD
|
||||
endif
|
||||
ifeq ($(UNAMEOS),NetBSD)
|
||||
PLATFORM_OS = BSD
|
||||
endif
|
||||
ifeq ($(UNAMEOS),DragonFly)
|
||||
PLATFORM_OS = BSD
|
||||
endif
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS = OSX
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
UNAMEOS = $(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS = LINUX
|
||||
endif
|
||||
endif
|
||||
|
||||
# RAYLIB_PATH adjustment for LINUX platform
|
||||
# TODO: Do we really need this?
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
RAYLIB_PREFIX ?= ..
|
||||
RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Default path for raylib on Raspberry Pi
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
RAYLIB_PATH ?= /home/pi/raylib
|
||||
endif
|
||||
|
||||
# Define raylib release directory for compiled library
|
||||
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# Emscripten required variables
|
||||
EMSDK_PATH ?= C:/raylib/emsdk
|
||||
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
||||
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
|
||||
NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
|
||||
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define default C compiler: CC
|
||||
#------------------------------------------------------------------------------------------------
|
||||
CC = gcc
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# OSX default compiler
|
||||
CC = clang
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
# FreeBSD, OpenBSD, NetBSD, DragonFly default compiler
|
||||
CC = clang
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
# HTML5 emscripten compiler
|
||||
# WARNING: To compile to HTML5, code must be redesigned
|
||||
# to use emscripten.h and emscripten_set_main_loop()
|
||||
CC = emcc
|
||||
endif
|
||||
|
||||
# Define default make program: MAKE
|
||||
#------------------------------------------------------------------------------------------------
|
||||
MAKE ?= make
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
MAKE = mingw32-make
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
|
||||
MAKE = mingw32-make
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
ifeq ($(OS),Windows_NT)
|
||||
MAKE = mingw32-make
|
||||
else
|
||||
EMMAKE != type emmake
|
||||
ifneq (, $(EMMAKE))
|
||||
MAKE = emmake make
|
||||
else
|
||||
MAKE = mingw32-make
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define compiler flags: CFLAGS
|
||||
#------------------------------------------------------------------------------------------------
|
||||
# -O1 defines optimization level
|
||||
# -g include debug information on compilation
|
||||
# -s strip unnecessary data from build
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 defines C language mode (standard C from 1999 revision)
|
||||
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
|
||||
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
|
||||
# -Wno-unused-value ignore unused return values of some functions (i.e. fread())
|
||||
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
|
||||
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
|
||||
|
||||
ifeq ($(BUILD_MODE),DEBUG)
|
||||
CFLAGS += -g -D_DEBUG
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS += -sASSERTIONS=1 --profiling
|
||||
endif
|
||||
else
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
ifeq ($(BUILD_WEB_ASYNCIFY),TRUE)
|
||||
CFLAGS += -O3
|
||||
else
|
||||
CFLAGS += -Os
|
||||
endif
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
endif
|
||||
|
||||
# Additional flags for compiler (if desired)
|
||||
# -Wextra enables some extra warning flags that are not enabled by -Wall
|
||||
# -Wmissing-prototypes warn if a global function is defined without a previous prototype declaration
|
||||
# -Wstrict-prototypes warn if a function is declared or defined without specifying the argument types
|
||||
# -Werror=implicit-function-declaration catch function calls without prior declaration
|
||||
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
ifeq ($(RAYLIB_LIBTYPE),STATIC)
|
||||
CFLAGS += -D_DEFAULT_SOURCE
|
||||
endif
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
# Explicitly enable runtime link to libraylib.so
|
||||
CFLAGS += -Wl,-rpath,$(RAYLIB_RELEASE_PATH)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
CFLAGS += -std=gnu99 -DEGL_NO_X11
|
||||
endif
|
||||
|
||||
# Define include paths for required headers: INCLUDE_PATHS
|
||||
# NOTE: Some external/extras libraries could be required (stb, easings...)
|
||||
#------------------------------------------------------------------------------------------------
|
||||
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external $(EXTRA_INCLUDE_PATHS)
|
||||
# Define additional directories containing required header files
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) -I/usr/pkg/include -I/usr/X11R7/include
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
|
||||
INCLUDE_PATHS += -I$(SDL_INCLUDE_PATH)
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH)
|
||||
INCLUDE_PATHS += -I/usr/include/libdrm
|
||||
endif
|
||||
|
||||
# Include GLFW required for examples/others/rlgl_standalone.c
|
||||
ifeq ($(USE_EXTERNAL_GLFW),FALSE)
|
||||
all others: INCLUDE_PATHS += -I$(RAYLIB_PATH)/src/external/glfw/include
|
||||
endif
|
||||
|
||||
# Define library paths containing required libs: LDFLAGS
|
||||
#------------------------------------------------------------------------------------------------
|
||||
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# NOTE: The resource .rc file contains windows executable icon and properties
|
||||
LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
ifeq ($(BUILD_MODE), RELEASE)
|
||||
LDFLAGS += -Wl,--subsystem,windows
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
LDFLAGS += -L$(RAYLIB_LIB_PATH)
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
LDFLAGS += -Lsrc -L$(RAYLIB_LIB_PATH)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# NOTE: The resource .rc file contains windows executable icon and properties
|
||||
LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
ifeq ($(BUILD_MODE), RELEASE)
|
||||
LDFLAGS += -Wl,--subsystem,windows
|
||||
endif
|
||||
endif
|
||||
LDFLAGS += -L$(SDL_LIBRARY_PATH)
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
# -Os # size optimization
|
||||
# -O2 # optimization level 2, if used, also set --memory-init-file 0
|
||||
# -sUSE_GLFW=3 # Use glfw3 library (context/input management)
|
||||
# -sALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
|
||||
# -sTOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) (67108864 = 64MB)
|
||||
# -sUSE_PTHREADS=1 # multithreading support
|
||||
# -sWASM=0 # disable Web Assembly, emitted by default
|
||||
# -sASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS
|
||||
# -sFORCE_FILESYSTEM=1 # force filesystem to load/save files data
|
||||
# -sASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
|
||||
# -sGL_ENABLE_GET_PROC_ADDRESS # enable using the *glGetProcAddress() family of functions, required for extensions loading
|
||||
# --profiling # include information for code profiling
|
||||
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
|
||||
# --preload-file resources # specify a resources folder for data compilation
|
||||
# --source-map-base # allow debugging in browser with source map
|
||||
LDFLAGS += -sUSE_GLFW=3 -sTOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -sFORCE_FILESYSTEM=1
|
||||
|
||||
# Build using asyncify
|
||||
ifeq ($(BUILD_WEB_ASYNCIFY),TRUE)
|
||||
LDFLAGS += -sASYNCIFY
|
||||
endif
|
||||
|
||||
# Add resources building if required
|
||||
ifeq ($(BUILD_WEB_RESOURCES),TRUE)
|
||||
LDFLAGS += --preload-file $(BUILD_WEB_RESOURCES_PATH)
|
||||
endif
|
||||
|
||||
# Add debug mode flags if required
|
||||
ifeq ($(BUILD_MODE),DEBUG)
|
||||
LDFLAGS += -sASSERTIONS=1 --profiling
|
||||
endif
|
||||
|
||||
# Define a custom shell .html and output extension
|
||||
LDFLAGS += --shell-file $(BUILD_WEB_SHELL)
|
||||
EXT = .html
|
||||
|
||||
# NOTE: Simple raylib examples are compiled to be interpreter with asyncify, that way,
|
||||
# we can compile same code for ALL platforms with no change required, but, working on bigger
|
||||
# projects, code needs to be refactored to avoid a blocking while() loop, moving Update and Draw
|
||||
# logic to a self contained function: UpdateDrawFrame(), check core_basic_window_web.c for reference.
|
||||
|
||||
endif
|
||||
|
||||
# Define libraries required on linking: LDLIBS
|
||||
# NOTE: To link libraries (lib<name>.so or lib<name>.a), use -l<name>
|
||||
#------------------------------------------------------------------------------------------------
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# Libraries for Windows desktop compilation
|
||||
# NOTE: WinMM library required to set high-res timer resolution
|
||||
LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# Libraries for Debian GNU/Linux desktop compiling
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
|
||||
|
||||
# On X11 requires also below libraries
|
||||
LDLIBS += -lX11
|
||||
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
||||
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
|
||||
# On Wayland windowing system, additional libraries requires
|
||||
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
|
||||
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
||||
endif
|
||||
# Explicit link to libc
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
LDLIBS += -lc
|
||||
endif
|
||||
|
||||
# NOTE: On ARM 32bit arch, miniaudio requires atomics library
|
||||
LDLIBS += -latomic
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# Libraries for OSX 10.9 desktop compiling
|
||||
# NOTE: Required packages: libopenal-dev libegl1-mesa-dev
|
||||
LDLIBS = -lraylib -framework OpenGL -framework Cocoa -framework IOKit -framework CoreAudio -framework CoreVideo
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
# Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling
|
||||
# NOTE: Required packages: mesa-libs
|
||||
LDFLAGS += -L/usr/X11R7/lib -Wl,-R/usr/X11R7/lib
|
||||
LDLIBS = -lraylib -lGL -lm -lpthread
|
||||
|
||||
# On XWindow requires also below libraries
|
||||
LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
endif
|
||||
ifeq ($(USE_EXTERNAL_GLFW),TRUE)
|
||||
# NOTE: It could require additional packages installed: libglfw3-dev
|
||||
LDLIBS += -lglfw
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# Libraries for Windows desktop compilation
|
||||
LDLIBS = -lraylib $(SDL_LIBRARIES) -lopengl32 -lgdi32
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# Libraries for Debian GNU/Linux desktop compiling
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDLIBS = -lraylib $(SDL_LIBRARIES) -lGL -lm -lpthread -ldl -lrt
|
||||
|
||||
# On X11 requires also below libraries
|
||||
LDLIBS += -lX11
|
||||
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
||||
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
|
||||
# On Wayland windowing system, additional libraries requires
|
||||
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
|
||||
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
||||
endif
|
||||
# Explicit link to libc
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
LDLIBS += -lc
|
||||
endif
|
||||
|
||||
# NOTE: On ARM 32bit arch, miniaudio requires atomics library
|
||||
LDLIBS += -latomic
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# Libraries for Windows desktop compilation
|
||||
LDFLAGS += -L..\src
|
||||
LDLIBS = -lraylib -lgdi32 -lwinmm -lopengl32
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# Libraries for Debian GNU/Linux desktop compipling
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDFLAGS += -L../src
|
||||
LDLIBS = -lraylib -lGL -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -lpthread -ldl -lrt
|
||||
|
||||
# Explicit link to libc
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
LDLIBS += -lc
|
||||
endif
|
||||
|
||||
# NOTE: On ARM 32bit arch, miniaudio requires atomics library
|
||||
LDLIBS += -latomic
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# Libraries for Debian GNU/Linux desktop compiling
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDFLAGS += -L../src
|
||||
LDLIBS = -lraylib -lm
|
||||
LDLIBS += -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
# Libraries for DRM compiling
|
||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||
LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
# Libraries for web (HTML5) compiling
|
||||
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a
|
||||
endif
|
||||
|
||||
# Define source code object files required
|
||||
#------------------------------------------------------------------------------------------------
|
||||
CORE = \
|
||||
core/core_2d_camera \
|
||||
core/core_2d_camera_mouse_zoom \
|
||||
core/core_2d_camera_platformer \
|
||||
core/core_2d_camera_split_screen \
|
||||
core/core_3d_camera_first_person \
|
||||
core/core_3d_camera_free \
|
||||
core/core_3d_camera_mode \
|
||||
core/core_3d_camera_split_screen \
|
||||
core/core_3d_picking \
|
||||
core/core_automation_events \
|
||||
core/core_basic_screen_manager \
|
||||
core/core_basic_window \
|
||||
core/core_basic_window_web \
|
||||
core/core_custom_frame_control \
|
||||
core/core_custom_logging \
|
||||
core/core_drop_files \
|
||||
core/core_input_gamepad \
|
||||
core/core_input_gamepad_info \
|
||||
core/core_input_gestures \
|
||||
core/core_input_gestures_web \
|
||||
core/core_input_keys \
|
||||
core/core_input_mouse \
|
||||
core/core_input_mouse_wheel \
|
||||
core/core_input_multitouch \
|
||||
core/core_input_virtual_controls \
|
||||
core/core_loading_thread \
|
||||
core/core_random_sequence \
|
||||
core/core_random_values \
|
||||
core/core_scissor_test \
|
||||
core/core_smooth_pixelperfect \
|
||||
core/core_storage_values \
|
||||
core/core_vr_simulator \
|
||||
core/core_window_flags \
|
||||
core/core_window_letterbox \
|
||||
core/core_window_should_close \
|
||||
core/core_world_screen
|
||||
|
||||
SHAPES = \
|
||||
shapes/shapes_basic_shapes \
|
||||
shapes/shapes_bouncing_ball \
|
||||
shapes/shapes_collision_area \
|
||||
shapes/shapes_colors_palette \
|
||||
shapes/shapes_draw_circle_sector \
|
||||
shapes/shapes_draw_rectangle_rounded \
|
||||
shapes/shapes_draw_ring \
|
||||
shapes/shapes_easings_ball_anim \
|
||||
shapes/shapes_easings_box_anim \
|
||||
shapes/shapes_easings_rectangle_array \
|
||||
shapes/shapes_following_eyes \
|
||||
shapes/shapes_lines_bezier \
|
||||
shapes/shapes_logo_raylib \
|
||||
shapes/shapes_logo_raylib_anim \
|
||||
shapes/shapes_rectangle_scaling \
|
||||
shapes/shapes_splines_drawing \
|
||||
shapes/shapes_top_down_lights \
|
||||
shapes/shapes_rectangle_advanced
|
||||
|
||||
TEXTURES = \
|
||||
textures/textures_background_scrolling \
|
||||
textures/textures_blend_modes \
|
||||
textures/textures_bunnymark \
|
||||
textures/textures_draw_tiled \
|
||||
textures/textures_fog_of_war \
|
||||
textures/textures_gif_player \
|
||||
textures/textures_image_channel \
|
||||
textures/textures_image_drawing \
|
||||
textures/textures_image_generation \
|
||||
textures/textures_image_kernel \
|
||||
textures/textures_image_loading \
|
||||
textures/textures_image_processing \
|
||||
textures/textures_image_rotate \
|
||||
textures/textures_image_text \
|
||||
textures/textures_logo_raylib \
|
||||
textures/textures_mouse_painting \
|
||||
textures/textures_npatch_drawing \
|
||||
textures/textures_particles_blending \
|
||||
textures/textures_polygon \
|
||||
textures/textures_raw_data \
|
||||
textures/textures_sprite_anim \
|
||||
textures/textures_sprite_button \
|
||||
textures/textures_sprite_explosion \
|
||||
textures/textures_srcrec_dstrec \
|
||||
textures/textures_textured_curve \
|
||||
textures/textures_to_image
|
||||
|
||||
TEXT = \
|
||||
text/text_codepoints_loading \
|
||||
text/text_draw_3d \
|
||||
text/text_font_filters \
|
||||
text/text_font_loading \
|
||||
text/text_font_sdf \
|
||||
text/text_font_spritefont \
|
||||
text/text_format_text \
|
||||
text/text_input_box \
|
||||
text/text_raylib_fonts \
|
||||
text/text_rectangle_bounds \
|
||||
text/text_unicode \
|
||||
text/text_writing_anim
|
||||
|
||||
MODELS = \
|
||||
models/models_animation \
|
||||
models/models_billboard \
|
||||
models/models_bone_socket \
|
||||
models/models_box_collisions \
|
||||
models/models_cubicmap \
|
||||
models/models_draw_cube_texture \
|
||||
models/models_first_person_maze \
|
||||
models/models_geometric_shapes \
|
||||
models/models_heightmap \
|
||||
models/models_loading \
|
||||
models/models_loading_gltf \
|
||||
models/models_loading_m3d \
|
||||
models/models_loading_vox \
|
||||
models/models_mesh_generation \
|
||||
models/models_mesh_picking \
|
||||
models/models_orthographic_projection \
|
||||
models/models_point_rendering \
|
||||
models/models_rlgl_solar_system \
|
||||
models/models_skybox \
|
||||
models/models_waving_cubes \
|
||||
models/models_yaw_pitch_roll \
|
||||
models/models_gpu_skinning
|
||||
|
||||
SHADERS = \
|
||||
shaders/shaders_basic_lighting \
|
||||
shaders/shaders_basic_pbr \
|
||||
shaders/shaders_custom_uniform \
|
||||
shaders/shaders_deferred_render \
|
||||
shaders/shaders_eratosthenes \
|
||||
shaders/shaders_fog \
|
||||
shaders/shaders_hot_reloading \
|
||||
shaders/shaders_hybrid_render \
|
||||
shaders/shaders_julia_set \
|
||||
shaders/shaders_lightmap \
|
||||
shaders/shaders_mesh_instancing \
|
||||
shaders/shaders_model_shader \
|
||||
shaders/shaders_multi_sample2d \
|
||||
shaders/shaders_palette_switch \
|
||||
shaders/shaders_postprocessing \
|
||||
shaders/shaders_raymarching \
|
||||
shaders/shaders_shadowmap \
|
||||
shaders/shaders_shapes_textures \
|
||||
shaders/shaders_simple_mask \
|
||||
shaders/shaders_spotlight \
|
||||
shaders/shaders_texture_drawing \
|
||||
shaders/shaders_texture_outline \
|
||||
shaders/shaders_texture_tiling \
|
||||
shaders/shaders_texture_waves \
|
||||
shaders/shaders_write_depth \
|
||||
shaders/shaders_vertex_displacement
|
||||
|
||||
AUDIO = \
|
||||
audio/audio_mixed_processor \
|
||||
audio/audio_module_playing \
|
||||
audio/audio_music_stream \
|
||||
audio/audio_raw_stream \
|
||||
audio/audio_sound_loading \
|
||||
audio/audio_sound_multi \
|
||||
audio/audio_stream_effects
|
||||
|
||||
OTHERS = \
|
||||
others/easings_testbed \
|
||||
others/embedded_files_loading \
|
||||
others/raylib_opengl_interop \
|
||||
others/raymath_vector_angle \
|
||||
others/rlgl_compute_shader
|
||||
|
||||
ifeq ($(TARGET_PLATFORM), PLATFORM_DESKTOP_GFLW)
|
||||
OTHERS += others/rlgl_standalone
|
||||
endif
|
||||
|
||||
|
||||
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
# Define processes to execute
|
||||
#------------------------------------------------------------------------------------------------
|
||||
# Default target entry
|
||||
all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO) $(OTHERS)
|
||||
|
||||
core: $(CORE)
|
||||
shapes: $(SHAPES)
|
||||
textures: $(TEXTURES)
|
||||
text: $(TEXT)
|
||||
models: $(MODELS)
|
||||
shaders: $(SHADERS)
|
||||
audio: $(AUDIO)
|
||||
others: $(OTHERS)
|
||||
|
||||
# Generic compilation pattern
|
||||
# NOTE: Examples must be ready for Android compilation!
|
||||
%: %.c
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
|
||||
$(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
|
||||
else ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
$(MAKE) -f Makefile.Web $@
|
||||
else
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -D$(TARGET_PLATFORM)
|
||||
endif
|
||||
|
||||
# Clean everything
|
||||
clean:
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.o *.exe /s
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
find . -type f -perm -ugo+x -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.wasm *.html *.js *.data
|
||||
else
|
||||
rm -f */*.wasm */*.html */*.js */*.data
|
||||
endif
|
||||
endif
|
||||
@echo Cleaning done
|
||||
412
raylib/examples/Makefile.Android
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
#**************************************************************************************************
|
||||
#
|
||||
# raylib makefile for Android project (APK building)
|
||||
#
|
||||
# Copyright (c) 2017-2024 Ramon Santamaria (@raysan5)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# Define required raylib variables
|
||||
PLATFORM ?= PLATFORM_ANDROID
|
||||
RAYLIB_PATH ?= ..\..
|
||||
|
||||
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
|
||||
# Starting in 2019 using ARM64 is mandatory for published apps,
|
||||
# Starting on August 2020, minimum required target API is Android 10 (API level 29)
|
||||
ANDROID_ARCH ?= ARM64
|
||||
ANDROID_API_VERSION = 29
|
||||
|
||||
# Android required path variables
|
||||
# NOTE: Starting with Android NDK r21, no more toolchain generation is required, NDK is the toolchain on itself
|
||||
ifeq ($(OS),Windows_NT)
|
||||
ANDROID_NDK = C:/android-ndk
|
||||
ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/windows-x86_64
|
||||
else
|
||||
ANDROID_NDK ?= /usr/lib/android/ndk
|
||||
ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64
|
||||
endif
|
||||
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
ANDROID_ARCH_NAME = armeabi-v7a
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
ANDROID_ARCH_NAME = arm64-v8a
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),x86)
|
||||
ANDROID_ARCH_NAME = x86
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),x86_64)
|
||||
ANDROID_ARCH_NAME = x86_64
|
||||
endif
|
||||
|
||||
# Required path variables
|
||||
# NOTE: JAVA_HOME must be set to JDK (using OpenJDK 13)
|
||||
JAVA_HOME ?= C:/open-jdk
|
||||
ANDROID_HOME ?= C:/android-sdk
|
||||
ANDROID_BUILD_TOOLS ?= $(ANDROID_HOME)/build-tools/29.0.3
|
||||
ANDROID_PLATFORM_TOOLS = $(ANDROID_HOME)/platform-tools
|
||||
|
||||
# Android project configuration variables
|
||||
PROJECT_NAME ?= raylib_game
|
||||
PROJECT_LIBRARY_NAME ?= main
|
||||
PROJECT_BUILD_ID ?= android
|
||||
PROJECT_BUILD_PATH ?= $(PROJECT_BUILD_ID).$(PROJECT_NAME)
|
||||
PROJECT_RESOURCES_PATH ?= resources
|
||||
PROJECT_SOURCE_FILES ?= raylib_game.c
|
||||
NATIVE_APP_GLUE_PATH = $(ANDROID_NDK)/sources/android/native_app_glue
|
||||
|
||||
# Some source files are placed in directories, when compiling to some
|
||||
# output directory other than source, that directory must pre-exist.
|
||||
# Here we get a list of required folders that need to be created on
|
||||
# code output folder $(PROJECT_BUILD_PATH)\obj to avoid GCC errors.
|
||||
PROJECT_SOURCE_DIRS = $(sort $(dir $(PROJECT_SOURCE_FILES)))
|
||||
|
||||
# Android app configuration variables
|
||||
APP_LABEL_NAME ?= rGame
|
||||
APP_COMPANY_NAME ?= raylib
|
||||
APP_PRODUCT_NAME ?= rgame
|
||||
APP_VERSION_CODE ?= 1
|
||||
APP_VERSION_NAME ?= 1.0
|
||||
APP_ICON_LDPI ?= $(RAYLIB_PATH)/logo/raylib_36x36.png
|
||||
APP_ICON_MDPI ?= $(RAYLIB_PATH)/logo/raylib_48x48.png
|
||||
APP_ICON_HDPI ?= $(RAYLIB_PATH)/logo/raylib_72x72.png
|
||||
APP_SCREEN_ORIENTATION ?= landscape
|
||||
APP_KEYSTORE_PASS ?= raylib
|
||||
|
||||
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
|
||||
RAYLIB_LIBTYPE ?= STATIC
|
||||
|
||||
# Library path for libraylib.a/libraylib.so
|
||||
RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src
|
||||
|
||||
# Define copy command depending on OS
|
||||
ifeq ($(OS),Windows_NT)
|
||||
COPY_COMMAND ?= copy /Y
|
||||
else
|
||||
COPY_COMMAND ?= cp -f
|
||||
endif
|
||||
|
||||
# Shared libs must be added to APK if required
|
||||
# NOTE: Generated NativeLoader.java automatically load those libraries
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
PROJECT_SHARED_LIBS = lib/$(ANDROID_ARCH_NAME)/libraylib.so
|
||||
endif
|
||||
|
||||
# Compiler and archiver
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),x86)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/i686-linux-android$(ANDROID_API_VERSION)-clang
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/i686-linux-android-ar
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),x86_64)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/x86_64-linux-android$(ANDROID_API_VERSION)-clang
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/x86_64-linux-android-ar
|
||||
endif
|
||||
|
||||
# Compiler flags for arquitecture
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769
|
||||
endif
|
||||
# Compilation functions attributes options
|
||||
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
|
||||
# Compiler options for the linker
|
||||
CFLAGS += -Wall -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical-prefixes
|
||||
# Preprocessor macro definitions
|
||||
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION)
|
||||
|
||||
# Paths containing required header files
|
||||
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(NATIVE_APP_GLUE_PATH)
|
||||
|
||||
# Linker options
|
||||
LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).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
|
||||
# Force linking of library module to define symbol
|
||||
LDFLAGS += -u ANativeActivity_onCreate
|
||||
# Library paths containing required libs
|
||||
LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME) -L$(ANDROID_TOOLCHAIN)\sysroot\usr\lib
|
||||
|
||||
# Define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
LDLIBS = -lm -lc -lraylib -llog -landroid -lEGL -lGLESv2 -lOpenSLES -ldl
|
||||
|
||||
# Generate target objects list from PROJECT_SOURCE_FILES
|
||||
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
|
||||
|
||||
# Android APK building process... some steps required...
|
||||
# NOTE: typing 'make' will invoke the default target entry called 'all'
|
||||
# TODO: Use apksigner for APK signing, jarsigner is not recommended
|
||||
all: create_temp_project_dirs \
|
||||
copy_project_required_libs \
|
||||
copy_project_resources \
|
||||
generate_loader_script \
|
||||
generate_android_manifest \
|
||||
generate_apk_keystore \
|
||||
config_project_package \
|
||||
compile_project_code \
|
||||
compile_project_class \
|
||||
compile_project_class_dex \
|
||||
create_project_apk_package \
|
||||
sign_project_apk_package \
|
||||
zipalign_project_apk_package
|
||||
|
||||
# WARNING: About build signing process:
|
||||
# - If using apksigner, zipalign must be used before the APK file has been signed.
|
||||
# - If using jarsigner (not recommended), zipalign must be used after the APK file has been signed.
|
||||
# REF: https://developer.android.com/tools/zipalign
|
||||
# REF: https://developer.android.com/tools/apksigner
|
||||
|
||||
# Create required temp directories for APK building
|
||||
create_temp_project_dirs:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
if not exist $(PROJECT_BUILD_PATH) mkdir $(PROJECT_BUILD_PATH)
|
||||
if not exist $(PROJECT_BUILD_PATH)\obj mkdir $(PROJECT_BUILD_PATH)\obj
|
||||
if not exist $(PROJECT_BUILD_PATH)\obj mkdir $(PROJECT_BUILD_PATH)\obj\src
|
||||
if not exist $(PROJECT_BUILD_PATH)\src mkdir $(PROJECT_BUILD_PATH)\src
|
||||
if not exist $(PROJECT_BUILD_PATH)\src\com mkdir $(PROJECT_BUILD_PATH)\src\com
|
||||
if not exist $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME) mkdir $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)
|
||||
if not exist $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)\$(APP_PRODUCT_NAME) mkdir $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)\$(APP_PRODUCT_NAME)
|
||||
if not exist $(PROJECT_BUILD_PATH)\lib mkdir $(PROJECT_BUILD_PATH)\lib
|
||||
if not exist $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME) mkdir $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME)
|
||||
if not exist $(PROJECT_BUILD_PATH)\bin mkdir $(PROJECT_BUILD_PATH)\bin
|
||||
if not exist $(PROJECT_BUILD_PATH)\res mkdir $(PROJECT_BUILD_PATH)\res
|
||||
if not exist $(PROJECT_BUILD_PATH)\res\drawable-ldpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-ldpi
|
||||
if not exist $(PROJECT_BUILD_PATH)\res\drawable-mdpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-mdpi
|
||||
if not exist $(PROJECT_BUILD_PATH)\res\drawable-hdpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-hdpi
|
||||
if not exist $(PROJECT_BUILD_PATH)\res\values mkdir $(PROJECT_BUILD_PATH)\res\values
|
||||
if not exist $(PROJECT_BUILD_PATH)\assets mkdir $(PROJECT_BUILD_PATH)\assets
|
||||
if not exist $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH) mkdir $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH)
|
||||
if not exist $(PROJECT_BUILD_PATH)\obj\screens mkdir $(PROJECT_BUILD_PATH)\obj\screens
|
||||
else
|
||||
mkdir -p $(PROJECT_BUILD_PATH)
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/obj
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/obj/src
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/src
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/src/com
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/lib
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/bin
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/res
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/res/drawable-ldpi
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/res/drawable-mdpi
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/res/drawable-hdpi
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/res/values
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/assets
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/assets/$(PROJECT_RESOURCES_PATH)
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/obj/screens
|
||||
endif
|
||||
$(foreach dir, $(PROJECT_SOURCE_DIRS), $(call create_dir, $(dir)))
|
||||
|
||||
define create_dir
|
||||
mkdir -p $(PROJECT_BUILD_PATH)/obj/$(1)
|
||||
endef
|
||||
|
||||
# Copy required shared libs for integration into APK
|
||||
# NOTE: If using shared libs they are loaded by generated NativeLoader.java
|
||||
copy_project_required_libs:
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
$(COPY_COMMAND) $(RAYLIB_LIB_PATH)/libraylib.so $(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)/libraylib.so
|
||||
endif
|
||||
ifeq ($(RAYLIB_LIBTYPE),STATIC)
|
||||
$(COPY_COMMAND) $(RAYLIB_LIB_PATH)/libraylib.a $(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)/libraylib.a
|
||||
endif
|
||||
|
||||
# Copy project required resources: strings.xml, icon.png, assets
|
||||
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
|
||||
copy_project_resources:
|
||||
$(COPY_COMMAND) $(APP_ICON_LDPI) $(PROJECT_BUILD_PATH)/res/drawable-ldpi/icon.png
|
||||
$(COPY_COMMAND) $(APP_ICON_MDPI) $(PROJECT_BUILD_PATH)/res/drawable-mdpi/icon.png
|
||||
$(COPY_COMMAND) $(APP_ICON_HDPI) $(PROJECT_BUILD_PATH)/res/drawable-hdpi/icon.png
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@echo ^<?xml version="1.0" encoding="utf-8"^?^> > $(PROJECT_BUILD_PATH)/res/values/strings.xml
|
||||
@echo ^<resources^>^<string name="app_name"^>$(APP_LABEL_NAME)^</string^>^</resources^> >> $(PROJECT_BUILD_PATH)/res/values/strings.xml
|
||||
if exist $(PROJECT_RESOURCES_PATH) C:\Windows\System32\xcopy $(PROJECT_RESOURCES_PATH) $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH) /Y /E /F
|
||||
else
|
||||
@echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > $(PROJECT_BUILD_PATH)/res/values/strings.xml
|
||||
@echo "<resources><string name=\"app_name\">$(APP_LABEL_NAME)</string></resources>" >> $(PROJECT_BUILD_PATH)/res/values/strings.xml
|
||||
@[ -d "$(PROJECT_RESOURCES_PATH)" ] || cp -rf $(PROJECT_RESOURCES_PATH) $(PROJECT_BUILD_PATH)/assets/$(PROJECT_RESOURCES_PATH)
|
||||
endif
|
||||
|
||||
# Generate NativeLoader.java to load required shared libraries
|
||||
# NOTE: Probably not the bet way to generate this file... but it works.
|
||||
generate_loader_script:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@echo package com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME); > $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
endif
|
||||
@echo System.loadLibrary("$(PROJECT_LIBRARY_NAME)"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo } >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo } >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
else
|
||||
@echo "package com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME);" > $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo "" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo "public class NativeLoader extends android.app.NativeActivity {" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo " static {" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
@echo " System.loadLibrary(\"raylib\");" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
endif
|
||||
@echo " System.loadLibrary(\"$(PROJECT_LIBRARY_NAME)\");" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo " }" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
@echo "}" >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
endif
|
||||
|
||||
# Generate AndroidManifest.xml with all the required options
|
||||
# NOTE: Probably not the bet way to generate this file... but it works.
|
||||
generate_android_manifest:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@echo ^<?xml version="1.0" encoding="utf-8"^?^> > $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<manifest xmlns:android="http://schemas.android.com/apk/res/android" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo package="com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME)" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo android:versionCode="$(APP_VERSION_CODE)" android:versionName="$(APP_VERSION_NAME)" ^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<uses-sdk android:minSdkVersion="$(ANDROID_API_VERSION)" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<uses-feature android:glEsVersion="0x00020000" android:required="true" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<application android:allowBackup="false" android:label="@string/app_name" android:icon="@drawable/icon" ^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<activity android:name="com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME).NativeLoader" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo android:configChanges="orientation|keyboardHidden|screenSize" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo android:screenOrientation="$(APP_SCREEN_ORIENTATION)" android:launchMode="singleTask" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo android:clearTaskOnLaunch="true"^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<meta-data android:name="android.app.lib_name" android:value="$(PROJECT_LIBRARY_NAME)" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<intent-filter^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<action android:name="android.intent.action.MAIN" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^<category android:name="android.intent.category.LAUNCHER" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^</intent-filter^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^</activity^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^</application^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo ^</manifest^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
else
|
||||
@echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " package=\"com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME)\" " >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " android:versionCode=\"$(APP_VERSION_CODE)\" android:versionName=\"$(APP_VERSION_NAME)\" >" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <uses-sdk android:minSdkVersion=\"$(ANDROID_API_VERSION)\" />" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <uses-feature android:glEsVersion=\"0x00020000\" android:required=\"true\" />" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <application android:allowBackup=\"false\" android:label=\"@string/app_name\" android:icon=\"@drawable/icon\" >" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <activity android:name=\"com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME).NativeLoader\"" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " android:theme=\"@android:style/Theme.NoTitleBar.Fullscreen\"" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " android:configChanges=\"orientation|keyboardHidden|screenSize\"" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " android:screenOrientation=\"$(APP_SCREEN_ORIENTATION)\" android:launchMode=\"singleTask\"" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " android:clearTaskOnLaunch=\"true\">" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <meta-data android:name=\"android.app.lib_name\" android:value=\"$(PROJECT_LIBRARY_NAME)\" />" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <intent-filter>" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <action android:name=\"android.intent.action.MAIN\" />" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " <category android:name=\"android.intent.category.LAUNCHER\" />" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " </intent-filter>" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " </activity>" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo " </application>" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
@echo "</manifest>" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
|
||||
endif
|
||||
|
||||
# Generate storekey for APK signing: $(PROJECT_NAME).keystore
|
||||
# NOTE: Configure here your Distinguished Names (-dname) if required!
|
||||
generate_apk_keystore:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
if not exist $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore $(JAVA_HOME)/bin/keytool -genkeypair -validity 10000 -dname "CN=$(APP_COMPANY_NAME),O=Android,C=ES" -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -alias $(PROJECT_NAME)Key -keyalg RSA
|
||||
else
|
||||
@[ -f "$(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore" ] || $(JAVA_HOME)/bin/keytool -genkeypair -validity 10000 -dname "CN=$(APP_COMPANY_NAME),O=Android,C=ES" -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -alias $(PROJECT_NAME)Key -keyalg RSA
|
||||
endif
|
||||
|
||||
# Config project package and resource using AndroidManifest.xml and res/values/strings.xml
|
||||
# NOTE: Generates resources file: src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/R.java
|
||||
config_project_package:
|
||||
$(ANDROID_BUILD_TOOLS)/aapt package -f -m -S $(PROJECT_BUILD_PATH)/res -J $(PROJECT_BUILD_PATH)/src -M $(PROJECT_BUILD_PATH)/AndroidManifest.xml -I $(ANDROID_HOME)/platforms/android-$(ANDROID_API_VERSION)/android.jar
|
||||
|
||||
# Compile native_app_glue code as static library: obj/libnative_app_glue.a
|
||||
compile_native_app_glue:
|
||||
$(CC) -c $(NATIVE_APP_GLUE_PATH)/android_native_app_glue.c -o $(PROJECT_BUILD_PATH)/obj/native_app_glue.o $(CFLAGS)
|
||||
$(AR) rcs $(PROJECT_BUILD_PATH)/obj/libnative_app_glue.a $(PROJECT_BUILD_PATH)/obj/native_app_glue.o
|
||||
|
||||
# Compile project code into a shared library: lib/lib$(PROJECT_LIBRARY_NAME).so
|
||||
compile_project_code: $(OBJS)
|
||||
$(CC) -o $(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)/lib$(PROJECT_LIBRARY_NAME).so $(OBJS) -shared $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
# Compile all .c files required into object (.o) files
|
||||
# NOTE: Those files will be linked into a shared library
|
||||
$(PROJECT_BUILD_PATH)/obj/%.o:%.c
|
||||
$(CC) -c $^ -o $@ $(INCLUDE_PATHS) $(CFLAGS) --sysroot=$(ANDROID_TOOLCHAIN)/sysroot
|
||||
|
||||
# Compile project .java code into .class (Java bytecode)
|
||||
compile_project_class:
|
||||
$(JAVA_HOME)/bin/javac -verbose -source 1.7 -target 1.7 -d $(PROJECT_BUILD_PATH)/obj -bootclasspath $(JAVA_HOME)/jre/lib/rt.jar -classpath $(ANDROID_HOME)/platforms/android-$(ANDROID_API_VERSION)/android.jar -d $(PROJECT_BUILD_PATH)/obj $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/R.java $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
|
||||
|
||||
# Compile .class files into Dalvik executable bytecode (.dex)
|
||||
# NOTE: Since Android 5.0, Dalvik interpreter (JIT) has been replaced by ART (AOT)
|
||||
compile_project_class_dex:
|
||||
$(ANDROID_BUILD_TOOLS)/dx --verbose --dex --output=$(PROJECT_BUILD_PATH)/bin/classes.dex $(PROJECT_BUILD_PATH)/obj
|
||||
|
||||
# Create Android APK package: bin/$(PROJECT_NAME).unsigned.apk
|
||||
# NOTE: Requires compiled classes.dex and lib$(PROJECT_LIBRARY_NAME).so
|
||||
# NOTE: Use -A resources to define additional directory in which to find raw asset files
|
||||
create_project_apk_package:
|
||||
$(ANDROID_BUILD_TOOLS)/aapt package -f -M $(PROJECT_BUILD_PATH)/AndroidManifest.xml -S $(PROJECT_BUILD_PATH)/res -A $(PROJECT_BUILD_PATH)/assets -I $(ANDROID_HOME)/platforms/android-$(ANDROID_API_VERSION)/android.jar -F $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).unsigned.apk $(PROJECT_BUILD_PATH)/bin
|
||||
cd $(PROJECT_BUILD_PATH) && $(ANDROID_BUILD_TOOLS)/aapt add bin/$(PROJECT_NAME).unsigned.apk lib/$(ANDROID_ARCH_NAME)/lib$(PROJECT_LIBRARY_NAME).so $(PROJECT_SHARED_LIBS)
|
||||
|
||||
# Create signed APK package using generated Key: bin/$(PROJECT_NAME).signed.apk
|
||||
sign_project_apk_package:
|
||||
$(JAVA_HOME)/bin/jarsigner -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -signedjar $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).signed.apk $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).unsigned.apk $(PROJECT_NAME)Key
|
||||
|
||||
# Create zip-aligned APK package: $(PROJECT_NAME).apk
|
||||
zipalign_project_apk_package:
|
||||
$(ANDROID_BUILD_TOOLS)/zipalign -f 4 $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).signed.apk $(PROJECT_NAME).apk
|
||||
|
||||
# Install $(PROJECT_NAME).apk to default emulator/device
|
||||
# NOTE: Use -e (emulator) or -d (device) parameters if required
|
||||
install:
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
|
||||
|
||||
# Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
|
||||
check_device_abi:
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb shell getprop ro.product.cpu.abi
|
||||
|
||||
# Monitorize output log coming from device, only raylib tag
|
||||
logcat:
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb logcat -c
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb logcat raylib:V *:S
|
||||
|
||||
# Install and monitorize $(PROJECT_NAME).apk to default emulator/device
|
||||
deploy:
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb logcat -c
|
||||
$(ANDROID_PLATFORM_TOOLS)/adb logcat raylib:V *:S
|
||||
|
||||
#$(ANDROID_PLATFORM_TOOLS)/adb logcat *:W
|
||||
|
||||
# Clean everything
|
||||
clean:
|
||||
ifeq ($(OS),Windows_NT)
|
||||
del $(PROJECT_BUILD_PATH)\* /f /s /q
|
||||
rmdir $(PROJECT_BUILD_PATH) /s /q
|
||||
else
|
||||
rm -r $(PROJECT_BUILD_PATH)
|
||||
endif
|
||||
@echo Cleaning done
|
||||
1232
raylib/examples/Makefile.Web
Normal file
209
raylib/examples/README.md
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
## Building the Examples
|
||||
|
||||
The examples assume you have already built the `raylib` library in `../src`.
|
||||
|
||||
### With GNU make
|
||||
|
||||
- `make` builds all examples
|
||||
- `make [module]` builds all examples for a particular module (e.g `make core`)
|
||||
|
||||
### With Zig
|
||||
|
||||
The [Zig](https://ziglang.org/) toolchain can compile `C` and `C++` in addition to `Zig`.
|
||||
You may find it easier to use than other toolchains, especially when it comes to cross-compiling.
|
||||
|
||||
- `zig build` to compile all examples
|
||||
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
||||
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||
|
||||
## EXAMPLES LIST
|
||||
|
||||
### category: core
|
||||
|
||||
Examples using raylib core platform functionality like window creation, inputs, drawing modes and system functionality.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 01 | [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||
| 02 | [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||
| 03 | [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 04 | [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐️☆☆☆ | 1.1 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||
| 05 | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐️☆☆☆ | 1.1 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 06 | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐️☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
|
||||
| 07 | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 08 | [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐️⭐️☆☆ | **5.0** | **5.0** | [oblerion](https://github.com/oblerion) |
|
||||
| 09 | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||
| 10 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| 11 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) |
|
||||
| 12 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) |
|
||||
| 13 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||
| 14 | [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||
| 15 | [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||
| 16 | [core_3d_camera:split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.0** | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| 17 | [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 18 | [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.4 | [Ray](https://github.com/raysan5) |
|
||||
| 19 | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
|
||||
| 20 | [core_window_flags](core/core_window_flags.c) | <img src="core/core_window_flags.png" alt="core_window_flags" width="80"> | ⭐️⭐️⭐️☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 21 | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) |
|
||||
| 22 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 23 | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 24 | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) |
|
||||
| 25 | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 26 | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 27 | [core_loading_thread](core/core_loading_thread.c) | <img src="core/core_loading_thread.png" alt="core_loading_thread" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||
| 28 | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
||||
| 29 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 30 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 31 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
|
||||
| 32 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 33 | [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐️☆☆☆ | **5.0** | **5.0** | [REDl3east](https://github.com/REDl3east) |
|
||||
|
||||
### category: shapes
|
||||
|
||||
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/shapes.c) module.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 34 | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 35 | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐️☆☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 36 | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐️⭐️☆☆ | 1.0 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 37 | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||
| 38 | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 39 | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 40 | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐️☆☆☆ | 1.7 | 1.7 | [Ray](https://github.com/raysan5) |
|
||||
| 41 | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 42 | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 43 | [shapes_easings_ball_anim](shapes/shapes_easings_ball_anim.c) | <img src="shapes/shapes_easings_ball_anim.png" alt="shapes_easings_ball_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 44 | [shapes_easings_box_anim](shapes/shapes_easings_box_anim.c) | <img src="shapes/shapes_easings_box_anim.png" alt="shapes_easings_box_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 45 | [shapes_easings_rectangle_array](shapes/shapes_easings_rectangle_array.c) | <img src="shapes/shapes_easings_rectangle_array.png" alt="shapes_easings_rectangle_array" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 46 | [shapes_draw_ring](shapes/shapes_draw_ring.c) | <img src="shapes/shapes_draw_ring.png" alt="shapes_draw_ring" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 47 | [shapes_draw_circle_sector](shapes/shapes_draw_circle_sector.c) | <img src="shapes/shapes_draw_circle_sector.png" alt="shapes_draw_circle_sector" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 48 | [shapes_draw_rectangle_rounded](shapes/shapes_draw_rectangle_rounded.c) | <img src="shapes/shapes_draw_rectangle_rounded.png" alt="shapes_draw_rectangle_rounded" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 49 | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐️⭐️⭐️⭐️ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| 50 | [shapes_rectangle_advanced](shapes/shapes_rectangle_advanced.c) | <img src="shapes/shapes_rectangle_advanced.png" alt="shapes_rectangle_advanced" width="80"> | ⭐️⭐️⭐️⭐️⭐️| **5.0** | **5.0** | [ExCyber](https://github.com/evertonse) |
|
||||
|
||||
### category: textures
|
||||
|
||||
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/textures.c) module.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 51 | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||
| 52 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||
| 53 | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
|
||||
| 54 | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | 1.8 | [Ray](https://github.com/raysan5) |
|
||||
| 55 | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||
| 56 | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 57 | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 58 | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐️☆☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 59 | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 60 | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 61 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
|
||||
| 62 | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 63 | [textures_sprite_anim](textures/textures_sprite_anim.c) | <img src="textures/textures_sprite_anim.png" alt="textures_sprite_anim" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||
| 64 | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 65 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 66 | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||
| 67 | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
||||
| 68 | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
|
||||
| 69 | [textures_draw_tiled](textures/textures_draw_tiled.c) | <img src="textures/textures_draw_tiled.png" alt="textures_draw_tiled" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | **4.2** | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 70 | [textures_polygon](textures/textures_polygon.c) | <img src="textures/textures_polygon.png" alt="textures_polygon" width="80"> | ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||
| 71 | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 72 | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
|
||||
### category: text
|
||||
|
||||
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/text.c) module.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 73 | [text_raylib_fonts](text/text_raylib_fonts.c) | <img src="text/text_raylib_fonts.png" alt="text_raylib_fonts" width="80"> | ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
|
||||
| 74 | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||
| 75 | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 76 | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||
| 77 | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 78 | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||
| 79 | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 80 | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
|
||||
| 81 | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 82 | [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 83 | [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐️⭐️⭐️⭐️ | 3.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| 84 | [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
|
||||
### category: models
|
||||
|
||||
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/models.c) module.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 85 | [models_animation](models/models_animation.c) | <img src="models/models_animation.png" alt="models_animation" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [culacant](https://github.com/culacant) |
|
||||
| 86 | [models_billboard](models/models_billboard.c) | <img src="models/models_billboard.png" alt="models_billboard" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 87 | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 88 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="80"> | ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 89 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 90 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 91 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 92 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐️⭐️⭐️☆ | 1.7 | **4.0** | [Joel Davis](https://github.com/joeld42) |
|
||||
| 93 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐️☆☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 94 | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐️☆☆☆ | 3.7 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 95 | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Johann Nadalutti](https://github.com/procfxgen) |
|
||||
| 96 | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [bzt](https://bztsrc.gitlab.io/model3d) |
|
||||
| 97 | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
|
||||
| 98 | [models_point_rendering](models/models_point_rendering.c) | <img src="models/models_point_rendering.png" alt="models_point_rendering" width="80"> | ⭐️⭐️☆☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) |
|
||||
| 99 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 100 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Berni](https://github.com/Berni8k) |
|
||||
| 101 | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [codecat](https://github.com/codecat) |
|
||||
| 102 | [models_heightmap](models/models_heightmap.c) | <img src="models/models_heightmap.png" alt="models_heightmap" width="80"> | ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 103 | [models_skybox](models/models_skybox.c) | <img src="models/models_skybox.png" alt="models_skybox" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
|
||||
### category: shaders
|
||||
|
||||
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 104 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐️⭐️⭐️⭐️ | 3.0 | **4.2** | [Chris Camacho](https://github.com/codifies) |
|
||||
| 105 | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) |
|
||||
| 106 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
|
||||
| 107 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 108 | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 109 | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
|
||||
| 110 | [shaders_raymarching](shaders/shaders_raymarching.c) | <img src="shaders/shaders_raymarching.png" alt="shaders_raymarching" width="80"> | ⭐️⭐️⭐️⭐️ | 2.0 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 111 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) | <img src="shaders/shaders_texture_drawing.png" alt="shaders_texture_drawing" width="80"> | ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/) |
|
||||
| 112 | [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐️⭐️⭐️☆ | **4.0** | **4.0** | [Samuel Skiff](https://github.com/GoldenThumbs) |
|
||||
| 113 | [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
|
||||
| 114 | [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [eggmund](https://github.com/eggmund) |
|
||||
| 115 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) | <img src="shaders/shaders_eratosthenes.png" alt="shaders_eratosthenes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [ProfJski](https://github.com/ProfJski) |
|
||||
| 116 | [shaders_fog](shaders/shaders_fog.c) | <img src="shaders/shaders_fog.png" alt="shaders_fog" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||
| 117 | [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||
| 118 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 119 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) |
|
||||
| 120 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 121 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||
| 122 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
|
||||
|
||||
### category: audio
|
||||
|
||||
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib, check [raudio_standalone](others/raudio_standalone.c) example.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 123 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
| 124 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 125 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 126 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||
|
||||
### category: others
|
||||
|
||||
Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.
|
||||
|
||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||
| 127 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 128 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
|
||||
| 129 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
| 130 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
|
||||
| 131 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
||||
|
||||
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
|
||||
|
||||
123
raylib/examples/audio/audio_mixed_processor.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Mixed audio processing
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
*
|
||||
* Example contributed by hkc (@hatkidchan) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 hkc (@hatkidchan)
|
||||
*
|
||||
********************************************************************************************/
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
|
||||
static float exponent = 1.0f; // Audio exponentiation value
|
||||
static float averageVolume[400] = { 0.0f }; // Average volume history
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio processing function
|
||||
//------------------------------------------------------------------------------------
|
||||
void ProcessAudio(void *buffer, unsigned int frames)
|
||||
{
|
||||
float *samples = (float *)buffer; // Samples internally stored as <float>s
|
||||
float average = 0.0f; // Temporary average volume
|
||||
|
||||
for (unsigned int frame = 0; frame < frames; frame++)
|
||||
{
|
||||
float *left = &samples[frame * 2 + 0], *right = &samples[frame * 2 + 1];
|
||||
|
||||
*left = powf(fabsf(*left), exponent) * ( (*left < 0.0f)? -1.0f : 1.0f );
|
||||
*right = powf(fabsf(*right), exponent) * ( (*right < 0.0f)? -1.0f : 1.0f );
|
||||
|
||||
average += fabsf(*left) / frames; // accumulating average volume
|
||||
average += fabsf(*right) / frames;
|
||||
}
|
||||
|
||||
// Moving history to the left
|
||||
for (int i = 0; i < 399; i++) averageVolume[i] = averageVolume[i + 1];
|
||||
|
||||
averageVolume[399] = average; // Adding last average value
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
AttachAudioMixedProcessor(ProcessAudio);
|
||||
|
||||
Music music = LoadMusicStream("resources/country.mp3");
|
||||
Sound sound = LoadSound("resources/coin.wav");
|
||||
|
||||
PlayMusicStream(music);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateMusicStream(music); // Update music buffer with new stream data
|
||||
|
||||
// Modify processing variables
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_LEFT)) exponent -= 0.05f;
|
||||
if (IsKeyPressed(KEY_RIGHT)) exponent += 0.05f;
|
||||
|
||||
if (exponent <= 0.5f) exponent = 0.5f;
|
||||
if (exponent >= 3.0f) exponent = 3.0f;
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) PlaySound(sound);
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
|
||||
|
||||
DrawText(TextFormat("EXPONENT = %.2f", exponent), 215, 180, 20, LIGHTGRAY);
|
||||
|
||||
DrawRectangle(199, 199, 402, 34, LIGHTGRAY);
|
||||
for (int i = 0; i < 400; i++)
|
||||
{
|
||||
DrawLine(201 + i, 232 - (int)(averageVolume[i] * 32), 201 + i, 232, MAROON);
|
||||
}
|
||||
DrawRectangleLines(199, 199, 402, 34, GRAY);
|
||||
|
||||
DrawText("PRESS SPACE TO PLAY OTHER SOUND", 200, 250, 20, LIGHTGRAY);
|
||||
DrawText("USE LEFT AND RIGHT ARROWS TO ALTER DISTORTION", 140, 280, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadMusicStream(music); // Unload music stream buffers from RAM
|
||||
|
||||
DetachAudioMixedProcessor(ProcessAudio); // Disconnect audio processor
|
||||
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_mixed_processor.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
160
raylib/examples/audio/audio_module_playing.c
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Module playing (streaming)
|
||||
*
|
||||
* Example originally created with raylib 1.5, last time updated with raylib 3.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2016-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_CIRCLES 64
|
||||
|
||||
typedef struct {
|
||||
Vector2 position;
|
||||
float radius;
|
||||
float alpha;
|
||||
float speed;
|
||||
Color color;
|
||||
} CircleWave;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
Color colors[14] = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK,
|
||||
YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE };
|
||||
|
||||
// Creates some circles for visual effect
|
||||
CircleWave circles[MAX_CIRCLES] = { 0 };
|
||||
|
||||
for (int i = MAX_CIRCLES - 1; i >= 0; i--)
|
||||
{
|
||||
circles[i].alpha = 0.0f;
|
||||
circles[i].radius = (float)GetRandomValue(10, 40);
|
||||
circles[i].position.x = (float)GetRandomValue((int)circles[i].radius, (int)(screenWidth - circles[i].radius));
|
||||
circles[i].position.y = (float)GetRandomValue((int)circles[i].radius, (int)(screenHeight - circles[i].radius));
|
||||
circles[i].speed = (float)GetRandomValue(1, 100)/2000.0f;
|
||||
circles[i].color = colors[GetRandomValue(0, 13)];
|
||||
}
|
||||
|
||||
Music music = LoadMusicStream("resources/mini1111.xm");
|
||||
music.looping = false;
|
||||
float pitch = 1.0f;
|
||||
|
||||
PlayMusicStream(music);
|
||||
|
||||
float timePlayed = 0.0f;
|
||||
bool pause = false;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateMusicStream(music); // Update music buffer with new stream data
|
||||
|
||||
// Restart music playing (stop and play)
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
StopMusicStream(music);
|
||||
PlayMusicStream(music);
|
||||
pause = false;
|
||||
}
|
||||
|
||||
// Pause/Resume music playing
|
||||
if (IsKeyPressed(KEY_P))
|
||||
{
|
||||
pause = !pause;
|
||||
|
||||
if (pause) PauseMusicStream(music);
|
||||
else ResumeMusicStream(music);
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_DOWN)) pitch -= 0.01f;
|
||||
else if (IsKeyDown(KEY_UP)) pitch += 0.01f;
|
||||
|
||||
SetMusicPitch(music, pitch);
|
||||
|
||||
// Get timePlayed scaled to bar dimensions
|
||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*(screenWidth - 40);
|
||||
|
||||
// Color circles animation
|
||||
for (int i = MAX_CIRCLES - 1; (i >= 0) && !pause; i--)
|
||||
{
|
||||
circles[i].alpha += circles[i].speed;
|
||||
circles[i].radius += circles[i].speed*10.0f;
|
||||
|
||||
if (circles[i].alpha > 1.0f) circles[i].speed *= -1;
|
||||
|
||||
if (circles[i].alpha <= 0.0f)
|
||||
{
|
||||
circles[i].alpha = 0.0f;
|
||||
circles[i].radius = (float)GetRandomValue(10, 40);
|
||||
circles[i].position.x = (float)GetRandomValue((int)circles[i].radius, (int)(screenWidth - circles[i].radius));
|
||||
circles[i].position.y = (float)GetRandomValue((int)circles[i].radius, (int)(screenHeight - circles[i].radius));
|
||||
circles[i].color = colors[GetRandomValue(0, 13)];
|
||||
circles[i].speed = (float)GetRandomValue(1, 100)/2000.0f;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = MAX_CIRCLES - 1; i >= 0; i--)
|
||||
{
|
||||
DrawCircleV(circles[i].position, circles[i].radius, Fade(circles[i].color, circles[i].alpha));
|
||||
}
|
||||
|
||||
// Draw time bar
|
||||
DrawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, LIGHTGRAY);
|
||||
DrawRectangle(20, screenHeight - 20 - 12, (int)timePlayed, 12, MAROON);
|
||||
DrawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, GRAY);
|
||||
|
||||
// Draw help instructions
|
||||
DrawRectangle(20, 20, 425, 145, WHITE);
|
||||
DrawRectangleLines(20, 20, 425, 145, GRAY);
|
||||
DrawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, BLACK);
|
||||
DrawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, BLACK);
|
||||
DrawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, BLACK);
|
||||
DrawText(TextFormat("SPEED: %f", pitch), 40, 130, 20, MAROON);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadMusicStream(music); // Unload music stream buffers from RAM
|
||||
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_module_playing.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
98
raylib/examples/audio/audio_music_stream.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Music playing (streaming)
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
Music music = LoadMusicStream("resources/country.mp3");
|
||||
|
||||
PlayMusicStream(music);
|
||||
|
||||
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
|
||||
bool pause = false; // Music playing paused
|
||||
|
||||
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateMusicStream(music); // Update music buffer with new stream data
|
||||
|
||||
// Restart music playing (stop and play)
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
StopMusicStream(music);
|
||||
PlayMusicStream(music);
|
||||
}
|
||||
|
||||
// Pause/Resume music playing
|
||||
if (IsKeyPressed(KEY_P))
|
||||
{
|
||||
pause = !pause;
|
||||
|
||||
if (pause) PauseMusicStream(music);
|
||||
else ResumeMusicStream(music);
|
||||
}
|
||||
|
||||
// Get normalized time played for current music stream
|
||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
|
||||
|
||||
if (timePlayed > 1.0f) timePlayed = 1.0f; // Make sure time played is no longer than music
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
|
||||
|
||||
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
|
||||
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
|
||||
DrawRectangleLines(200, 200, 400, 12, GRAY);
|
||||
|
||||
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
|
||||
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadMusicStream(music); // Unload music stream buffers from RAM
|
||||
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_music_stream.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
214
raylib/examples/audio/audio_raw_stream.c
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Raw audio streaming
|
||||
*
|
||||
* Example originally created with raylib 1.6, last time updated with raylib 4.2
|
||||
*
|
||||
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
#include <math.h> // Required for: sinf()
|
||||
#include <string.h> // Required for: memcpy()
|
||||
|
||||
#define MAX_SAMPLES 512
|
||||
#define MAX_SAMPLES_PER_UPDATE 4096
|
||||
|
||||
// Cycles per second (hz)
|
||||
float frequency = 440.0f;
|
||||
|
||||
// Audio frequency, for smoothing
|
||||
float audioFrequency = 440.0f;
|
||||
|
||||
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
||||
float oldFrequency = 1.0f;
|
||||
|
||||
// Index for audio rendering
|
||||
float sineIdx = 0.0f;
|
||||
|
||||
// Audio input processing callback
|
||||
void AudioInputCallback(void *buffer, unsigned int frames)
|
||||
{
|
||||
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
|
||||
|
||||
float incr = audioFrequency/44100.0f;
|
||||
short *d = (short *)buffer;
|
||||
|
||||
for (unsigned int i = 0; i < frames; i++)
|
||||
{
|
||||
d[i] = (short)(32000.0f*sinf(2*PI*sineIdx));
|
||||
sineIdx += incr;
|
||||
if (sineIdx > 1.0f) sineIdx -= 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE);
|
||||
|
||||
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
|
||||
AudioStream stream = LoadAudioStream(44100, 16, 1);
|
||||
|
||||
SetAudioStreamCallback(stream, AudioInputCallback);
|
||||
|
||||
// Buffer for the single cycle waveform we are synthesizing
|
||||
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
|
||||
|
||||
// Frame buffer, describing the waveform when repeated over the course of a frame
|
||||
short *writeBuf = (short *)malloc(sizeof(short)*MAX_SAMPLES_PER_UPDATE);
|
||||
|
||||
PlayAudioStream(stream); // Start processing stream buffer (no data loaded currently)
|
||||
|
||||
// Position read in to determine next frequency
|
||||
Vector2 mousePosition = { -100.0f, -100.0f };
|
||||
|
||||
/*
|
||||
// Cycles per second (hz)
|
||||
float frequency = 440.0f;
|
||||
|
||||
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
||||
float oldFrequency = 1.0f;
|
||||
|
||||
// Cursor to read and copy the samples of the sine wave buffer
|
||||
int readCursor = 0;
|
||||
*/
|
||||
|
||||
// Computed size in samples of the sine wave
|
||||
int waveLength = 1;
|
||||
|
||||
Vector2 position = { 0, 0 };
|
||||
|
||||
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Sample mouse input.
|
||||
mousePosition = GetMousePosition();
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
float fp = (float)(mousePosition.y);
|
||||
frequency = 40.0f + (float)(fp);
|
||||
|
||||
float pan = (float)(mousePosition.x) / (float)screenWidth;
|
||||
SetAudioStreamPan(stream, pan);
|
||||
}
|
||||
|
||||
// Rewrite the sine wave
|
||||
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
|
||||
if (frequency != oldFrequency)
|
||||
{
|
||||
// Compute wavelength. Limit size in both directions.
|
||||
//int oldWavelength = waveLength;
|
||||
waveLength = (int)(22050/frequency);
|
||||
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
|
||||
if (waveLength < 1) waveLength = 1;
|
||||
|
||||
// Write sine wave
|
||||
for (int i = 0; i < waveLength*2; i++)
|
||||
{
|
||||
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
|
||||
}
|
||||
// Make sure the rest of the line is flat
|
||||
for (int j = waveLength*2; j < MAX_SAMPLES; j++)
|
||||
{
|
||||
data[j] = (short)0;
|
||||
}
|
||||
|
||||
// Scale read cursor's position to minimize transition artifacts
|
||||
//readCursor = (int)(readCursor * ((float)waveLength / (float)oldWavelength));
|
||||
oldFrequency = frequency;
|
||||
}
|
||||
|
||||
/*
|
||||
// Refill audio stream if required
|
||||
if (IsAudioStreamProcessed(stream))
|
||||
{
|
||||
// Synthesize a buffer that is exactly the requested size
|
||||
int writeCursor = 0;
|
||||
|
||||
while (writeCursor < MAX_SAMPLES_PER_UPDATE)
|
||||
{
|
||||
// Start by trying to write the whole chunk at once
|
||||
int writeLength = MAX_SAMPLES_PER_UPDATE-writeCursor;
|
||||
|
||||
// Limit to the maximum readable size
|
||||
int readLength = waveLength-readCursor;
|
||||
|
||||
if (writeLength > readLength) writeLength = readLength;
|
||||
|
||||
// Write the slice
|
||||
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
|
||||
|
||||
// Update cursors and loop audio
|
||||
readCursor = (readCursor + writeLength) % waveLength;
|
||||
|
||||
writeCursor += writeLength;
|
||||
}
|
||||
|
||||
// Copy finished frame to audio stream
|
||||
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
|
||||
}
|
||||
*/
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText(TextFormat("sine frequency: %i",(int)frequency), GetScreenWidth() - 220, 10, 20, RED);
|
||||
DrawText("click mouse button to change frequency or pan", 10, 10, 20, DARKGRAY);
|
||||
|
||||
// Draw the current buffer state proportionate to the screen
|
||||
for (int i = 0; i < screenWidth; i++)
|
||||
{
|
||||
position.x = (float)i;
|
||||
position.y = 250 + 50*data[i*MAX_SAMPLES/screenWidth]/32000.0f;
|
||||
|
||||
DrawPixelV(position, RED);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
free(data); // Unload sine wave data
|
||||
free(writeBuf); // Unload write buffer
|
||||
|
||||
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_raw_stream.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
69
raylib/examples/audio/audio_sound_loading.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Sound loading and playing
|
||||
*
|
||||
* Example originally created with raylib 1.1, last time updated with raylib 3.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
Sound fxWav = LoadSound("resources/sound.wav"); // Load WAV audio file
|
||||
Sound fxOgg = LoadSound("resources/target.ogg"); // Load OGG audio file
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE)) PlaySound(fxWav); // Play WAV sound
|
||||
if (IsKeyPressed(KEY_ENTER)) PlaySound(fxOgg); // Play OGG sound
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, LIGHTGRAY);
|
||||
DrawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadSound(fxWav); // Unload sound data
|
||||
UnloadSound(fxOgg); // Unload sound data
|
||||
|
||||
CloseAudioDevice(); // Close audio device
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_sound_loading.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
87
raylib/examples/audio/audio_sound_multi.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Playing sound multiple times
|
||||
*
|
||||
* Example originally created with raylib 4.6
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 Jeffery Myers (@JeffM2501)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_SOUNDS 10
|
||||
Sound soundArray[MAX_SOUNDS] = { 0 };
|
||||
int currentSound;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - playing sound multiple times");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
// load the sound list
|
||||
soundArray[0] = LoadSound("resources/sound.wav"); // Load WAV audio file into the first slot as the 'source' sound
|
||||
// this sound owns the sample data
|
||||
for (int i = 1; i < MAX_SOUNDS; i++)
|
||||
{
|
||||
soundArray[i] = LoadSoundAlias(soundArray[0]); // Load an alias of the sound into slots 1-9. These do not own the sound data, but can be played
|
||||
}
|
||||
currentSound = 0; // set the sound list to the start
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
PlaySound(soundArray[currentSound]); // play the next open sound slot
|
||||
currentSound++; // increment the sound slot
|
||||
if (currentSound >= MAX_SOUNDS) // if the sound slot is out of bounds, go back to 0
|
||||
currentSound = 0;
|
||||
|
||||
// Note: a better way would be to look at the list for the first sound that is not playing and use that slot
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Press SPACE to PLAY a WAV sound!", 200, 180, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 1; i < MAX_SOUNDS; i++)
|
||||
UnloadSoundAlias(soundArray[i]); // Unload sound aliases
|
||||
UnloadSound(soundArray[0]); // Unload source sound data
|
||||
|
||||
CloseAudioDevice(); // Close audio device
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_sound_multi.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
183
raylib/examples/audio/audio_stream_effects.c
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Music stream processing effects
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 5.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2022-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h> // Required for: NULL
|
||||
|
||||
// Required delay effect variables
|
||||
static float *delayBuffer = NULL;
|
||||
static unsigned int delayBufferSize = 0;
|
||||
static unsigned int delayReadIndex = 2;
|
||||
static unsigned int delayWriteIndex = 0;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static void AudioProcessEffectLPF(void *buffer, unsigned int frames); // Audio effect: lowpass filter
|
||||
static void AudioProcessEffectDelay(void *buffer, unsigned int frames); // Audio effect: delay
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - stream effects");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
Music music = LoadMusicStream("resources/country.mp3");
|
||||
|
||||
// Allocate buffer for the delay effect
|
||||
delayBufferSize = 48000*2; // 1 second delay (device sampleRate*channels)
|
||||
delayBuffer = (float *)RL_CALLOC(delayBufferSize, sizeof(float));
|
||||
|
||||
PlayMusicStream(music);
|
||||
|
||||
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
|
||||
bool pause = false; // Music playing paused
|
||||
|
||||
bool enableEffectLPF = false; // Enable effect low-pass-filter
|
||||
bool enableEffectDelay = false; // Enable effect delay (1 second)
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateMusicStream(music); // Update music buffer with new stream data
|
||||
|
||||
// Restart music playing (stop and play)
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
StopMusicStream(music);
|
||||
PlayMusicStream(music);
|
||||
}
|
||||
|
||||
// Pause/Resume music playing
|
||||
if (IsKeyPressed(KEY_P))
|
||||
{
|
||||
pause = !pause;
|
||||
|
||||
if (pause) PauseMusicStream(music);
|
||||
else ResumeMusicStream(music);
|
||||
}
|
||||
|
||||
// Add/Remove effect: lowpass filter
|
||||
if (IsKeyPressed(KEY_F))
|
||||
{
|
||||
enableEffectLPF = !enableEffectLPF;
|
||||
if (enableEffectLPF) AttachAudioStreamProcessor(music.stream, AudioProcessEffectLPF);
|
||||
else DetachAudioStreamProcessor(music.stream, AudioProcessEffectLPF);
|
||||
}
|
||||
|
||||
// Add/Remove effect: delay
|
||||
if (IsKeyPressed(KEY_D))
|
||||
{
|
||||
enableEffectDelay = !enableEffectDelay;
|
||||
if (enableEffectDelay) AttachAudioStreamProcessor(music.stream, AudioProcessEffectDelay);
|
||||
else DetachAudioStreamProcessor(music.stream, AudioProcessEffectDelay);
|
||||
}
|
||||
|
||||
// Get normalized time played for current music stream
|
||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
|
||||
|
||||
if (timePlayed > 1.0f) timePlayed = 1.0f; // Make sure time played is no longer than music
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("MUSIC SHOULD BE PLAYING!", 245, 150, 20, LIGHTGRAY);
|
||||
|
||||
DrawRectangle(200, 180, 400, 12, LIGHTGRAY);
|
||||
DrawRectangle(200, 180, (int)(timePlayed*400.0f), 12, MAROON);
|
||||
DrawRectangleLines(200, 180, 400, 12, GRAY);
|
||||
|
||||
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 230, 20, LIGHTGRAY);
|
||||
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 260, 20, LIGHTGRAY);
|
||||
|
||||
DrawText(TextFormat("PRESS F TO TOGGLE LPF EFFECT: %s", enableEffectLPF? "ON" : "OFF"), 200, 320, 20, GRAY);
|
||||
DrawText(TextFormat("PRESS D TO TOGGLE DELAY EFFECT: %s", enableEffectDelay? "ON" : "OFF"), 180, 350, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadMusicStream(music); // Unload music stream buffers from RAM
|
||||
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
RL_FREE(delayBuffer); // Free delay buffer
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio effect: lowpass filter
|
||||
static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
|
||||
{
|
||||
static float low[2] = { 0.0f, 0.0f };
|
||||
static const float cutoff = 70.0f / 44100.0f; // 70 Hz lowpass filter
|
||||
const float k = cutoff / (cutoff + 0.1591549431f); // RC filter formula
|
||||
|
||||
// Converts the buffer data before using it
|
||||
float *bufferData = (float *)buffer;
|
||||
for (unsigned int i = 0; i < frames*2; i += 2)
|
||||
{
|
||||
const float l = bufferData[i];
|
||||
const float r = bufferData[i + 1];
|
||||
|
||||
low[0] += k * (l - low[0]);
|
||||
low[1] += k * (r - low[1]);
|
||||
bufferData[i] = low[0];
|
||||
bufferData[i + 1] = low[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Audio effect: delay
|
||||
static void AudioProcessEffectDelay(void *buffer, unsigned int frames)
|
||||
{
|
||||
for (unsigned int i = 0; i < frames*2; i += 2)
|
||||
{
|
||||
float leftDelay = delayBuffer[delayReadIndex++]; // ERROR: Reading buffer -> WHY??? Maybe thread related???
|
||||
float rightDelay = delayBuffer[delayReadIndex++];
|
||||
|
||||
if (delayReadIndex == delayBufferSize) delayReadIndex = 0;
|
||||
|
||||
((float *)buffer)[i] = 0.5f*((float *)buffer)[i] + 0.5f*leftDelay;
|
||||
((float *)buffer)[i + 1] = 0.5f*((float *)buffer)[i + 1] + 0.5f*rightDelay;
|
||||
|
||||
delayBuffer[delayWriteIndex++] = ((float *)buffer)[i];
|
||||
delayBuffer[delayWriteIndex++] = ((float *)buffer)[i + 1];
|
||||
if (delayWriteIndex == delayBufferSize) delayWriteIndex = 0;
|
||||
}
|
||||
}
|
||||
BIN
raylib/examples/audio/audio_stream_effects.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
10
raylib/examples/audio/resources/LICENSE.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
| resource | author | licence | notes |
|
||||
| :------------------- | :---------: | :------ | :---- |
|
||||
| country.mp3 | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Originally created for "DART that TARGET" game |
|
||||
| target.ogg | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Originally created for "DART that TARGET" game |
|
||||
| target.flac | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Originally created for "DART that TARGET" game |
|
||||
| coin.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
|
||||
| sound.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
|
||||
| spring.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
|
||||
| weird.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
|
||||
| mini1111.xm | [tPORt](https://modarchive.org/index.php?request=view_by_moduleid&query=51891) | [Mod Archive Distribution license](https://modarchive.org/index.php?terms-upload) | - |
|
||||
BIN
raylib/examples/audio/resources/coin.wav
Normal file
BIN
raylib/examples/audio/resources/country.mp3
Normal file
BIN
raylib/examples/audio/resources/mini1111.xm
Normal file
BIN
raylib/examples/audio/resources/sound.wav
Normal file
BIN
raylib/examples/audio/resources/spring.wav
Normal file
BIN
raylib/examples/audio/resources/target.flac
Normal file
BIN
raylib/examples/audio/resources/target.ogg
Normal file
BIN
raylib/examples/audio/resources/target.qoa
Normal file
BIN
raylib/examples/audio/resources/weird.wav
Normal file
110
raylib/examples/build.zig
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
// This has been tested to work with zig 0.12.0
|
||||
fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) !*std.Build.Step {
|
||||
if (target.result.os.tag == .emscripten) {
|
||||
@panic("Emscripten building via Zig unsupported");
|
||||
}
|
||||
|
||||
const all = b.step(module, "All " ++ module ++ " examples");
|
||||
var dir = try std.fs.cwd().openDir(module, .{ .iterate = true });
|
||||
defer if (comptime builtin.zig_version.minor >= 12) dir.close();
|
||||
|
||||
var iter = dir.iterate();
|
||||
while (try iter.next()) |entry| {
|
||||
if (entry.kind != .file) continue;
|
||||
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
|
||||
const name = entry.name[0..extension_idx];
|
||||
const path = try std.fs.path.join(b.allocator, &.{ module, entry.name });
|
||||
|
||||
// zig's mingw headers do not include pthread.h
|
||||
if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue;
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = name,
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
|
||||
exe.linkLibC();
|
||||
exe.addObjectFile(switch (target.result.os.tag) {
|
||||
.windows => b.path("../zig-out/lib/raylib.lib"),
|
||||
.linux => b.path("../zig-out/lib/libraylib.a"),
|
||||
.macos => b.path("../zig-out/lib/libraylib.a"),
|
||||
.emscripten => b.path("../zig-out/lib/libraylib.a"),
|
||||
else => @panic("Unsupported OS"),
|
||||
});
|
||||
|
||||
exe.addIncludePath(b.path("../src"));
|
||||
exe.addIncludePath(b.path("../src/external"));
|
||||
exe.addIncludePath(b.path("../src/external/glfw/include"));
|
||||
|
||||
switch (target.result.os.tag) {
|
||||
.windows => {
|
||||
exe.linkSystemLibrary("winmm");
|
||||
exe.linkSystemLibrary("gdi32");
|
||||
exe.linkSystemLibrary("opengl32");
|
||||
|
||||
exe.defineCMacro("PLATFORM_DESKTOP", null);
|
||||
},
|
||||
.linux => {
|
||||
exe.linkSystemLibrary("GL");
|
||||
exe.linkSystemLibrary("rt");
|
||||
exe.linkSystemLibrary("dl");
|
||||
exe.linkSystemLibrary("m");
|
||||
exe.linkSystemLibrary("X11");
|
||||
|
||||
exe.defineCMacro("PLATFORM_DESKTOP", null);
|
||||
},
|
||||
.macos => {
|
||||
exe.linkFramework("Foundation");
|
||||
exe.linkFramework("Cocoa");
|
||||
exe.linkFramework("OpenGL");
|
||||
exe.linkFramework("CoreAudio");
|
||||
exe.linkFramework("CoreVideo");
|
||||
exe.linkFramework("IOKit");
|
||||
|
||||
exe.defineCMacro("PLATFORM_DESKTOP", null);
|
||||
},
|
||||
else => {
|
||||
@panic("Unsupported OS");
|
||||
},
|
||||
}
|
||||
|
||||
const install_cmd = b.addInstallArtifact(exe, .{});
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.cwd = b.path(module);
|
||||
run_cmd.step.dependOn(&install_cmd.step);
|
||||
|
||||
const run_step = b.step(name, name);
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
all.dependOn(&install_cmd.step);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
// Standard optimization options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const all = b.getInstallStep();
|
||||
|
||||
all.dependOn(try add_module("audio", b, target, optimize));
|
||||
all.dependOn(try add_module("core", b, target, optimize));
|
||||
all.dependOn(try add_module("models", b, target, optimize));
|
||||
all.dependOn(try add_module("others", b, target, optimize));
|
||||
all.dependOn(try add_module("shaders", b, target, optimize));
|
||||
all.dependOn(try add_module("shapes", b, target, optimize));
|
||||
all.dependOn(try add_module("text", b, target, optimize));
|
||||
all.dependOn(try add_module("textures", b, target, optimize));
|
||||
}
|
||||
136
raylib/examples/core/core_2d_camera.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 2D Camera system
|
||||
*
|
||||
* Example originally created with raylib 1.5, last time updated with raylib 3.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2016-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_BUILDINGS 100
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
|
||||
|
||||
Rectangle player = { 400, 280, 40, 40 };
|
||||
Rectangle buildings[MAX_BUILDINGS] = { 0 };
|
||||
Color buildColors[MAX_BUILDINGS] = { 0 };
|
||||
|
||||
int spacing = 0;
|
||||
|
||||
for (int i = 0; i < MAX_BUILDINGS; i++)
|
||||
{
|
||||
buildings[i].width = (float)GetRandomValue(50, 200);
|
||||
buildings[i].height = (float)GetRandomValue(100, 800);
|
||||
buildings[i].y = screenHeight - 130.0f - buildings[i].height;
|
||||
buildings[i].x = -6000.0f + spacing;
|
||||
|
||||
spacing += (int)buildings[i].width;
|
||||
|
||||
buildColors[i] = (Color){ GetRandomValue(200, 240), GetRandomValue(200, 240), GetRandomValue(200, 250), 255 };
|
||||
}
|
||||
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = (Vector2){ player.x + 20.0f, player.y + 20.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Player movement
|
||||
if (IsKeyDown(KEY_RIGHT)) player.x += 2;
|
||||
else if (IsKeyDown(KEY_LEFT)) player.x -= 2;
|
||||
|
||||
// Camera target follows player
|
||||
camera.target = (Vector2){ player.x + 20, player.y + 20 };
|
||||
|
||||
// Camera rotation controls
|
||||
if (IsKeyDown(KEY_A)) camera.rotation--;
|
||||
else if (IsKeyDown(KEY_S)) camera.rotation++;
|
||||
|
||||
// Limit camera rotation to 80 degrees (-40 to 40)
|
||||
if (camera.rotation > 40) camera.rotation = 40;
|
||||
else if (camera.rotation < -40) camera.rotation = -40;
|
||||
|
||||
// Camera zoom controls
|
||||
camera.zoom += ((float)GetMouseWheelMove()*0.05f);
|
||||
|
||||
if (camera.zoom > 3.0f) camera.zoom = 3.0f;
|
||||
else if (camera.zoom < 0.1f) camera.zoom = 0.1f;
|
||||
|
||||
// Camera reset (zoom and rotation)
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
camera.zoom = 1.0f;
|
||||
camera.rotation = 0.0f;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(camera);
|
||||
|
||||
DrawRectangle(-6000, 320, 13000, 8000, DARKGRAY);
|
||||
|
||||
for (int i = 0; i < MAX_BUILDINGS; i++) DrawRectangleRec(buildings[i], buildColors[i]);
|
||||
|
||||
DrawRectangleRec(player, RED);
|
||||
|
||||
DrawLine((int)camera.target.x, -screenHeight*10, (int)camera.target.x, screenHeight*10, GREEN);
|
||||
DrawLine(-screenWidth*10, (int)camera.target.y, screenWidth*10, (int)camera.target.y, GREEN);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
DrawText("SCREEN AREA", 640, 10, 20, RED);
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, 5, RED);
|
||||
DrawRectangle(0, 5, 5, screenHeight - 10, RED);
|
||||
DrawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, RED);
|
||||
DrawRectangle(0, screenHeight - 5, screenWidth, 5, RED);
|
||||
|
||||
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines( 10, 10, 250, 113, BLUE);
|
||||
|
||||
DrawText("Free 2d camera controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY);
|
||||
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
|
||||
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
|
||||
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_2d_camera.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
142
raylib/examples/core/core_2d_camera_mouse_zoom.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 2d camera mouse zoom
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2022-2024 Jeffery Myers (@JeffM2501)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "rlgl.h"
|
||||
#include "raymath.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main ()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera mouse zoom");
|
||||
|
||||
Camera2D camera = { 0 };
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_ONE)) zoomMode = 0;
|
||||
else if (IsKeyPressed(KEY_TWO)) zoomMode = 1;
|
||||
|
||||
// Translate based on mouse right click
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
Vector2 delta = GetMouseDelta();
|
||||
delta = Vector2Scale(delta, -1.0f/camera.zoom);
|
||||
camera.target = Vector2Add(camera.target, delta);
|
||||
}
|
||||
|
||||
if (zoomMode == 0)
|
||||
{
|
||||
// Zoom based on mouse wheel
|
||||
float wheel = GetMouseWheelMove();
|
||||
if (wheel != 0)
|
||||
{
|
||||
// Get the world point that is under the mouse
|
||||
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||
|
||||
// Set the offset to where the mouse is
|
||||
camera.offset = GetMousePosition();
|
||||
|
||||
// Set the target to match, so that the camera maps the world space point
|
||||
// under the cursor to the screen space point under the cursor at any zoom
|
||||
camera.target = mouseWorldPos;
|
||||
|
||||
// Zoom increment
|
||||
float scaleFactor = 1.0f + (0.25f*fabsf(wheel));
|
||||
if (wheel < 0) scaleFactor = 1.0f/scaleFactor;
|
||||
camera.zoom = Clamp(camera.zoom*scaleFactor, 0.125f, 64.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Zoom based on mouse right click
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT))
|
||||
{
|
||||
// Get the world point that is under the mouse
|
||||
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||
|
||||
// Set the offset to where the mouse is
|
||||
camera.offset = GetMousePosition();
|
||||
|
||||
// Set the target to match, so that the camera maps the world space point
|
||||
// under the cursor to the screen space point under the cursor at any zoom
|
||||
camera.target = mouseWorldPos;
|
||||
}
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
||||
{
|
||||
// Zoom increment
|
||||
float deltaX = GetMouseDelta().x;
|
||||
float scaleFactor = 1.0f + (0.01f*fabsf(deltaX));
|
||||
if (deltaX < 0) scaleFactor = 1.0f/scaleFactor;
|
||||
camera.zoom = Clamp(camera.zoom*scaleFactor, 0.125f, 64.0f);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(camera);
|
||||
|
||||
// Draw the 3d grid, rotated 90 degrees and centered around 0,0
|
||||
// just so we have something in the XY plane
|
||||
rlPushMatrix();
|
||||
rlTranslatef(0, 25*50, 0);
|
||||
rlRotatef(90, 1, 0, 0);
|
||||
DrawGrid(100, 50);
|
||||
rlPopMatrix();
|
||||
|
||||
// Draw a reference circle
|
||||
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 50, MAROON);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
// Draw mouse reference
|
||||
//Vector2 mousePos = GetWorldToScreen2D(GetMousePosition(), camera)
|
||||
DrawCircleV(GetMousePosition(), 4, DARKGRAY);
|
||||
DrawTextEx(GetFontDefault(), TextFormat("[%i, %i]", GetMouseX(), GetMouseY()),
|
||||
Vector2Add(GetMousePosition(), (Vector2){ -44, -24 }), 20, 2, BLACK);
|
||||
|
||||
DrawText("[1][2] Select mouse zoom mode (Wheel or Move)", 20, 20, 20, DARKGRAY);
|
||||
if (zoomMode == 0) DrawText("Mouse left button drag to move, mouse wheel to zoom", 20, 50, 20, DARKGRAY);
|
||||
else DrawText("Mouse left button drag to move, mouse press and move to zoom", 20, 50, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_2d_camera_mouse_zoom.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
301
raylib/examples/core/core_2d_camera_platformer.c
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 2D Camera platformer
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 3.0
|
||||
*
|
||||
* Example contributed by arvyy (@arvyy) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2024 arvyy (@arvyy)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#define G 400
|
||||
#define PLAYER_JUMP_SPD 350.0f
|
||||
#define PLAYER_HOR_SPD 200.0f
|
||||
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
float speed;
|
||||
bool canJump;
|
||||
} Player;
|
||||
|
||||
typedef struct EnvItem {
|
||||
Rectangle rect;
|
||||
int blocking;
|
||||
Color color;
|
||||
} EnvItem;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module functions declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta);
|
||||
void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
|
||||
void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
|
||||
void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
|
||||
void UpdateCameraEvenOutOnLanding(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
|
||||
void UpdateCameraPlayerBoundsPush(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
|
||||
|
||||
Player player = { 0 };
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
player.speed = 0;
|
||||
player.canJump = false;
|
||||
EnvItem envItems[] = {
|
||||
{{ 0, 0, 1000, 400 }, 0, LIGHTGRAY },
|
||||
{{ 0, 400, 1000, 200 }, 1, GRAY },
|
||||
{{ 300, 200, 400, 10 }, 1, GRAY },
|
||||
{{ 250, 300, 100, 10 }, 1, GRAY },
|
||||
{{ 650, 300, 100, 10 }, 1, GRAY }
|
||||
};
|
||||
|
||||
int envItemsLength = sizeof(envItems)/sizeof(envItems[0]);
|
||||
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
// Store pointers to the multiple update camera functions
|
||||
void (*cameraUpdaters[])(Camera2D*, Player*, EnvItem*, int, float, int, int) = {
|
||||
UpdateCameraCenter,
|
||||
UpdateCameraCenterInsideMap,
|
||||
UpdateCameraCenterSmoothFollow,
|
||||
UpdateCameraEvenOutOnLanding,
|
||||
UpdateCameraPlayerBoundsPush
|
||||
};
|
||||
|
||||
int cameraOption = 0;
|
||||
int cameraUpdatersLength = sizeof(cameraUpdaters)/sizeof(cameraUpdaters[0]);
|
||||
|
||||
char *cameraDescriptions[] = {
|
||||
"Follow player center",
|
||||
"Follow player center, but clamp to map edges",
|
||||
"Follow player center; smoothed",
|
||||
"Follow player center horizontally; update player center vertically after landing",
|
||||
"Player push camera on getting too close to screen edge"
|
||||
};
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
float deltaTime = GetFrameTime();
|
||||
|
||||
UpdatePlayer(&player, envItems, envItemsLength, deltaTime);
|
||||
|
||||
camera.zoom += ((float)GetMouseWheelMove()*0.05f);
|
||||
|
||||
if (camera.zoom > 3.0f) camera.zoom = 3.0f;
|
||||
else if (camera.zoom < 0.25f) camera.zoom = 0.25f;
|
||||
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
camera.zoom = 1.0f;
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_C)) cameraOption = (cameraOption + 1)%cameraUpdatersLength;
|
||||
|
||||
// Call update camera function by its pointer
|
||||
cameraUpdaters[cameraOption](&camera, &player, envItems, envItemsLength, deltaTime, screenWidth, screenHeight);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(LIGHTGRAY);
|
||||
|
||||
BeginMode2D(camera);
|
||||
|
||||
for (int i = 0; i < envItemsLength; i++) DrawRectangleRec(envItems[i].rect, envItems[i].color);
|
||||
|
||||
Rectangle playerRect = { player.position.x - 20, player.position.y - 40, 40.0f, 40.0f };
|
||||
DrawRectangleRec(playerRect, RED);
|
||||
|
||||
DrawCircleV(player.position, 5.0f, GOLD);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
DrawText("Controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- Right/Left to move", 40, 40, 10, DARKGRAY);
|
||||
DrawText("- Space to jump", 40, 60, 10, DARKGRAY);
|
||||
DrawText("- Mouse Wheel to Zoom in-out, R to reset zoom", 40, 80, 10, DARKGRAY);
|
||||
DrawText("- C to change camera mode", 40, 100, 10, DARKGRAY);
|
||||
DrawText("Current camera mode:", 20, 120, 10, BLACK);
|
||||
DrawText(cameraDescriptions[cameraOption], 40, 140, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta)
|
||||
{
|
||||
if (IsKeyDown(KEY_LEFT)) player->position.x -= PLAYER_HOR_SPD*delta;
|
||||
if (IsKeyDown(KEY_RIGHT)) player->position.x += PLAYER_HOR_SPD*delta;
|
||||
if (IsKeyDown(KEY_SPACE) && player->canJump)
|
||||
{
|
||||
player->speed = -PLAYER_JUMP_SPD;
|
||||
player->canJump = false;
|
||||
}
|
||||
|
||||
bool hitObstacle = false;
|
||||
for (int i = 0; i < envItemsLength; i++)
|
||||
{
|
||||
EnvItem *ei = envItems + i;
|
||||
Vector2 *p = &(player->position);
|
||||
if (ei->blocking &&
|
||||
ei->rect.x <= p->x &&
|
||||
ei->rect.x + ei->rect.width >= p->x &&
|
||||
ei->rect.y >= p->y &&
|
||||
ei->rect.y <= p->y + player->speed*delta)
|
||||
{
|
||||
hitObstacle = true;
|
||||
player->speed = 0.0f;
|
||||
p->y = ei->rect.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hitObstacle)
|
||||
{
|
||||
player->position.y += player->speed*delta;
|
||||
player->speed += G*delta;
|
||||
player->canJump = false;
|
||||
}
|
||||
else player->canJump = true;
|
||||
}
|
||||
|
||||
void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
||||
{
|
||||
camera->offset = (Vector2){ width/2.0f, height/2.0f };
|
||||
camera->target = player->position;
|
||||
}
|
||||
|
||||
void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
||||
{
|
||||
camera->target = player->position;
|
||||
camera->offset = (Vector2){ width/2.0f, height/2.0f };
|
||||
float minX = 1000, minY = 1000, maxX = -1000, maxY = -1000;
|
||||
|
||||
for (int i = 0; i < envItemsLength; i++)
|
||||
{
|
||||
EnvItem *ei = envItems + i;
|
||||
minX = fminf(ei->rect.x, minX);
|
||||
maxX = fmaxf(ei->rect.x + ei->rect.width, maxX);
|
||||
minY = fminf(ei->rect.y, minY);
|
||||
maxY = fmaxf(ei->rect.y + ei->rect.height, maxY);
|
||||
}
|
||||
|
||||
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera);
|
||||
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera);
|
||||
|
||||
if (max.x < width) camera->offset.x = width - (max.x - width/2);
|
||||
if (max.y < height) camera->offset.y = height - (max.y - height/2);
|
||||
if (min.x > 0) camera->offset.x = width/2 - min.x;
|
||||
if (min.y > 0) camera->offset.y = height/2 - min.y;
|
||||
}
|
||||
|
||||
void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
||||
{
|
||||
static float minSpeed = 30;
|
||||
static float minEffectLength = 10;
|
||||
static float fractionSpeed = 0.8f;
|
||||
|
||||
camera->offset = (Vector2){ width/2.0f, height/2.0f };
|
||||
Vector2 diff = Vector2Subtract(player->position, camera->target);
|
||||
float length = Vector2Length(diff);
|
||||
|
||||
if (length > minEffectLength)
|
||||
{
|
||||
float speed = fmaxf(fractionSpeed*length, minSpeed);
|
||||
camera->target = Vector2Add(camera->target, Vector2Scale(diff, speed*delta/length));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCameraEvenOutOnLanding(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
||||
{
|
||||
static float evenOutSpeed = 700;
|
||||
static int eveningOut = false;
|
||||
static float evenOutTarget;
|
||||
|
||||
camera->offset = (Vector2){ width/2.0f, height/2.0f };
|
||||
camera->target.x = player->position.x;
|
||||
|
||||
if (eveningOut)
|
||||
{
|
||||
if (evenOutTarget > camera->target.y)
|
||||
{
|
||||
camera->target.y += evenOutSpeed*delta;
|
||||
|
||||
if (camera->target.y > evenOutTarget)
|
||||
{
|
||||
camera->target.y = evenOutTarget;
|
||||
eveningOut = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
camera->target.y -= evenOutSpeed*delta;
|
||||
|
||||
if (camera->target.y < evenOutTarget)
|
||||
{
|
||||
camera->target.y = evenOutTarget;
|
||||
eveningOut = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->canJump && (player->speed == 0) && (player->position.y != camera->target.y))
|
||||
{
|
||||
eveningOut = 1;
|
||||
evenOutTarget = player->position.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCameraPlayerBoundsPush(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
||||
{
|
||||
static Vector2 bbox = { 0.2f, 0.2f };
|
||||
|
||||
Vector2 bboxWorldMin = GetScreenToWorld2D((Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height }, *camera);
|
||||
Vector2 bboxWorldMax = GetScreenToWorld2D((Vector2){ (1 + bbox.x)*0.5f*width, (1 + bbox.y)*0.5f*height }, *camera);
|
||||
camera->offset = (Vector2){ (1 - bbox.x)*0.5f * width, (1 - bbox.y)*0.5f*height };
|
||||
|
||||
if (player->position.x < bboxWorldMin.x) camera->target.x = player->position.x;
|
||||
if (player->position.y < bboxWorldMin.y) camera->target.y = player->position.y;
|
||||
if (player->position.x > bboxWorldMax.x) camera->target.x = bboxWorldMin.x + (player->position.x - bboxWorldMax.x);
|
||||
if (player->position.y > bboxWorldMax.y) camera->target.y = bboxWorldMin.y + (player->position.y - bboxWorldMax.y);
|
||||
}
|
||||
BIN
raylib/examples/core/core_2d_camera_platformer.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
167
raylib/examples/core/core_2d_camera_split_screen.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 2d camera split screen
|
||||
*
|
||||
* Addapted from the core_3d_camera_split_screen example:
|
||||
* https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_split_screen.c
|
||||
*
|
||||
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||
*
|
||||
* Example contributed by Gabriel dos Santos Sanches (@gabrielssanches) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 Gabriel dos Santos Sanches (@gabrielssanches)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define PLAYER_SIZE 40
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 440;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera split screen");
|
||||
|
||||
Rectangle player1 = { 200, 200, PLAYER_SIZE, PLAYER_SIZE };
|
||||
Rectangle player2 = { 250, 200, PLAYER_SIZE, PLAYER_SIZE };
|
||||
|
||||
Camera2D camera1 = { 0 };
|
||||
camera1.target = (Vector2){ player1.x, player1.y };
|
||||
camera1.offset = (Vector2){ 200.0f, 200.0f };
|
||||
camera1.rotation = 0.0f;
|
||||
camera1.zoom = 1.0f;
|
||||
|
||||
Camera2D camera2 = { 0 };
|
||||
camera2.target = (Vector2){ player2.x, player2.y };
|
||||
camera2.offset = (Vector2){ 200.0f, 200.0f };
|
||||
camera2.rotation = 0.0f;
|
||||
camera2.zoom = 1.0f;
|
||||
|
||||
RenderTexture screenCamera1 = LoadRenderTexture(screenWidth/2, screenHeight);
|
||||
RenderTexture screenCamera2 = LoadRenderTexture(screenWidth/2, screenHeight);
|
||||
|
||||
// Build a flipped rectangle the size of the split view to use for drawing later
|
||||
Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenCamera1.texture.width, (float)-screenCamera1.texture.height };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_S)) player1.y += 3.0f;
|
||||
else if (IsKeyDown(KEY_W)) player1.y -= 3.0f;
|
||||
if (IsKeyDown(KEY_D)) player1.x += 3.0f;
|
||||
else if (IsKeyDown(KEY_A)) player1.x -= 3.0f;
|
||||
|
||||
if (IsKeyDown(KEY_UP)) player2.y -= 3.0f;
|
||||
else if (IsKeyDown(KEY_DOWN)) player2.y += 3.0f;
|
||||
if (IsKeyDown(KEY_RIGHT)) player2.x += 3.0f;
|
||||
else if (IsKeyDown(KEY_LEFT)) player2.x -= 3.0f;
|
||||
|
||||
camera1.target = (Vector2){ player1.x, player1.y };
|
||||
camera2.target = (Vector2){ player2.x, player2.y };
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginTextureMode(screenCamera1);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(camera1);
|
||||
|
||||
// Draw full scene with first camera
|
||||
for (int i = 0; i < screenWidth/PLAYER_SIZE + 1; i++)
|
||||
{
|
||||
DrawLineV((Vector2){(float)PLAYER_SIZE*i, 0}, (Vector2){ (float)PLAYER_SIZE*i, (float)screenHeight}, LIGHTGRAY);
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++)
|
||||
{
|
||||
DrawLineV((Vector2){0, (float)PLAYER_SIZE*i}, (Vector2){ (float)screenWidth, (float)PLAYER_SIZE*i}, LIGHTGRAY);
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenWidth/PLAYER_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < screenHeight/PLAYER_SIZE; j++)
|
||||
{
|
||||
DrawText(TextFormat("[%i,%i]", i, j), 10 + PLAYER_SIZE*i, 15 + PLAYER_SIZE*j, 10, LIGHTGRAY);
|
||||
}
|
||||
}
|
||||
|
||||
DrawRectangleRec(player1, RED);
|
||||
DrawRectangleRec(player2, BLUE);
|
||||
EndMode2D();
|
||||
|
||||
DrawRectangle(0, 0, GetScreenWidth()/2, 30, Fade(RAYWHITE, 0.6f));
|
||||
DrawText("PLAYER1: W/S/A/D to move", 10, 10, 10, MAROON);
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
BeginTextureMode(screenCamera2);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(camera2);
|
||||
|
||||
// Draw full scene with second camera
|
||||
for (int i = 0; i < screenWidth/PLAYER_SIZE + 1; i++)
|
||||
{
|
||||
DrawLineV((Vector2){ (float)PLAYER_SIZE*i, 0}, (Vector2){ (float)PLAYER_SIZE*i, (float)screenHeight}, LIGHTGRAY);
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenHeight/PLAYER_SIZE + 1; i++)
|
||||
{
|
||||
DrawLineV((Vector2){0, (float)PLAYER_SIZE*i}, (Vector2){ (float)screenWidth, (float)PLAYER_SIZE*i}, LIGHTGRAY);
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenWidth/PLAYER_SIZE; i++)
|
||||
{
|
||||
for (int j = 0; j < screenHeight/PLAYER_SIZE; j++)
|
||||
{
|
||||
DrawText(TextFormat("[%i,%i]", i, j), 10 + PLAYER_SIZE*i, 15 + PLAYER_SIZE*j, 10, LIGHTGRAY);
|
||||
}
|
||||
}
|
||||
|
||||
DrawRectangleRec(player1, RED);
|
||||
DrawRectangleRec(player2, BLUE);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
DrawRectangle(0, 0, GetScreenWidth()/2, 30, Fade(RAYWHITE, 0.6f));
|
||||
DrawText("PLAYER2: UP/DOWN/LEFT/RIGHT to move", 10, 10, 10, DARKBLUE);
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
// Draw both views render textures to the screen side by side
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
|
||||
DrawTextureRec(screenCamera1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE);
|
||||
DrawTextureRec(screenCamera2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE);
|
||||
|
||||
DrawRectangle(GetScreenWidth()/2 - 2, 0, 4, GetScreenHeight(), LIGHTGRAY);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(screenCamera1); // Unload render texture
|
||||
UnloadRenderTexture(screenCamera2); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_2d_camera_split_screen.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
206
raylib/examples/core/core_3d_camera_first_person.c
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 3d camera first person
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "rcamera.h"
|
||||
|
||||
#define MAX_COLUMNS 20
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person");
|
||||
|
||||
// Define the camera to look into our 3d world (position, target, up vector)
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 0.0f, 2.0f, 4.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 60.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
int cameraMode = CAMERA_FIRST_PERSON;
|
||||
|
||||
// Generates some random columns
|
||||
float heights[MAX_COLUMNS] = { 0 };
|
||||
Vector3 positions[MAX_COLUMNS] = { 0 };
|
||||
Color colors[MAX_COLUMNS] = { 0 };
|
||||
|
||||
for (int i = 0; i < MAX_COLUMNS; i++)
|
||||
{
|
||||
heights[i] = (float)GetRandomValue(1, 12);
|
||||
positions[i] = (Vector3){ (float)GetRandomValue(-15, 15), heights[i]/2.0f, (float)GetRandomValue(-15, 15) };
|
||||
colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 };
|
||||
}
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Switch camera mode
|
||||
if (IsKeyPressed(KEY_ONE))
|
||||
{
|
||||
cameraMode = CAMERA_FREE;
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_TWO))
|
||||
{
|
||||
cameraMode = CAMERA_FIRST_PERSON;
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_THREE))
|
||||
{
|
||||
cameraMode = CAMERA_THIRD_PERSON;
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_FOUR))
|
||||
{
|
||||
cameraMode = CAMERA_ORBITAL;
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll
|
||||
}
|
||||
|
||||
// Switch camera projection
|
||||
if (IsKeyPressed(KEY_P))
|
||||
{
|
||||
if (camera.projection == CAMERA_PERSPECTIVE)
|
||||
{
|
||||
// Create isometric view
|
||||
cameraMode = CAMERA_THIRD_PERSON;
|
||||
// Note: The target distance is related to the render distance in the orthographic projection
|
||||
camera.position = (Vector3){ 0.0f, 2.0f, -100.0f };
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.projection = CAMERA_ORTHOGRAPHIC;
|
||||
camera.fovy = 20.0f; // near plane width in CAMERA_ORTHOGRAPHIC
|
||||
CameraYaw(&camera, -135 * DEG2RAD, true);
|
||||
CameraPitch(&camera, -45 * DEG2RAD, true, true, false);
|
||||
}
|
||||
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
||||
{
|
||||
// Reset to default view
|
||||
cameraMode = CAMERA_THIRD_PERSON;
|
||||
camera.position = (Vector3){ 0.0f, 2.0f, 10.0f };
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
camera.fovy = 60.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Update camera computes movement internally depending on the camera mode
|
||||
// Some default standard keyboard/mouse inputs are hardcoded to simplify use
|
||||
// For advanced camera controls, it's recommended to compute camera movement manually
|
||||
UpdateCamera(&camera, cameraMode); // Update camera
|
||||
|
||||
/*
|
||||
// Camera PRO usage example (EXPERIMENTAL)
|
||||
// This new camera function allows custom movement/rotation values to be directly provided
|
||||
// as input parameters, with this approach, rcamera module is internally independent of raylib inputs
|
||||
UpdateCameraPro(&camera,
|
||||
(Vector3){
|
||||
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
|
||||
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
|
||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
|
||||
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
|
||||
0.0f // Move up-down
|
||||
},
|
||||
(Vector3){
|
||||
GetMouseDelta().x*0.05f, // Rotation: yaw
|
||||
GetMouseDelta().y*0.05f, // Rotation: pitch
|
||||
0.0f // Rotation: roll
|
||||
},
|
||||
GetMouseWheelMove()*2.0f); // Move to target (zoom)
|
||||
*/
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawPlane((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector2){ 32.0f, 32.0f }, LIGHTGRAY); // Draw ground
|
||||
DrawCube((Vector3){ -16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, BLUE); // Draw a blue wall
|
||||
DrawCube((Vector3){ 16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, LIME); // Draw a green wall
|
||||
DrawCube((Vector3){ 0.0f, 2.5f, 16.0f }, 32.0f, 5.0f, 1.0f, GOLD); // Draw a yellow wall
|
||||
|
||||
// Draw some cubes around
|
||||
for (int i = 0; i < MAX_COLUMNS; i++)
|
||||
{
|
||||
DrawCube(positions[i], 2.0f, heights[i], 2.0f, colors[i]);
|
||||
DrawCubeWires(positions[i], 2.0f, heights[i], 2.0f, MAROON);
|
||||
}
|
||||
|
||||
// Draw player cube
|
||||
if (cameraMode == CAMERA_THIRD_PERSON)
|
||||
{
|
||||
DrawCube(camera.target, 0.5f, 0.5f, 0.5f, PURPLE);
|
||||
DrawCubeWires(camera.target, 0.5f, 0.5f, 0.5f, DARKPURPLE);
|
||||
}
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Draw info boxes
|
||||
DrawRectangle(5, 5, 330, 100, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(5, 5, 330, 100, BLUE);
|
||||
|
||||
DrawText("Camera controls:", 15, 15, 10, BLACK);
|
||||
DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK);
|
||||
DrawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK);
|
||||
DrawText("- Camera mode keys: 1, 2, 3, 4", 15, 60, 10, BLACK);
|
||||
DrawText("- Zoom keys: num-plus, num-minus or mouse scroll", 15, 75, 10, BLACK);
|
||||
DrawText("- Camera projection key: P", 15, 90, 10, BLACK);
|
||||
|
||||
DrawRectangle(600, 5, 195, 100, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(600, 5, 195, 100, BLUE);
|
||||
|
||||
DrawText("Camera status:", 610, 15, 10, BLACK);
|
||||
DrawText(TextFormat("- Mode: %s", (cameraMode == CAMERA_FREE) ? "FREE" :
|
||||
(cameraMode == CAMERA_FIRST_PERSON) ? "FIRST_PERSON" :
|
||||
(cameraMode == CAMERA_THIRD_PERSON) ? "THIRD_PERSON" :
|
||||
(cameraMode == CAMERA_ORBITAL) ? "ORBITAL" : "CUSTOM"), 610, 30, 10, BLACK);
|
||||
DrawText(TextFormat("- Projection: %s", (camera.projection == CAMERA_PERSPECTIVE) ? "PERSPECTIVE" :
|
||||
(camera.projection == CAMERA_ORTHOGRAPHIC) ? "ORTHOGRAPHIC" : "CUSTOM"), 610, 45, 10, BLACK);
|
||||
DrawText(TextFormat("- Position: (%06.3f, %06.3f, %06.3f)", camera.position.x, camera.position.y, camera.position.z), 610, 60, 10, BLACK);
|
||||
DrawText(TextFormat("- Target: (%06.3f, %06.3f, %06.3f)", camera.target.x, camera.target.y, camera.target.z), 610, 75, 10, BLACK);
|
||||
DrawText(TextFormat("- Up: (%06.3f, %06.3f, %06.3f)", camera.up.x, camera.up.y, camera.up.z), 610, 90, 10, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_3d_camera_first_person.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
86
raylib/examples/core/core_3d_camera_free.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Initialize 3d camera free
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera3D camera = { 0 };
|
||||
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_FREE);
|
||||
|
||||
if (IsKeyPressed('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawRectangle( 10, 10, 320, 93, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines( 10, 10, 320, 93, BLUE);
|
||||
|
||||
DrawText("Free camera default controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, DARKGRAY);
|
||||
DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, DARKGRAY);
|
||||
DrawText("- Z to zoom to (0, 0, 0)", 40, 80, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_3d_camera_free.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
78
raylib/examples/core/core_3d_camera_mode.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Initialize 3d camera mode
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera mode");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera3D camera = { 0 };
|
||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Welcome to the third dimension!", 10, 40, 20, DARKGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_3d_camera_mode.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
174
raylib/examples/core/core_3d_camera_split_screen.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 3d cmaera split screen
|
||||
*
|
||||
* Example originally created with raylib 3.7, last time updated with raylib 4.0
|
||||
*
|
||||
* Example contributed by Jeffery Myers (@JeffM2501) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2021-2024 Jeffery Myers (@JeffM2501)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera split screen");
|
||||
|
||||
// Setup player 1 camera and screen
|
||||
Camera cameraPlayer1 = { 0 };
|
||||
cameraPlayer1.fovy = 45.0f;
|
||||
cameraPlayer1.up.y = 1.0f;
|
||||
cameraPlayer1.target.y = 1.0f;
|
||||
cameraPlayer1.position.z = -3.0f;
|
||||
cameraPlayer1.position.y = 1.0f;
|
||||
|
||||
RenderTexture screenPlayer1 = LoadRenderTexture(screenWidth/2, screenHeight);
|
||||
|
||||
// Setup player two camera and screen
|
||||
Camera cameraPlayer2 = { 0 };
|
||||
cameraPlayer2.fovy = 45.0f;
|
||||
cameraPlayer2.up.y = 1.0f;
|
||||
cameraPlayer2.target.y = 3.0f;
|
||||
cameraPlayer2.position.x = -3.0f;
|
||||
cameraPlayer2.position.y = 3.0f;
|
||||
|
||||
RenderTexture screenPlayer2 = LoadRenderTexture(screenWidth / 2, screenHeight);
|
||||
|
||||
// Build a flipped rectangle the size of the split view to use for drawing later
|
||||
Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenPlayer1.texture.width, (float)-screenPlayer1.texture.height };
|
||||
|
||||
// Grid data
|
||||
int count = 5;
|
||||
float spacing = 4;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// If anyone moves this frame, how far will they move based on the time since the last frame
|
||||
// this moves thigns at 10 world units per second, regardless of the actual FPS
|
||||
float offsetThisFrame = 10.0f*GetFrameTime();
|
||||
|
||||
// Move Player1 forward and backwards (no turning)
|
||||
if (IsKeyDown(KEY_W))
|
||||
{
|
||||
cameraPlayer1.position.z += offsetThisFrame;
|
||||
cameraPlayer1.target.z += offsetThisFrame;
|
||||
}
|
||||
else if (IsKeyDown(KEY_S))
|
||||
{
|
||||
cameraPlayer1.position.z -= offsetThisFrame;
|
||||
cameraPlayer1.target.z -= offsetThisFrame;
|
||||
}
|
||||
|
||||
// Move Player2 forward and backwards (no turning)
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
cameraPlayer2.position.x += offsetThisFrame;
|
||||
cameraPlayer2.target.x += offsetThisFrame;
|
||||
}
|
||||
else if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
cameraPlayer2.position.x -= offsetThisFrame;
|
||||
cameraPlayer2.target.x -= offsetThisFrame;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw Player1 view to the render texture
|
||||
BeginTextureMode(screenPlayer1);
|
||||
ClearBackground(SKYBLUE);
|
||||
|
||||
BeginMode3D(cameraPlayer1);
|
||||
|
||||
// Draw scene: grid of cube trees on a plane to make a "world"
|
||||
DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 50, 50 }, BEIGE); // Simple world plane
|
||||
|
||||
for (float x = -count*spacing; x <= count*spacing; x += spacing)
|
||||
{
|
||||
for (float z = -count*spacing; z <= count*spacing; z += spacing)
|
||||
{
|
||||
DrawCube((Vector3) { x, 1.5f, z }, 1, 1, 1, LIME);
|
||||
DrawCube((Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a cube at each player's position
|
||||
DrawCube(cameraPlayer1.position, 1, 1, 1, RED);
|
||||
DrawCube(cameraPlayer2.position, 1, 1, 1, BLUE);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawRectangle(0, 0, GetScreenWidth()/2, 40, Fade(RAYWHITE, 0.8f));
|
||||
DrawText("PLAYER1: W/S to move", 10, 10, 20, MAROON);
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
// Draw Player2 view to the render texture
|
||||
BeginTextureMode(screenPlayer2);
|
||||
ClearBackground(SKYBLUE);
|
||||
|
||||
BeginMode3D(cameraPlayer2);
|
||||
|
||||
// Draw scene: grid of cube trees on a plane to make a "world"
|
||||
DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 50, 50 }, BEIGE); // Simple world plane
|
||||
|
||||
for (float x = -count*spacing; x <= count*spacing; x += spacing)
|
||||
{
|
||||
for (float z = -count*spacing; z <= count*spacing; z += spacing)
|
||||
{
|
||||
DrawCube((Vector3) { x, 1.5f, z }, 1, 1, 1, LIME);
|
||||
DrawCube((Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a cube at each player's position
|
||||
DrawCube(cameraPlayer1.position, 1, 1, 1, RED);
|
||||
DrawCube(cameraPlayer2.position, 1, 1, 1, BLUE);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawRectangle(0, 0, GetScreenWidth()/2, 40, Fade(RAYWHITE, 0.8f));
|
||||
DrawText("PLAYER2: UP/DOWN to move", 10, 10, 20, DARKBLUE);
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
// Draw both views render textures to the screen side by side
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
|
||||
DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE);
|
||||
DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE);
|
||||
|
||||
DrawRectangle(GetScreenWidth()/2 - 2, 0, 4, GetScreenHeight(), LIGHTGRAY);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(screenPlayer1); // Unload render texture
|
||||
UnloadRenderTexture(screenPlayer2); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_3d_camera_split_screen.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
118
raylib/examples/core/core_3d_picking.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Picking in 3d mode
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d picking");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 1.0f, 0.0f };
|
||||
Vector3 cubeSize = { 2.0f, 2.0f, 2.0f };
|
||||
|
||||
Ray ray = { 0 }; // Picking line ray
|
||||
RayCollision collision = { 0 }; // Ray collision hit info
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsCursorHidden()) UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
||||
|
||||
// Toggle camera controls
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT))
|
||||
{
|
||||
if (IsCursorHidden()) EnableCursor();
|
||||
else DisableCursor();
|
||||
}
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
if (!collision.hit)
|
||||
{
|
||||
ray = GetScreenToWorldRay(GetMousePosition(), camera);
|
||||
|
||||
// Check collision between ray and box
|
||||
collision = GetRayCollisionBox(ray,
|
||||
(BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 },
|
||||
(Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }});
|
||||
}
|
||||
else collision.hit = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
if (collision.hit)
|
||||
{
|
||||
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED);
|
||||
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON);
|
||||
|
||||
DrawCubeWires(cubePosition, cubeSize.x + 0.2f, cubeSize.y + 0.2f, cubeSize.z + 0.2f, GREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY);
|
||||
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY);
|
||||
}
|
||||
|
||||
DrawRay(ray, MAROON);
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Try clicking on the box with your mouse!", 240, 10, 20, DARKGRAY);
|
||||
|
||||
if (collision.hit) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, (int)(screenHeight * 0.1f), 30, GREEN);
|
||||
|
||||
DrawText("Right click mouse to toggle camera controls", 10, 430, 10, GRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_3d_picking.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
336
raylib/examples/core/core_automation_events.c
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - automation events
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* Example based on 2d_camera_platformer example by arvyy (@arvyy)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#define GRAVITY 400
|
||||
#define PLAYER_JUMP_SPD 350.0f
|
||||
#define PLAYER_HOR_SPD 200.0f
|
||||
|
||||
#define MAX_ENVIRONMENT_ELEMENTS 5
|
||||
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
float speed;
|
||||
bool canJump;
|
||||
} Player;
|
||||
|
||||
typedef struct EnvElement {
|
||||
Rectangle rect;
|
||||
int blocking;
|
||||
Color color;
|
||||
} EnvElement;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - automation events");
|
||||
|
||||
// Define player
|
||||
Player player = { 0 };
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
player.speed = 0;
|
||||
player.canJump = false;
|
||||
|
||||
// Define environment elements (platforms)
|
||||
EnvElement envElements[MAX_ENVIRONMENT_ELEMENTS] = {
|
||||
{{ 0, 0, 1000, 400 }, 0, LIGHTGRAY },
|
||||
{{ 0, 400, 1000, 200 }, 1, GRAY },
|
||||
{{ 300, 200, 400, 10 }, 1, GRAY },
|
||||
{{ 250, 300, 100, 10 }, 1, GRAY },
|
||||
{{ 650, 300, 100, 10 }, 1, GRAY }
|
||||
};
|
||||
|
||||
// Define camera
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
// Automation events
|
||||
AutomationEventList aelist = LoadAutomationEventList(0); // Initialize list of automation events to record new events
|
||||
SetAutomationEventList(&aelist);
|
||||
bool eventRecording = false;
|
||||
bool eventPlaying = false;
|
||||
|
||||
unsigned int frameCounter = 0;
|
||||
unsigned int playFrameCounter = 0;
|
||||
unsigned int currentPlayFrame = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
float deltaTime = 0.015f;//GetFrameTime();
|
||||
|
||||
// Dropped files logic
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsFileDropped())
|
||||
{
|
||||
FilePathList droppedFiles = LoadDroppedFiles();
|
||||
|
||||
// Supports loading .rgs style files (text or binary) and .png style palette images
|
||||
if (IsFileExtension(droppedFiles.paths[0], ".txt;.rae"))
|
||||
{
|
||||
UnloadAutomationEventList(aelist);
|
||||
aelist = LoadAutomationEventList(droppedFiles.paths[0]);
|
||||
|
||||
eventRecording = false;
|
||||
|
||||
// Reset scene state to play
|
||||
eventPlaying = true;
|
||||
playFrameCounter = 0;
|
||||
currentPlayFrame = 0;
|
||||
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
player.speed = 0;
|
||||
player.canJump = false;
|
||||
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
}
|
||||
|
||||
UnloadDroppedFiles(droppedFiles); // Unload filepaths from memory
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Update player
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_LEFT)) player.position.x -= PLAYER_HOR_SPD*deltaTime;
|
||||
if (IsKeyDown(KEY_RIGHT)) player.position.x += PLAYER_HOR_SPD*deltaTime;
|
||||
if (IsKeyDown(KEY_SPACE) && player.canJump)
|
||||
{
|
||||
player.speed = -PLAYER_JUMP_SPD;
|
||||
player.canJump = false;
|
||||
}
|
||||
|
||||
int hitObstacle = 0;
|
||||
for (int i = 0; i < MAX_ENVIRONMENT_ELEMENTS; i++)
|
||||
{
|
||||
EnvElement *element = &envElements[i];
|
||||
Vector2 *p = &(player.position);
|
||||
if (element->blocking &&
|
||||
element->rect.x <= p->x &&
|
||||
element->rect.x + element->rect.width >= p->x &&
|
||||
element->rect.y >= p->y &&
|
||||
element->rect.y <= p->y + player.speed*deltaTime)
|
||||
{
|
||||
hitObstacle = 1;
|
||||
player.speed = 0.0f;
|
||||
p->y = element->rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hitObstacle)
|
||||
{
|
||||
player.position.y += player.speed*deltaTime;
|
||||
player.speed += GRAVITY*deltaTime;
|
||||
player.canJump = false;
|
||||
}
|
||||
else player.canJump = true;
|
||||
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
// Reset game state
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
player.speed = 0;
|
||||
player.canJump = false;
|
||||
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Events playing
|
||||
// NOTE: Logic must be before Camera update because it depends on mouse-wheel value,
|
||||
// that can be set by the played event... but some other inputs could be affected
|
||||
//----------------------------------------------------------------------------------
|
||||
if (eventPlaying)
|
||||
{
|
||||
// NOTE: Multiple events could be executed in a single frame
|
||||
while (playFrameCounter == aelist.events[currentPlayFrame].frame)
|
||||
{
|
||||
PlayAutomationEvent(aelist.events[currentPlayFrame]);
|
||||
currentPlayFrame++;
|
||||
|
||||
if (currentPlayFrame == aelist.count)
|
||||
{
|
||||
eventPlaying = false;
|
||||
currentPlayFrame = 0;
|
||||
playFrameCounter = 0;
|
||||
|
||||
TraceLog(LOG_INFO, "FINISH PLAYING!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
playFrameCounter++;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Update camera
|
||||
//----------------------------------------------------------------------------------
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
float minX = 1000, minY = 1000, maxX = -1000, maxY = -1000;
|
||||
|
||||
// WARNING: On event replay, mouse-wheel internal value is set
|
||||
camera.zoom += ((float)GetMouseWheelMove()*0.05f);
|
||||
if (camera.zoom > 3.0f) camera.zoom = 3.0f;
|
||||
else if (camera.zoom < 0.25f) camera.zoom = 0.25f;
|
||||
|
||||
for (int i = 0; i < MAX_ENVIRONMENT_ELEMENTS; i++)
|
||||
{
|
||||
EnvElement *element = &envElements[i];
|
||||
minX = fminf(element->rect.x, minX);
|
||||
maxX = fmaxf(element->rect.x + element->rect.width, maxX);
|
||||
minY = fminf(element->rect.y, minY);
|
||||
maxY = fmaxf(element->rect.y + element->rect.height, maxY);
|
||||
}
|
||||
|
||||
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera);
|
||||
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera);
|
||||
|
||||
if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2);
|
||||
if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2);
|
||||
if (min.x > 0) camera.offset.x = screenWidth/2 - min.x;
|
||||
if (min.y > 0) camera.offset.y = screenHeight/2 - min.y;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Events management
|
||||
if (IsKeyPressed(KEY_S)) // Toggle events recording
|
||||
{
|
||||
if (!eventPlaying)
|
||||
{
|
||||
if (eventRecording)
|
||||
{
|
||||
StopAutomationEventRecording();
|
||||
eventRecording = false;
|
||||
|
||||
ExportAutomationEventList(aelist, "automation.rae");
|
||||
|
||||
TraceLog(LOG_INFO, "RECORDED FRAMES: %i", aelist.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAutomationEventBaseFrame(180);
|
||||
StartAutomationEventRecording();
|
||||
eventRecording = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IsKeyPressed(KEY_A)) // Toggle events playing (WARNING: Starts next frame)
|
||||
{
|
||||
if (!eventRecording && (aelist.count > 0))
|
||||
{
|
||||
// Reset scene state to play
|
||||
eventPlaying = true;
|
||||
playFrameCounter = 0;
|
||||
currentPlayFrame = 0;
|
||||
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
player.speed = 0;
|
||||
player.canJump = false;
|
||||
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventRecording || eventPlaying) frameCounter++;
|
||||
else frameCounter = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(LIGHTGRAY);
|
||||
|
||||
BeginMode2D(camera);
|
||||
|
||||
// Draw environment elements
|
||||
for (int i = 0; i < MAX_ENVIRONMENT_ELEMENTS; i++)
|
||||
{
|
||||
DrawRectangleRec(envElements[i].rect, envElements[i].color);
|
||||
}
|
||||
|
||||
// Draw player rectangle
|
||||
DrawRectangleRec((Rectangle){ player.position.x - 20, player.position.y - 40, 40, 40 }, RED);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
// Draw game controls
|
||||
DrawRectangle(10, 10, 290, 145, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(10, 10, 290, 145, Fade(BLUE, 0.8f));
|
||||
|
||||
DrawText("Controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- RIGHT | LEFT: Player movement", 30, 40, 10, DARKGRAY);
|
||||
DrawText("- SPACE: Player jump", 30, 60, 10, DARKGRAY);
|
||||
DrawText("- R: Reset game state", 30, 80, 10, DARKGRAY);
|
||||
|
||||
DrawText("- S: START/STOP RECORDING INPUT EVENTS", 30, 110, 10, BLACK);
|
||||
DrawText("- A: REPLAY LAST RECORDED INPUT EVENTS", 30, 130, 10, BLACK);
|
||||
|
||||
// Draw automation events recording indicator
|
||||
if (eventRecording)
|
||||
{
|
||||
DrawRectangle(10, 160, 290, 30, Fade(RED, 0.3f));
|
||||
DrawRectangleLines(10, 160, 290, 30, Fade(MAROON, 0.8f));
|
||||
DrawCircle(30, 175, 10, MAROON);
|
||||
|
||||
if (((frameCounter/15)%2) == 1) DrawText(TextFormat("RECORDING EVENTS... [%i]", aelist.count), 50, 170, 10, MAROON);
|
||||
}
|
||||
else if (eventPlaying)
|
||||
{
|
||||
DrawRectangle(10, 160, 290, 30, Fade(LIME, 0.3f));
|
||||
DrawRectangleLines(10, 160, 290, 30, Fade(DARKGREEN, 0.8f));
|
||||
DrawTriangle((Vector2){ 20, 155 + 10 }, (Vector2){ 20, 155 + 30 }, (Vector2){ 40, 155 + 20 }, DARKGREEN);
|
||||
|
||||
if (((frameCounter/15)%2) == 1) DrawText(TextFormat("PLAYING RECORDED EVENTS... [%i]", currentPlayFrame), 50, 170, 10, DARKGREEN);
|
||||
}
|
||||
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_automation_events.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
152
raylib/examples/core/core_basic_screen_manager.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] examples - basic screen manager
|
||||
*
|
||||
* NOTE: This example illustrates a very simple screen manager based on a states machines
|
||||
*
|
||||
* Example originally created with raylib 4.0, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2021-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//------------------------------------------------------------------------------------------
|
||||
typedef enum GameScreen { LOGO = 0, TITLE, GAMEPLAY, ENDING } GameScreen;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic screen manager");
|
||||
|
||||
GameScreen currentScreen = LOGO;
|
||||
|
||||
// TODO: Initialize all required variables and load all required data here!
|
||||
|
||||
int framesCounter = 0; // Useful to count frames
|
||||
|
||||
SetTargetFPS(60); // Set desired framerate (frames-per-second)
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOGO:
|
||||
{
|
||||
// TODO: Update LOGO screen variables here!
|
||||
|
||||
framesCounter++; // Count frames
|
||||
|
||||
// Wait for 2 seconds (120 frames) before jumping to TITLE screen
|
||||
if (framesCounter > 120)
|
||||
{
|
||||
currentScreen = TITLE;
|
||||
}
|
||||
} break;
|
||||
case TITLE:
|
||||
{
|
||||
// TODO: Update TITLE screen variables here!
|
||||
|
||||
// Press enter to change to GAMEPLAY screen
|
||||
if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP))
|
||||
{
|
||||
currentScreen = GAMEPLAY;
|
||||
}
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
{
|
||||
// TODO: Update GAMEPLAY screen variables here!
|
||||
|
||||
// Press enter to change to ENDING screen
|
||||
if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP))
|
||||
{
|
||||
currentScreen = ENDING;
|
||||
}
|
||||
} break;
|
||||
case ENDING:
|
||||
{
|
||||
// TODO: Update ENDING screen variables here!
|
||||
|
||||
// Press enter to return to TITLE screen
|
||||
if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP))
|
||||
{
|
||||
currentScreen = TITLE;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOGO:
|
||||
{
|
||||
// TODO: Draw LOGO screen here!
|
||||
DrawText("LOGO SCREEN", 20, 20, 40, LIGHTGRAY);
|
||||
DrawText("WAIT for 2 SECONDS...", 290, 220, 20, GRAY);
|
||||
|
||||
} break;
|
||||
case TITLE:
|
||||
{
|
||||
// TODO: Draw TITLE screen here!
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, GREEN);
|
||||
DrawText("TITLE SCREEN", 20, 20, 40, DARKGREEN);
|
||||
DrawText("PRESS ENTER or TAP to JUMP to GAMEPLAY SCREEN", 120, 220, 20, DARKGREEN);
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
{
|
||||
// TODO: Draw GAMEPLAY screen here!
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, PURPLE);
|
||||
DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON);
|
||||
DrawText("PRESS ENTER or TAP to JUMP to ENDING SCREEN", 130, 220, 20, MAROON);
|
||||
|
||||
} break;
|
||||
case ENDING:
|
||||
{
|
||||
// TODO: Draw ENDING screen here!
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, BLUE);
|
||||
DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE);
|
||||
DrawText("PRESS ENTER or TAP to RETURN to TITLE SCREEN", 120, 220, 20, DARKBLUE);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// TODO: Unload all loaded data (textures, fonts, audio) here!
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_basic_screen_manager.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
70
raylib/examples/core/core_basic_window.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Basic window
|
||||
*
|
||||
* Welcome to raylib!
|
||||
*
|
||||
* To test examples, just press F6 and execute 'raylib_compile_execute' script
|
||||
* Note that compiled executable is placed in the same folder as .c file
|
||||
*
|
||||
* To test the examples on Web, press F6 and execute 'raylib_compile_execute_web' script
|
||||
* Web version of the program is generated in the same folder as .c file
|
||||
*
|
||||
* You can find all basic examples on C:\raylib\raylib\examples folder or
|
||||
* raylib official webpage: www.raylib.com
|
||||
*
|
||||
* Enjoy using raylib. :)
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_basic_window.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
87
raylib/examples/core/core_basic_window_web.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Basic window (adapted for HTML5 platform)
|
||||
*
|
||||
* NOTE: This example is prepared to compile for PLATFORM_WEB, and PLATFORM_DESKTOP
|
||||
* As you will notice, code structure is slightly diferent to the other examples...
|
||||
* To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//#define PLATFORM_WEB
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module functions declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateDrawFrame(void); // Update and Draw one frame
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
130
raylib/examples/core/core_custom_frame_control.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - custom frame control
|
||||
*
|
||||
* NOTE: WARNING: This is an example for advanced users willing to have full control over
|
||||
* the frame processes. By default, EndDrawing() calls the following processes:
|
||||
* 1. Draw remaining batch data: rlDrawRenderBatchActive()
|
||||
* 2. SwapScreenBuffer()
|
||||
* 3. Frame time control: WaitTime()
|
||||
* 4. PollInputEvents()
|
||||
*
|
||||
* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in
|
||||
* config.h (it requires recompiling raylib). This way those steps are up to the user.
|
||||
*
|
||||
* Note that enabling this flag invalidates some functions:
|
||||
* - GetFrameTime()
|
||||
* - SetTargetFPS()
|
||||
* - GetFPS()
|
||||
*
|
||||
* Example originally created with raylib 4.0, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2021-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom frame control");
|
||||
|
||||
// Custom timming variables
|
||||
double previousTime = GetTime(); // Previous time measure
|
||||
double currentTime = 0.0; // Current time measure
|
||||
double updateDrawTime = 0.0; // Update + Draw time
|
||||
double waitTime = 0.0; // Wait time (if target fps required)
|
||||
float deltaTime = 0.0f; // Frame time (Update + Draw + Wait time)
|
||||
|
||||
float timeCounter = 0.0f; // Accumulative time counter (seconds)
|
||||
float position = 0.0f; // Circle position
|
||||
bool pause = false; // Pause control flag
|
||||
|
||||
int targetFPS = 60; // Our initial target fps
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL)
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
||||
|
||||
if (IsKeyPressed(KEY_UP)) targetFPS += 20;
|
||||
else if (IsKeyPressed(KEY_DOWN)) targetFPS -= 20;
|
||||
|
||||
if (targetFPS < 0) targetFPS = 0;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
position += 200*deltaTime; // We move at 200 pixels per second
|
||||
if (position >= GetScreenWidth()) position = 0;
|
||||
timeCounter += deltaTime; // We count time (seconds)
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = 0; i < GetScreenWidth()/200; i++) DrawRectangle(200*i, 0, 1, GetScreenHeight(), SKYBLUE);
|
||||
|
||||
DrawCircle((int)position, GetScreenHeight()/2 - 25, 50, RED);
|
||||
|
||||
DrawText(TextFormat("%03.0f ms", timeCounter*1000.0f), (int)position - 40, GetScreenHeight()/2 - 100, 20, MAROON);
|
||||
DrawText(TextFormat("PosX: %03.0f", position), (int)position - 50, GetScreenHeight()/2 + 40, 20, BLACK);
|
||||
|
||||
DrawText("Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate.", 10, 10, 20, DARKGRAY);
|
||||
DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 60, 20, GRAY);
|
||||
DrawText("PRESS UP | DOWN to CHANGE TARGET FPS", 10, GetScreenHeight() - 30, 20, GRAY);
|
||||
DrawText(TextFormat("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME);
|
||||
DrawText(TextFormat("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN);
|
||||
|
||||
EndDrawing();
|
||||
|
||||
// NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL,
|
||||
// Events polling, screen buffer swap and frame time control must be managed by the user
|
||||
|
||||
SwapScreenBuffer(); // Flip the back buffer to screen (front buffer)
|
||||
|
||||
currentTime = GetTime();
|
||||
updateDrawTime = currentTime - previousTime;
|
||||
|
||||
if (targetFPS > 0) // We want a fixed frame rate
|
||||
{
|
||||
waitTime = (1.0f/(float)targetFPS) - updateDrawTime;
|
||||
if (waitTime > 0.0)
|
||||
{
|
||||
WaitTime((float)waitTime);
|
||||
currentTime = GetTime();
|
||||
deltaTime = (float)(currentTime - previousTime);
|
||||
}
|
||||
}
|
||||
else deltaTime = (float)updateDrawTime; // Framerate could be variable
|
||||
|
||||
previousTime = currentTime;
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_custom_frame_control.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
88
raylib/examples/core/core_custom_logging.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Custom logging
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Pablo Marcos Oltra (@pamarcos) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2018-2024 Pablo Marcos Oltra (@pamarcos) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()
|
||||
#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()
|
||||
|
||||
// Custom logging function
|
||||
void CustomLog(int msgType, const char *text, va_list args)
|
||||
{
|
||||
char timeStr[64] = { 0 };
|
||||
time_t now = time(NULL);
|
||||
struct tm *tm_info = localtime(&now);
|
||||
|
||||
strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", tm_info);
|
||||
printf("[%s] ", timeStr);
|
||||
|
||||
switch (msgType)
|
||||
{
|
||||
case LOG_INFO: printf("[INFO] : "); break;
|
||||
case LOG_ERROR: printf("[ERROR]: "); break;
|
||||
case LOG_WARNING: printf("[WARN] : "); break;
|
||||
case LOG_DEBUG: printf("[DEBUG]: "); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
vprintf(text, args);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
// Set custom logger
|
||||
SetTraceLogCallback(CustomLog);
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Check out the console output to see the custom logger in action!", 60, 200, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_custom_logging.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
106
raylib/examples/core/core_drop_files.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Windows drop files
|
||||
*
|
||||
* NOTE: This example only works on platforms that support drag & drop (Windows, Linux, OSX, Html5?)
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h> // Required for: calloc(), free()
|
||||
|
||||
#define MAX_FILEPATH_RECORDED 4096
|
||||
#define MAX_FILEPATH_SIZE 2048
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - drop files");
|
||||
|
||||
int filePathCounter = 0;
|
||||
char *filePaths[MAX_FILEPATH_RECORDED] = { 0 }; // We will register a maximum of filepaths
|
||||
|
||||
// Allocate space for the required file paths
|
||||
for (int i = 0; i < MAX_FILEPATH_RECORDED; i++)
|
||||
{
|
||||
filePaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_SIZE, 1);
|
||||
}
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsFileDropped())
|
||||
{
|
||||
FilePathList droppedFiles = LoadDroppedFiles();
|
||||
|
||||
for (int i = 0, offset = filePathCounter; i < (int)droppedFiles.count; i++)
|
||||
{
|
||||
if (filePathCounter < (MAX_FILEPATH_RECORDED - 1))
|
||||
{
|
||||
TextCopy(filePaths[offset + i], droppedFiles.paths[i]);
|
||||
filePathCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
UnloadDroppedFiles(droppedFiles); // Unload filepaths from memory
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (filePathCounter == 0) DrawText("Drop your files to this window!", 100, 40, 20, DARKGRAY);
|
||||
else
|
||||
{
|
||||
DrawText("Dropped files:", 100, 40, 20, DARKGRAY);
|
||||
|
||||
for (int i = 0; i < filePathCounter; i++)
|
||||
{
|
||||
if (i%2 == 0) DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.5f));
|
||||
else DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.3f));
|
||||
|
||||
DrawText(filePaths[i], 120, 100 + 40*i, 10, GRAY);
|
||||
}
|
||||
|
||||
DrawText("Drop new files...", 100, 110 + 40*filePathCounter, 20, DARKGRAY);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < MAX_FILEPATH_RECORDED; i++)
|
||||
{
|
||||
RL_FREE(filePaths[i]); // Free allocated memory for all filepaths
|
||||
}
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_drop_files.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
287
raylib/examples/core/core_input_gamepad.c
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Gamepad input
|
||||
*
|
||||
* NOTE: This example requires a Gamepad connected to the system
|
||||
* raylib is configured to work with the following gamepads:
|
||||
* - Xbox 360 Controller (Xbox 360, Xbox One)
|
||||
* - PLAYSTATION(R)3 Controller
|
||||
* Check raylib.h for buttons configuration
|
||||
*
|
||||
* Example originally created with raylib 1.1, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
// NOTE: Gamepad name ID depends on drivers and OS
|
||||
#define XBOX_ALIAS_1 "xbox"
|
||||
#define XBOX_ALIAS_2 "x-box"
|
||||
#define PS_ALIAS "playstation"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT); // Set MSAA 4X hint before windows creation
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad input");
|
||||
|
||||
Texture2D texPs3Pad = LoadTexture("resources/ps3.png");
|
||||
Texture2D texXboxPad = LoadTexture("resources/xbox.png");
|
||||
|
||||
// Set axis deadzones
|
||||
const float leftStickDeadzoneX = 0.1f;
|
||||
const float leftStickDeadzoneY = 0.1f;
|
||||
const float rightStickDeadzoneX = 0.1f;
|
||||
const float rightStickDeadzoneY = 0.1f;
|
||||
const float leftTriggerDeadzone = -0.9f;
|
||||
const float rightTriggerDeadzone = -0.9f;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
int gamepad = 0; // which gamepad to display
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// ...
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
|
||||
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
|
||||
|
||||
if (IsGamepadAvailable(gamepad))
|
||||
{
|
||||
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
|
||||
|
||||
// Get axis values
|
||||
float leftStickX = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_X);
|
||||
float leftStickY = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_Y);
|
||||
float rightStickX = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_X);
|
||||
float rightStickY = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_Y);
|
||||
float leftTrigger = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER);
|
||||
float rightTrigger = GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER);
|
||||
|
||||
// Calculate deadzones
|
||||
if (leftStickX > -leftStickDeadzoneX && leftStickX < leftStickDeadzoneX) leftStickX = 0.0f;
|
||||
if (leftStickY > -leftStickDeadzoneY && leftStickY < leftStickDeadzoneY) leftStickY = 0.0f;
|
||||
if (rightStickX > -rightStickDeadzoneX && rightStickX < rightStickDeadzoneX) rightStickX = 0.0f;
|
||||
if (rightStickY > -rightStickDeadzoneY && rightStickY < rightStickDeadzoneY) rightStickY = 0.0f;
|
||||
if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f;
|
||||
if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f;
|
||||
|
||||
if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)
|
||||
{
|
||||
DrawTexture(texXboxPad, 0, 0, DARKGRAY);
|
||||
|
||||
// Draw buttons: xbox home
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(394, 89, 19, RED);
|
||||
|
||||
// Draw buttons: basic
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawCircle(436, 150, 9, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawCircle(352, 150, 9, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(501, 151, 15, BLUE);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(536, 187, 15, LIME);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(572, 151, 15, MAROON);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(536, 115, 15, GOLD);
|
||||
|
||||
// Draw buttons: d-pad
|
||||
DrawRectangle(317, 202, 19, 71, BLACK);
|
||||
DrawRectangle(293, 228, 69, 19, BLACK);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(317, 202, 19, 26, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(317, 202 + 45, 19, 26, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(292, 228, 25, 19, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(292 + 44, 228, 26, 19, RED);
|
||||
|
||||
// Draw buttons: left-right back
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(259, 61, 20, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(536, 61, 20, RED);
|
||||
|
||||
// Draw axis: left joystick
|
||||
Color leftGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||
DrawCircle(259, 152, 39, BLACK);
|
||||
DrawCircle(259, 152, 34, LIGHTGRAY);
|
||||
DrawCircle(259 + (int)(leftStickX*20),
|
||||
152 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
|
||||
// Draw axis: right joystick
|
||||
Color rightGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||
DrawCircle(461, 237, 38, BLACK);
|
||||
DrawCircle(461, 237, 33, LIGHTGRAY);
|
||||
DrawCircle(461 + (int)(rightStickX*20),
|
||||
237 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(170, 30, 15, 70, GRAY);
|
||||
DrawRectangle(604, 30, 15, 70, GRAY);
|
||||
DrawRectangle(170, 30, 15, (int)(((1 + leftTrigger)/2)*70), RED);
|
||||
DrawRectangle(604, 30, 15, (int)(((1 + rightTrigger)/2)*70), RED);
|
||||
|
||||
//DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK);
|
||||
//DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
|
||||
}
|
||||
else if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS) > -1)
|
||||
{
|
||||
DrawTexture(texPs3Pad, 0, 0, DARKGRAY);
|
||||
|
||||
// Draw buttons: ps
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(396, 222, 13, RED);
|
||||
|
||||
// Draw buttons: basic
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawRectangle(328, 170, 32, 13, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(557, 144, 13, LIME);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(586, 173, 13, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(557, 203, 13, VIOLET);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(527, 173, 13, PINK);
|
||||
|
||||
// Draw buttons: d-pad
|
||||
DrawRectangle(225, 132, 24, 84, BLACK);
|
||||
DrawRectangle(195, 161, 84, 25, BLACK);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(225, 132, 24, 29, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(225, 132 + 54, 24, 30, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(195, 161, 30, 25, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(195 + 54, 161, 30, 25, RED);
|
||||
|
||||
// Draw buttons: left-right back buttons
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawCircle(239, 82, 20, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawCircle(557, 82, 20, RED);
|
||||
|
||||
// Draw axis: left joystick
|
||||
Color leftGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||
DrawCircle(319, 255, 35, BLACK);
|
||||
DrawCircle(319, 255, 31, LIGHTGRAY);
|
||||
DrawCircle(319 + (int)(leftStickX*20),
|
||||
255 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
|
||||
// Draw axis: right joystick
|
||||
Color rightGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||
DrawCircle(475, 255, 35, BLACK);
|
||||
DrawCircle(475, 255, 31, LIGHTGRAY);
|
||||
DrawCircle(475 + (int)(rightStickX*20),
|
||||
255 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(169, 48, 15, 70, GRAY);
|
||||
DrawRectangle(611, 48, 15, 70, GRAY);
|
||||
DrawRectangle(169, 48, 15, (int)(((1 + leftTrigger)/2)*70), RED);
|
||||
DrawRectangle(611, 48, 15, (int)(((1 + rightTrigger)/2)*70), RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Draw background: generic
|
||||
DrawRectangleRounded((Rectangle){ 175, 110, 460, 220}, 0.3f, 16, DARKGRAY);
|
||||
|
||||
// Draw buttons: basic
|
||||
DrawCircle(365, 170, 12, RAYWHITE);
|
||||
DrawCircle(405, 170, 12, RAYWHITE);
|
||||
DrawCircle(445, 170, 12, RAYWHITE);
|
||||
DrawCircle(516, 191, 17, RAYWHITE);
|
||||
DrawCircle(551, 227, 17, RAYWHITE);
|
||||
DrawCircle(587, 191, 17, RAYWHITE);
|
||||
DrawCircle(551, 155, 17, RAYWHITE);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_LEFT)) DrawCircle(365, 170, 10, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE)) DrawCircle(405, 170, 10, GREEN);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_MIDDLE_RIGHT)) DrawCircle(445, 170, 10, BLUE);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_LEFT)) DrawCircle(516, 191, 15, GOLD);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_DOWN)) DrawCircle(551, 227, 15, BLUE);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT)) DrawCircle(587, 191, 15, GREEN);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_FACE_UP)) DrawCircle(551, 155, 15, RED);
|
||||
|
||||
// Draw buttons: d-pad
|
||||
DrawRectangle(245, 145, 28, 88, RAYWHITE);
|
||||
DrawRectangle(215, 174, 88, 29, RAYWHITE);
|
||||
DrawRectangle(247, 147, 24, 84, BLACK);
|
||||
DrawRectangle(217, 176, 84, 25, BLACK);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_UP)) DrawRectangle(247, 147, 24, 29, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_DOWN)) DrawRectangle(247, 147 + 54, 24, 30, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) DrawRectangle(217, 176, 30, 25, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) DrawRectangle(217 + 54, 176, 30, 25, RED);
|
||||
|
||||
// Draw buttons: left-right back
|
||||
DrawRectangleRounded((Rectangle){ 215, 98, 100, 10}, 0.5f, 16, DARKGRAY);
|
||||
DrawRectangleRounded((Rectangle){ 495, 98, 100, 10}, 0.5f, 16, DARKGRAY);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_TRIGGER_1)) DrawRectangleRounded((Rectangle){ 215, 98, 100, 10}, 0.5f, 16, RED);
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_TRIGGER_1)) DrawRectangleRounded((Rectangle){ 495, 98, 100, 10}, 0.5f, 16, RED);
|
||||
|
||||
// Draw axis: left joystick
|
||||
Color leftGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||
DrawCircle(345, 260, 40, BLACK);
|
||||
DrawCircle(345, 260, 35, LIGHTGRAY);
|
||||
DrawCircle(345 + (int)(leftStickX*20),
|
||||
260 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
|
||||
// Draw axis: right joystick
|
||||
Color rightGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||
DrawCircle(465, 260, 40, BLACK);
|
||||
DrawCircle(465, 260, 35, LIGHTGRAY);
|
||||
DrawCircle(465 + (int)(rightStickX*20),
|
||||
260 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(151, 110, 15, 70, GRAY);
|
||||
DrawRectangle(644, 110, 15, 70, GRAY);
|
||||
DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED);
|
||||
DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED);
|
||||
|
||||
}
|
||||
|
||||
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(0)), 10, 50, 10, MAROON);
|
||||
|
||||
for (int i = 0; i < GetGamepadAxisCount(0); i++)
|
||||
{
|
||||
DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(0, i)), 20, 70 + 20*i, 10, DARKGRAY);
|
||||
}
|
||||
|
||||
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
|
||||
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText(TextFormat("GP%d: NOT DETECTED", gamepad), 10, 10, 10, GRAY);
|
||||
|
||||
DrawTexture(texXboxPad, 0, 0, LIGHTGRAY);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texPs3Pad);
|
||||
UnloadTexture(texXboxPad);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_gamepad.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
83
raylib/examples/core/core_input_gamepad_info.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Gamepad information
|
||||
*
|
||||
* NOTE: This example requires a Gamepad connected to the system
|
||||
* Check raylib.h for buttons configuration
|
||||
*
|
||||
* Example originally created with raylib 4.6, last time updated with raylib 4.6
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT); // Set MSAA 4X hint before windows creation
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad information");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = 0, y = 5; i < 4; i++) // MAX_GAMEPADS = 4
|
||||
{
|
||||
if (IsGamepadAvailable(i))
|
||||
{
|
||||
DrawText(TextFormat("Gamepad name: %s", GetGamepadName(i)), 10, y, 10, BLACK);
|
||||
y += 11;
|
||||
DrawText(TextFormat("\tAxis count: %d", GetGamepadAxisCount(i)), 10, y, 10, BLACK);
|
||||
y += 11;
|
||||
|
||||
for (int axis = 0; axis < GetGamepadAxisCount(i); axis++)
|
||||
{
|
||||
DrawText(TextFormat("\tAxis %d = %f", axis, GetGamepadAxisMovement(i, axis)), 10, y, 10, BLACK);
|
||||
y += 11;
|
||||
}
|
||||
|
||||
for (int button = 0; button < 32; button++)
|
||||
{
|
||||
DrawText(TextFormat("\tButton %d = %d", button, IsGamepadButtonDown(i, button)), 10, y, 10, BLACK);
|
||||
y += 11;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DrawFPS(GetScreenWidth() - 100, 100);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
119
raylib/examples/core/core_input_gestures.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Input Gestures Detection
|
||||
*
|
||||
* Example originally created with raylib 1.4, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2016-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_GESTURE_STRINGS 20
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures");
|
||||
|
||||
Vector2 touchPosition = { 0, 0 };
|
||||
Rectangle touchArea = { 220, 10, screenWidth - 230.0f, screenHeight - 20.0f };
|
||||
|
||||
int gesturesCount = 0;
|
||||
char gestureStrings[MAX_GESTURE_STRINGS][32];
|
||||
|
||||
int currentGesture = GESTURE_NONE;
|
||||
int lastGesture = GESTURE_NONE;
|
||||
|
||||
//SetGesturesEnabled(0b0000000000001001); // Enable only some gestures to be detected
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
lastGesture = currentGesture;
|
||||
currentGesture = GetGestureDetected();
|
||||
touchPosition = GetTouchPosition(0);
|
||||
|
||||
if (CheckCollisionPointRec(touchPosition, touchArea) && (currentGesture != GESTURE_NONE))
|
||||
{
|
||||
if (currentGesture != lastGesture)
|
||||
{
|
||||
// Store gesture string
|
||||
switch (currentGesture)
|
||||
{
|
||||
case GESTURE_TAP: TextCopy(gestureStrings[gesturesCount], "GESTURE TAP"); break;
|
||||
case GESTURE_DOUBLETAP: TextCopy(gestureStrings[gesturesCount], "GESTURE DOUBLETAP"); break;
|
||||
case GESTURE_HOLD: TextCopy(gestureStrings[gesturesCount], "GESTURE HOLD"); break;
|
||||
case GESTURE_DRAG: TextCopy(gestureStrings[gesturesCount], "GESTURE DRAG"); break;
|
||||
case GESTURE_SWIPE_RIGHT: TextCopy(gestureStrings[gesturesCount], "GESTURE SWIPE RIGHT"); break;
|
||||
case GESTURE_SWIPE_LEFT: TextCopy(gestureStrings[gesturesCount], "GESTURE SWIPE LEFT"); break;
|
||||
case GESTURE_SWIPE_UP: TextCopy(gestureStrings[gesturesCount], "GESTURE SWIPE UP"); break;
|
||||
case GESTURE_SWIPE_DOWN: TextCopy(gestureStrings[gesturesCount], "GESTURE SWIPE DOWN"); break;
|
||||
case GESTURE_PINCH_IN: TextCopy(gestureStrings[gesturesCount], "GESTURE PINCH IN"); break;
|
||||
case GESTURE_PINCH_OUT: TextCopy(gestureStrings[gesturesCount], "GESTURE PINCH OUT"); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
gesturesCount++;
|
||||
|
||||
// Reset gestures strings
|
||||
if (gesturesCount >= MAX_GESTURE_STRINGS)
|
||||
{
|
||||
for (int i = 0; i < MAX_GESTURE_STRINGS; i++) TextCopy(gestureStrings[i], "\0");
|
||||
|
||||
gesturesCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangleRec(touchArea, GRAY);
|
||||
DrawRectangle(225, 15, screenWidth - 240, screenHeight - 30, RAYWHITE);
|
||||
|
||||
DrawText("GESTURES TEST AREA", screenWidth - 270, screenHeight - 40, 20, Fade(GRAY, 0.5f));
|
||||
|
||||
for (int i = 0; i < gesturesCount; i++)
|
||||
{
|
||||
if (i%2 == 0) DrawRectangle(10, 30 + 20*i, 200, 20, Fade(LIGHTGRAY, 0.5f));
|
||||
else DrawRectangle(10, 30 + 20*i, 200, 20, Fade(LIGHTGRAY, 0.3f));
|
||||
|
||||
if (i < gesturesCount - 1) DrawText(gestureStrings[i], 35, 36 + 20*i, 10, DARKGRAY);
|
||||
else DrawText(gestureStrings[i], 35, 36 + 20*i, 10, MAROON);
|
||||
}
|
||||
|
||||
DrawRectangleLines(10, 29, 200, screenHeight - 50, GRAY);
|
||||
DrawText("DETECTED GESTURES", 50, 15, 10, GRAY);
|
||||
|
||||
if (currentGesture != GESTURE_NONE) DrawCircleV(touchPosition, 30, MAROON);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_gestures.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
330
raylib/examples/core/core_input_gestures_web.c
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Input Gestures for Web
|
||||
*
|
||||
* Example originally created with raylib 4.6-dev, last time updated with raylib 4.6-dev
|
||||
*
|
||||
* Example contributed by ubkp (@ubkp) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 ubkp (@ubkp)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "math.h" // Required for the protractor angle graphic drawing
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h> // Required for the Web/HTML5
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global definitions and declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Common variables definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800; // Update depending on web canvas
|
||||
const int screenHeight = 450;
|
||||
Vector2 messagePosition = { 160, 7 };
|
||||
|
||||
// Last gesture variables definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
int lastGesture = 0;
|
||||
Vector2 lastGesturePosition = { 165, 130 };
|
||||
|
||||
// Gesture log variables definitions and functions declarations
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define GESTURE_LOG_SIZE 20
|
||||
char gestureLog[GESTURE_LOG_SIZE][12] = { "" }; // The gesture log uses an array (as an inverted circular queue) to store the performed gestures
|
||||
int gestureLogIndex = GESTURE_LOG_SIZE; // The index for the inverted circular queue (moving from last to first direction, then looping around)
|
||||
int previousGesture = 0;
|
||||
|
||||
char const *GetGestureName(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0: return "None"; break;
|
||||
case 1: return "Tap"; break;
|
||||
case 2: return "Double Tap"; break;
|
||||
case 4: return "Hold"; break;
|
||||
case 8: return "Drag"; break;
|
||||
case 16: return "Swipe Right"; break;
|
||||
case 32: return "Swipe Left"; break;
|
||||
case 64: return "Swipe Up"; break;
|
||||
case 128: return "Swipe Down"; break;
|
||||
case 256: return "Pinch In"; break;
|
||||
case 512: return "Pinch Out"; break;
|
||||
default: return "Unknown"; break;
|
||||
}
|
||||
}
|
||||
|
||||
Color GetGestureColor(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case 0: return BLACK; break;
|
||||
case 1: return BLUE; break;
|
||||
case 2: return SKYBLUE; break;
|
||||
case 4: return BLACK; break;
|
||||
case 8: return LIME; break;
|
||||
case 16: return RED; break;
|
||||
case 32: return RED; break;
|
||||
case 64: return RED; break;
|
||||
case 128: return RED; break;
|
||||
case 256: return VIOLET; break;
|
||||
case 512: return ORANGE; break;
|
||||
default: return BLACK; break;
|
||||
}
|
||||
}
|
||||
|
||||
int logMode = 1; // Log mode values: 0 shows repeated events; 1 hides repeated events; 2 shows repeated events but hide hold events; 3 hides repeated events and hide hold events
|
||||
|
||||
Color gestureColor = { 0, 0, 0, 255 };
|
||||
Rectangle logButton1 = { 53, 7, 48, 26 };
|
||||
Rectangle logButton2 = { 108, 7, 36, 26 };
|
||||
Vector2 gestureLogPosition = { 10, 10 };
|
||||
|
||||
// Protractor variables definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
float angleLength = 90.0f;
|
||||
float currentAngleDegrees = 0.0f;
|
||||
Vector2 finalVector = { 0.0f, 0.0f };
|
||||
char currentAngleStr[7] = "";
|
||||
Vector2 protractorPosition = { 266.0f, 315.0f };
|
||||
|
||||
// Update
|
||||
//--------------------------------------------------------------------------------------
|
||||
void Update(void)
|
||||
{
|
||||
// Handle common
|
||||
//--------------------------------------------------------------------------------------
|
||||
int i, ii; // Iterators that will be reused by all for loops
|
||||
const int currentGesture = GetGestureDetected();
|
||||
const float currentDragDegrees = GetGestureDragAngle();
|
||||
const float currentPitchDegrees = GetGesturePinchAngle();
|
||||
const int touchCount = GetTouchPointCount();
|
||||
|
||||
// Handle last gesture
|
||||
//--------------------------------------------------------------------------------------
|
||||
if ((currentGesture != 0) && (currentGesture != 4) && (currentGesture != previousGesture)) lastGesture = currentGesture; // Filter the meaningful gestures (1, 2, 8 to 512) for the display
|
||||
|
||||
// Handle gesture log
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), logButton1))
|
||||
{
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logMode=2; break;
|
||||
case 2: logMode=3; break;
|
||||
case 1: logMode=0; break;
|
||||
default: logMode=1; break;
|
||||
}
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), logButton2))
|
||||
{
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logMode=1; break;
|
||||
case 2: logMode=0; break;
|
||||
case 1: logMode=3; break;
|
||||
default: logMode=2; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fillLog = 0; // Gate variable to be used to allow or not the gesture log to be filled
|
||||
if (currentGesture !=0)
|
||||
{
|
||||
if (logMode == 3) // 3 hides repeated events and hide hold events
|
||||
{
|
||||
if (((currentGesture != 4) && (currentGesture != previousGesture)) || (currentGesture < 3)) fillLog = 1;
|
||||
}
|
||||
else if (logMode == 2) // 2 shows repeated events but hide hold events
|
||||
{
|
||||
if (currentGesture != 4) fillLog = 1;
|
||||
}
|
||||
else if (logMode == 1) // 1 hides repeated events
|
||||
{
|
||||
if (currentGesture != previousGesture) fillLog = 1;
|
||||
}
|
||||
else // 0 shows repeated events
|
||||
{
|
||||
fillLog = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillLog) // If one of the conditions from logMode was met, fill the gesture log
|
||||
{
|
||||
previousGesture = currentGesture;
|
||||
gestureColor = GetGestureColor(currentGesture);
|
||||
if (gestureLogIndex <= 0) gestureLogIndex = GESTURE_LOG_SIZE;
|
||||
gestureLogIndex--;
|
||||
|
||||
// Copy the gesture respective name to the gesture log array
|
||||
TextCopy(gestureLog[gestureLogIndex], GetGestureName(currentGesture));
|
||||
}
|
||||
|
||||
// Handle protractor
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (currentGesture > 255) // aka Pinch In and Pinch Out
|
||||
{
|
||||
currentAngleDegrees = currentPitchDegrees;
|
||||
}
|
||||
else if (currentGesture > 15) // aka Swipe Right, Swipe Left, Swipe Up and Swipe Down
|
||||
{
|
||||
currentAngleDegrees = currentDragDegrees;
|
||||
}
|
||||
else if (currentGesture > 0) // aka Tap, Doubletap, Hold and Grab
|
||||
{
|
||||
currentAngleDegrees = 0.0f;
|
||||
}
|
||||
|
||||
float currentAngleRadians = ((currentAngleDegrees +90.0f)*PI/180); // Convert the current angle to Radians
|
||||
finalVector = (Vector2){ (angleLength*sinf(currentAngleRadians)) + protractorPosition.x, (angleLength*cosf(currentAngleRadians)) + protractorPosition.y }; // Calculate the final vector for display
|
||||
|
||||
// Handle touch and mouse pointer points
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define MAX_TOUCH_COUNT 32
|
||||
|
||||
Vector2 touchPosition[MAX_TOUCH_COUNT] = { 0 };
|
||||
Vector2 mousePosition = {0, 0};
|
||||
if (currentGesture != GESTURE_NONE)
|
||||
{
|
||||
if (touchCount != 0)
|
||||
{
|
||||
for (i = 0; i < touchCount; i++) touchPosition[i] = GetTouchPosition(i); // Fill the touch positions
|
||||
}
|
||||
else mousePosition = GetMousePosition();
|
||||
}
|
||||
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw common
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("*", messagePosition.x + 5, messagePosition.y + 5, 10, BLACK);
|
||||
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", messagePosition.x + 15, messagePosition.y + 5, 10, BLACK);
|
||||
DrawText("*", messagePosition.x + 5, messagePosition.y + 35, 10, BLACK);
|
||||
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", messagePosition.x + 15, messagePosition.y + 35, 10, BLACK);
|
||||
|
||||
// Draw last gesture
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("Last gesture", lastGesturePosition.x + 33, lastGesturePosition.y - 47, 20, BLACK);
|
||||
DrawText("Swipe Tap Pinch Touch", lastGesturePosition.x + 17, lastGesturePosition.y - 18, 10, BLACK);
|
||||
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
|
||||
DrawRectangle(lastGesturePosition.x, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
|
||||
DrawRectangle(lastGesturePosition.x + 40, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
|
||||
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
|
||||
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
|
||||
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
|
||||
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
||||
DrawCircle(lastGesturePosition.x + 103, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
||||
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
||||
for (i = 0; i < 4; i++) DrawCircle(lastGesturePosition.x + 180, lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
|
||||
|
||||
// Draw gesture log
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("Log", gestureLogPosition.x, gestureLogPosition.y, 20, BLACK);
|
||||
|
||||
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
||||
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
|
||||
Color logButton1Color, logButton2Color;
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logButton1Color=MAROON; logButton2Color=MAROON; break;
|
||||
case 2: logButton1Color=GRAY; logButton2Color=MAROON; break;
|
||||
case 1: logButton1Color=MAROON; logButton2Color=GRAY; break;
|
||||
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
|
||||
}
|
||||
DrawRectangleRec(logButton1, logButton1Color);
|
||||
DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
|
||||
DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
|
||||
DrawRectangleRec(logButton2, logButton2Color);
|
||||
DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
|
||||
DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
|
||||
|
||||
// Draw protractor
|
||||
//--------------------------------------------------------------------------------------
|
||||
DrawText("Angle", protractorPosition.x + 55, protractorPosition.y + 76, 10, BLACK);
|
||||
const char *angleString = TextFormat("%f", currentAngleDegrees);
|
||||
const int angleStringDot = TextFindIndex(angleString, ".");
|
||||
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
|
||||
DrawText( angleStringTrim, protractorPosition.x + 55, protractorPosition.y + 92, 20, gestureColor);
|
||||
DrawCircle(protractorPosition.x, protractorPosition.y, 80.0f, WHITE);
|
||||
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
|
||||
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
|
||||
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
|
||||
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
|
||||
DrawText("0", protractorPosition.x + 96, protractorPosition.y - 9, 20, BLACK);
|
||||
DrawText("30", protractorPosition.x + 74, protractorPosition.y - 68, 20, BLACK);
|
||||
DrawText("90", protractorPosition.x - 11, protractorPosition.y - 110, 20, BLACK);
|
||||
DrawText("150", protractorPosition.x - 100, protractorPosition.y - 68, 20, BLACK);
|
||||
DrawText("180", protractorPosition.x - 124, protractorPosition.y - 9, 20, BLACK);
|
||||
DrawText("210", protractorPosition.x - 100, protractorPosition.y + 50, 20, BLACK);
|
||||
DrawText("270", protractorPosition.x - 18, protractorPosition.y + 92, 20, BLACK);
|
||||
DrawText("330", protractorPosition.x + 72, protractorPosition.y + 50, 20, BLACK);
|
||||
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
|
||||
|
||||
// Draw touch and mouse pointer points
|
||||
//--------------------------------------------------------------------------------------
|
||||
if (currentGesture != GESTURE_NONE)
|
||||
{
|
||||
if ( touchCount != 0 )
|
||||
{
|
||||
for (i = 0; i < touchCount; i++)
|
||||
{
|
||||
DrawCircleV(touchPosition[i], 50.0f, Fade(gestureColor, 0.5f));
|
||||
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
|
||||
}
|
||||
|
||||
if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8 : 12), gestureColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCircleV(mousePosition, 35.0f, Fade(gestureColor, 0.5f));
|
||||
DrawCircleV(mousePosition, 5.0f, gestureColor);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures web");
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
//--------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(Update, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60);
|
||||
while (!WindowShouldClose()) Update(); // Detect window close button or ESC key
|
||||
#endif
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_gestures_web.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
64
raylib/examples/core/core_input_keys.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Keyboard input
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard input");
|
||||
|
||||
Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_RIGHT)) ballPosition.x += 2.0f;
|
||||
if (IsKeyDown(KEY_LEFT)) ballPosition.x -= 2.0f;
|
||||
if (IsKeyDown(KEY_UP)) ballPosition.y -= 2.0f;
|
||||
if (IsKeyDown(KEY_DOWN)) ballPosition.y += 2.0f;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("move the ball with arrow keys", 10, 10, 20, DARKGRAY);
|
||||
|
||||
DrawCircleV(ballPosition, 50, MAROON);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_keys.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
70
raylib/examples/core/core_input_mouse.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Mouse input
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input");
|
||||
|
||||
Vector2 ballPosition = { -100.0f, -100.0f };
|
||||
Color ballColor = DARKBLUE;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
ballPosition = GetMousePosition();
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) ballColor = MAROON;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) ballColor = LIME;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) ballColor = DARKBLUE;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_SIDE)) ballColor = PURPLE;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_EXTRA)) ballColor = YELLOW;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_FORWARD)) ballColor = ORANGE;
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_BACK)) ballColor = BEIGE;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawCircleV(ballPosition, 40, ballColor);
|
||||
|
||||
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_mouse.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
63
raylib/examples/core/core_input_mouse_wheel.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] examples - Mouse wheel input
|
||||
*
|
||||
* Example originally created with raylib 1.1, last time updated with raylib 1.3
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel");
|
||||
|
||||
int boxPositionY = screenHeight/2 - 40;
|
||||
int scrollSpeed = 4; // Scrolling speed in pixels
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
boxPositionY -= (int)(GetMouseWheelMove()*scrollSpeed);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangle(screenWidth/2 - 40, boxPositionY, 80, 80, MAROON);
|
||||
|
||||
DrawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, GRAY);
|
||||
DrawText(TextFormat("Box position Y: %03i", boxPositionY), 10, 40, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_mouse_wheel.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
79
raylib/examples/core/core_input_multitouch.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Input multitouch
|
||||
*
|
||||
* Example originally created with raylib 2.1, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2024 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_TOUCH_POINTS 10
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input multitouch");
|
||||
|
||||
Vector2 touchPositions[MAX_TOUCH_POINTS] = { 0 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Get the touch point count ( how many fingers are touching the screen )
|
||||
int tCount = GetTouchPointCount();
|
||||
// Clamp touch points available ( set the maximum touch points allowed )
|
||||
if(tCount > MAX_TOUCH_POINTS) tCount = MAX_TOUCH_POINTS;
|
||||
// Get touch points positions
|
||||
for (int i = 0; i < tCount; ++i) touchPositions[i] = GetTouchPosition(i);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = 0; i < tCount; ++i)
|
||||
{
|
||||
// Make sure point is not (0, 0) as this means there is no touch for it
|
||||
if ((touchPositions[i].x > 0) && (touchPositions[i].y > 0))
|
||||
{
|
||||
// Draw circle and touch index number
|
||||
DrawCircleV(touchPositions[i], 34, ORANGE);
|
||||
DrawText(TextFormat("%d", i), (int)touchPositions[i].x - 10, (int)touchPositions[i].y - 70, 40, BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
DrawText("touch the screen at multiple locations to get multiple balls", 10, 10, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_input_multitouch.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
174
raylib/examples/core/core_input_virtual_controls.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - input virtual controls
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* Example create by GreenSnakeLinux (@GreenSnakeLinux),
|
||||
* lighter by oblerion (@oblerion) and
|
||||
* reviewed by Ramon Santamaria (@raysan5) and
|
||||
* improved by danilwhale (@danilwhale)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
|
||||
typedef enum {
|
||||
BUTTON_NONE = -1,
|
||||
BUTTON_UP,
|
||||
BUTTON_LEFT,
|
||||
BUTTON_RIGHT,
|
||||
BUTTON_DOWN,
|
||||
BUTTON_MAX
|
||||
} PadButton;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
|
||||
|
||||
Vector2 padPosition = { 100, 350 };
|
||||
float buttonRadius = 30;
|
||||
|
||||
Vector2 buttonPositions[BUTTON_MAX] =
|
||||
{
|
||||
{ padPosition.x,padPosition.y - buttonRadius*1.5f }, // Up
|
||||
{ padPosition.x - buttonRadius*1.5f, padPosition.y }, // Left
|
||||
{ padPosition.x + buttonRadius*1.5f, padPosition.y }, // Right
|
||||
{ padPosition.x, padPosition.y + buttonRadius*1.5f } // Down
|
||||
};
|
||||
|
||||
const char *buttonLabels[BUTTON_MAX] =
|
||||
{
|
||||
"Y", // Up
|
||||
"X", // Left
|
||||
"B", // Right
|
||||
"A" // Down
|
||||
};
|
||||
|
||||
Color buttonLabelColors[BUTTON_MAX] =
|
||||
{
|
||||
YELLOW, // Up
|
||||
BLUE, // Left
|
||||
RED, // Right
|
||||
GREEN // Down
|
||||
};
|
||||
|
||||
int pressedButton = BUTTON_NONE;
|
||||
Vector2 inputPosition = { 0, 0 };
|
||||
|
||||
Vector2 playerPosition = { (float)screenWidth/2, (float)screenHeight/2 };
|
||||
float playerSpeed = 75;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//--------------------------------------------------------------------------
|
||||
if ((GetTouchPointCount() > 0))
|
||||
{
|
||||
// Use touch position
|
||||
inputPosition = GetTouchPosition(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use mouse position
|
||||
inputPosition = GetMousePosition();
|
||||
}
|
||||
|
||||
// Reset pressed button to none
|
||||
pressedButton = BUTTON_NONE;
|
||||
|
||||
// Make sure user is pressing left mouse button if they're from desktop
|
||||
if ((GetTouchPointCount() > 0) || ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
|
||||
{
|
||||
// Find nearest D-Pad button to the input position
|
||||
for (int i = 0; i < BUTTON_MAX; i++)
|
||||
{
|
||||
float distX = fabsf(buttonPositions[i].x - inputPosition.x);
|
||||
float distY = fabsf(buttonPositions[i].y - inputPosition.y);
|
||||
|
||||
if ((distX + distY < buttonRadius))
|
||||
{
|
||||
pressedButton = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move player according to pressed button
|
||||
switch (pressedButton)
|
||||
{
|
||||
case BUTTON_UP:
|
||||
{
|
||||
playerPosition.y -= playerSpeed*GetFrameTime();
|
||||
break;
|
||||
}
|
||||
case BUTTON_LEFT:
|
||||
{
|
||||
playerPosition.x -= playerSpeed*GetFrameTime();
|
||||
break;
|
||||
}
|
||||
case BUTTON_RIGHT:
|
||||
{
|
||||
playerPosition.x += playerSpeed*GetFrameTime();
|
||||
break;
|
||||
}
|
||||
case BUTTON_DOWN:
|
||||
{
|
||||
playerPosition.y += playerSpeed*GetFrameTime();
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw world
|
||||
DrawCircleV(playerPosition, 50, MAROON);
|
||||
|
||||
// Draw GUI
|
||||
for (int i = 0; i < BUTTON_MAX; i++)
|
||||
{
|
||||
DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK);
|
||||
|
||||
DrawText(buttonLabels[i],
|
||||
(int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8,
|
||||
20, buttonLabelColors[i]);
|
||||
}
|
||||
|
||||
DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
raylib/examples/core/core_input_virtual_controls.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
156
raylib/examples/core/core_loading_thread.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - loading thread
|
||||
*
|
||||
* NOTE: This example requires linking with pthreads library on MinGW,
|
||||
* it can be accomplished passing -static parameter to compiler
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 3.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
// WARNING: This example does not build on Windows with MSVC compiler
|
||||
#include "pthread.h" // POSIX style threads management
|
||||
|
||||
#include <stdatomic.h> // C11 atomic data types
|
||||
|
||||
#include <time.h> // Required for: clock()
|
||||
|
||||
// Using C11 atomics for synchronization
|
||||
// NOTE: A plain bool (or any plain data type for that matter) can't be used for inter-thread synchronization
|
||||
static atomic_bool dataLoaded = false; // Data Loaded completion indicator
|
||||
static void *LoadDataThread(void *arg); // Loading data thread function declaration
|
||||
|
||||
static atomic_int dataProgress = 0; // Data progress accumulator
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - loading thread");
|
||||
|
||||
pthread_t threadId = { 0 }; // Loading data thread id
|
||||
|
||||
enum { STATE_WAITING, STATE_LOADING, STATE_FINISHED } state = STATE_WAITING;
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
switch (state)
|
||||
{
|
||||
case STATE_WAITING:
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
int error = pthread_create(&threadId, NULL, &LoadDataThread, NULL);
|
||||
if (error != 0) TraceLog(LOG_ERROR, "Error creating loading thread");
|
||||
else TraceLog(LOG_INFO, "Loading thread initialized successfully");
|
||||
|
||||
state = STATE_LOADING;
|
||||
}
|
||||
} break;
|
||||
case STATE_LOADING:
|
||||
{
|
||||
framesCounter++;
|
||||
if (atomic_load_explicit(&dataLoaded, memory_order_relaxed))
|
||||
{
|
||||
framesCounter = 0;
|
||||
int error = pthread_join(threadId, NULL);
|
||||
if (error != 0) TraceLog(LOG_ERROR, "Error joining loading thread");
|
||||
else TraceLog(LOG_INFO, "Loading thread terminated successfully");
|
||||
|
||||
state = STATE_FINISHED;
|
||||
}
|
||||
} break;
|
||||
case STATE_FINISHED:
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
// Reset everything to launch again
|
||||
atomic_store_explicit(&dataLoaded, false, memory_order_relaxed);
|
||||
atomic_store_explicit(&dataProgress, 0, memory_order_relaxed);
|
||||
state = STATE_WAITING;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case STATE_WAITING: DrawText("PRESS ENTER to START LOADING DATA", 150, 170, 20, DARKGRAY); break;
|
||||
case STATE_LOADING:
|
||||
{
|
||||
DrawRectangle(150, 200, atomic_load_explicit(&dataProgress, memory_order_relaxed), 60, SKYBLUE);
|
||||
if ((framesCounter/15)%2) DrawText("LOADING DATA...", 240, 210, 40, DARKBLUE);
|
||||
|
||||
} break;
|
||||
case STATE_FINISHED:
|
||||
{
|
||||
DrawRectangle(150, 200, 500, 60, LIME);
|
||||
DrawText("DATA LOADED!", 250, 210, 40, GREEN);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
DrawRectangleLines(150, 200, 500, 60, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Loading data thread function definition
|
||||
static void *LoadDataThread(void *arg)
|
||||
{
|
||||
int timeCounter = 0; // Time counted in ms
|
||||
clock_t prevTime = clock(); // Previous time
|
||||
|
||||
// We simulate data loading with a time counter for 5 seconds
|
||||
while (timeCounter < 5000)
|
||||
{
|
||||
clock_t currentTime = clock() - prevTime;
|
||||
timeCounter = currentTime*1000/CLOCKS_PER_SEC;
|
||||
|
||||
// We accumulate time over a global variable to be used in
|
||||
// main thread as a progress bar
|
||||
atomic_store_explicit(&dataProgress, timeCounter/10, memory_order_relaxed);
|
||||
}
|
||||
|
||||
// When data has finished loading, we set global variable
|
||||
atomic_store_explicit(&dataLoaded, true, memory_order_relaxed);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
BIN
raylib/examples/core/core_loading_thread.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
176
raylib/examples/core/core_random_sequence.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Generates a random sequence
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* Example contributed by Dalton Overmyer (@REDl3east) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 Dalton Overmyer (@REDl3east)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#include <stdlib.h> // Required for: malloc() and free()
|
||||
|
||||
typedef struct ColorRect{
|
||||
Color c;
|
||||
Rectangle r;
|
||||
} ColorRect;
|
||||
|
||||
static Color GenerateRandomColor();
|
||||
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight);
|
||||
static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount);
|
||||
static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void) {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - Generates a random sequence");
|
||||
|
||||
int rectCount = 20;
|
||||
float rectSize = (float)screenWidth/rectCount;
|
||||
ColorRect* rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
if(IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
ShuffleColorRectSequence(rectangles, rectCount);
|
||||
}
|
||||
|
||||
if(IsKeyPressed(KEY_UP))
|
||||
{
|
||||
rectCount++;
|
||||
rectSize = (float)screenWidth/rectCount;
|
||||
free(rectangles);
|
||||
rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
|
||||
}
|
||||
|
||||
if(IsKeyPressed(KEY_DOWN))
|
||||
{
|
||||
if(rectCount >= 4){
|
||||
rectCount--;
|
||||
rectSize = (float)screenWidth/rectCount;
|
||||
free(rectangles);
|
||||
rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
int fontSize = 20;
|
||||
for(int x=0;x<rectCount;x++)
|
||||
{
|
||||
DrawRectangleRec(rectangles[x].r, rectangles[x].c);
|
||||
DrawTextCenterKeyHelp("SPACE", "to shuffle the sequence.", 10, screenHeight - 96, fontSize, BLACK);
|
||||
DrawTextCenterKeyHelp("UP", "to add a rectangle and generate a new sequence.", 10, screenHeight - 64, fontSize, BLACK);
|
||||
DrawTextCenterKeyHelp("DOWN", "to remove a rectangle and generate a new sequence.", 10, screenHeight - 32, fontSize, BLACK);
|
||||
}
|
||||
|
||||
const char* rectCountText = TextFormat("%d rectangles", rectCount);
|
||||
int rectCountTextSize = MeasureText(rectCountText, fontSize);
|
||||
DrawText(rectCountText, screenWidth - rectCountTextSize - 10, 10, fontSize, BLACK);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
free(rectangles);
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Color GenerateRandomColor()
|
||||
{
|
||||
return CLITERAL(Color){
|
||||
GetRandomValue(0, 255),
|
||||
GetRandomValue(0, 255),
|
||||
GetRandomValue(0, 255),
|
||||
255,
|
||||
};
|
||||
}
|
||||
|
||||
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){
|
||||
int *seq = LoadRandomSequence((unsigned int)rectCount, 0, (unsigned int)rectCount-1);
|
||||
ColorRect* rectangles = (ColorRect *)malloc((int)rectCount*sizeof(ColorRect));
|
||||
|
||||
float rectSeqWidth = rectCount * rectWidth;
|
||||
float startX = (screenWidth - rectSeqWidth) * 0.5f;
|
||||
|
||||
for(int x=0;x<rectCount;x++){
|
||||
int rectHeight = (int)Remap((float)seq[x], 0, rectCount-1, 0, screenHeight);
|
||||
rectangles[x].c = GenerateRandomColor();
|
||||
rectangles[x].r = CLITERAL(Rectangle){
|
||||
startX + x * rectWidth, screenHeight - rectHeight, rectWidth, (float)rectHeight
|
||||
};
|
||||
}
|
||||
UnloadRandomSequence(seq);
|
||||
return rectangles;
|
||||
}
|
||||
|
||||
static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount)
|
||||
{
|
||||
int *seq = LoadRandomSequence(rectCount, 0, rectCount-1);
|
||||
for(int i1=0;i1<rectCount;i1++){
|
||||
ColorRect* r1 = &rectangles[i1];
|
||||
ColorRect* r2 = &rectangles[seq[i1]];
|
||||
|
||||
// swap only the color and height
|
||||
ColorRect tmp = *r1;
|
||||
r1->c = r2->c;
|
||||
r1->r.height = r2->r.height;
|
||||
r1->r.y = r2->r.y;
|
||||
r2->c = tmp.c;
|
||||
r2->r.height = tmp.r.height;
|
||||
r2->r.y = tmp.r.y;
|
||||
|
||||
}
|
||||
UnloadRandomSequence(seq);
|
||||
}
|
||||
|
||||
static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color)
|
||||
{
|
||||
int spaceSize = MeasureText(" ", fontSize);
|
||||
int pressSize = MeasureText("Press", fontSize);
|
||||
int keySize = MeasureText(key, fontSize);
|
||||
int textSize = MeasureText(text, fontSize);
|
||||
int totalSize = pressSize + 2 * spaceSize + keySize + 2 * spaceSize + textSize;
|
||||
int textSizeCurrent = 0;
|
||||
|
||||
DrawText("Press", posX, posY, fontSize, color);
|
||||
textSizeCurrent += pressSize + 2 * spaceSize;
|
||||
DrawText(key, posX + textSizeCurrent, posY, fontSize, RED);
|
||||
DrawRectangle(posX + textSizeCurrent, posY + fontSize, keySize, 3, RED);
|
||||
textSizeCurrent += keySize + 2 * spaceSize;
|
||||
DrawText(text, posX + textSizeCurrent, posY, fontSize, color);
|
||||
}
|
||||
BIN
raylib/examples/core/core_random_sequence.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
72
raylib/examples/core/core_random_values.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Generate random values
|
||||
*
|
||||
* Example originally created with raylib 1.1, last time updated with raylib 1.1
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - generate random values");
|
||||
|
||||
// SetRandomSeed(0xaabbccff); // Set a custom random seed if desired, by default: "time(NULL)"
|
||||
|
||||
int randValue = GetRandomValue(-8, 5); // Get a random integer number between -8 and 5 (both included)
|
||||
|
||||
unsigned int framesCounter = 0; // Variable used to count frames
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
framesCounter++;
|
||||
|
||||
// Every two seconds (120 frames) a new random value is generated
|
||||
if (((framesCounter/120)%2) == 1)
|
||||
{
|
||||
randValue = GetRandomValue(-8, 5);
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Every 2 seconds a new random value is generated:", 130, 100, 20, MAROON);
|
||||
|
||||
DrawText(TextFormat("%i", randValue), 360, 180, 80, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_random_values.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
76
raylib/examples/core/core_scissor_test.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Scissor test
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 3.0
|
||||
*
|
||||
* Example contributed by Chris Dill (@MysteriousSpace) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2024 Chris Dill (@MysteriousSpace)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - scissor test");
|
||||
|
||||
Rectangle scissorArea = { 0, 0, 300, 300 };
|
||||
bool scissorMode = true;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_S)) scissorMode = !scissorMode;
|
||||
|
||||
// Centre the scissor area around the mouse position
|
||||
scissorArea.x = GetMouseX() - scissorArea.width/2;
|
||||
scissorArea.y = GetMouseY() - scissorArea.height/2;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (scissorMode) BeginScissorMode((int)scissorArea.x, (int)scissorArea.y, (int)scissorArea.width, (int)scissorArea.height);
|
||||
|
||||
// Draw full screen rectangle and some text
|
||||
// NOTE: Only part defined by scissor area will be rendered
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), RED);
|
||||
DrawText("Move the mouse around to reveal this text!", 190, 200, 20, LIGHTGRAY);
|
||||
|
||||
if (scissorMode) EndScissorMode();
|
||||
|
||||
DrawRectangleLinesEx(scissorArea, 1, BLACK);
|
||||
DrawText("Press S to toggle scissor test", 10, 10, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_scissor_test.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
122
raylib/examples/core/core_smooth_pixelperfect.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Smooth Pixel-perfect camera
|
||||
*
|
||||
* Example originally created with raylib 3.7, last time updated with raylib 4.0
|
||||
*
|
||||
* Example contributed by Giancamillo Alessandroni (@NotManyIdeasDev) and
|
||||
* reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2021-2024 Giancamillo Alessandroni (@NotManyIdeasDev) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h> // Required for: sinf(), cosf()
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
const int virtualScreenWidth = 160;
|
||||
const int virtualScreenHeight = 90;
|
||||
|
||||
const float virtualRatio = (float)screenWidth/(float)virtualScreenWidth;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - smooth pixel-perfect camera");
|
||||
|
||||
Camera2D worldSpaceCamera = { 0 }; // Game world camera
|
||||
worldSpaceCamera.zoom = 1.0f;
|
||||
|
||||
Camera2D screenSpaceCamera = { 0 }; // Smoothing camera
|
||||
screenSpaceCamera.zoom = 1.0f;
|
||||
|
||||
RenderTexture2D target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight); // This is where we'll draw all our objects.
|
||||
|
||||
Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f };
|
||||
Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f };
|
||||
Rectangle rec03 = { 80.0f, 65.0f, 15.0f, 25.0f };
|
||||
|
||||
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||
Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
|
||||
Rectangle destRec = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
||||
|
||||
Vector2 origin = { 0.0f, 0.0f };
|
||||
|
||||
float rotation = 0.0f;
|
||||
|
||||
float cameraX = 0.0f;
|
||||
float cameraY = 0.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rotation += 60.0f*GetFrameTime(); // Rotate the rectangles, 60 degrees per second
|
||||
|
||||
// Make the camera move to demonstrate the effect
|
||||
cameraX = (sinf((float)GetTime())*50.0f) - 10.0f;
|
||||
cameraY = cosf((float)GetTime())*30.0f;
|
||||
|
||||
// Set the camera's target to the values computed above
|
||||
screenSpaceCamera.target = (Vector2){ cameraX, cameraY };
|
||||
|
||||
// Round worldSpace coordinates, keep decimals into screenSpace coordinates
|
||||
worldSpaceCamera.target.x = truncf(screenSpaceCamera.target.x);
|
||||
screenSpaceCamera.target.x -= worldSpaceCamera.target.x;
|
||||
screenSpaceCamera.target.x *= virtualRatio;
|
||||
|
||||
worldSpaceCamera.target.y = truncf(screenSpaceCamera.target.y);
|
||||
screenSpaceCamera.target.y -= worldSpaceCamera.target.y;
|
||||
screenSpaceCamera.target.y *= virtualRatio;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(worldSpaceCamera);
|
||||
DrawRectanglePro(rec01, origin, rotation, BLACK);
|
||||
DrawRectanglePro(rec02, origin, -rotation, RED);
|
||||
DrawRectanglePro(rec03, origin, rotation + 45.0f, BLUE);
|
||||
EndMode2D();
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RED);
|
||||
|
||||
BeginMode2D(screenSpaceCamera);
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||
EndMode2D();
|
||||
|
||||
DrawText(TextFormat("Screen resolution: %ix%i", screenWidth, screenHeight), 10, 10, 20, DARKBLUE);
|
||||
DrawText(TextFormat("World resolution: %ix%i", virtualScreenWidth, virtualScreenHeight), 10, 40, 20, DARKGREEN);
|
||||
DrawFPS(GetScreenWidth() - 95, 10);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_smooth_pixelperfect.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
193
raylib/examples/core/core_storage_values.c
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Storage save/load values
|
||||
*
|
||||
* Example originally created with raylib 1.4, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h> // Required for: calloc(), free()
|
||||
|
||||
#define STORAGE_DATA_FILE "storage.data" // Storage file
|
||||
|
||||
// NOTE: Storage positions must start with 0, directly related to file memory layout
|
||||
typedef enum {
|
||||
STORAGE_POSITION_SCORE = 0,
|
||||
STORAGE_POSITION_HISCORE = 1
|
||||
} StorageData;
|
||||
|
||||
// Persistent storage functions
|
||||
static bool SaveStorageValue(unsigned int position, int value);
|
||||
static int LoadStorageValue(unsigned int position);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - storage save/load values");
|
||||
|
||||
int score = 0;
|
||||
int hiscore = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
score = GetRandomValue(1000, 2000);
|
||||
hiscore = GetRandomValue(2000, 4000);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
SaveStorageValue(STORAGE_POSITION_SCORE, score);
|
||||
SaveStorageValue(STORAGE_POSITION_HISCORE, hiscore);
|
||||
}
|
||||
else if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
// NOTE: If requested position could not be found, value 0 is returned
|
||||
score = LoadStorageValue(STORAGE_POSITION_SCORE);
|
||||
hiscore = LoadStorageValue(STORAGE_POSITION_HISCORE);
|
||||
}
|
||||
|
||||
framesCounter++;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText(TextFormat("SCORE: %i", score), 280, 130, 40, MAROON);
|
||||
DrawText(TextFormat("HI-SCORE: %i", hiscore), 210, 200, 50, BLACK);
|
||||
|
||||
DrawText(TextFormat("frames: %i", framesCounter), 10, 10, 20, LIME);
|
||||
|
||||
DrawText("Press R to generate random numbers", 220, 40, 20, LIGHTGRAY);
|
||||
DrawText("Press ENTER to SAVE values", 250, 310, 20, LIGHTGRAY);
|
||||
DrawText("Press SPACE to LOAD values", 252, 350, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Save integer value to storage file (to defined position)
|
||||
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
|
||||
bool SaveStorageValue(unsigned int position, int value)
|
||||
{
|
||||
bool success = false;
|
||||
int dataSize = 0;
|
||||
unsigned int newDataSize = 0;
|
||||
unsigned char *fileData = LoadFileData(STORAGE_DATA_FILE, &dataSize);
|
||||
unsigned char *newFileData = NULL;
|
||||
|
||||
if (fileData != NULL)
|
||||
{
|
||||
if (dataSize <= (position*sizeof(int)))
|
||||
{
|
||||
// Increase data size up to position and store value
|
||||
newDataSize = (position + 1)*sizeof(int);
|
||||
newFileData = (unsigned char *)RL_REALLOC(fileData, newDataSize);
|
||||
|
||||
if (newFileData != NULL)
|
||||
{
|
||||
// RL_REALLOC succeded
|
||||
int *dataPtr = (int *)newFileData;
|
||||
dataPtr[position] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// RL_REALLOC failed
|
||||
TraceLog(LOG_WARNING, "FILEIO: [%s] Failed to realloc data (%u), position in bytes (%u) bigger than actual file size", STORAGE_DATA_FILE, dataSize, position*sizeof(int));
|
||||
|
||||
// We store the old size of the file
|
||||
newFileData = fileData;
|
||||
newDataSize = dataSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store the old size of the file
|
||||
newFileData = fileData;
|
||||
newDataSize = dataSize;
|
||||
|
||||
// Replace value on selected position
|
||||
int *dataPtr = (int *)newFileData;
|
||||
dataPtr[position] = value;
|
||||
}
|
||||
|
||||
success = SaveFileData(STORAGE_DATA_FILE, newFileData, newDataSize);
|
||||
RL_FREE(newFileData);
|
||||
|
||||
TraceLog(LOG_INFO, "FILEIO: [%s] Saved storage value: %i", STORAGE_DATA_FILE, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(LOG_INFO, "FILEIO: [%s] File created successfully", STORAGE_DATA_FILE);
|
||||
|
||||
dataSize = (position + 1)*sizeof(int);
|
||||
fileData = (unsigned char *)RL_MALLOC(dataSize);
|
||||
int *dataPtr = (int *)fileData;
|
||||
dataPtr[position] = value;
|
||||
|
||||
success = SaveFileData(STORAGE_DATA_FILE, fileData, dataSize);
|
||||
UnloadFileData(fileData);
|
||||
|
||||
TraceLog(LOG_INFO, "FILEIO: [%s] Saved storage value: %i", STORAGE_DATA_FILE, value);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Load integer value from storage file (from defined position)
|
||||
// NOTE: If requested position could not be found, value 0 is returned
|
||||
int LoadStorageValue(unsigned int position)
|
||||
{
|
||||
int value = 0;
|
||||
int dataSize = 0;
|
||||
unsigned char *fileData = LoadFileData(STORAGE_DATA_FILE, &dataSize);
|
||||
|
||||
if (fileData != NULL)
|
||||
{
|
||||
if (dataSize < ((int)(position*4))) TraceLog(LOG_WARNING, "FILEIO: [%s] Failed to find storage position: %i", STORAGE_DATA_FILE, position);
|
||||
else
|
||||
{
|
||||
int *dataPtr = (int *)fileData;
|
||||
value = dataPtr[position];
|
||||
}
|
||||
|
||||
UnloadFileData(fileData);
|
||||
|
||||
TraceLog(LOG_INFO, "FILEIO: [%s] Loaded storage value: %i", STORAGE_DATA_FILE, value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
BIN
raylib/examples/core/core_storage_values.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
150
raylib/examples/core/core_vr_simulator.c
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters)
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2017-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
// NOTE: screenWidth/screenHeight should match VR device aspect ratio
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator");
|
||||
|
||||
// VR device parameters definition
|
||||
VrDeviceInfo device = {
|
||||
// Oculus Rift CV1 parameters for simulator
|
||||
.hResolution = 2160, // Horizontal resolution in pixels
|
||||
.vResolution = 1200, // Vertical resolution in pixels
|
||||
.hScreenSize = 0.133793f, // Horizontal size in meters
|
||||
.vScreenSize = 0.0669f, // Vertical size in meters
|
||||
.eyeToScreenDistance = 0.041f, // Distance between eye and display in meters
|
||||
.lensSeparationDistance = 0.07f, // Lens separation distance in meters
|
||||
.interpupillaryDistance = 0.07f, // IPD (distance between pupils) in meters
|
||||
|
||||
// NOTE: CV1 uses fresnel-hybrid-asymmetric lenses with specific compute shaders
|
||||
// Following parameters are just an approximation to CV1 distortion stereo rendering
|
||||
.lensDistortionValues[0] = 1.0f, // Lens distortion constant parameter 0
|
||||
.lensDistortionValues[1] = 0.22f, // Lens distortion constant parameter 1
|
||||
.lensDistortionValues[2] = 0.24f, // Lens distortion constant parameter 2
|
||||
.lensDistortionValues[3] = 0.0f, // Lens distortion constant parameter 3
|
||||
.chromaAbCorrection[0] = 0.996f, // Chromatic aberration correction parameter 0
|
||||
.chromaAbCorrection[1] = -0.004f, // Chromatic aberration correction parameter 1
|
||||
.chromaAbCorrection[2] = 1.014f, // Chromatic aberration correction parameter 2
|
||||
.chromaAbCorrection[3] = 0.0f, // Chromatic aberration correction parameter 3
|
||||
};
|
||||
|
||||
// Load VR stereo config for VR device parameteres (Oculus Rift CV1 parameters)
|
||||
VrStereoConfig config = LoadVrStereoConfig(device);
|
||||
|
||||
// Distortion shader (uses device lens distortion and chroma)
|
||||
Shader distortion = LoadShader(0, TextFormat("resources/distortion%i.fs", GLSL_VERSION));
|
||||
|
||||
// Update distortion shader with lens and distortion-scale parameters
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "leftLensCenter"),
|
||||
config.leftLensCenter, SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "rightLensCenter"),
|
||||
config.rightLensCenter, SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "leftScreenCenter"),
|
||||
config.leftScreenCenter, SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "rightScreenCenter"),
|
||||
config.rightScreenCenter, SHADER_UNIFORM_VEC2);
|
||||
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "scale"),
|
||||
config.scale, SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "scaleIn"),
|
||||
config.scaleIn, SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "deviceWarpParam"),
|
||||
device.lensDistortionValues, SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(distortion, GetShaderLocation(distortion, "chromaAbParam"),
|
||||
device.chromaAbCorrection, SHADER_UNIFORM_VEC4);
|
||||
|
||||
// Initialize framebuffer for stereo rendering
|
||||
// NOTE: Screen size should match HMD aspect ratio
|
||||
RenderTexture2D target = LoadRenderTexture(device.hResolution, device.vResolution);
|
||||
|
||||
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||
Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
|
||||
Rectangle destRec = { 0.0f, 0.0f, (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 5.0f, 2.0f, 5.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector
|
||||
camera.fovy = 60.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginVrStereoMode(config);
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||
DrawGrid(40, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
EndVrStereoMode();
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginShaderMode(distortion);
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
|
||||
EndShaderMode();
|
||||
DrawFPS(10, 10);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadVrStereoConfig(config); // Unload stereo config
|
||||
|
||||
UnloadRenderTexture(target); // Unload stereo render fbo
|
||||
UnloadShader(distortion); // Unload distortion shader
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_vr_simulator.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
196
raylib/examples/core/core_window_flags.c
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - window flags
|
||||
*
|
||||
* Example originally created with raylib 3.5, last time updated with raylib 3.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2020-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
// Possible window flags
|
||||
/*
|
||||
FLAG_VSYNC_HINT
|
||||
FLAG_FULLSCREEN_MODE -> not working properly -> wrong scaling!
|
||||
FLAG_WINDOW_RESIZABLE
|
||||
FLAG_WINDOW_UNDECORATED
|
||||
FLAG_WINDOW_TRANSPARENT
|
||||
FLAG_WINDOW_HIDDEN
|
||||
FLAG_WINDOW_MINIMIZED -> Not supported on window creation
|
||||
FLAG_WINDOW_MAXIMIZED -> Not supported on window creation
|
||||
FLAG_WINDOW_UNFOCUSED
|
||||
FLAG_WINDOW_TOPMOST
|
||||
FLAG_WINDOW_HIGHDPI -> errors after minimize-resize, fb size is recalculated
|
||||
FLAG_WINDOW_ALWAYS_RUN
|
||||
FLAG_MSAA_4X_HINT
|
||||
*/
|
||||
|
||||
// Set configuration flags for window creation
|
||||
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - window flags");
|
||||
|
||||
Vector2 ballPosition = { GetScreenWidth() / 2.0f, GetScreenHeight() / 2.0f };
|
||||
Vector2 ballSpeed = { 5.0f, 4.0f };
|
||||
float ballRadius = 20;
|
||||
|
||||
int framesCounter = 0;
|
||||
|
||||
//SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//----------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//-----------------------------------------------------
|
||||
if (IsKeyPressed(KEY_F)) ToggleFullscreen(); // modifies window size when scaling!
|
||||
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
if (IsWindowState(FLAG_WINDOW_RESIZABLE)) ClearWindowState(FLAG_WINDOW_RESIZABLE);
|
||||
else SetWindowState(FLAG_WINDOW_RESIZABLE);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_D))
|
||||
{
|
||||
if (IsWindowState(FLAG_WINDOW_UNDECORATED)) ClearWindowState(FLAG_WINDOW_UNDECORATED);
|
||||
else SetWindowState(FLAG_WINDOW_UNDECORATED);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_H))
|
||||
{
|
||||
if (!IsWindowState(FLAG_WINDOW_HIDDEN)) SetWindowState(FLAG_WINDOW_HIDDEN);
|
||||
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (IsWindowState(FLAG_WINDOW_HIDDEN))
|
||||
{
|
||||
framesCounter++;
|
||||
if (framesCounter >= 240) ClearWindowState(FLAG_WINDOW_HIDDEN); // Show window after 3 seconds
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_N))
|
||||
{
|
||||
if (!IsWindowState(FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
|
||||
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (IsWindowState(FLAG_WINDOW_MINIMIZED))
|
||||
{
|
||||
framesCounter++;
|
||||
if (framesCounter >= 240) RestoreWindow(); // Restore window after 3 seconds
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_M))
|
||||
{
|
||||
// NOTE: Requires FLAG_WINDOW_RESIZABLE enabled!
|
||||
if (IsWindowState(FLAG_WINDOW_MAXIMIZED)) RestoreWindow();
|
||||
else MaximizeWindow();
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_U))
|
||||
{
|
||||
if (IsWindowState(FLAG_WINDOW_UNFOCUSED)) ClearWindowState(FLAG_WINDOW_UNFOCUSED);
|
||||
else SetWindowState(FLAG_WINDOW_UNFOCUSED);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_T))
|
||||
{
|
||||
if (IsWindowState(FLAG_WINDOW_TOPMOST)) ClearWindowState(FLAG_WINDOW_TOPMOST);
|
||||
else SetWindowState(FLAG_WINDOW_TOPMOST);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_A))
|
||||
{
|
||||
if (IsWindowState(FLAG_WINDOW_ALWAYS_RUN)) ClearWindowState(FLAG_WINDOW_ALWAYS_RUN);
|
||||
else SetWindowState(FLAG_WINDOW_ALWAYS_RUN);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_V))
|
||||
{
|
||||
if (IsWindowState(FLAG_VSYNC_HINT)) ClearWindowState(FLAG_VSYNC_HINT);
|
||||
else SetWindowState(FLAG_VSYNC_HINT);
|
||||
}
|
||||
|
||||
// Bouncing ball logic
|
||||
ballPosition.x += ballSpeed.x;
|
||||
ballPosition.y += ballSpeed.y;
|
||||
if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f;
|
||||
if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -1.0f;
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
if (IsWindowState(FLAG_WINDOW_TRANSPARENT)) ClearBackground(BLANK);
|
||||
else ClearBackground(RAYWHITE);
|
||||
|
||||
DrawCircleV(ballPosition, ballRadius, MAROON);
|
||||
DrawRectangleLinesEx((Rectangle) { 0, 0, (float)GetScreenWidth(), (float)GetScreenHeight() }, 4, RAYWHITE);
|
||||
|
||||
DrawCircleV(GetMousePosition(), 10, DARKBLUE);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
DrawText(TextFormat("Screen Size: [%i, %i]", GetScreenWidth(), GetScreenHeight()), 10, 40, 10, GREEN);
|
||||
|
||||
// Draw window state info
|
||||
DrawText("Following flags can be set after window creation:", 10, 60, 10, GRAY);
|
||||
if (IsWindowState(FLAG_FULLSCREEN_MODE)) DrawText("[F] FLAG_FULLSCREEN_MODE: on", 10, 80, 10, LIME);
|
||||
else DrawText("[F] FLAG_FULLSCREEN_MODE: off", 10, 80, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_RESIZABLE)) DrawText("[R] FLAG_WINDOW_RESIZABLE: on", 10, 100, 10, LIME);
|
||||
else DrawText("[R] FLAG_WINDOW_RESIZABLE: off", 10, 100, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_UNDECORATED)) DrawText("[D] FLAG_WINDOW_UNDECORATED: on", 10, 120, 10, LIME);
|
||||
else DrawText("[D] FLAG_WINDOW_UNDECORATED: off", 10, 120, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_HIDDEN)) DrawText("[H] FLAG_WINDOW_HIDDEN: on", 10, 140, 10, LIME);
|
||||
else DrawText("[H] FLAG_WINDOW_HIDDEN: off", 10, 140, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_MINIMIZED)) DrawText("[N] FLAG_WINDOW_MINIMIZED: on", 10, 160, 10, LIME);
|
||||
else DrawText("[N] FLAG_WINDOW_MINIMIZED: off", 10, 160, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_MAXIMIZED)) DrawText("[M] FLAG_WINDOW_MAXIMIZED: on", 10, 180, 10, LIME);
|
||||
else DrawText("[M] FLAG_WINDOW_MAXIMIZED: off", 10, 180, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_UNFOCUSED)) DrawText("[G] FLAG_WINDOW_UNFOCUSED: on", 10, 200, 10, LIME);
|
||||
else DrawText("[U] FLAG_WINDOW_UNFOCUSED: off", 10, 200, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_TOPMOST)) DrawText("[T] FLAG_WINDOW_TOPMOST: on", 10, 220, 10, LIME);
|
||||
else DrawText("[T] FLAG_WINDOW_TOPMOST: off", 10, 220, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_ALWAYS_RUN)) DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: on", 10, 240, 10, LIME);
|
||||
else DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: off", 10, 240, 10, MAROON);
|
||||
if (IsWindowState(FLAG_VSYNC_HINT)) DrawText("[V] FLAG_VSYNC_HINT: on", 10, 260, 10, LIME);
|
||||
else DrawText("[V] FLAG_VSYNC_HINT: off", 10, 260, 10, MAROON);
|
||||
|
||||
DrawText("Following flags can only be set before window creation:", 10, 300, 10, GRAY);
|
||||
if (IsWindowState(FLAG_WINDOW_HIGHDPI)) DrawText("FLAG_WINDOW_HIGHDPI: on", 10, 320, 10, LIME);
|
||||
else DrawText("FLAG_WINDOW_HIGHDPI: off", 10, 320, 10, MAROON);
|
||||
if (IsWindowState(FLAG_WINDOW_TRANSPARENT)) DrawText("FLAG_WINDOW_TRANSPARENT: on", 10, 340, 10, LIME);
|
||||
else DrawText("FLAG_WINDOW_TRANSPARENT: off", 10, 340, 10, MAROON);
|
||||
if (IsWindowState(FLAG_MSAA_4X_HINT)) DrawText("FLAG_MSAA_4X_HINT: on", 10, 360, 10, LIME);
|
||||
else DrawText("FLAG_MSAA_4X_HINT: off", 10, 360, 10, MAROON);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_window_flags.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
107
raylib/examples/core/core_window_letterbox.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - window scale letterbox (and virtual mouse)
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||
*
|
||||
* Example contributed by Anata (@anatagawa) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2019-2024 Anata (@anatagawa) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h" // Required for: Vector2Clamp()
|
||||
|
||||
#define MAX(a, b) ((a)>(b)? (a) : (b))
|
||||
#define MIN(a, b) ((a)<(b)? (a) : (b))
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
const int windowWidth = 800;
|
||||
const int windowHeight = 450;
|
||||
|
||||
// Enable config flags for resizable window and vertical synchro
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
|
||||
InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox");
|
||||
SetWindowMinSize(320, 240);
|
||||
|
||||
int gameScreenWidth = 640;
|
||||
int gameScreenHeight = 480;
|
||||
|
||||
// Render texture initialization, used to hold the rendering result so we can easily resize it
|
||||
RenderTexture2D target = LoadRenderTexture(gameScreenWidth, gameScreenHeight);
|
||||
SetTextureFilter(target.texture, TEXTURE_FILTER_BILINEAR); // Texture scale filter to use
|
||||
|
||||
Color colors[10] = { 0 };
|
||||
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Compute required framebuffer scaling
|
||||
float scale = MIN((float)GetScreenWidth()/gameScreenWidth, (float)GetScreenHeight()/gameScreenHeight);
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
// Recalculate random colors for the bars
|
||||
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
|
||||
}
|
||||
|
||||
// Update virtual mouse (clamped mouse value behind game screen)
|
||||
Vector2 mouse = GetMousePosition();
|
||||
Vector2 virtualMouse = { 0 };
|
||||
virtualMouse.x = (mouse.x - (GetScreenWidth() - (gameScreenWidth*scale))*0.5f)/scale;
|
||||
virtualMouse.y = (mouse.y - (GetScreenHeight() - (gameScreenHeight*scale))*0.5f)/scale;
|
||||
virtualMouse = Vector2Clamp(virtualMouse, (Vector2){ 0, 0 }, (Vector2){ (float)gameScreenWidth, (float)gameScreenHeight });
|
||||
|
||||
// Apply the same transformation as the virtual mouse to the real mouse (i.e. to work with raygui)
|
||||
//SetMouseOffset(-(GetScreenWidth() - (gameScreenWidth*scale))*0.5f, -(GetScreenHeight() - (gameScreenHeight*scale))*0.5f);
|
||||
//SetMouseScale(1/scale, 1/scale);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw everything in the render texture, note this will not be rendered on screen, yet
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(RAYWHITE); // Clear render texture background color
|
||||
|
||||
for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]);
|
||||
|
||||
DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE);
|
||||
DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN);
|
||||
DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW);
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK); // Clear screen background
|
||||
|
||||
// Draw render texture to screen, properly scaled
|
||||
DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height },
|
||||
(Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5f, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5f,
|
||||
(float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_window_letterbox.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
77
raylib/examples/core/core_window_should_close.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Window should close
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - window should close");
|
||||
|
||||
SetExitKey(KEY_NULL); // Disable KEY_ESCAPE to close window, X-button still works
|
||||
|
||||
bool exitWindowRequested = false; // Flag to request window to exit
|
||||
bool exitWindow = false; // Flag to set window to exit
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!exitWindow)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Detect if X-button or KEY_ESCAPE have been pressed to close window
|
||||
if (WindowShouldClose() || IsKeyPressed(KEY_ESCAPE)) exitWindowRequested = true;
|
||||
|
||||
if (exitWindowRequested)
|
||||
{
|
||||
// A request for close window has been issued, we can save data before closing
|
||||
// or just show a message asking for confirmation
|
||||
|
||||
if (IsKeyPressed(KEY_Y)) exitWindow = true;
|
||||
else if (IsKeyPressed(KEY_N)) exitWindowRequested = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (exitWindowRequested)
|
||||
{
|
||||
DrawRectangle(0, 100, screenWidth, 200, BLACK);
|
||||
DrawText("Are you sure you want to exit program? [Y/N]", 40, 180, 30, WHITE);
|
||||
}
|
||||
else DrawText("Try to close the window to get confirmation message!", 120, 200, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_window_should_close.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
85
raylib/examples/core/core_world_screen.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - World to screen
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.4
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - core world screen");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||
Vector2 cubeScreenPosition = { 0.0f, 0.0f };
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
|
||||
// Calculate cube screen space position (with a little offset to be in top)
|
||||
cubeScreenPosition = GetWorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Enemy: 100 / 100", (int)cubeScreenPosition.x - MeasureText("Enemy: 100/100", 20)/2, (int)cubeScreenPosition.y, 20, BLACK);
|
||||
|
||||
DrawText(TextFormat("Cube position in screen space coordinates: [%i, %i]", (int)cubeScreenPosition.x, (int)cubeScreenPosition.y), 10, 10, 20, LIME);
|
||||
DrawText("Text 2d should be always on top of the cube", 10, 40, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/core/core_world_screen.png
Normal file
|
After Width: | Height: | Size: 23 KiB |