Compare commits
1 Commits
e18de07224
...
patch-1
| Author | SHA1 | Date | |
|---|---|---|---|
| 46b9579f0c |
8
.github/workflows/analyze_codeql.yml
vendored
@ -71,7 +71,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@ -90,7 +90,7 @@ jobs:
|
||||
cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
upload: false
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
# Filter out rules with low severity or high false positve rate
|
||||
# Also filter out warnings in third-party code
|
||||
- name: Filter out unwanted errors and warnings
|
||||
uses: advanced-security/filter-sarif@v1.1
|
||||
uses: advanced-security/filter-sarif@v1
|
||||
with:
|
||||
patterns: |
|
||||
-**:cpp/path-injection
|
||||
@ -121,7 +121,7 @@ jobs:
|
||||
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
|
||||
|
||||
- name: Upload CodeQL results to code scanning
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: ${{ steps.step1.outputs.sarif-output }}
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
2
.github/workflows/build_examples_windows.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
- uses: actions/checkout@master
|
||||
|
||||
- name: Add MSBuild to PATH
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Build Library (MSVC16)
|
||||
run: |
|
||||
|
||||
81
.github/workflows/clang_tidy.yml
vendored
@ -1,81 +0,0 @@
|
||||
name: Clang Tidy Lints
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: clang-tidy-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
clang-tidy:
|
||||
name: C lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install clang-tidy 19
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes clang-tidy-19
|
||||
|
||||
- name: Run clang-tidy
|
||||
shell: bash
|
||||
run: |
|
||||
checks='-*,
|
||||
bugprone-assignment-in-if-condition,
|
||||
bugprone-infinite-loop,
|
||||
bugprone-misplaced-widening-cast,
|
||||
bugprone-multiple-statement-macro,
|
||||
bugprone-suspicious-memory-comparison,
|
||||
bugprone-suspicious-memset-usage,
|
||||
readability-duplicate-include,
|
||||
readability-redundant-casting,
|
||||
readability-simplify-boolean-expr'
|
||||
|
||||
lint_log="$(mktemp)"
|
||||
filtered_log="$(mktemp)"
|
||||
lint_pattern='\[(bugprone|readability)-[^]]+\]'
|
||||
|
||||
echo "Using clang-tidy:"
|
||||
clang-tidy-19 --version
|
||||
|
||||
echo
|
||||
echo "Running clang-tidy..."
|
||||
|
||||
# Capture everything silently. Do not use tee here.
|
||||
find src \
|
||||
-path 'src/external' -prune \
|
||||
-o -type f -name '*.c' -exec \
|
||||
clang-tidy-19 \
|
||||
--quiet \
|
||||
--checks="$checks" \
|
||||
--header-filter='.*' \
|
||||
--exclude-header-filter='(^|.*/)external/.*' \
|
||||
{} -- \
|
||||
-std=c11 \
|
||||
-Isrc \
|
||||
-isystem src/external \
|
||||
\; >"$lint_log" 2>&1 || true
|
||||
|
||||
# Retain only selected lint warnings, then remove any remaining
|
||||
# diagnostics whose path passes through an external directory.
|
||||
grep -E "$lint_pattern" "$lint_log" |
|
||||
grep -Ev '(^|/)([^/]+/\.\./)*external/' \
|
||||
>"$filtered_log" || true
|
||||
|
||||
if [[ -s "$filtered_log" ]]; then
|
||||
echo "clang-tidy found the following lint violations:"
|
||||
echo
|
||||
cat "$filtered_log"
|
||||
echo
|
||||
echo "::error::clang-tidy found lint violations."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "clang-tidy found no selected lint violations."
|
||||
364
BINDINGS.md
@ -1,218 +1,190 @@
|
||||
# raylib bindings and wrappers
|
||||
|
||||
Some people ported raylib to other languages in the form of bindings or wrappers to the library. Here is a list with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list or if it had been updated/archived.
|
||||
|
||||
# Recommendations for binding authors.
|
||||
This is a set of recomendations and guidelines for binding authors, meant to help your binding be as useful as possible to your users.
|
||||
|
||||
* Binding should be reasonably up to date with the last release, out of date bindings may be removed from bindings.md
|
||||
* Binding should expose all of raylib's API. This is to ensure compatibility with all raylib features, and allow your users to do everything in the target language they can do in C raylib.
|
||||
* raylib.h
|
||||
* raymath.h
|
||||
* rcamera.h
|
||||
* rlgl.h
|
||||
* rgestures.h
|
||||
* Bindings should expose the base API in order to match the C examples when possible.
|
||||
* Bindings that expose additional 'high level' functions to make the binding more native to the host language, should also include the base C style API in addition to those other functions. This is requested in order to make it easier for people to understand the raylib API independent of the language being used.
|
||||
* Bindings should have clear usage and setup instructions. Examples in the host language are highly recommended. You want your users to be able to get started right away.
|
||||
* If a binding exists for a language, before making a new one, binding authors should try to work together on maintaining a single binding for a language, this is requested in order to prevent fragmentation and confusion for users.
|
||||
* Instructions on how to build for web are highly recomeneed if the langauge supports it. This allows your bindings to be used for game jams :)
|
||||
Some people ported raylib to other languages in the form of bindings or wrappers to the library. Here is a list with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list.
|
||||
|
||||
### Language Bindings
|
||||
|
||||
| Name | raylib Version | Language | License |
|
||||
| :--------------------------------------------------------------------------------------: | :--------------: | :---------------------------------------------------------------------: | :------------------: |
|
||||
| [raylib](https://github.com/raysan5/raylib) | **6.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **6.0** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
||||
| [raylib-asm](https://github.com/gAndy50/ASMRay) | **6.0** | [Assembly (x86)](https://en.wikipedia.org/wiki/X86_assembly_language) | Zlib |
|
||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **auto** | [Beef](https://www.beeflang.org) | MIT |
|
||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT |
|
||||
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **6.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
|
||||
| [Raylib-cs.BleedingEdge](https://github.com/danilwhale/Raylib-cs.BleedingEdge) | **5.6-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT |
|
||||
| [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
|
||||
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
|
||||
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
|
||||
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
|
||||
| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT |
|
||||
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
|
||||
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 6.0 | [Crystal](https://crystal-lang.org) | Apache-2.0 |
|
||||
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
|
||||
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [raylib_dart](https://pub.dev/packages/raylib_dart) | 6.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **6.0** | [D](https://dlang.org) | Zlib |
|
||||
| [Deno-Raylib](https://github.com/JJLDonley/Deno-Raylib) | **6.0** | [Deno / TS](https://deno.land) | MIT |
|
||||
| [rayex](https://github.com/shiryel/rayex) | 5.5 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||
| [raylib-elfscript](https://github.com/ohmtal/raylib-elfscript) | 6.0 | [ElfScript](https://github.com/ohmtal/ElfScript) | MIT |
|
||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 6.0 | [Factor](https://factorcode.org) | BSD |
|
||||
| [raystar](https://github.com/RobertFlexx/raystar) | **6.0** | [F*](https://www.fstar-lang.org/) | EPL-2.0 |
|
||||
| [raylib4fb](https://codeberg.org/mudhairless/raylib4fb) | **6.0** | [FreeBASIC](https://www.freebasic.net) | Zlib |
|
||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **6.0** | [Fortran](https://fortran-lang.org) | ISC |
|
||||
| [raylib-go](https://github.com/gen2brain/raylib-go) | **6.0** | [Go](https://golang.org) | Zlib |
|
||||
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
||||
| [h-raylib](https://github.com/Anut-py/h-raylib) | **6.1-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
|
||||
| [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 5.5 | [Haxe](https://haxe.org) | Zlib |
|
||||
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
|
||||
| [jaylib](https://github.com/electronstudio/jaylib/) | **6.0** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE |
|
||||
| [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.2 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib |
|
||||
| [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib |
|
||||
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
|
||||
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.5 | [Lua](http://www.lua.org) | ISC |
|
||||
| [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 6.0 | [Lua](http://www.lua.org) | ISC |
|
||||
| [ReiLua](https://github.com/nullstare/ReiLua) | 6.0 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
|
||||
| [raylib-luajit](https://github.com/homma/raylib-luajit) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-luajit-generated](https://github.com/james2doyle/raylib-luajit-generated) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** |
|
||||
| [raylib_mojo](https://github.com/willGuimont/raylib_mojo) | **6.0** | [Mojo](https://www.modular.com/mojo) | ZLib |
|
||||
| [raymojo](https://github.com/RobertFlexx/raymojo) | **6.0** | [Mojo](https://www.modular.com/mojo) | GPLv3 |
|
||||
| [raymod](https://github.com/RobertFlexx/raymod) | **6.0** | [Modula-2](https://en.wikipedia.org/wiki/Modula-2) / [Modula-3](https://en.wikipedia.org/wiki/Modula-3) | Apache-2.0 |
|
||||
| [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | 6.1-dev | [nelua](https://nelua.io) | Zlib |
|
||||
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 6.1-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
|
||||
| [node-raylib](https://github.com/RobLoach/node-raylib) | 5.5 | [Node.js](https://nodejs.org/en) | Zlib |
|
||||
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **6.0** | [Odin](https://odin-lang.org) | Zlib |
|
||||
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **6.0** | [OCaml](https://ocaml.org) | MIT |
|
||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||
| [Rayberon](https://github.com/RobertFlexx/Rayberon) | **6.0** | [Oberon-2](https://en.wikipedia.org/wiki/Oberon-2) | MIT |
|
||||
| [EuRaylib](https://github.com/gAndy50/EuRaylib6) | **6.0** | [openEuphoria](https://openeuphoria.org/) | Zlib |
|
||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **6.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **6.0** | [Python](https://www.python.org) | EPL-2.0 |
|
||||
| [raylibpyctbg](https://github.com/overdev/raylibpyctbg) | 5.5 | [Python](https://www.python.org) | MIT |
|
||||
| [raylib-py](https://github.com/overdev/raylib-py) | **6.0** | [Python](https://www.python.org) | MIT |
|
||||
| [raylib-python-ctypes](https://github.com/sDos280/raylib-python-ctypes) | 4.6-dev | [Python](https://www.python.org) | MIT |
|
||||
| [raylib-pkpy-bindings](https://github.com/blueloveTH/pkpy-bindings) | 5.5 | [pocketpy](https://pocketpy.dev) | MIT |
|
||||
| [raylib-php](https://github.com/joseph-montanez/raylib-php) | 4.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib |
|
||||
| [raylibr](https://github.com/jeroenjanssens/raylibr) | auto | [R](https://www.r-project.org) | MIT |
|
||||
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
|
||||
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **6.0** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [sola-raylib](https://github.com/brettchalupa/sola-raylib) | **6.0** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
|
||||
| [racket-raylib](https://github.com/eutro/racket-raylib) | **6.0** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
|
||||
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |
|
||||
| [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT |
|
||||
| [raylib-SmallBASIC](https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib) | **6.0** | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 |
|
||||
| [raylib-solod](https://github.com/solod-dev/raylib) | 6.0 | [Solod](https://solod.dev) | BSD-3-Clause |
|
||||
| [rayscal](https://github.com/RobertFlexx/rayscal) | **6.0** | [Scala Native](https://scala-native.org) | MIT |
|
||||
| [raylib-umka](https://github.com/robloach/raylib-umka) | 4.5 | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib |
|
||||
| [raylib-v](https://github.com/vlang/raylib) | auto | [V](https://vlang.io) | MIT/Unlicense |
|
||||
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
|
||||
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **6.0** | [Vala](https://vala.dev) | Zlib |
|
||||
| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** | [Wave](http://wave-lang.dev) | Zlib |
|
||||
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
|
||||
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **6.0** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
|
||||
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
|
||||
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
|
||||
| [raylib-bqn](https://github.com/Brian-ED/raylib-bqn) | **auto** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||
| [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT |
|
||||
| [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 |
|
||||
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.6-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
|
||||
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
|
||||
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **auto** | [Dyalog APL](https://www.dyalog.com/) | MIT |
|
||||
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **6.0** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
|
||||
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
|
||||
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
|
||||
| [Target](https://github.com/FinnDemonCat/Target/tree/main/lib/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license |
|
||||
| [mach-raylib](https://github.com/angluca/mach-raylib) | **6.x-dev** | [Mach](https://machlang.org/) | MIT |
|
||||
| [gcl native raylib module](https://github.com/gnuchanos/GnuchanOS/tree/main/language) | **6.0** | [gclang](https://github.com/gnuchanos/GnuchanOS/tree/main/language) | GPLv3 |
|
||||
| Name | raylib Version | Language | License |
|
||||
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
|
||||
| [raylib](https://github.com/raysan5/raylib) | **6.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT |
|
||||
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **6.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
|
||||
| [Raylib-cs.BleedingEdge](https://github.com/danilwhale/Raylib-cs.BleedingEdge) | **5.6-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||
| [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT |
|
||||
| [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
|
||||
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
|
||||
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
|
||||
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
|
||||
| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT |
|
||||
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
|
||||
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
|
||||
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
|
||||
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [raylib_dart](https://pub.dev/packages/raylib_dart) | 6.0 | [Dart](https://dart.dev) | MIT |
|
||||
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
||||
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
|
||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **6.0** | [D](https://dlang.org) | Zlib |
|
||||
| [Deno-Raylib](https://github.com/JJLDonley/Deno-Raylib) | **6.0** | [Deno / TS](https://deno.land) | MIT |
|
||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 5.5 | [Factor](https://factorcode.org) | BSD |
|
||||
| [raylib4fb](https://github.com/mudhairless/raylib4fb) | **6.0** | [FreeBASIC](https://www.freebasic.net) | Zlib |
|
||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
||||
| [raylib-go](https://github.com/gen2brain/raylib-go) | **6.0** | [Go](https://golang.org) | Zlib |
|
||||
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
||||
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
|
||||
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
|
||||
| [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 4.2 | [Haxe](https://haxe.org) | Zlib |
|
||||
| [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.5 | [Harbour](https://harbour.github.io) | MIT |
|
||||
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
|
||||
| [jaylib](https://github.com/electronstudio/jaylib/) | **5.5** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE |
|
||||
| [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib |
|
||||
| [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib |
|
||||
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** |
|
||||
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
|
||||
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.5 | [Lua](http://www.lua.org) | ISC |
|
||||
| [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 5.5 | [Lua](http://www.lua.org) | ISC |
|
||||
| [ReiLua](https://github.com/nullstare/ReiLua) | 6.0 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
|
||||
| [raylib-luajit](https://github.com/homma/raylib-luajit) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-luajit-generated](https://github.com/james2doyle/raylib-luajit-generated) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** |
|
||||
| [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | **5.5** | [nelua](https://nelua.io) | Zlib |
|
||||
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
|
||||
| [naylib](https://github.com/planetis-m/naylib) | **5.6-dev** | [Nim](https://nim-lang.org) | MIT |
|
||||
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
|
||||
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | Zlib |
|
||||
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **6.0** | [OCaml](https://ocaml.org) | MIT |
|
||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **6.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)/[Delphi](https://en.wikipedia.org/wiki/Delphi_(software)) | Zlib |
|
||||
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||
| [pyraylib](https://github.com/Ho011/pyraylib) | 3.7 | [Python](https://www.python.org) | Zlib |
|
||||
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **5.5** | [Python](https://www.python.org) | EPL-2.0 |
|
||||
| [raylibpyctbg](https://github.com/overdev/raylibpyctbg) | 5.5 | [Python](https://www.python.org) | MIT |
|
||||
| [raylib-py](https://github.com/overdev/raylib-py) | 5.5 | [Python](https://www.python.org) | MIT |
|
||||
| [raylib-python-ctypes](https://github.com/sDos280/raylib-python-ctypes) | 4.6-dev | [Python](https://www.python.org) | MIT |
|
||||
| [raylib-pkpy-bindings](https://github.com/blueloveTH/pkpy-bindings) | 5.1-dev | [pocketpy](https://pocketpy.dev) | MIT |
|
||||
| [raylib-php](https://github.com/joseph-montanez/raylib-php) | 4.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib |
|
||||
| [raylib-phpcpp](https://github.com/oraoto/raylib-phpcpp) | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib |
|
||||
| [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT |
|
||||
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
|
||||
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [sola-raylib](https://github.com/brettchalupa/sola-raylib) | **6.0** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
|
||||
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
|
||||
| [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
|
||||
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |
|
||||
| [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT |
|
||||
| [raylib-SmallBASIC](https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib) | **5.5** | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 |
|
||||
| [raylib-umka](https://github.com/robloach/raylib-umka) | 4.5 | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib |
|
||||
| [raylib-v](https://github.com/vlang/raylib) | 5.5 | [V](https://vlang.io) | MIT/Unlicense |
|
||||
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
|
||||
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **6.0** | [Vala](https://vala.dev) | Zlib |
|
||||
| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib |
|
||||
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
|
||||
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **6.0** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
|
||||
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
|
||||
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
|
||||
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
|
||||
| [raylib-bqn](https://github.com/Brian-ED/raylib-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||
| [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT |
|
||||
| [rayjule](https://github.com/SabeDoesThings/rayjule) | **5.5** | [Jule](https://jule.dev/) | MIT |
|
||||
| [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 |
|
||||
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
|
||||
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
|
||||
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT |
|
||||
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **6.0** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
|
||||
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
|
||||
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
|
||||
| [Target](https://github.com/FinnDemonCat/Target/tree/main/libs/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license |
|
||||
| [gclang-raylib](https://github.com/gnuchanos/gcLang_Compiler/tree/main/windows_version/raylib_version)| **6.0** | [gclang](https://github.com/gnuchanos/gcLang_Compiler) | AGPL-3.0 |
|
||||
|
||||
|
||||
### Utility Wrappers
|
||||
### Utility Wrapers
|
||||
|
||||
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's paradigm.
|
||||
| Name | raylib Version | Language | License |
|
||||
| ---------------------------------------------------- | :------------: | :------------------------------------------: | :-----: |
|
||||
| [raylib-cpp](https://github.com/robloach/raylib-cpp) | **6.0** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib |
|
||||
| [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
|
||||
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **auto** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||
| [DOOR](https://github.com/RealDoigt/DOOR) | 4.0 | [D](https://dlang.org) | MIT |
|
||||
| [Iris](https://github.com/Marcos-cat/iris) | **5.5** | [Uiua](https://www.uiua.org/) | MIT |
|
||||
|
||||
### Older or Unmaintained Language Bindings
|
||||
|
||||
These are older raylib bindings that are more than 2 versions old or have not been maintained.
|
||||
| Name | raylib Version | Language |
|
||||
| :--------------------------------------------------------------------------------------: | :--------------: | :---------------------------------------------------------------------: |
|
||||
| [raylib-cppsharp](https://github.com/phxvyper/raylib-cppsharp) | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) |
|
||||
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) |
|
||||
| [RaylibFS](https://github.com/dallinbeutler/RaylibFS) | 2.5 | [F#](https://fsharp.org) |
|
||||
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) |
|
||||
| [raylib\*d](https://github.com/Sepheus/raylib_d) | 2.5 | [D](https://dlang.org) |
|
||||
| [bindbc-raylib](https://github.com/o3o/bindbc-raylib) | 3.0 | [D](https://dlang.org) |
|
||||
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) |
|
||||
| [go-raylib](https://github.com/chunqian/go-raylib) | 3.5 | [Go](https://golang.org) |
|
||||
| [raylib-goplus](https://github.com/Lachee/raylib-goplus) | 2.6-dev | [Go](https://golang.org) |
|
||||
| [ray-go](https://github.com/hecate-tech/ray-go) | 2.6-dev | [Go](https://golang.org) |
|
||||
| [raylib-luamore](https://github.com/HDPLocust/raylib-luamore) | 3.0 | [Lua](http://www.lua.org) |
|
||||
| [LuaJIT-Raylib](https://github.com/Bambofy/LuaJIT-Raylib) | 2.6 | [Lua](http://www.lua.org) |
|
||||
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 2.5 | [Lua](http://www.lua.org) |
|
||||
| [raylib-lua-ffi](https://github.com/raysan5/raylib/issues/693) | 2.0 | [Lua](http://www.lua.org) |
|
||||
| [raylib-lua](https://github.com/raysan5/raylib-lua) | 1.7 | [Lua](http://www.lua.org) |
|
||||
| [raylib-nelua](https://github.com/Andre-LA/raylib-nelua) | 3.0 | [Nelua](https://nelua.io) |
|
||||
| [raylib-nim](https://github.com/Skrylar/raylib-nim) | 2.0 | [Nim](https://nim-lang.org) |
|
||||
| [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) | 1.7 | [Nim](https://nim-lang.org) |
|
||||
| [nim-raylib](https://github.com/tomc1998/nim-raylib) | 3.1-dev | [Nim](https://nim-lang.org) |
|
||||
| [raylib-Forever](https://github.com/Guevara-chan/Raylib-Forever) | auto | [Nim](https://nim-lang.org) |
|
||||
| [NimraylibNow!](https://github.com/greenfork/nimraylib_now) | 4.2 | [Nim](https://nim-lang.org) |
|
||||
| [naylib](https://github.com/planetis-m/naylib) | **5.6-dev** | [Nim](https://nim-lang.org) |
|
||||
| [raylib-haskell](https://github.com/DevJac/raylib-haskell) | 2.0 | [Haskell](https://www.haskell.org) |
|
||||
| [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.7 | [Harbour](https://harbour.github.io) |
|
||||
| [raylib-cr](https://github.com/AregevDev/raylib-cr) | 2.5-dev | [Crystal](https://crystal-lang.org) |
|
||||
| [raylib.cr](https://github.com/sam0x17/raylib.cr) | 2.0 | [Crystal](https://crystal-lang.org) |
|
||||
| [cray](https://gitlab.com/Zatherz/cray) | 1.8 | [Crystal](https://crystal-lang.org) |
|
||||
| [raylib-pas](https://github.com/tazdij/raylib-pas) | 3.0 | [Pascal](https://en.wikipedia.org/wiki/Pascal*(programming*language)) |
|
||||
| [raylib-pascal](https://github.com/drezgames/raylib-pascal) | 2.0 | [Pascal](https://en.wikipedia.org/wiki/Pascal*(programming*language)) |
|
||||
| [Graphics-Raylib](https://github.com/athreef/Graphics-Raylib) | 1.4 | [Perl](https://www.perl.org) |
|
||||
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) |
|
||||
| [raylib-ruby](https://github.com/a0/raylib-ruby) | 2.6 | [Ruby](https://www.ruby-lang.org/en) |
|
||||
| [raylib-ruby-ffi](https://github.com/D3nX/raylib-ruby-ffi) | 2.0 | [Ruby](https://www.ruby-lang.org/en) |
|
||||
| [raylib-mruby](https://github.com/lihaochen910/raylib-mruby) | 2.5-dev | [mruby](https://github.com/mruby/mruby) |
|
||||
| [raylib-java](https://github.com/XoanaIO/raylib-java) | 2.0 | [Java](https://en.wikipedia.org/wiki/Java*(programming_language)) |
|
||||
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) |
|
||||
| [clj-raylib](https://github.com/lsevero/clj-raylib) | 3.0 | [Clojure](https://clojure.org) |
|
||||
| [QuickJS-raylib](https://github.com/sntg-p/QuickJS-raylib) | 3.0 | [QuickJS](https://bellard.org/quickjs) |
|
||||
| [raylib-duktape](https://github.com/RobLoach/raylib-duktape) | 2.6 | [JavaScript (Duktape)](https://en.wikipedia.org/wiki/JavaScript) |
|
||||
| [rayjule](https://github.com/SabeDoesThings/rayjule) | **5.5** | [Jule](https://jule.dev/) |
|
||||
| [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) | 2.6 | [ChaiScript](http://chaiscript.com) |
|
||||
| [raylib-squirrel](https://github.com/RobLoach/raylib-squirrel) | 2.5 | [Squirrel](http://www.squirrel-lang.org) |
|
||||
| [racket-raylib-2d](https://github.com/arvyy/racket-raylib-2d) | 2.5 | [Racket](https://racket-lang.org) |
|
||||
| [raylib-php-ffi](https://github.com/oraoto/raylib-php-ffi) | 2.4-dev | [PHP](https://en.wikipedia.org/wiki/PHP) |
|
||||
| [raylib-phpcpp](https://github.com/oraoto/raylib-phpcpp) | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) |
|
||||
| [raylib-haxe](https://github.com/ibilon/raylib-haxe) | 2.4 | [Haxe](https://haxe.org) |
|
||||
| [ringraylib](https://github.com/ringpackages/ringraylib) | 2.6 | [Ring](http://ring-lang.sourceforge.net) |
|
||||
| [raylib-scm](https://github.com/yashrk/raylib-scm) | 2.5 | [Chicken Scheme](https://www.call-cc.org) |
|
||||
| [raylib-chibi](https://github.com/VincentToups/raylib-chibi) | 2.5 | [Chibi-Scheme](https://github.com/ashinn/chibi-scheme) |
|
||||
| [raylib-gambit-scheme](https://github.com/georgjz/raylib-gambit-scheme) | 3.1-dev | [Gambit Scheme](https://github.com/gambit/gambit) |
|
||||
| [Euraylib](https://github.com/gAndy50/Euraylib) | 3.0 | [Euphoria](https://openeuphoria.org) |
|
||||
| [raylib-odin](https://github.com/kevinw/raylib-odin) | 3.0 | [Odin](https://odin-lang.org) |
|
||||
| [vraylib](https://github.com/waotzi/vraylib) | 3.5 | [V](https://vlang.io) |
|
||||
| [raylib-vala](https://code.guddler.uk/mart/raylibVapi) | 3.0 | [Vala](https://wiki.gnome.org/Projects/Vala) |
|
||||
| [raylib-jai](https://github.com/kujukuju/raylib-jai) | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) |
|
||||
| [ray.zig](https://github.com/BitPuffin/zig-raylib-experiments) | 2.5 | [Zig](https://ziglang.org) |
|
||||
| [raylib-Ada](https://github.com/mimo/raylib-Ada) | 3.0 | [Ada](https://www.adacore.com/about-ada) |
|
||||
| [raykit](https://github.com/Gamerfiend/raykit) | **???** | [Kit](https://www.kitlang.org) |
|
||||
| [ray.mod](https://github.com/bmx-ng/ray.mod) | 3.0 | [BlitzMax](https://blitzmax.org) |
|
||||
| [raylib-mosaic](https://github.com/pluckyporcupine/raylib-mosaic) | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) |
|
||||
| [raylib-xdpw](https://github.com/vtereshkov/raylib-xdpw) | 2.6 | [XD Pascal](https://github.com/vtereshkov/xdpw) |
|
||||
| [raylib-carp](https://github.com/sacredbirdman/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
|
||||
| [raylib-fb](https://github.com/IchMagBier/raylib-fb) | 3.0 | [FreeBasic](https://www.freebasic.net) |
|
||||
| [raylib-purebasic](https://github.com/D-a-n-i-l-o/raylib-purebasic) | 3.0 | [PureBasic](https://www.purebasic.com) |
|
||||
| [pyraylib](https://github.com/Ho011/pyraylib) | 3.7 | [Python](https://www.python.org) |
|
||||
| [raylib-ats2](https://github.com/mephistopheles-8/raylib-ats2) | 3.0 | [ATS2](http://www.ats-lang.org) |
|
||||
| [raylib-beef](https://github.com/M0n7y5/raylib-beef) | 3.0 | [Beef](https://www.beeflang.org) |
|
||||
| [raylib-never](https://github.com/never-lang/raylib-never) | 3.0 | [Never](https://github.com/never-lang/never) |
|
||||
| [raylib.cbl](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib) | 2.0 | [COBOL](https://en.wikipedia.org/wiki/COBOL) |
|
||||
|
||||
| Name | raylib Version | Language |
|
||||
| ---------------------------------------------------------------------------------- | :------------: | :---------------------------------------------------------------------: |
|
||||
| [raylib-cppsharp](https://github.com/phxvyper/raylib-cppsharp) | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) |
|
||||
| [RaylibFS](https://github.com/dallinbeutler/RaylibFS) | 2.5 | [F#](https://fsharp.org) |
|
||||
| [raylib\*d](https://github.com/Sepheus/raylib_d) | 2.5 | [D](https://dlang.org) |
|
||||
| [bindbc-raylib](https://github.com/o3o/bindbc-raylib) | 3.0 | [D](https://dlang.org) |
|
||||
| [go-raylib](https://github.com/chunqian/go-raylib) | 3.5 | [Go](https://golang.org) |
|
||||
| [raylib-goplus](https://github.com/Lachee/raylib-goplus) | 2.6-dev | [Go](https://golang.org) |
|
||||
| [ray-go](https://github.com/hecate-tech/ray-go) | 2.6-dev | [Go](https://golang.org) |
|
||||
| [raylib-luamore](https://github.com/HDPLocust/raylib-luamore) | 3.0 | [Lua](http://www.lua.org) |
|
||||
| [LuaJIT-Raylib](https://github.com/Bambofy/LuaJIT-Raylib) | 2.6 | [Lua](http://www.lua.org) |
|
||||
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 2.5 | [Lua](http://www.lua.org) |
|
||||
| [raylib-lua-ffi](https://github.com/raysan5/raylib/issues/693) | 2.0 | [Lua](http://www.lua.org) |
|
||||
| [raylib-lua](https://github.com/raysan5/raylib-lua) | 1.7 | [Lua](http://www.lua.org) |
|
||||
| [raylib-nelua](https://github.com/Andre-LA/raylib-nelua) | 3.0 | [Nelua](https://nelua.io) |
|
||||
| [raylib-nim](https://github.com/Skrylar/raylib-nim) | 2.0 | [Nim](https://nim-lang.org) |
|
||||
| [raylib-Nim](https://gitlab.com/define-private-public/raylib-Nim) | 1.7 | [Nim](https://nim-lang.org) |
|
||||
| [nim-raylib](https://github.com/tomc1998/nim-raylib) | 3.1-dev | [Nim](https://nim-lang.org) |
|
||||
| [raylib-Forever](https://github.com/Guevara-chan/Raylib-Forever) | auto | [Nim](https://nim-lang.org) |
|
||||
| [NimraylibNow!](https://github.com/greenfork/nimraylib_now) | 4.2 | [Nim](https://nim-lang.org) |
|
||||
| [raylib-haskell](https://github.com/DevJac/raylib-haskell) | 2.0 | [Haskell](https://www.haskell.org) |
|
||||
| [raylib-cr](https://github.com/AregevDev/raylib-cr) | 2.5-dev | [Crystal](https://crystal-lang.org) |
|
||||
| [raylib.cr](https://github.com/sam0x17/raylib.cr) | 2.0 | [Crystal](https://crystal-lang.org) |
|
||||
| [cray](https://gitlab.com/Zatherz/cray) | 1.8 | [Crystal](https://crystal-lang.org) |
|
||||
| [raylib-pas](https://github.com/tazdij/raylib-pas) | 3.0 | [Pascal](https://en.wikipedia.org/wiki/Pascal*(programming*language)) |
|
||||
| [raylib-pascal](https://github.com/drezgames/raylib-pascal) | 2.0 | [Pascal](https://en.wikipedia.org/wiki/Pascal*(programming*language)) |
|
||||
| [Graphics-Raylib](https://github.com/athreef/Graphics-Raylib) | 1.4 | [Perl](https://www.perl.org) |
|
||||
| [raylib-ruby](https://github.com/a0/raylib-ruby) | 2.6 | [Ruby](https://www.ruby-lang.org/en) |
|
||||
| [raylib-ruby-ffi](https://github.com/D3nX/raylib-ruby-ffi) | 2.0 | [Ruby](https://www.ruby-lang.org/en) |
|
||||
| [raylib-mruby](https://github.com/lihaochen910/raylib-mruby) | 2.5-dev | [mruby](https://github.com/mruby/mruby) |
|
||||
| [raylib-java](https://github.com/XoanaIO/raylib-java) | 2.0 | [Java](https://en.wikipedia.org/wiki/Java*(programming_language)) |
|
||||
| [clj-raylib](https://github.com/lsevero/clj-raylib) | 3.0 | [Clojure](https://clojure.org) |
|
||||
| [QuickJS-raylib](https://github.com/sntg-p/QuickJS-raylib) | 3.0 | [QuickJS](https://bellard.org/quickjs) |
|
||||
| [raylib-duktape](https://github.com/RobLoach/raylib-duktape) | 2.6 | [JavaScript (Duktape)](https://en.wikipedia.org/wiki/JavaScript) |
|
||||
| [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) | 2.6 | [ChaiScript](http://chaiscript.com) |
|
||||
| [raylib-squirrel](https://github.com/RobLoach/raylib-squirrel) | 2.5 | [Squirrel](http://www.squirrel-lang.org) |
|
||||
| [racket-raylib-2d](https://github.com/arvyy/racket-raylib-2d) | 2.5 | [Racket](https://racket-lang.org) |
|
||||
| [raylib-php-ffi](https://github.com/oraoto/raylib-php-ffi) | 2.4-dev | [PHP](https://en.wikipedia.org/wiki/PHP) |
|
||||
| [raylib-haxe](https://github.com/ibilon/raylib-haxe) | 2.4 | [Haxe](https://haxe.org) |
|
||||
| [ringraylib](https://github.com/ringpackages/ringraylib) | 2.6 | [Ring](http://ring-lang.sourceforge.net) |
|
||||
| [raylib-scm](https://github.com/yashrk/raylib-scm) | 2.5 | [Chicken Scheme](https://www.call-cc.org) |
|
||||
| [raylib-chibi](https://github.com/VincentToups/raylib-chibi) | 2.5 | [Chibi-Scheme](https://github.com/ashinn/chibi-scheme) |
|
||||
| [raylib-gambit-scheme](https://github.com/georgjz/raylib-gambit-scheme) | 3.1-dev | [Gambit Scheme](https://github.com/gambit/gambit) |
|
||||
| [Euraylib](https://github.com/gAndy50/Euraylib) | 3.0 | [Euphoria](https://openeuphoria.org) |
|
||||
| [raylib-odin](https://github.com/kevinw/raylib-odin) | 3.0 | [Odin](https://odin-lang.org) |
|
||||
| [vraylib](https://github.com/waotzi/vraylib) | 3.5 | [V](https://vlang.io) |
|
||||
| [raylib-vala](https://code.guddler.uk/mart/raylibVapi) | 3.0 | [Vala](https://wiki.gnome.org/Projects/Vala) |
|
||||
| [raylib-jai](https://github.com/kujukuju/raylib-jai) | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) |
|
||||
| [ray.zig](https://github.com/BitPuffin/zig-raylib-experiments) | 2.5 | [Zig](https://ziglang.org) |
|
||||
| [raylib-Ada](https://github.com/mimo/raylib-Ada) | 3.0 | [Ada](https://www.adacore.com/about-ada) |
|
||||
| [raykit](https://github.com/Gamerfiend/raykit) | **???** | [Kit](https://www.kitlang.org) |
|
||||
| [ray.mod](https://github.com/bmx-ng/ray.mod) | 3.0 | [BlitzMax](https://blitzmax.org) |
|
||||
| [raylib-mosaic](https://github.com/pluckyporcupine/raylib-mosaic) | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) |
|
||||
| [raylib-xdpw](https://github.com/vtereshkov/raylib-xdpw) | 2.6 | [XD Pascal](https://github.com/vtereshkov/xdpw) |
|
||||
| [raylib-carp](https://github.com/sacredbirdman/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
|
||||
| [raylib-fb](https://github.com/IchMagBier/raylib-fb) | 3.0 | [FreeBasic](https://www.freebasic.net) |
|
||||
| [raylib-purebasic](https://github.com/D-a-n-i-l-o/raylib-purebasic) | 3.0 | [PureBasic](https://www.purebasic.com) |
|
||||
| [raylib-ats2](https://github.com/mephistopheles-8/raylib-ats2) | 3.0 | [ATS2](http://www.ats-lang.org) |
|
||||
| [raylib-beef](https://github.com/M0n7y5/raylib-beef) | 3.0 | [Beef](https://www.beeflang.org) |
|
||||
| [raylib-never](https://github.com/never-lang/raylib-never) | 3.0 | [Never](https://github.com/never-lang/never) |
|
||||
| [raylib.cbl](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib) | 2.0 | [COBOL](https://en.wikipedia.org/wiki/COBOL) |
|
||||
|
||||
Missing some language or wrapper? Feel free to create a new one! :)
|
||||
|
||||
|
||||
252
CHANGELOG
@ -3,258 +3,6 @@ changelog
|
||||
|
||||
Current Release: raylib 6.0 (23 April 2026)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Release: raylib 6.2 (xx Sep 2026)
|
||||
-------------------------------------------------------------------------
|
||||
KEY CHANGES:
|
||||
- REDESIGNED: Image API for more alignment with Texture API
|
||||
- REDESIGNED: File API for more standard return result values
|
||||
- REVIEWED: Shapes lines drawing functions, added new ones and unify behaviour
|
||||
|
||||
Detailed changes (until 12-Sept-2026):
|
||||
|
||||
[rcore] ADDED: `IsPathDirectory()`, for convenience and more readability at user code by @raysan5
|
||||
[rcore] ADDED: `IsPathAbsolute()`, check absolute paths by @raysan5
|
||||
[rcore] ADDED: `IsFileHidden()`, check file hidden (OS-dependant) by @raysan5
|
||||
[rcore] REVIEWED: `File*()` functions for consistent return result value by @raysan5 -WARNING-
|
||||
[rcore] REVIEWED: Not updating mouse.previousPosition when `SeMousePosition()` #5962 by @raysan5 -WARNING-
|
||||
[rcore] REVIEWED: Use `rlgl` provided interface instead of `rlsw` direct access by @raysan5
|
||||
[rcore] REVIEWED: Set mouse position to (0,0) when mouse leaves window area #5945 by @raysan5
|
||||
[rcore] REVIEWED: Multiple string boundary handling (#5812) by @zhaob1n
|
||||
[rcore] REVIEWED: Gamepad lower-bound guard to six sibling functions (#5938) by @mahirhir
|
||||
[rcore] REVIEWED: Fix logging format for automation event capacity warning (#5986) by @GideonSerf
|
||||
[rcore] REVIEWED: Fix initial macOS window size (#5967) by @loukamb
|
||||
[rcore] REVIEWED: Fix clipboard image memory leak (#5968) by @LuisR385
|
||||
[rcore] REVIEWED: `TakeScreenshot()`, support absolute paths by @raysan5
|
||||
[rcore] REVIEWED: `OpenURL()`, added some safety checks to mitigate malicious url inputs - ROS: `CLN-002 by @raysan5 -WARNING-
|
||||
[rcore] REVIEWED: `LoadAutomationEventList()` - ROS: `CLN-005`, `CLN-006` by @raysan5
|
||||
[rcore] REVIEWED: `GetWindowHandle()`, to be consistent between backends, fix #5885 by @raysan5
|
||||
[rcore] REVIEWED: `GetWindowPosition()` #5932 by @raysan5
|
||||
[rcore] REVIEWED: `GetTime()`, small addition for RPI Pico 2 by @raysan5
|
||||
[rcore] REVIEWED: `GetCurrentMonitor()`, fix for integer overflow in distance calculation (#5842) by @Vasilis-Narain
|
||||
[rcore] REVIEWED: `FileMove()`, additional security checks by @raysan5
|
||||
[rcore] REVIEWED: `FileCopy()`, create directory to copy if it does not exist (#5920) by @InviseDivine
|
||||
[rcore] REVIEWED: `FileMove()`, fix deleting files if `FileCopy()` fails (#5806) by @Lucrecious -WARNING-
|
||||
[rcore] REVIEWED: `IsPathAbsolute()`, remove `isalpha()` dependency by @raysan5
|
||||
[rcore] REVIEWED: `ComputeSHA1()`, fix undefined behaviour (#5957) by @TheFissk
|
||||
[rcore] REVIEWED: `ComputeSHA256()`, wrong hash when message length mod 64 is 56..59 (#6144) by @killerdevildog -WARNING-
|
||||
[rcore] REVIEWED: `GetPrevDirectoryPath()` behavior to better support side cases (#6073) by @luphi
|
||||
[rcore] REVIEWED: `GetGamepadAxisCount()`, `GetGamepadName()`, bounds-check gamepad index (#5937) by @szarta
|
||||
[rcore][GLFW] REVIEWED: `GetClipboardImage()`, fix creating new connection under X11 (#5871) by @steampuker
|
||||
[rcore][GLFW] REVIEWED: Borderless-windowed mode being always on top (#5868) by @auwsmit
|
||||
[rcore][GLFW] REVIEWED: Clipboard image memory leak (GLFW, RGFW) (#6103) by @omaribrahimsaad
|
||||
[rcore][GLFW] REVIEWED: Do not reset mouse position user when user is off window (#6134) by @jestarray
|
||||
[rcore][GLFW] REVIEWED: `Font` symbol conflict (#6094) by @M374LX
|
||||
[rcore][RGFW] REVIEWED: Add fullscreen behaviour on size 0 window creation (#5859) by @keks137
|
||||
[rcore][RGFW] REVIEWED: Fix window Y position reading X in RGFW move callback (#6044) by @latent-9
|
||||
[rcore][SDL] REVIEWED: Use precise mouse wheel values (#5830) by @Menduist
|
||||
[rcore][SDL] REVIEWED: Fix SDL3 wrong joystick functions usage (#5948) by @0xFishbyte
|
||||
[rcore][DRM] REVIEWED: Silence warnings when using GRAPHICS_API_OPENGL_SOFTWARE (#5839) by @NighthowlerStudios
|
||||
[rcore][DRM] REVIEWED: Segfault on some NVIDIA proprietary drivers (#5960) by @girvel
|
||||
[rcore][DRM] REVIEWED: Raise MAX_DRM_CACHED_BUFFERS to 4 and warn when the cache fills (#6107) by @jtakakura
|
||||
[rcore][Web] REVIEWED: Fix for stale mouse position (#5981) by @largenumberhere
|
||||
[rcore][Win32] ADDED: GetClipboardImage() (#6091) by @omaribrahimsaad
|
||||
[rcore][Win32] REVIEWED: Use `CORE.Input.Keyboard.exitKey` when handling window closing (#5911) by @aceinetx
|
||||
[rcore][Win32] REVIEWED: Security fixes (#5899) by @M374LX
|
||||
[rcore][Win32] REVIEWED: Handle conflict with `PlaySoundW()` for wide string builds (#6140) by @JeffM2501
|
||||
[rcore][Android] REVIEWED: Restore face-button input on Android gamepads (#5824) by @Tubbles
|
||||
[rcore][Android] REVIEWED: Relaunch hang after destroy while paused (#6040) by @get-charlie
|
||||
[rcore][Emscripten] REVIEWED: GetTime(), fix time calculation (#6061) by @andzdroid
|
||||
[rcore][Emscripten] REVIEWED: Handle emscripten keyboard events (#6067) by @andzdroid
|
||||
[rcore][Emscripten] REVIEWED: Invert emscripten scroll wheel direction (#6104) by @andzdroid
|
||||
[rcore][Emscripten] REVIEWED: Update emscripten mouse handling (#6070) by @andzdroid
|
||||
[rlsw] ADDED: Double buffering support and compiler requirements Pico 2 (#5994) by @NighthowlerStudios
|
||||
[rlsw] ADDED: `GL_SHADING_LANGUAGE_VERSION` for `swGetString()` by @raysan5
|
||||
[rlsw] REVIEWED: Variant dispatch refactor and render optimizations (#5996) by @Bigfoot71
|
||||
[rlgl] REVIEWED: `rlGetPixelDataSize()`, fix pixel data size regressions (#5984) by @GideonSerf
|
||||
[rlgl] REVIEWED: `rlPushMatrix()`, fix matrix stack overflow (#5935) by @szarta
|
||||
[rlgl] REVIEWED: `rlLoadTexture()`, add power-of-two check for GL_REPEAT wrap mode (#5820) by @noinodev
|
||||
[rlgl] REVIEWED: Shader attribute/uniform default names can not be overriden #5925 by @raysan5
|
||||
[rlgl] REVIEWED: Fix DRM/EGL segfault on some NVIDIA proprietary drivers (#5960) by @girvel
|
||||
[rlgl] REVIEWED: Use `rlGetPixelDataSize()` instead of `GetPixelDataSize()` (#6024) by @leoagomes
|
||||
[rlgl] REVIEWED: `rlGetActiveFramebuffer()` supported on OpenGL ES 2.0 (#6115) by @JoeStrout
|
||||
[rlsw] REVIEWED: Replace `SW_TEXTURE_REPEAT_POT_FAST` with `SW_SUPPORT_NPOT_TEXTURE` (#5901) by @Bigfoot71
|
||||
[rlsw] REVIEWED: Fix triangle and quad spans applying pixels out of bounds (#5849) by @NighthowlerStudios
|
||||
[rlsw] REVIEWED: Fix swScissor() Y-axis clipping inversion in software renderer (#5976) by @thiagomucci
|
||||
[rlsw] REVIEWED: Fix persistent alpha blending state (#5964) by @iztanos
|
||||
[rlsw] REVIEWED: ESP32 optimizations (#5827) by @jensroth-git
|
||||
[rlsw] REVIEWED: Internal functions declarations (#6028) by @Bigfoot71
|
||||
[rlsw] REVIEWED: Optimizations for embedded and compiler requirements Pico 2 (#5994) by @NighthowlerStudios
|
||||
[rlsw] REVIEWED: Rename public compile-time option prefix to `RLSW_` (#6029) by @Bigfoot71
|
||||
[rlsw] REVIEWED: Variant dispatch refactor and other improvements (#5996) by @Bigfoot71
|
||||
[rshapes] ADDED: `Draw*LinesEx()` functions (#6072) by @MatthewRoush
|
||||
[rshapes] RENAMED: `GetSplinePointBezierQuad()` to `GetSplinePointBezierQuadratic()` by @raysan5 -WARNING-
|
||||
[rshapes] REVIEWED: Reorder drawing functions by number of vertices by @raysan5
|
||||
[rshapes] REVIEWED: Comments to be more descriptive by @raysan5
|
||||
[rshapes] REVIEWED: `DrawRectangleRoundedLinesEx()`, not scaling with transform when thick=1 (#5980) by @SamaelHeaven
|
||||
[rshapes] REVIEWED: `DrawRectangleRoundedLines()` (#5992) by @MatthewRoush
|
||||
[rshapes] REVIEWED: `DrawRectangleRounded()`, automatic segments count (#5875) by @anstropleuton
|
||||
[rshapes] REVIEWED: `DrawRectangleRounded()`, `DrawRectangleRoundedLinesEx()`, fix auto segment rounded-corner math (#5883) by @ghera
|
||||
[rshapes] REVIEWED: `CheckCollisionLines()`, add NULL check (#5802) by @bielern
|
||||
[rshapes] REVIEWED: `Draw*LinesEx()`, inconsistencies handling of `thick` parameter (#6035) by @MatthewRoush
|
||||
[rshapes] REVIEWED: `DrawCircleSector()` (#6045) by @MatthewRoush
|
||||
[rshapes] REVIEWED: `DrawPolyLinesEx()` (#6004) by @MatthewRoush
|
||||
[rshapes] REVIEWED: `DrawPolyLinesEx()` line thickness (#6014) by @MatthewRoush
|
||||
[rshapes] REVIEWED: `DrawRectangleLinesEx()` (#6027) by @MatthewRoush
|
||||
[rshapes] REVIEWED: `DrawRectangleRoundedLines()` (#5992) by @MatthewRoush
|
||||
[rtextures] ADDED: `LoadRenderTextureEx()` with user defined pixel format (#6114) by @JeffM2501
|
||||
[rtextures] ADDED: `ImageDrawLineStrip()` by @raysan5
|
||||
[rtextures] ADDED: `DrawTriangleGradient()` by @raysan5
|
||||
[rtextures] ADDED: `DrawCircleLinesEx()`, simpler naming than `DrawRing()` by @raysan5
|
||||
[rtextures] ADDED: `ImageDrawCircleGradient()` by @raysan5
|
||||
[rtextures] ADDED: Support for .pep image fileformat, useful for pixel-art by @raysan5
|
||||
[rtextures] RENAMED: `ImageDrawTriangleEx()` to `ImageDrawTriangleGradient()` by @raysan5 -WARNING-
|
||||
[rtextures] REDESIGNED: `ImageDraw()`, align with `DrawTexture()` by @raysan5 -WARNING-
|
||||
[rtextures] REDESIGNED: `ImageDrawRectangleLines()`, consistency with `DrawRectangleLines()` by @raysan5 -WARNING-
|
||||
[rtextures] REVIEWED: `DrawRectangleLinesEx()`, avoid early-return by @raysan5
|
||||
[rtextures] REVIEWED: `GetPixelColor()` reading the wrong bits for R5G5B5A1 blue (#6113) by @dylanpulver
|
||||
[rtextures] REVIEWED: `ImageDrawCircle()`, asymmetry compared with `DrawCircle()` (#6118) by @Risu-swift
|
||||
[rtextures] REVIEWED: `LoadImageFromTexture()` for wasm by @raysan5
|
||||
[rtextures] REVIEWED: `ImageFromImage()` - ROS: `CLN-007` by @raysan5
|
||||
[rtextures] REVIEWED: `ImageFromImage()`, rectangle validation using strict comparisons (#5979) by @CommandPrompt-Wang
|
||||
[rtextures] REVIEWED: `ImageFromImage()` heap-buffer-overflow on compressed formats (#5991) by @gummyniki
|
||||
[rtextures] REVIEWED: `ImageToImage()`, reorganize conditionals checks optimization by @raysan5
|
||||
[rtextures] REVIEWED: `ImageDrawLine()`, rounding and length fix (#5896) by @Kaggen67
|
||||
[rtextures] REVIEWED: `ImageColorContrast()` parameter type, consistent with other `Image*()` functions by @raysan5 -WARNING-
|
||||
[rtextures] REVIEWED: `GetPixelDataSize()`, avoid allocations >2GB - ROS: `CLN-013` by @raysan5
|
||||
[rtextures] REVIEWED: `GetPixelColor()` const by @raysan5
|
||||
[rtext] REVIEWED: `LoadFontEx()`, `LoadFontFromMemory()`, additional warnings (#5864) by @CrackedPixel
|
||||
[rtext] REVIEWED: `TextToSnake()`, not considering spaces properly by @raysan5
|
||||
[rtext] REVIEWED: `TextSubtext()`, fix returning empty string when position is 0 (#5975) by @thiagomucci
|
||||
[rtext] REVIEWED: `TextReplaceBetween()`, fix buffer overflow (#5936) by @szarta
|
||||
[rtext] REVIEWED: `TextInsertAlloc()`, overflow by correcting loop bounds (#5982) by @GideonSerf
|
||||
[rtext] REVIEWED: `TextJoin()`, `TextSubtext()`, `TextInsert*()` - ROS: `CLN-018` by @raysan5
|
||||
[rtext] REVIEWED: `LoadFontFromImage()`, memory leak (#6100) by @ApexNadir
|
||||
[rtext] REVIEWED: `TextInsert()`/`TextInsertAlloc()` (#6021) by @SewerynKaminski
|
||||
[rtext] REVIEWED: `TextSplit()` reading past its buffer on text of 1024 bytes (#6136) by @MaxFreedomPollard
|
||||
[rtext] REVIEWED: `TextToPascal()`/`TextToCamel()` truncating text after a separator (#6132) by @MaxFreedomPollard
|
||||
[rmodels] REDESIGNED: `DrawCapsule()`, `DrawCapsuleWires()`, parameter order by @raysan5 -WARNING-
|
||||
[rmodels] REVIEWED: Fix glTF skinning when joints have non-joint parent nodes (#5876) by @cseelhoff
|
||||
[rmodels] REVIEWED: Change `boneCount` field type to `unsigned int` (#5955) by @lauchimoon
|
||||
[rmodels] REVIEWED: `LoadGLTF()`, use inverse bind matrices for bind pose (#5832) by @fyl2xp1
|
||||
[rmodels] REVIEWED: `IsModelValid()` #5780 by @raysan5
|
||||
[rmodels] REVIEWED: `GenMeshTorus()`, improved comments (#5934) by @EugenioBarbieriViale
|
||||
[rmodels] REVIEWED: `DrawSphereWires()`, code optimization (#6000) by @oscujic
|
||||
[rmodels] REVIEWED: `DrawSphereWires()`, code optimization (#6000) by @oscujic
|
||||
[rmodels] REVIEWED: `DrawCapsule()`, `DrawCapsuleWires()`, validate minimum rings (#5909) by @LuisR385
|
||||
[rmodels] REVIEWED: `UnloadModel()`, fix memory leak (#5907) by @LuisR385
|
||||
[rmodels] REVIEWED: GLTF animation interpolation (#6007) by @lassade
|
||||
[rmodels] REVIEWED: glTF pose sampled at the end of an animation returning a pose from the start (#6048) by @LeFede
|
||||
[raudio] REVIEWED: `UpdateSound()`, missleading parameter name by @raysan5
|
||||
[raudio] REVIEWED: `UnloadSoundAlias()`, prevent leak (#5857) by @Peter0x44
|
||||
[raudio] REVIEWED: Remove extra `drflac_free()` call (#5916) by @CrackedPixel
|
||||
[raudio] REVIEWED: Fix memory leak when loading .wav files (#5963) by @LuisR385
|
||||
[raudio] REVIEWED: Define missing `UnloadFileData()` on standalone mode (#5787) by @rigidatoms
|
||||
[raudio] REVIEWED: Update to latest DR libs to fix some warnings in MSVC (#5808) by @JeffM2501
|
||||
[raudio] REVIEWED: `CloseAudioDevice()`, crash when uninit device before mutex (#6039) by @get-charlie
|
||||
[raymath] ADDED: Operator overload for (float * Vector) (#5815) by @alphahex99
|
||||
[raymath] REVIEWED: `MatrixCompose()` to follow raymath conventions (#6133) by @carlost0
|
||||
|
||||
[build] REMOVED: Unmaintained project: 4coder by @raysan5
|
||||
[build] REMOVED: Unmaintained project: VS2019-Android by @raysan5
|
||||
[build][Make] REVIEWED: Add `ANDROID_ARCH` check (#5888) by @Fipaan
|
||||
[build][Make] REVIEWED: Re-enable `GLFW_LINUX_ENABLE_WAYLAND` flag by default #5816 by @raysan5
|
||||
[build][Make] REVIEWED: examples/Makefile after testing on OSX (#6077) by @WilliamIsMe1
|
||||
[build][Make] REVIEWED: Detect the recipe shell for proper clean (#6146) by @Peter0x44
|
||||
[build][VS2022] REVIEWED: x64 build compatibility support (#6052) (#6053) by @yoobezxc
|
||||
[build][CMake] ADDED: Support for Win32 platform + examples (#5855) by @CrackedPixel
|
||||
[build][CMake] REVIEWED: Fix config.h parsing into cmake options (#5844) by @Peter0x44
|
||||
[build][CMake] REVIEWED: Add configure-time test for libatomic requirement (#5847) by @Peter0x44
|
||||
[build][CMake] REVIEWED: Remove `raudio` and `rmodels` modules if disabled (#5878) by @NighthowlerStudios
|
||||
[build][CMake] REVIEWED: Remove GLFW_BUILD warnings for platform SDL (#5865) by @jestarray
|
||||
[build][CMake] REVIEWED: Reduce minimum CMake version from 3.25 to 3.22 (#5890) by @RobLoach
|
||||
[build][CMake] REVIEWED: Fix static link dependencies (#5990) by @meta-legend
|
||||
[build][CMake] REVIEWED: Fix standalone configuration of examples project (#6079) by @zaveshaa
|
||||
[build][CMake] REVIEWED: Propagate Cocoa backend frameworks to consumers of static raylib on macOS (#6086) by @zaveshaa
|
||||
[build][Zig] REVIEWED: Support wasm examples building (#5811) by @shadeops
|
||||
[build][Zig] REVIEWED: Avoid building examples all the time (#5869) by @jn-jairo
|
||||
[build][Zig] REVIEWED: Avoid building web examples all the time (#6006) by @jn-jairo
|
||||
[build][Zig] REVIEWED: Update to raygui 5.0 (#6005) by @jn-jairo
|
||||
[build][CI] REVIEWED: GitHub Actions update to latest actions versions by @raysan5
|
||||
[build][CI] REVIEWED: `build_examples_windows.yml`, use latest actions versions by @raysan5
|
||||
[build][CI] REVIEWED: `analyze_codeql.yml`, use latest actions versions by @raysan5
|
||||
[build][CI] REVIEWED: `setup-emsdk`, use latest actions version by @raysan5
|
||||
|
||||
[bindings] ADDED: Recomendations for binding authors (#6141) by @JeffM2501
|
||||
[bindings] ADDED: sola-raylib (6.0) (#5790, #5795) by @brettchalupa
|
||||
[bindings] ADDED: gclang-raylib (6.0) (#5850) by @gnuchanos
|
||||
[bindings] ADDED: mach-raylib (#6059) by @Angluca
|
||||
[bindings] ADDED: solod (#6102) by @nalgeon
|
||||
[bindings] ADDED: raymojo (#6076) by @RobertFlexx
|
||||
[bindings] ADDED: raylib_mojo, for Mojo language (#6093) by @willGuimont
|
||||
[bindings] ADDED: rayscal, for Scala Native (#6019) by @RobertFlexx
|
||||
[bindings] ADDED: raylib-elfscript, for ElfScript (#6036) by @ohmtal
|
||||
[bindings] ADDED: raylib component pascal/oberon2 bindings (#6055) by @RobertFlexx
|
||||
[bindings] ADDED: raylib binding for modula 2 and 3 (#6068) by @RobertFlexx
|
||||
[bindings] ADDED: raystar (#6075) by @RobertFlexx
|
||||
[bindings] UPDATED: vala-vapi to raylib 6.0 (#5789) by @edwood-grant
|
||||
[bindings] UPDATED: raylib_dart to raylib 6.0 (#5917) by @dzylikecode
|
||||
[bindings] UPDATED: raylib4fb to raylib 6.0 (#5813) by @mudhairless
|
||||
[bindings] UPDATED: raylib-d to raylib 6.0 (#5799) by @schveiguy
|
||||
[bindings] UPDATED: raylib-cpp to raylib 6.0 (#5785) by @RobLoach
|
||||
[bindings] UPDATED: raylib-go to raylib 6.0 (#5866) by @JupiterRider
|
||||
[bindings] UPDATED: raylib-cpp to raylib 6.0 (#5785) by @RobLoach
|
||||
[bindings] UPDATED: raylib-zig to raylib 6.0 (#5886) by @coal-rock
|
||||
[bindings] UPDATED: Deno-Raylib to raylib 6.0 (#5821) by @JJLDonley
|
||||
[bindings] UPDATED: raylib-cs to raylib 6.0 (#5887) by @rgebee
|
||||
[bindings] UPDATED: ReiLua to raylib 6.0 (#5959) by @nullstare
|
||||
[bindings] UPDATED: Raylib-lua to raylib 5.5 (#5884) by @keyle
|
||||
[bindings] UPDATED: Ray4Laz to raylib 6.0 (#5784) by @GuvaCode
|
||||
[bindings] UPDATED: EuRaylib to raylib 6.0 (#6034) by @gAndy50
|
||||
[bindings] UPDATED: raylib-ocaml to raylib 6.0 (#5912) by @tjammer
|
||||
[bindings] UPDATED: raylib-jai to raylib 6.0 (#5928) by @ahmedqarmout2
|
||||
[bindings] UPDATED: raylib-c3 to raylib 6.0 (#5819) by @surrealism21
|
||||
[bindings] UPDATED: raylib-asm to raylib 6.0 (#6033) by @gAndy50
|
||||
[bindings] UPDATED: fortran-raylib to raylib 6.0 (#6060) by @interkosmos
|
||||
[bindings] UPDATED: raylib-py to raylib 6.0 (#6095) by @overdev
|
||||
[bindings] UPDATED: h-raylib to raylib 6.0 (#6142) by @Anut-py
|
||||
|
||||
[examples] ADDED: `core_scissor_shape` (#6032) by @davidbuzatto
|
||||
[examples] ADDED: `models_mesh_uv_painting` (#6084) by @PanicTitan
|
||||
[examples] ADDED: `models_procedural_decals` (#6083) by @PanicTitan
|
||||
[examples] ADDED: `shaders_lights_bloom` (#6081) by @PanicTitan
|
||||
[examples] ADDED: `shapes_outlines_testbed` (#6072) by @MatthewRoush
|
||||
[examples] ADDED: `shapes_outlines_thickness` (#6037) by @MatthewRoush
|
||||
[examples] ADDED: `shapes_polygon_lines` (#6023) by @MatthewRoush
|
||||
[examples] ADDED: `textures_portal_window` (#6082) by @PanicTitan
|
||||
[examples] REVIEWED: `shaders_shadowmap_rendering` by @raysan5
|
||||
[examples] REVIEWED: `models_mesh_uv_painting` by @raysan5
|
||||
[examples] REVIEWED: `shaders_lights_bloom` by @raysan5
|
||||
[examples] REVIEWED: `textures_portal_window` by @raysan5
|
||||
[examples] REVIEWED: `core_smooth_pixelperfect` (#5803) by @rose-mtz
|
||||
[examples] REVIEWED: `core_directory_files` (#5823) by @MAXDVVV
|
||||
[examples] REVIEWED: `shapes_ball_physics`, move window for ball shake (#5791) by @Sebbl0508
|
||||
[examples] REVIEWED: `textures_image_drawing` by @raysan5
|
||||
[examples] REVIEWED: `models_basic_voxel` by @raysan5
|
||||
[examples] REVIEWED: `models_animation_blending` by @raysan5
|
||||
[examples] REVIEWED: `shaders_*`, `pbr.fs`, using wrong uniform value (#5965) by @raysan5
|
||||
|
||||
[rlparser] ADDED: S-Expression output type (#5943) by @VisenDev
|
||||
[rlparser] REVIEWED: Path fixes (#5794) by @gigamonster256
|
||||
[rlparser] REVIEWED: Fix formatting to follow raylib conventions (#6127) by @Nomobyte
|
||||
[rlparser] REVIEWED: Fix type aliases, added support to type pointers (#6126) by @Nomobyte
|
||||
[rexm] ADDED: New command: clean (#6124) by @MatthewRoush
|
||||
[rexm] REVIEWED: Crash when adding a new textures or audio examples (#6089) by @PanicTitan
|
||||
[rexm] REVIEWED: Leave environment setup up to the user (#6101) by @MatthewRoush
|
||||
[rexm] REVIEWED: Makefile and change web local testing port number (#6123) by @MatthewRoush
|
||||
[rexm] REVIEWED: Simplify code, latest w64devkit supports `make` directly, no need for `mingw32-make` by @raysan5
|
||||
[misc] ADDED: SECURITY.md document by @raysan5
|
||||
[misc] REVIEWED: Several functions `const` correctness by @raysan5
|
||||
[misc] REVIEWED: `strncpy()` replaced by `snprintf()` for safety by @raysan5
|
||||
[misc] REVIEWED: Minimize `long long` usage in all raylib by @raysan5
|
||||
[misc] REVIEWED: Comments for consistency and spelling by @raysan5
|
||||
[misc] REVIEWED: Some Rectangle parameters with more descriptive names by @raysan5
|
||||
[misc] REVIEWED: Shift `__cplusplus` check to a higher level for `bool` type define (#5804) by @lamweilun
|
||||
[external] ADDED: `rprand_get_value_raw()` to `rprand` library by @raysan5
|
||||
[external] UPDATED: GLFW to 3.5.1 (#6051) by @M374LX
|
||||
[external] UPDATED: miniaudio to 0.11.25 (#6050) by @M374LX
|
||||
[external] UPDATED: `raygui` to latest master (raygui 5.0) by @raysan5
|
||||
[external] REVIEWED: `jar_mod_load_file()`, check fread return value (#5840) by @fffaraz
|
||||
[external] REVIEWED: `tiny_obj_loader` Replace `assert()` by runtime checks - ROS: `CLN-012` by @raysan5
|
||||
[external] REVIEWED: `fix_win32_compatibility.h`, fix for newer windows SDK versions (#6088) by @JeffM2501
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Release: raylib 6.0 (23 April 2026)
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
@ -25,7 +25,7 @@ Functions params | lowerCase | `width`, `height`
|
||||
Ternary Operator | (condition)? result1 : result2 | `printf("Value is 0: %s", (value == 0)? "yes" : "no");`
|
||||
|
||||
Some other conventions to follow:
|
||||
- **ALWAYS** initialize all defined variables, avoid defining variables in same code line, use multiple lines.
|
||||
- **ALWAYS** initialize all defined variables.
|
||||
- **Do not use TABS**, use 4 spaces instead.
|
||||
- Avoid trailing spaces, please, avoid them
|
||||
- Comments always start with space + capital letter and never end with a '.', place them **before** the line(s) they refer to
|
||||
|
||||
22
README.md
@ -16,11 +16,12 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
|
||||
[](https://github.com/raysan5/raylib/stargazers)
|
||||
[](https://github.com/raysan5/raylib/commits/master)
|
||||
[](https://github.com/sponsors/raysan5)
|
||||
[](https://repology.org/project/raylib/versions)
|
||||
[](LICENSE)
|
||||
|
||||
[](https://discord.gg/raylib)
|
||||
[](https://www.reddit.com/r/raylib/)
|
||||
[](https://www.youtube.com/c/raylib)
|
||||
[](https://www.youtube.com/c/raylib)
|
||||
[](https://www.twitch.tv/raysan5)
|
||||
|
||||
[](https://github.com/raysan5/raylib/actions/workflows/build_windows.yml)
|
||||
@ -34,7 +35,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
|
||||
|
||||
features
|
||||
--------
|
||||
- **NO external dependencies**, all required libraries are [included in raylib](https://github.com/raysan5/raylib/tree/master/src/external)
|
||||
- **NO external dependencies**, all required libraries are [included into raylib](https://github.com/raysan5/raylib/tree/master/src/external)
|
||||
- Multiple platforms supported: **Windows, Linux, MacOS, RPI, Android, HTML5... and more!**
|
||||
- Written in plain C code (C99) using PascalCase/camelCase notation
|
||||
- Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
|
||||
@ -49,21 +50,10 @@ features
|
||||
- **Powerful math module** for Vector, Matrix and Quaternion operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h)
|
||||
- Audio loading and playing with streaming support (WAV, QOA, OGG, MP3, FLAC, XM, MOD)
|
||||
- **VR stereo rendering** support with configurable HMD device parameters
|
||||
- Huge examples collection with [+200 code examples](https://github.com/raysan5/raylib/tree/master/examples)!
|
||||
- Huge examples collection with [+140 code examples](https://github.com/raysan5/raylib/tree/master/examples)!
|
||||
- Bindings to [+70 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)!
|
||||
- **Free and open source**
|
||||
|
||||
limitations
|
||||
-----------
|
||||
|
||||
raylib presents some limitations by design for code simplicity. Some forks, alternatives, and samples are available to overcome most of them but it's up to the users to modify the library for their specific needs.
|
||||
|
||||
- Single window with single OpenGL context by default, no multi-window support
|
||||
- Window resize and move stops the rendering loop on platforms supporting a window
|
||||
- `RenderTextures` are flipped vertically, as provided by OpenGL, it's up to the user to draw them flipped to the screen
|
||||
- Font rasterization has lower quality than alternatives using `Freetype2`, `HarfBuzz` or `Slug`
|
||||
- Text drawing does not support RTL, ligatures or emojis
|
||||
|
||||
basic example
|
||||
--------------
|
||||
This is a basic raylib example, it creates a window and draws the text `"Congrats! You created your first window!"` in the middle of the screen. Check this example [running live on web here](https://www.raylib.com/examples/core/loader.html?name=core_basic_window).
|
||||
@ -109,7 +99,7 @@ raylib is also available via multiple package managers on multiple OS distributi
|
||||
- [Working for Web (HTML5)](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5))
|
||||
- [Working anywhere with CMake](https://github.com/raysan5/raylib/wiki/Working-with-CMake)
|
||||
|
||||
*Note that the Wiki is open to edits, if you find some issues while building raylib for your target platform, feel free to edit the Wiki or open an issue related to it.*
|
||||
*Note that the Wiki is open for edit, if you find some issues while building raylib for your target platform, feel free to edit the Wiki or open an issue related to it.*
|
||||
|
||||
#### Setup raylib with multiple IDEs
|
||||
|
||||
@ -122,7 +112,7 @@ raylib has been developed on Windows platform using [Notepad++](https://notepad-
|
||||
learning and docs
|
||||
------------------
|
||||
|
||||
raylib is designed to be learned using [the examples](https://github.com/raysan5/raylib/tree/master/examples) as the main reference. There is no standard API documentation but there is a [**cheatsheet**](https://www.raylib.com/cheatsheet/cheatsheet.html) containing all the functions available in the library with a short description of each one; input parameters and result value names should be intuitive enough to understand how each function works.
|
||||
raylib is designed to be learned using [the examples](https://github.com/raysan5/raylib/tree/master/examples) as the main reference. There is no standard API documentation but there is a [**cheatsheet**](https://www.raylib.com/cheatsheet/cheatsheet.html) containing all the functions available on the library a short description of each one of them, input parameters and result value names should be intuitive enough to understand how each function works.
|
||||
|
||||
Some additional documentation about raylib design can be found in [raylib GitHub Wiki](https://github.com/raysan5/raylib/wiki). Here are the relevant links:
|
||||
|
||||
|
||||
398
build.zig
@ -2,257 +2,85 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const emsdk = struct {
|
||||
const emsdk_version = "4.0.19"; // inline constant used only in activate
|
||||
var emsdk_dep: ?*std.Build.Dependency = null;
|
||||
const zemscripten = @import("zemscripten");
|
||||
|
||||
// ---------- core types ----------
|
||||
pub const EmccFlags = std.StringHashMap(void);
|
||||
pub const EmccSettings = std.StringHashMap([]const u8);
|
||||
const EmsdkAllocator = enum {
|
||||
none,
|
||||
dlmalloc,
|
||||
emmalloc,
|
||||
@"emmalloc-debug",
|
||||
@"emmalloc-memvalidate",
|
||||
@"emmalloc-verbose",
|
||||
mimalloc,
|
||||
};
|
||||
|
||||
pub const ResourceFile = struct {
|
||||
src_path: std.Build.LazyPath,
|
||||
virtual_path: ?[]const u8 = null,
|
||||
|
||||
fn get(self: ResourceFile, b: *std.Build) []const u8 {
|
||||
return if (self.virtual_path) |vp|
|
||||
b.fmt("{s}@{s}", .{ self.src_path.getDisplayName(), vp })
|
||||
else
|
||||
self.src_path.getDisplayName();
|
||||
}
|
||||
};
|
||||
|
||||
pub const EmccStepOptions = struct {
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
flags: EmccFlags,
|
||||
settings: EmccSettings,
|
||||
use_preload_plugins: bool = false,
|
||||
embed_paths: ?[]const ResourceFile = null,
|
||||
preload_paths: ?[]const ResourceFile = null,
|
||||
shell_file_path: ?std.Build.LazyPath = null,
|
||||
js_library_path: ?std.Build.LazyPath = null,
|
||||
out_file_name: []const u8,
|
||||
install_dir: std.Build.InstallDir,
|
||||
};
|
||||
|
||||
// ---------- helpers ----------
|
||||
pub fn emsdkDep(b: *std.Build) !*std.Build.Dependency {
|
||||
if (emsdk_dep == null) {
|
||||
emsdk_dep = try b.dependencyLazy("emsdk", .{});
|
||||
}
|
||||
|
||||
return emsdk_dep.?;
|
||||
pub fn shell(raylib_dep: *std.Build.Dependency) std.Build.LazyPath {
|
||||
return raylib_dep.path("src/shell.html");
|
||||
}
|
||||
|
||||
pub fn path(b: *std.Build, sub_path: []const u8) !std.Build.LazyPath {
|
||||
return (try emsdkDep(b)).path(sub_path);
|
||||
}
|
||||
|
||||
pub fn emccPath(b: *std.Build) !std.Build.LazyPath {
|
||||
return try emsdk.path(b, "upstream/emscripten/emcc.py");
|
||||
}
|
||||
|
||||
pub fn emrunPath(b: *std.Build) !std.Build.LazyPath {
|
||||
return switch (builtin.target.os.tag) {
|
||||
.windows => try emsdk.path(b, "upstream/emscripten/emrun.bat"),
|
||||
else => try emsdk.path(b, "upstream/emscripten/emrun"),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn emccDefaultFlags(allocator: std.mem.Allocator, options: struct {
|
||||
pub const FlagsOptions = struct {
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
asyncify: bool = true,
|
||||
fsanitize: bool = true,
|
||||
}) EmccFlags {
|
||||
var flags = EmccFlags.init(allocator);
|
||||
switch (options.optimize) {
|
||||
.Debug => {
|
||||
flags.put("-O0", {}) catch @panic("OOM");
|
||||
flags.put("-gsource-map", {}) catch @panic("OOM");
|
||||
if (options.fsanitize)
|
||||
flags.put("-fsanitize=undefined", {}) catch @panic("OOM");
|
||||
},
|
||||
.ReleaseSafe => {
|
||||
flags.put("-O3", {}) catch @panic("OOM");
|
||||
if (options.fsanitize) {
|
||||
flags.put("-fsanitize=undefined", {}) catch @panic("OOM");
|
||||
flags.put("-fsanitize-minimal-runtime", {}) catch @panic("OOM");
|
||||
}
|
||||
},
|
||||
.ReleaseFast => flags.put("-O3", {}) catch @panic("OOM"),
|
||||
.ReleaseSmall => flags.put("-Oz", {}) catch @panic("OOM"),
|
||||
}
|
||||
};
|
||||
|
||||
pub fn emccDefaultFlags(allocator: std.mem.Allocator, options: FlagsOptions) zemscripten.EmccFlags {
|
||||
var emcc_flags = zemscripten.emccDefaultFlags(allocator, .{
|
||||
.optimize = options.optimize,
|
||||
.fsanitize = true,
|
||||
});
|
||||
|
||||
if (options.asyncify)
|
||||
flags.put("-sASYNCIFY", {}) catch @panic("OOM");
|
||||
return flags;
|
||||
emcc_flags.put("-sASYNCIFY", {}) catch unreachable;
|
||||
|
||||
return emcc_flags;
|
||||
}
|
||||
|
||||
pub fn emccDefaultSettings(allocator: std.mem.Allocator, options: struct {
|
||||
pub const SettingsOptions = struct {
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
es3: bool = false,
|
||||
glfw3: bool = true,
|
||||
memory_growth: bool = false,
|
||||
total_memory: u32 = 134217728,
|
||||
emsdk_allocator: EmsdkAllocator = .emmalloc,
|
||||
}) EmccSettings {
|
||||
var settings = EmccSettings.init(allocator);
|
||||
switch (options.optimize) {
|
||||
.Debug, .ReleaseSafe => {
|
||||
settings.put("SAFE_HEAP", "1") catch @panic("OOM");
|
||||
settings.put("STACK_OVERFLOW_CHECK", "1") catch @panic("OOM");
|
||||
settings.put("ASSERTIONS", "1") catch @panic("OOM");
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
settings.put("MALLOC", @tagName(options.emsdk_allocator)) catch @panic("OOM");
|
||||
emsdk_allocator: zemscripten.EmsdkAllocator = .emmalloc,
|
||||
};
|
||||
|
||||
pub fn emccDefaultSettings(allocator: std.mem.Allocator, options: SettingsOptions) zemscripten.EmccSettings {
|
||||
var emcc_settings = zemscripten.emccDefaultSettings(allocator, .{
|
||||
.optimize = options.optimize,
|
||||
.emsdk_allocator = options.emsdk_allocator,
|
||||
});
|
||||
|
||||
if (options.es3) {
|
||||
settings.put("FULL_ES3", "1") catch @panic("OOM");
|
||||
settings.put("MIN_WEBGL_VERSION", "2") catch @panic("OOM");
|
||||
settings.put("MAX_WEBGL_VERSION", "2") catch @panic("OOM");
|
||||
emcc_settings.put("FULL_ES3", "1") catch unreachable;
|
||||
emcc_settings.put("MIN_WEBGL_VERSION", "2") catch unreachable;
|
||||
emcc_settings.put("MAX_WEBGL_VERSION", "2") catch unreachable;
|
||||
}
|
||||
if (options.glfw3) {
|
||||
emcc_settings.put("USE_GLFW", "3") catch unreachable;
|
||||
}
|
||||
if (options.glfw3)
|
||||
settings.put("USE_GLFW", "3") catch @panic("OOM");
|
||||
|
||||
const total_memory = std.fmt.allocPrint(allocator, "{d}", .{options.total_memory}) catch @panic("OOM");
|
||||
settings.put("EXPORTED_RUNTIME_METHODS", "['requestFullscreen']") catch @panic("OOM");
|
||||
settings.put("TOTAL_MEMORY", total_memory) catch @panic("OOM");
|
||||
settings.put("FORCE_FILESYSTEM", "1") catch @panic("OOM");
|
||||
settings.put("EXPORTED_RUNTIME_METHODS", "ccall") catch @panic("OOM");
|
||||
const total_memory = std.fmt.allocPrint(allocator, "{d}", .{options.total_memory}) catch unreachable;
|
||||
|
||||
emcc_settings.put("EXPORTED_RUNTIME_METHODS", "['requestFullscreen']") catch unreachable;
|
||||
emcc_settings.put("TOTAL_MEMORY", total_memory) catch unreachable;
|
||||
emcc_settings.put("FORCE_FILESYSTEM", "1") catch unreachable;
|
||||
emcc_settings.put("EXPORTED_RUNTIME_METHODS", "ccall") catch unreachable;
|
||||
|
||||
if (options.memory_growth)
|
||||
settings.put("ALLOW_MEMORY_GROWTH", "1") catch @panic("OOM");
|
||||
emcc_settings.put("ALLOW_MEMORY_GROWTH", "1") catch unreachable;
|
||||
|
||||
return settings;
|
||||
return emcc_settings;
|
||||
}
|
||||
|
||||
// ---------- step builders ----------
|
||||
pub fn emccStep(b: *std.Build, src_paths: []const std.Build.LazyPath, compile_steps: []const *std.Build.Step.Compile, options: EmccStepOptions) !*std.Build.Step {
|
||||
var emcc = b.addRunFile(try emccPath(b));
|
||||
pub fn emccStep(b: *std.Build, raylib: *std.Build.Step.Compile, wasm: *std.Build.Step.Compile, options: zemscripten.StepOptions) *std.Build.Step {
|
||||
const activate_emsdk_step = zemscripten.activateEmsdkStep(b);
|
||||
|
||||
// flags
|
||||
{
|
||||
var it = options.flags.iterator();
|
||||
while (it.next()) |kv| emcc.addArg(kv.key_ptr.*);
|
||||
}
|
||||
const emsdk_dep = b.dependency("emsdk", .{});
|
||||
raylib.root_module.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
|
||||
wasm.root_module.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
|
||||
|
||||
// settings
|
||||
{
|
||||
var it = options.settings.iterator();
|
||||
while (it.next()) |kv| {
|
||||
emcc.addArg(b.fmt("-s{s}={s}", .{ kv.key_ptr.*, kv.value_ptr.* }));
|
||||
}
|
||||
}
|
||||
const emcc_step = zemscripten.emccStep(b, wasm, options);
|
||||
emcc_step.dependOn(activate_emsdk_step);
|
||||
|
||||
// source files & artifact dependencies
|
||||
for (src_paths) |sp| emcc.addFileArg(sp);
|
||||
for (compile_steps) |cs| {
|
||||
emcc.addArtifactArg(cs);
|
||||
cs.root_module.addIncludePath(try emsdk.path(b, "upstream/emscripten/cache/sysroot/include"));
|
||||
for (cs.root_module.getGraph().modules) |mod| {
|
||||
for (mod.link_objects.items) |lo| {
|
||||
if (lo == .other_step) {
|
||||
const linked = lo.other_step;
|
||||
if (linked.kind == .lib) emcc.addArtifactArg(linked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emcc.addArg("-o");
|
||||
const out_file = emcc.addOutputFileArg(options.out_file_name);
|
||||
|
||||
// optional args
|
||||
if (options.use_preload_plugins) emcc.addArg("--use-preload-plugins");
|
||||
if (options.embed_paths) |eps| for (eps) |ep| {
|
||||
emcc.addArg("--embed-file");
|
||||
emcc.addFileArg(ep.src_path);
|
||||
};
|
||||
if (options.preload_paths) |pps| for (pps) |pp| {
|
||||
emcc.addArg("--preload-file");
|
||||
emcc.addArg(pp.get(b));
|
||||
};
|
||||
if (options.shell_file_path) |sfp| {
|
||||
emcc.addArg("--shell-file");
|
||||
emcc.addFileArg(sfp);
|
||||
}
|
||||
if (options.js_library_path) |jlp| {
|
||||
emcc.addArg("--js-library");
|
||||
emcc.addFileArg(jlp);
|
||||
}
|
||||
|
||||
const install = b.addInstallDirectory(.{
|
||||
.source_dir = out_file.dirname(),
|
||||
.install_dir = options.install_dir,
|
||||
.install_subdir = "",
|
||||
});
|
||||
install.step.dependOn(&emcc.step);
|
||||
return &install.step;
|
||||
return emcc_step;
|
||||
}
|
||||
|
||||
pub fn emrunStep(b: *std.Build, html_path: std.Build.LazyPath, extra_args: []const []const u8) !*std.Build.Step {
|
||||
var emrun = b.addRunFile(try emrunPath(b));
|
||||
emrun.addArgs(extra_args);
|
||||
emrun.addFileArg(html_path);
|
||||
return &emrun.step;
|
||||
}
|
||||
|
||||
pub fn activateEmsdkStep(b: *std.Build) !*std.Build.Step {
|
||||
const user = b.step("Activate EMSDK", "Install/Update and prepare emscripten sdk");
|
||||
const script = switch (builtin.target.os.tag) {
|
||||
.windows => try emsdk.path(b, "emsdk.bat"),
|
||||
else => try emsdk.path(b, "emsdk"),
|
||||
};
|
||||
|
||||
var update = b.addRunFile(script);
|
||||
update.addArg("update");
|
||||
|
||||
// chmod / takeown for script
|
||||
const make_script_exec: ?*std.Build.Step.Run = switch (builtin.target.os.tag) {
|
||||
.linux, .macos => blk: {
|
||||
var cmd = b.addSystemCommand(&.{ "chmod", "+x" });
|
||||
cmd.addFileArg(script);
|
||||
break :blk cmd;
|
||||
},
|
||||
.windows => blk: {
|
||||
var cmd = b.addSystemCommand(&.{ "takeown", "/f" });
|
||||
cmd.addFileArg(script);
|
||||
break :blk cmd;
|
||||
},
|
||||
else => null,
|
||||
};
|
||||
if (make_script_exec) |mse| update.step.dependOn(&mse.step);
|
||||
|
||||
var install = b.addRunFile(script);
|
||||
install.addArg("install");
|
||||
install.addArg(emsdk_version);
|
||||
install.step.dependOn(&update.step);
|
||||
|
||||
var activate = b.addRunFile(script);
|
||||
activate.addArg("activate");
|
||||
activate.addArg(emsdk_version);
|
||||
activate.step.dependOn(&install.step);
|
||||
user.dependOn(&activate.step);
|
||||
|
||||
// also ensure emcc/emrun are executable on Unix
|
||||
if (builtin.target.os.tag == .linux or builtin.target.os.tag == .macos) {
|
||||
for ([_]std.Build.LazyPath{ try emccPath(b), try emrunPath(b) }) |p| {
|
||||
var cmd = b.addSystemCommand(&.{ "chmod", "a+x" });
|
||||
cmd.addFileArg(p);
|
||||
cmd.step.dependOn(&install.step);
|
||||
user.dependOn(&cmd.step);
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
pub fn emrunStep(
|
||||
b: *std.Build,
|
||||
html_path: []const u8,
|
||||
extra_args: []const []const u8,
|
||||
) *std.Build.Step {
|
||||
return zemscripten.emrunStep(b, html_path, extra_args);
|
||||
}
|
||||
};
|
||||
|
||||
@ -264,7 +92,7 @@ pub fn linkWindows(mod: *std.Build.Module, opengl: bool, comptime shcore: bool)
|
||||
}
|
||||
|
||||
fn findWaylandScanner(b: *std.Build) void {
|
||||
_ = b.findProgram(.{ .names = &.{"wayland-scanner"} }) orelse {
|
||||
_ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch {
|
||||
std.log.err(
|
||||
\\ `wayland-scanner` may not be installed on the system.
|
||||
\\ You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
|
||||
@ -298,20 +126,19 @@ pub fn linkBSD(_: *std.Build, mod: *std.Build.Module) void {
|
||||
mod.linkSystemLibrary("GL", .{});
|
||||
}
|
||||
|
||||
pub fn linkMacOS(b: *std.Build, mod: *std.Build.Module) !void {
|
||||
pub fn linkMacOS(b: *std.Build, mod: *std.Build.Module) void {
|
||||
// Include xcode_frameworks for cross compilation
|
||||
const dep = try b.dependencyLazy("xcode_frameworks", .{});
|
||||
|
||||
mod.addSystemFrameworkPath(dep.path("Frameworks"));
|
||||
mod.addSystemIncludePath(dep.path("include"));
|
||||
mod.addLibraryPath(dep.path("lib"));
|
||||
if (b.lazyDependency("xcode_frameworks", .{})) |dep| {
|
||||
mod.addSystemFrameworkPath(dep.path("Frameworks"));
|
||||
mod.addSystemIncludePath(dep.path("include"));
|
||||
mod.addLibraryPath(dep.path("lib"));
|
||||
}
|
||||
|
||||
mod.linkFramework("Foundation", .{});
|
||||
mod.linkFramework("CoreServices", .{});
|
||||
mod.linkFramework("CoreGraphics", .{});
|
||||
mod.linkFramework("AppKit", .{});
|
||||
mod.linkFramework("IOKit", .{});
|
||||
mod.linkFramework("QuartzCore", .{});
|
||||
}
|
||||
|
||||
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
@ -327,13 +154,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
.root_module = raylib_mod,
|
||||
});
|
||||
|
||||
// On Linux (glibc) avoid _GNU_SOURCE, on glibc >= 2.38 it redirects sscanf(), strtol()...
|
||||
// to __isoc23_*() symbols, so the generated library fails to link with older glibc versions
|
||||
if (target.result.os.tag == .linux and !target.result.abi.isAndroid()) {
|
||||
raylib_mod.addCMacro("_DEFAULT_SOURCE", "");
|
||||
} else {
|
||||
raylib_mod.addCMacro("_GNU_SOURCE", "");
|
||||
}
|
||||
raylib_mod.addCMacro("_GNU_SOURCE", "");
|
||||
raylib_mod.addCMacro("GL_SILENCE_DEPRECATION", "199309L");
|
||||
|
||||
var arena: std.heap.ArenaAllocator = .init(b.allocator);
|
||||
@ -440,7 +261,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
});
|
||||
_ = raylib_flags_arr.pop();
|
||||
|
||||
try linkMacOS(b, raylib_mod);
|
||||
linkMacOS(b, raylib_mod);
|
||||
},
|
||||
.emscripten => {
|
||||
switch (opengl_version) {
|
||||
@ -451,9 +272,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
|
||||
raylib_mod.addCMacro("PLATFORM_WEB", "");
|
||||
|
||||
raylib_mod.addIncludePath(try emsdk.path(b, "upstream/emscripten/cache/sysroot/include"));
|
||||
|
||||
const activate_emsdk_step = try emsdk.activateEmsdkStep(b);
|
||||
const activate_emsdk_step = emsdk.zemscripten.activateEmsdkStep(b);
|
||||
raylib.step.dependOn(activate_emsdk_step);
|
||||
},
|
||||
else => @panic("Target is not supported with this platform"),
|
||||
@ -502,7 +321,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
}
|
||||
},
|
||||
.freebsd, .openbsd, .netbsd, .dragonfly => linkBSD(b, raylib_mod),
|
||||
.macos => try linkMacOS(b, raylib_mod),
|
||||
.macos => linkMacOS(b, raylib_mod),
|
||||
.emscripten => {
|
||||
switch (opengl_version) {
|
||||
.auto => opengl_version = OpenglVersion.gles_2,
|
||||
@ -511,10 +330,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
}
|
||||
|
||||
raylib_mod.addCMacro("PLATFORM_WEB_RGFW", "");
|
||||
|
||||
raylib_mod.addIncludePath(try emsdk.path(b, "upstream/emscripten/cache/sysroot/include"));
|
||||
|
||||
const activate_emsdk_step = try emsdk.activateEmsdkStep(b);
|
||||
const activate_emsdk_step = emsdk.zemscripten.activateEmsdkStep(b);
|
||||
raylib.step.dependOn(activate_emsdk_step);
|
||||
},
|
||||
else => @panic("Target is not supported with this platform"),
|
||||
@ -660,33 +476,33 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
return raylib;
|
||||
}
|
||||
|
||||
fn addRaygui(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, raylib: *std.Build.Step.Compile) !void {
|
||||
const raygui_dep = try b.dependencyLazy("raygui", .{
|
||||
fn addRaygui(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, raylib: *std.Build.Step.Compile) void {
|
||||
if (b.lazyDependency("raygui", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
})) |raygui_dep| {
|
||||
var gen_step = b.addWriteFiles();
|
||||
raylib.step.dependOn(&gen_step.step);
|
||||
|
||||
var gen_step = b.addWriteFiles();
|
||||
raylib.step.dependOn(&gen_step.step);
|
||||
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
|
||||
raylib.root_module.addCSourceFile(.{ .file = raygui_c_path });
|
||||
raylib.root_module.addIncludePath(raygui_dep.path("src"));
|
||||
raylib.root_module.addIncludePath(b.path("src"));
|
||||
|
||||
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
|
||||
raylib.root_module.addCSourceFile(.{ .file = raygui_c_path });
|
||||
raylib.root_module.addIncludePath(raygui_dep.path("src"));
|
||||
raylib.root_module.addIncludePath(b.path("src"));
|
||||
raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
|
||||
|
||||
raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
|
||||
|
||||
const c = b.addTranslateC(.{
|
||||
.root_source_file = raygui_dep.path("src/raygui.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
c.addIncludePath(b.path("src"));
|
||||
const c_mod = c.createModule();
|
||||
c_mod.linkLibrary(raylib);
|
||||
b.modules.put(b.graph.arena, "raygui", c_mod) catch @panic("OOM");
|
||||
const c = b.addTranslateC(.{
|
||||
.root_source_file = raygui_dep.path("src/raygui.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
c.addIncludePath(b.path("src"));
|
||||
const c_mod = c.createModule();
|
||||
c_mod.linkLibrary(raylib);
|
||||
b.modules.put(b.graph.arena, "raygui", c_mod) catch @panic("OOM");
|
||||
}
|
||||
}
|
||||
|
||||
pub const Options = struct {
|
||||
@ -807,7 +623,7 @@ pub fn build(b: *std.Build) !void {
|
||||
translateCMod("rlgl", b, target, optimize, lib);
|
||||
|
||||
if (options.raygui) {
|
||||
try addRaygui(b, target, optimize, lib);
|
||||
addRaygui(b, target, optimize, lib);
|
||||
}
|
||||
|
||||
const examples = b.step("examples", "build/install all examples");
|
||||
@ -832,7 +648,7 @@ fn addExamples(
|
||||
const all = b.step(module, "All " ++ module ++ " examples");
|
||||
const module_subpath = b.pathJoin(&.{ "examples", module });
|
||||
|
||||
var dir = try b.root.openDir(b.graph.io, module_subpath, .{ .iterate = true });
|
||||
var dir = try b.build_root.handle.openDir(b.graph.io, module_subpath, .{ .iterate = true });
|
||||
defer dir.close(b.graph.io);
|
||||
|
||||
var iter = dir.iterate();
|
||||
@ -882,7 +698,7 @@ fn addExamples(
|
||||
exe_mod.addCMacro("PLATFORM_WEB", "");
|
||||
|
||||
const wasm = b.addLibrary(.{
|
||||
.name = b.fmt("{s}.html", .{filename}),
|
||||
.name = filename,
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
|
||||
@ -890,40 +706,25 @@ fn addExamples(
|
||||
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
|
||||
const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{ .optimize = optimize });
|
||||
|
||||
const SerialResourceFile = struct { src_path: []const u8, virtual_path: []const u8 };
|
||||
const EmccExamplesPreloadMap = std.static_string_map.StaticStringMap([]const SerialResourceFile);
|
||||
const EmccExamplesPreloadSerial = struct { []const u8, []const SerialResourceFile };
|
||||
const emcc_examples_preloads_serial: []const EmccExamplesPreloadSerial = @import("examples/example_resources.zon");
|
||||
const emcc_examples_preloads_map = EmccExamplesPreloadMap.initComptime(emcc_examples_preloads_serial);
|
||||
const preload_paths: ?[]emsdk.ResourceFile = blk: {
|
||||
if (emcc_examples_preloads_map.get(filename)) |resource_files| {
|
||||
var rfs = try b.allocator.alloc(emsdk.ResourceFile, resource_files.len);
|
||||
for (resource_files, 0..) |resource_file, rfidx| {
|
||||
rfs[rfidx] = .{
|
||||
.src_path = b.path(resource_file.src_path),
|
||||
.virtual_path = resource_file.virtual_path,
|
||||
};
|
||||
}
|
||||
break :blk rfs;
|
||||
} else break :blk null;
|
||||
};
|
||||
const EmccExamplesPreloadMap = std.static_string_map.StaticStringMap([]const emsdk.zemscripten.EmccFilePath);
|
||||
const EmccExamplesPreloadKV = struct { []const u8, []const emsdk.zemscripten.EmccFilePath };
|
||||
const emcc_examples_preloads: []const EmccExamplesPreloadKV = @import("examples/example_resources.zon");
|
||||
const emcc_examples_preloads_map = EmccExamplesPreloadMap.initComptime(emcc_examples_preloads);
|
||||
|
||||
const emcc_step = try emsdk.emccStep(b, &.{}, &.{ raylib, wasm }, .{
|
||||
const emcc_step = emsdk.emccStep(b, raylib, wasm, .{
|
||||
.optimize = optimize,
|
||||
.flags = emcc_flags,
|
||||
.settings = emcc_settings,
|
||||
.preload_paths = preload_paths,
|
||||
.preload_paths = emcc_examples_preloads_map.get(filename) orelse &.{},
|
||||
.shell_file_path = b.path("src/shell.html"),
|
||||
.install_dir = install_dir,
|
||||
.out_file_name = wasm.name,
|
||||
});
|
||||
b.getInstallStep().dependOn(emcc_step);
|
||||
|
||||
const emrun_step = try emsdk.emrunStep(
|
||||
const html_filename = try std.fmt.allocPrint(b.allocator, "{s}.html", .{wasm.name});
|
||||
const emrun_step = emsdk.emrunStep(
|
||||
b,
|
||||
b.graph.path(.install_prefix, b.fmt(
|
||||
"web/{s}/{s}/{s}",
|
||||
.{ module, filename, wasm.name },
|
||||
)),
|
||||
b.getInstallPath(install_dir, html_filename),
|
||||
&.{},
|
||||
);
|
||||
|
||||
@ -958,7 +759,7 @@ fn waylandGenerate(
|
||||
comptime waylandDir: []const u8,
|
||||
comptime source: bool,
|
||||
) !void {
|
||||
const dir = try b.root.openDir(b.graph.io, waylandDir, .{ .iterate = true });
|
||||
const dir = try b.build_root.handle.openDir(b.graph.io, waylandDir, .{ .iterate = true });
|
||||
defer dir.close(b.graph.io);
|
||||
|
||||
var iter = dir.iterate();
|
||||
@ -992,3 +793,4 @@ fn waylandGenerate(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
.{
|
||||
.name = .raylib,
|
||||
.version = "6.0.0",
|
||||
.minimum_zig_version = "0.17.0",
|
||||
.minimum_zig_version = "0.16.0",
|
||||
|
||||
.fingerprint = 0x13035e5cb8bc1ac2, // Changing this has security and trust implications.
|
||||
|
||||
@ -12,14 +12,17 @@
|
||||
.lazy = true,
|
||||
},
|
||||
.raygui = .{
|
||||
.url = "git+https://github.com/raysan5/raygui#3f81e2bd02bf08dcd9d350e8e8b3cf58044d6877",
|
||||
.hash = "N-V-__8AAPPCmABYkTrLoRGTR6whFQP1bvg7p5vpLsKIcn4G",
|
||||
.url = "git+https://github.com/raysan5/raygui#3b2855842ab578a034f827c38cf8f62c042fc983",
|
||||
.hash = "N-V-__8AAHvybwBw1kyBGn0BW_s1RqIpycNjLf_XbE-fpLUF",
|
||||
.lazy = true,
|
||||
},
|
||||
.emsdk = .{
|
||||
.url = "git+https://github.com/emscripten-core/emsdk#4.0.9",
|
||||
.hash = "N-V-__8AAJl1DwBezhYo_VE6f53mPVm00R-Fk28NPW7P14EQ",
|
||||
.lazy = true,
|
||||
},
|
||||
.zemscripten = .{
|
||||
.url = "git+https://github.com/zig-gamedev/zemscripten#3fa4b778852226c7346bdcc3c1486e875a9a6d02",
|
||||
.hash = "zemscripten-0.2.0-dev-sRlDqApRAACspTbAZnuNKWIzfWzSYgYkb2nWAXZ-tqqt",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@ -1,18 +1,6 @@
|
||||
# Setup the project and settings
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(examples)
|
||||
|
||||
# Include raylib's cmake helper functions, so the examples can also be
|
||||
# configured standalone (`cd examples && cmake .`) and not only as part
|
||||
# of the raylib project.
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
|
||||
include(AddIfFlagCompiles)
|
||||
|
||||
# Default to the Desktop platform when configured standalone.
|
||||
if (NOT DEFINED PLATFORM)
|
||||
set(PLATFORM "Desktop" CACHE STRING "Platform to build examples for")
|
||||
endif ()
|
||||
|
||||
# Directories that contain examples
|
||||
set(example_dirs
|
||||
audio
|
||||
@ -201,7 +189,6 @@ foreach (example_source ${example_sources})
|
||||
target_link_libraries(${example_name} "-framework IOKit")
|
||||
target_link_libraries(${example_name} "-framework Cocoa")
|
||||
target_link_libraries(${example_name} "-framework OpenGL")
|
||||
target_link_libraries(${example_name} "-framework QuartzCore")
|
||||
endif()
|
||||
|
||||
elseif (${PLATFORM} MATCHES "RGFW")
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
# > PLATFORM_DESKTOP_RGFW (RGFW backend):
|
||||
# - Windows (Win32, Win64)
|
||||
# - Linux (X11 desktop mode)
|
||||
# - macOS/OSX (x64, arm64)
|
||||
# - macOS/OSX (x64, arm64 (not tested))
|
||||
# - Others (not tested)
|
||||
# > PLATFORM_DESKTOP_WIN32 (native Win32):
|
||||
# - Windows (Win32, Win64)
|
||||
@ -122,14 +122,6 @@ BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources
|
||||
# WARNING: Requires raylib compiled with GRAPHICS_API_OPENGL_ES3
|
||||
BUILD_WEB_WEBGL2 ?= FALSE
|
||||
|
||||
# Detect the shell used by make: cmd preserves quotes, while sh removes them.
|
||||
ifndef PLATFORM_SHELL
|
||||
PLATFORM_SHELL = sh
|
||||
ifeq ($(shell echo "test"),"test")
|
||||
PLATFORM_SHELL = cmd
|
||||
endif
|
||||
endif
|
||||
|
||||
# Determine PLATFORM_OS when required
|
||||
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_WEB_RGFW))
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
|
||||
@ -322,9 +314,6 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
LDFLAGS += -Lsrc -L$(RAYLIB_LIB_PATH)
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
LDFLAGS += -L/opt/homebrew/lib -L$(RAYLIB_LIB_PATH)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
@ -429,7 +418,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
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 -framework QuartzCore
|
||||
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
|
||||
@ -507,7 +496,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDFLAGS += -L../src
|
||||
LDLIBS = -lraylib -lm
|
||||
LDLIBS += -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo -framework QuartzCore
|
||||
LDLIBS += -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
@ -600,12 +589,10 @@ SHAPES = \
|
||||
shapes/shapes_dashed_line \
|
||||
shapes/shapes_digital_clock \
|
||||
shapes/shapes_double_pendulum \
|
||||
shapes/shapes_drag_puzzle \
|
||||
shapes/shapes_easings_ball \
|
||||
shapes/shapes_easings_box \
|
||||
shapes/shapes_easings_rectangles \
|
||||
shapes/shapes_easings_testbed \
|
||||
shapes/shapes_ellipse_collision \
|
||||
shapes/shapes_following_eyes \
|
||||
shapes/shapes_hilbert_curve \
|
||||
shapes/shapes_kaleidoscope \
|
||||
@ -616,11 +603,8 @@ SHAPES = \
|
||||
shapes/shapes_math_angle_rotation \
|
||||
shapes/shapes_math_sine_cosine \
|
||||
shapes/shapes_mouse_trail \
|
||||
shapes/shapes_outlines_testbed \
|
||||
shapes/shapes_outlines_thickness \
|
||||
shapes/shapes_penrose_tile \
|
||||
shapes/shapes_pie_chart \
|
||||
shapes/shapes_polygon_lines \
|
||||
shapes/shapes_rectangle_advanced \
|
||||
shapes/shapes_rectangle_scaling \
|
||||
shapes/shapes_recursive_tree \
|
||||
@ -658,7 +642,6 @@ TEXTURES = \
|
||||
textures/textures_npatch_drawing \
|
||||
textures/textures_particles_blending \
|
||||
textures/textures_polygon_drawing \
|
||||
textures/textures_portal_window \
|
||||
textures/textures_raw_data \
|
||||
textures/textures_screen_buffer \
|
||||
textures/textures_sprite_animation \
|
||||
@ -710,10 +693,8 @@ MODELS = \
|
||||
models/models_loading_vox \
|
||||
models/models_mesh_generation \
|
||||
models/models_mesh_picking \
|
||||
models/models_mesh_uv_painting \
|
||||
models/models_orthographic_projection \
|
||||
models/models_point_rendering \
|
||||
models/models_procedural_decals \
|
||||
models/models_rlgl_solar_system \
|
||||
models/models_rotating_cube \
|
||||
models/models_skybox_rendering \
|
||||
@ -739,7 +720,6 @@ SHADERS = \
|
||||
shaders/shaders_hybrid_rendering \
|
||||
shaders/shaders_julia_set \
|
||||
shaders/shaders_lightmap_rendering \
|
||||
shaders/shaders_lights_bloom \
|
||||
shaders/shaders_mandelbrot_set \
|
||||
shaders/shaders_mesh_instancing \
|
||||
shaders/shaders_model_shader \
|
||||
@ -761,7 +741,6 @@ SHADERS = \
|
||||
shaders/shaders_vertex_displacement
|
||||
|
||||
AUDIO = \
|
||||
audio/audio_amp_envelope \
|
||||
audio/audio_mixed_processor \
|
||||
audio/audio_module_playing \
|
||||
audio/audio_music_stream \
|
||||
@ -802,11 +781,7 @@ endif
|
||||
clean:
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
ifeq ($(PLATFORM_SHELL),cmd)
|
||||
del *.o *.exe /s
|
||||
else
|
||||
find . -type f '(' -name '*.o' -o -name '*.exe' ')' -exec rm -f {} +
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
find . -type f -perm -ugo+x -delete
|
||||
@ -823,23 +798,19 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
ifeq ($(PLATFORM_SHELL),cmd)
|
||||
del *.o *.exe /s
|
||||
else
|
||||
find . -type f '(' -name '*.o' -o -name '*.exe' ')' -exec rm -f {} +
|
||||
endif
|
||||
del *.o *.exe /s
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
find . -type f -perm -ugo+x -delete
|
||||
rm -fv *.o
|
||||
find . -type f -perm -ugo+x -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
@ -847,7 +818,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
||||
ifeq ($(PLATFORM_SHELL),cmd)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.wasm *.html *.js *.data
|
||||
else
|
||||
rm -f */*.wasm */*.html */*.js */*.data
|
||||
|
||||
@ -411,7 +411,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
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 -framework QuartzCore
|
||||
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
|
||||
@ -480,7 +480,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDFLAGS += -L../src
|
||||
LDLIBS = -lraylib -lm
|
||||
LDLIBS += -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo -framework QuartzCore
|
||||
LDLIBS += -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
@ -561,12 +561,10 @@ SHAPES = \
|
||||
shapes/shapes_dashed_line \
|
||||
shapes/shapes_digital_clock \
|
||||
shapes/shapes_double_pendulum \
|
||||
shapes/shapes_drag_puzzle \
|
||||
shapes/shapes_easings_ball \
|
||||
shapes/shapes_easings_box \
|
||||
shapes/shapes_easings_rectangles \
|
||||
shapes/shapes_easings_testbed \
|
||||
shapes/shapes_ellipse_collision \
|
||||
shapes/shapes_following_eyes \
|
||||
shapes/shapes_hilbert_curve \
|
||||
shapes/shapes_kaleidoscope \
|
||||
@ -577,11 +575,8 @@ SHAPES = \
|
||||
shapes/shapes_math_angle_rotation \
|
||||
shapes/shapes_math_sine_cosine \
|
||||
shapes/shapes_mouse_trail \
|
||||
shapes/shapes_outlines_testbed \
|
||||
shapes/shapes_outlines_thickness \
|
||||
shapes/shapes_penrose_tile \
|
||||
shapes/shapes_pie_chart \
|
||||
shapes/shapes_polygon_lines \
|
||||
shapes/shapes_rectangle_advanced \
|
||||
shapes/shapes_rectangle_scaling \
|
||||
shapes/shapes_recursive_tree \
|
||||
@ -619,7 +614,6 @@ TEXTURES = \
|
||||
textures/textures_npatch_drawing \
|
||||
textures/textures_particles_blending \
|
||||
textures/textures_polygon_drawing \
|
||||
textures/textures_portal_window \
|
||||
textures/textures_raw_data \
|
||||
textures/textures_screen_buffer \
|
||||
textures/textures_sprite_animation \
|
||||
@ -671,10 +665,8 @@ MODELS = \
|
||||
models/models_loading_vox \
|
||||
models/models_mesh_generation \
|
||||
models/models_mesh_picking \
|
||||
models/models_mesh_uv_painting \
|
||||
models/models_orthographic_projection \
|
||||
models/models_point_rendering \
|
||||
models/models_procedural_decals \
|
||||
models/models_rlgl_solar_system \
|
||||
models/models_rotating_cube \
|
||||
models/models_skybox_rendering \
|
||||
@ -700,7 +692,6 @@ SHADERS = \
|
||||
shaders/shaders_hybrid_rendering \
|
||||
shaders/shaders_julia_set \
|
||||
shaders/shaders_lightmap_rendering \
|
||||
shaders/shaders_lights_bloom \
|
||||
shaders/shaders_mandelbrot_set \
|
||||
shaders/shaders_mesh_instancing \
|
||||
shaders/shaders_model_shader \
|
||||
@ -722,7 +713,6 @@ SHADERS = \
|
||||
shaders/shaders_vertex_displacement
|
||||
|
||||
AUDIO = \
|
||||
audio/audio_amp_envelope \
|
||||
audio/audio_mixed_processor \
|
||||
audio/audio_module_playing \
|
||||
audio/audio_music_stream \
|
||||
@ -931,9 +921,6 @@ shapes/shapes_digital_clock: shapes/shapes_digital_clock.c
|
||||
shapes/shapes_double_pendulum: shapes/shapes_double_pendulum.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_drag_puzzle: shapes/shapes_drag_puzzle.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_easings_ball: shapes/shapes_easings_ball.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -946,9 +933,6 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
|
||||
shapes/shapes_easings_testbed: shapes/shapes_easings_testbed.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_ellipse_collision: shapes/shapes_ellipse_collision.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -979,21 +963,12 @@ shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c
|
||||
shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_outlines_testbed: shapes/shapes_outlines_testbed.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_outlines_thickness: shapes/shapes_outlines_thickness.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_penrose_tile: shapes/shapes_penrose_tile.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_pie_chart: shapes/shapes_pie_chart.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_polygon_lines: shapes/shapes_polygon_lines.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_rectangle_advanced: shapes/shapes_rectangle_advanced.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -1123,9 +1098,6 @@ textures/textures_polygon_drawing: textures/textures_polygon_drawing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/cat.png@resources/cat.png
|
||||
|
||||
textures/textures_portal_window: textures/textures_portal_window.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
textures/textures_raw_data: textures/textures_raw_data.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw
|
||||
@ -1345,18 +1317,12 @@ models/models_mesh_picking: models/models_mesh_picking.c
|
||||
--preload-file models/resources/models/obj/turret.obj@resources/models/obj/turret.obj \
|
||||
--preload-file models/resources/models/obj/turret_diffuse.png@resources/models/obj/turret_diffuse.png
|
||||
|
||||
models/models_mesh_uv_painting: models/models_mesh_uv_painting.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
models/models_orthographic_projection: models/models_orthographic_projection.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
models/models_point_rendering: models/models_point_rendering.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
models/models_procedural_decals: models/models_procedural_decals.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
models/models_rlgl_solar_system: models/models_rlgl_solar_system.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -1494,12 +1460,6 @@ shaders/shaders_lightmap_rendering: shaders/shaders_lightmap_rendering.c
|
||||
--preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png \
|
||||
--preload-file shaders/resources/spark_flame.png@resources/spark_flame.png
|
||||
|
||||
shaders/shaders_lights_bloom: shaders/shaders_lights_bloom.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/shaders/glsl100/lights_bloom.vs@resources/shaders/glsl100/lights_bloom.vs \
|
||||
--preload-file shaders/resources/shaders/glsl100/lights_bloom.fs@resources/shaders/glsl100/lights_bloom.fs \
|
||||
--preload-file shaders/resources/shaders/glsl100/lights_bloom_post.fs@resources/shaders/glsl100/lights_bloom_post.fs
|
||||
|
||||
shaders/shaders_mandelbrot_set: shaders/shaders_mandelbrot_set.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/shaders/glsl100/mandelbrot_set.fs@resources/shaders/glsl100/mandelbrot_set.fs
|
||||
@ -1607,9 +1567,6 @@ shaders/shaders_vertex_displacement: shaders/shaders_vertex_displacement.c
|
||||
--preload-file shaders/resources/shaders/glsl100/vertex_displacement.fs@resources/shaders/glsl100/vertex_displacement.fs
|
||||
|
||||
# Compile AUDIO examples
|
||||
audio/audio_amp_envelope: audio/audio_amp_envelope.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
audio/audio_mixed_processor: audio/audio_mixed_processor.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file audio/resources/country.mp3@resources/country.mp3 \
|
||||
|
||||
@ -13,13 +13,11 @@ The examples assume you have already built the `raylib` library in `../src`.
|
||||
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.
|
||||
|
||||
Run the following commands from the repository root:
|
||||
|
||||
- `zig build examples` to compile all examples
|
||||
- `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 COLLECTION [TOTAL: 222]
|
||||
## EXAMPLES COLLECTION [TOTAL: 212]
|
||||
|
||||
### category: core [49]
|
||||
|
||||
@ -77,7 +75,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
||||
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_window_web](core/core_window_web.c) | <img src="core/core_window_web.png" alt="core_window_web" width="80"> | ⭐☆☆☆ | 1.3 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
### category: shapes [45]
|
||||
### category: shapes [40]
|
||||
|
||||
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
||||
|
||||
@ -123,13 +121,8 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||
| [shapes_easings_testbed](shapes/shapes_easings_testbed.c) | <img src="shapes/shapes_easings_testbed.png" alt="shapes_easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
| [shapes_drag_puzzle](shapes/shapes_drag_puzzle.c) | <img src="shapes/shapes_drag_puzzle.png" alt="shapes_drag_puzzle" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Gabriel Piangers](https://github.com/gabriel-piangers) |
|
||||
| [shapes_ellipse_collision](shapes/shapes_ellipse_collision.c) | <img src="shapes/shapes_ellipse_collision.png" alt="shapes_ellipse_collision" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Ziya](https://github.com/Monjaris) |
|
||||
| [shapes_outlines_testbed](shapes/shapes_outlines_testbed.c) | <img src="shapes/shapes_outlines_testbed.png" alt="shapes_outlines_testbed" width="80"> | ⭐⭐⭐☆ | 6.1 | 6.1 | [Matthew Roush](https://github.com/MatthewRoush) |
|
||||
| [shapes_outlines_thickness](shapes/shapes_outlines_thickness.c) | <img src="shapes/shapes_outlines_thickness.png" alt="shapes_outlines_thickness" width="80"> | ⭐☆☆☆ | 6.1 | 6.1 | [Matthew Roush](https://github.com/MatthewRoush) |
|
||||
| [shapes_polygon_lines](shapes/shapes_polygon_lines.c) | <img src="shapes/shapes_polygon_lines.png" alt="shapes_polygon_lines" width="80"> | ⭐⭐☆☆ | 6.1 | 6.1 | [Matthew Roush](https://github.com/MatthewRoush) |
|
||||
|
||||
### category: textures [33]
|
||||
### category: textures [32]
|
||||
|
||||
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
|
||||
|
||||
@ -153,7 +146,7 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐⭐⭐☆ | 1.6 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐⭐⭐☆ | 3.0 | 6.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
||||
| [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) |
|
||||
| [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) |
|
||||
| [textures_tiled_drawing](textures/textures_tiled_drawing.c) | <img src="textures/textures_tiled_drawing.png" alt="textures_tiled_drawing" width="80"> | ⭐⭐⭐☆ | 3.0 | 4.2 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| [textures_polygon_drawing](textures/textures_polygon_drawing.c) | <img src="textures/textures_polygon_drawing.png" alt="textures_polygon_drawing" width="80"> | ⭐☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||
@ -167,7 +160,6 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
|
||||
| [textures_portal_window](textures/textures_portal_window.c) | <img src="textures/textures_portal_window.png" alt="textures_portal_window" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [PanicTitan](https://github.com/PanicTitan) |
|
||||
|
||||
### category: text [16]
|
||||
|
||||
@ -192,7 +184,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
||||
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
|
||||
### category: models [32]
|
||||
### category: models [30]
|
||||
|
||||
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
||||
|
||||
@ -228,10 +220,8 @@ Examples using raylib models functionality, including models loading/generation
|
||||
| [models_animation_blend_custom](models/models_animation_blend_custom.c) | <img src="models/models_animation_blend_custom.png" alt="models_animation_blend_custom" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [dmitrii-brand](https://github.com/dmitrii-brand) |
|
||||
| [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) |
|
||||
| [models_animation_timing](models/models_animation_timing.c) | <img src="models/models_animation_timing.png" alt="models_animation_timing" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [models_mesh_uv_painting](models/models_mesh_uv_painting.c) | <img src="models/models_mesh_uv_painting.png" alt="models_mesh_uv_painting" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [PanicTitan](https://github.com/PanicTitan) |
|
||||
| [models_procedural_decals](models/models_procedural_decals.c) | <img src="models/models_procedural_decals.png" alt="models_procedural_decals" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [PanicTitan](https://github.com/PanicTitan) |
|
||||
|
||||
### category: shaders [36]
|
||||
### category: shaders [35]
|
||||
|
||||
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.h) module.
|
||||
|
||||
@ -272,9 +262,8 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
||||
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_rlgl_compute](shaders/shaders_rlgl_compute.c) | <img src="shaders/shaders_rlgl_compute.png" alt="shaders_rlgl_compute" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
||||
| [shaders_cel_shading](shaders/shaders_cel_shading.c) | <img src="shaders/shaders_cel_shading.png" alt="shaders_cel_shading" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Gleb A](https://github.com/ggrizzly) |
|
||||
| [shaders_lights_bloom](shaders/shaders_lights_bloom.c) | <img src="shaders/shaders_lights_bloom.png" alt="shaders_lights_bloom" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [PanicTitan](https://github.com/PanicTitan) |
|
||||
|
||||
### category: audio [11]
|
||||
### category: audio [10]
|
||||
|
||||
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.
|
||||
|
||||
@ -287,10 +276,9 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
||||
| [audio_mixed_processor](audio/audio_mixed_processor.c) | <img src="audio/audio_mixed_processor.png" alt="audio_mixed_processor" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
|
||||
| [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
||||
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
||||
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [IANN](https://github.com/meisei4) |
|
||||
| [audio_stream_callback](audio/audio_stream_callback.c) | <img src="audio/audio_stream_callback.png" alt="audio_stream_callback" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Dan Hoang](https://github.com/dan-hoang) |
|
||||
| [audio_amp_envelope](audio/audio_amp_envelope.c) | <img src="audio/audio_amp_envelope.png" alt="audio_amp_envelope" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Arbinda Rizki Muhammad](https://github.com/arbipink) |
|
||||
|
||||
Some example missing? As always, contributions are welcome, feel free to send new examples!
|
||||
Here is an [examples template](examples_template.c) with instructions to start with!
|
||||
|
||||
@ -113,7 +113,6 @@ int main(void)
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadMusicStream(music); // Unload music stream buffers from RAM
|
||||
UnloadSound(sound);
|
||||
|
||||
DetachAudioMixedProcessor(ProcessAudio); // Disconnect audio processor
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ int main(void)
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||
buffer[i] = sinf(2*PI*sineIndex/wavelength);
|
||||
buffer[i] = sin(2*PI*sineIndex/wavelength);
|
||||
sineIndex++;
|
||||
|
||||
if (sineIndex >= wavelength)
|
||||
@ -116,8 +116,8 @@ int main(void)
|
||||
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
||||
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
|
||||
|
||||
int windowStart = (int)((GetTime() - sineStartTime)*SAMPLE_RATE);
|
||||
int windowSize = SAMPLE_RATE/10;
|
||||
int windowStart = (GetTime() - sineStartTime)*SAMPLE_RATE;
|
||||
int windowSize = 0.1f*SAMPLE_RATE;
|
||||
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||
|
||||
// Draw a sine wave with the same frequency as the one being sent to the audio stream
|
||||
@ -125,8 +125,8 @@ int main(void)
|
||||
{
|
||||
int t0 = windowStart + i*windowSize/screenWidth;
|
||||
int t1 = windowStart + (i + 1)*windowSize/screenWidth;
|
||||
Vector2 startPos = { (float)i, 250 + 50*sinf(2*PI*t0/wavelength) };
|
||||
Vector2 endPos = { (float)i + 1, 250 + 50*sinf(2*PI*t1/wavelength) };
|
||||
Vector2 startPos = { i, 250 + 50*sin(2*PI*t0/wavelength) };
|
||||
Vector2 endPos = { i + 1, 250 + 50*sin(2*PI*t1/wavelength) };
|
||||
DrawLineV(startPos, endPos, RED);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Le Juez Victor (@Bigfoot71) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
@ -116,14 +116,14 @@ static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, flo
|
||||
// Calculate normalized vectors for spatial positioning
|
||||
Vector3 normalizedDirection = Vector3Normalize(direction);
|
||||
Vector3 forward = Vector3Normalize(Vector3Subtract(listener.target, listener.position));
|
||||
Vector3 right = Vector3Normalize(Vector3CrossProduct(forward, listener.up));
|
||||
Vector3 right = Vector3Normalize(Vector3CrossProduct(listener.up, forward));
|
||||
|
||||
// Reduce volume for sounds behind the listener
|
||||
float dotProduct = Vector3DotProduct(forward, normalizedDirection);
|
||||
if (dotProduct < 0.0f) attenuation *= (1.0f + dotProduct*0.5f);
|
||||
|
||||
// Set stereo panning based on sound position relative to listener
|
||||
float pan = Vector3DotProduct(normalizedDirection, right);
|
||||
float pan = 0.5f + 0.5f*Vector3DotProduct(normalizedDirection, right);
|
||||
|
||||
// Apply final sound properties
|
||||
SetSoundVolume(sound, attenuation);
|
||||
|
||||
@ -133,8 +133,8 @@ int main(void)
|
||||
// Draw the last 10 ms of uploaded audio
|
||||
for (int i = 0; i < screenWidth; i++)
|
||||
{
|
||||
Vector2 startPos = {(float)i, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + i*SAMPLE_RATE/100/screenWidth] };
|
||||
Vector2 endPos = { (float)(i + 1), 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + (i + 1)*SAMPLE_RATE/100/screenWidth] };
|
||||
Vector2 startPos = { i, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + i*SAMPLE_RATE/100/screenWidth] };
|
||||
Vector2 endPos = { i + 1, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + (i + 1)*SAMPLE_RATE/100/screenWidth] };
|
||||
DrawLineV(startPos, endPos, RED);
|
||||
}
|
||||
|
||||
@ -161,9 +161,9 @@ static void SineCallback(void *framesOut, unsigned int frameCount)
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the sine wave
|
||||
for (unsigned int i = 0; i < frameCount; i++)
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = sinf(2*PI*waveIndex/wavelength);
|
||||
((float *)framesOut)[i] = sin(2*PI*waveIndex/wavelength);
|
||||
|
||||
waveIndex++;
|
||||
|
||||
@ -175,8 +175,8 @@ static void SineCallback(void *framesOut, unsigned int frameCount)
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (unsigned int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (unsigned int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
static void SquareCallback(void *framesOut, unsigned int frameCount)
|
||||
@ -184,9 +184,9 @@ static void SquareCallback(void *framesOut, unsigned int frameCount)
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the square wave
|
||||
for (unsigned int i = 0; i < frameCount; i++)
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = (waveIndex < wavelength/2)? 1.0f : -1.0f;
|
||||
((float *)framesOut)[i] = (waveIndex < wavelength/2)? 1 : -1;
|
||||
waveIndex++;
|
||||
|
||||
if (waveIndex >= wavelength)
|
||||
@ -197,8 +197,8 @@ static void SquareCallback(void *framesOut, unsigned int frameCount)
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (unsigned int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (unsigned int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
static void TriangleCallback(void *framesOut, unsigned int frameCount)
|
||||
@ -206,7 +206,7 @@ static void TriangleCallback(void *framesOut, unsigned int frameCount)
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the triangle wave
|
||||
for (unsigned int i = 0; i < frameCount; i++)
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = (waveIndex < wavelength/2)? (-1 + 2.0f*waveIndex/(wavelength/2)) : (1 - 2.0f*(waveIndex - wavelength/2)/(wavelength/2));
|
||||
waveIndex++;
|
||||
@ -219,8 +219,8 @@ static void TriangleCallback(void *framesOut, unsigned int frameCount)
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (unsigned int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (unsigned int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
static void SawtoothCallback(void *framesOut, unsigned int frameCount)
|
||||
@ -228,7 +228,7 @@ static void SawtoothCallback(void *framesOut, unsigned int frameCount)
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the sawtooth wave
|
||||
for (unsigned int i = 0; i < frameCount; i++)
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = -1 + 2.0f*waveIndex/wavelength;
|
||||
waveIndex++;
|
||||
@ -241,6 +241,6 @@ static void SawtoothCallback(void *framesOut, unsigned int frameCount)
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (unsigned int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (unsigned int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float*)framesOut)[i];
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ int main(void)
|
||||
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = (Vector2){ player.x + 20.0f, player.y + 20.0f };
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
|
||||
@ -65,8 +65,8 @@ int main(void)
|
||||
// Get the world point that is under the mouse
|
||||
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||
|
||||
// Set the offset to where the mouse is, mouse is scaled to viewport space, but offset is in unscaled pixels
|
||||
camera.offset = Vector2Multiply(GetMousePosition(), GetWindowScaleDPI());
|
||||
// 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
|
||||
@ -86,8 +86,8 @@ int main(void)
|
||||
// Get the world point that is under the mouse
|
||||
Vector2 mouseWorldPos = GetScreenToWorld2D(GetMousePosition(), camera);
|
||||
|
||||
// Set the offset to where the mouse is, mouse is scaled to viewport space, but offset is in unscaled pixels
|
||||
camera.offset = Vector2Multiply(GetMousePosition(), GetWindowScaleDPI());
|
||||
// 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
|
||||
|
||||
@ -75,7 +75,7 @@ int main(void)
|
||||
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#define PLAYER_SIZE 40
|
||||
|
||||
@ -40,13 +39,13 @@ int main(void)
|
||||
|
||||
Camera2D camera1 = { 0 };
|
||||
camera1.target = (Vector2){ player1.x, player1.y };
|
||||
camera1.offset = Vector2Multiply((Vector2){ 200.0f, 200.0f }, GetWindowScaleDPI());
|
||||
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 = Vector2Multiply((Vector2){ 200.0f, 200.0f }, GetWindowScaleDPI());
|
||||
camera2.offset = (Vector2){ 200.0f, 200.0f };
|
||||
camera2.rotation = 0.0f;
|
||||
camera2.zoom = 1.0f;
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ int main(void)
|
||||
// Define camera
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
@ -117,7 +117,7 @@ int main(void)
|
||||
player.canJump = false;
|
||||
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
}
|
||||
@ -169,7 +169,7 @@ int main(void)
|
||||
player.canJump = false;
|
||||
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
}
|
||||
@ -205,7 +205,7 @@ int main(void)
|
||||
// Update camera
|
||||
//----------------------------------------------------------------------------------
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
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
|
||||
@ -267,7 +267,7 @@ int main(void)
|
||||
player.canJump = false;
|
||||
|
||||
camera.target = player.position;
|
||||
camera.offset = (Vector2){ GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
|
||||
camera.rotation = 0.0f;
|
||||
camera.zoom = 1.0f;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ int main(void)
|
||||
if (currentFps <= 0) fpsText = TextFormat("FPS: unlimited (%i)", GetFPS());
|
||||
else fpsText = TextFormat("FPS: %i (target: %i)", GetFPS(), currentFps);
|
||||
DrawText(fpsText, 10, 10, 20, DARKGRAY);
|
||||
DrawText(TextFormat("Frame time: %02.02f ms", GetFrameTime()*1000.0f), 10, 30, 20, DARKGRAY);
|
||||
DrawText(TextFormat("Frame time: %02.02f ms", GetFrameTime()), 10, 30, 20, DARKGRAY);
|
||||
DrawText("Use the scroll wheel to change the fps limit, r to reset", 10, 50, 20, DARKGRAY);
|
||||
|
||||
// Draw the text above the circles
|
||||
|
||||
@ -88,7 +88,7 @@ int main(void)
|
||||
DrawCircleV(GetMousePosition(), 20, MAROON);
|
||||
DrawRectangleRec((Rectangle) { mousePos.x - 25, mousePos.y, 50, 2 }, BLACK);
|
||||
DrawRectangleRec((Rectangle) { mousePos.x, mousePos.y - 25, 2, 50 }, BLACK);
|
||||
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), (int)mousePos.x - 44,
|
||||
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
|
||||
(mousePos.y > GetScreenHeight() - 60)? (int)mousePos.y - 46 : (int)mousePos.y + 30, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
@ -97,6 +97,9 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// TODO: Unload all loaded resources at this point
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -94,7 +94,6 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
UnloadRenderTexture(target);
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#
|
||||
# This list is used as the main reference by [rexm] tool for examples collection validation and management
|
||||
#
|
||||
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2026;"Ramon Santamaria";@raysan5
|
||||
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_delta_time;★☆☆☆;5.5;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
core;core_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_input_mouse;★☆☆☆;1.0;5.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||
@ -98,11 +98,6 @@ shapes;shapes_ball_physics;★★☆☆;6.0;6.0;2025;2025;"David Buzatto";@david
|
||||
shapes;shapes_penrose_tile;★★★★;5.5;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||
shapes;shapes_easings_testbed;★★★☆;2.5;2.5;2019;2025;"Juan Miguel López";@flashback-fx
|
||||
shapes;shapes_drag_puzzle;★☆☆☆;6.0;6.0;2026;2026;"Gabriel Piangers";@gabriel-piangers
|
||||
shapes;shapes_ellipse_collision;★★☆☆;5.5;5.5;2025;2025;"Ziya";@Monjaris
|
||||
shapes;shapes_outlines_testbed;★★★☆;6.1;6.1;2026;2026;"Matthew Roush";@MatthewRoush
|
||||
shapes;shapes_outlines_thickness;★☆☆☆;6.1;6.1;2026;2026;"Matthew Roush";@MatthewRoush
|
||||
shapes;shapes_polygon_lines;★★☆☆;6.1;6.1;2026;2026;"Matthew Roush";@MatthewRoush
|
||||
textures;textures_clipboard_image;★☆☆☆;6.0;6.0;2026;2026;"Maicon Santana";@maiconpintoabreu
|
||||
textures;textures_magnifying_glass;★★★☆;5.6;5.6;2026;2026;"Luke Vaughan";@badram
|
||||
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
@ -121,7 +116,7 @@ textures;textures_sprite_animation;★★☆☆;1.3;1.3;2014;2025;"Ramon Santama
|
||||
textures;textures_sprite_button;★★☆☆;2.5;2.5;2019;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_sprite_explosion;★★☆☆;2.5;3.5;2019;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_bunnymark;★★★☆;1.6;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_mouse_painting;★★★☆;3.0;6.0;2019;2025;"Chris Dill";@MysteriousSpace
|
||||
textures;textures_mouse_painting;★★★☆;3.0;3.0;2019;2025;"Chris Dill";@MysteriousSpace
|
||||
textures;textures_blend_modes;★☆☆☆;3.5;3.5;2020;2025;"Karlo Licudine";@accidentalrebel
|
||||
textures;textures_tiled_drawing;★★★☆;3.0;4.2;2020;2025;"Vlad Adrian";@demizdor
|
||||
textures;textures_polygon_drawing;★☆☆☆;3.7;3.7;2021;2025;"Chris Camacho";@chriscamacho
|
||||
@ -135,7 +130,6 @@ textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";
|
||||
textures;textures_sprite_stacking;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
|
||||
textures;textures_portal_window;★★★★;6.0;6.0;2025;2025;"PanicTitan";@PanicTitan
|
||||
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
|
||||
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
@ -182,8 +176,6 @@ models;models_directional_billboard;★★☆☆;6.0;6.0;2025;2025;"Robin";@Robi
|
||||
models;models_animation_blend_custom;★★★★;5.5;6.0;2026;2026;"dmitrii-brand";@dmitrii-brand
|
||||
models;models_animation_blending;★★★★;5.5;6.0;2024;2026;"Kirandeep";@Kirandeep-Singh-Khehra
|
||||
models;models_animation_timing;★★★☆;6.0;6.0;2026;2026;"Ramon Santamaria";@raysan5
|
||||
models;models_mesh_uv_painting;★★★★;6.0;6.0;2025;2025;"PanicTitan";@PanicTitan
|
||||
models;models_procedural_decals;★★★★;6.0;6.0;2025;2025;"PanicTitan";@PanicTitan
|
||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;6.0;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
||||
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
||||
@ -219,7 +211,6 @@ shaders;shaders_depth_rendering;★★★☆;6.0;6.0;2025;2025;"Luís Almeida";@
|
||||
shaders;shaders_game_of_life;★★★☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_rlgl_compute;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||
shaders;shaders_cel_shading;★★★☆;6.0;6.0;2026;2026;"Gleb A";@ggrizzly
|
||||
shaders;shaders_lights_bloom;★★★☆;6.0;6.0;2025;2025;"PanicTitan";@PanicTitan
|
||||
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_raw_stream;★★★☆;1.6;6.0;2015;2026;"Ramon Santamaria";@raysan5
|
||||
@ -227,7 +218,6 @@ audio;audio_sound_loading;★☆☆☆;1.1;3.5;2014;2025;"Ramon Santamaria";@ray
|
||||
audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan
|
||||
audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501
|
||||
audio;audio_sound_positioning;★★☆☆;5.5;6.0;2025;2025;"Le Juez Victor";@Bigfoot71
|
||||
audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
|
||||
audio;audio_spectrum_visualizer;★★★☆;6.0;6.0;2025;2025;"IANN";@meisei4
|
||||
audio;audio_stream_callback;★★★☆;6.0;6.0;2026;2026;"Dan Hoang";@dan-hoang
|
||||
audio;audio_amp_envelope;★☆☆☆;6.0;6.0;2026;2026;"Arbinda Rizki Muhammad";@arbipink
|
||||
|
||||
@ -212,12 +212,12 @@ static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int f
|
||||
if (frame1 < 0) frame1 = 0;
|
||||
|
||||
// Get bone count (use minimum of all to be safe)
|
||||
unsigned int boneCount = model->skeleton.boneCount;
|
||||
int boneCount = model->skeleton.boneCount;
|
||||
if (anim0->boneCount < boneCount) boneCount = anim0->boneCount;
|
||||
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
||||
|
||||
// Blend each bone
|
||||
for (unsigned int boneIndex = 0; boneIndex < boneCount; boneIndex++)
|
||||
for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
|
||||
{
|
||||
// Determine blend factor for this bone
|
||||
float boneBlendFactor = blend;
|
||||
|
||||
@ -252,7 +252,7 @@ int main(void)
|
||||
|
||||
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize*2);
|
||||
GuiLabel((Rectangle){ 0, GetScreenHeight() - 100.0f, (float)GetScreenWidth(), 40 }, "PRESS SPACE to START BLENDING");
|
||||
GuiLabel((Rectangle){ 0, GetScreenHeight() - 100.0f, GetScreenWidth(), 40 }, "PRESS SPACE to START BLENDING");
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize);
|
||||
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ int main(void)
|
||||
if (collision.hit && (collision.distance < closestDistance))
|
||||
{
|
||||
closestDistance = collision.distance;
|
||||
closestVoxelPosition = (Vector3){ (float)x, (float)y, (float)z };
|
||||
closestVoxelPosition = (Vector3){ x, y, z };
|
||||
voxelFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ int main(void)
|
||||
int boneSocketIndex[BONE_SOCKETS] = { -1, -1, -1 };
|
||||
|
||||
// Search bones for sockets
|
||||
for (unsigned int i = 0; i < characterModel.skeleton.boneCount; i++)
|
||||
for (int i = 0; i < characterModel.skeleton.boneCount; i++)
|
||||
{
|
||||
if (TextIsEqual(characterModel.skeleton.bones[i].name, "socket_hat"))
|
||||
{
|
||||
|
||||
@ -249,7 +249,7 @@ int main(void)
|
||||
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
|
||||
|
||||
// UI elements
|
||||
if (GuiButton((Rectangle){ 10, screenHeight - 100.0f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel;
|
||||
if (GuiButton((Rectangle){ 10, screenHeight - 1000.f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel;
|
||||
|
||||
if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100.0f, 100, 60 }, "Clear Decals"))
|
||||
{
|
||||
@ -267,7 +267,6 @@ int main(void)
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModel(model);
|
||||
UnloadModel(placementCube);
|
||||
UnloadTexture(modelTexture);
|
||||
|
||||
// Unload decal models
|
||||
|
||||
@ -106,3 +106,4 @@ int main(void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -21,8 +21,6 @@
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h> // Required for: fmaxf(), fminf()
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -55,7 +53,6 @@ int main(void)
|
||||
// Animation playing variables
|
||||
unsigned int animIndex = 0; // Current animation playing
|
||||
float animCurrentFrame = 0.0f; // Current animation frame (supporting interpolated frames)
|
||||
float animSpeed = 1.0f; // How fast the animation plays
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
@ -67,23 +64,10 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
if (IsKeyPressed(KEY_RIGHT))
|
||||
{
|
||||
animIndex = (animIndex == animCount - 1)? 0 : animIndex + 1;
|
||||
animCurrentFrame = 0.0f;
|
||||
}
|
||||
if (IsKeyPressed(KEY_LEFT))
|
||||
{
|
||||
animIndex = (animIndex == 0)? animCount - 1 : animIndex - 1;
|
||||
animCurrentFrame = 0.0f;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_UP)) animSpeed = fminf(5.0f, animSpeed + 0.1f);
|
||||
if (IsKeyPressed(KEY_DOWN)) animSpeed = fmaxf(0.0f, animSpeed - 0.1f);
|
||||
|
||||
animCurrentFrame += animSpeed;
|
||||
UpdateModelAnimation(model, anims[animIndex], animCurrentFrame);
|
||||
if (animCurrentFrame >= anims[animIndex].keyframeCount) animCurrentFrame = 0;
|
||||
// Play animation when spacebar is held down
|
||||
animCurrentFrame += 1.0f;
|
||||
UpdateModelAnimation(model, anims[0], animCurrentFrame);
|
||||
if (animCurrentFrame >= anims[0].keyframeCount) animCurrentFrame = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -101,9 +85,6 @@ int main(void)
|
||||
EndMode3D();
|
||||
|
||||
DrawText(TextFormat("Current animation: %s", anims[animIndex].name), 10, 10, 20, MAROON);
|
||||
DrawText(TextFormat("Animation speed: %.2f", animSpeed), 10, 40, 20, MAROON);
|
||||
DrawText("Use left and right arrow keys to change current animation", 10, screenHeight - 34, 10, BLACK);
|
||||
DrawText("Use up and down arrow keys to change animation speed", 10, screenHeight - 20, 10, BLACK);
|
||||
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
|
||||
@ -119,7 +119,7 @@ static void DrawModelSkeleton(ModelSkeleton skeleton, ModelAnimPose pose, float
|
||||
{
|
||||
// Loop to (boneCount - 1) because the last one is a special "no bone" bone,
|
||||
// needed to workaround buggy models without a -1, a cube is always drawn at the origin
|
||||
for (unsigned int i = 0; i < skeleton.boneCount - 1; i++)
|
||||
for (int i = 0; i < skeleton.boneCount - 1; i++)
|
||||
{
|
||||
// Display the frame-pose skeleton
|
||||
DrawCube(pose[i].translation, scale*0.05f, scale*0.05f, scale*0.05f, color);
|
||||
|
||||
@ -185,9 +185,6 @@ int main(void)
|
||||
// Unload models data (GPU VRAM)
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
|
||||
|
||||
// Unload shader data
|
||||
UnloadShader(shader);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -1,323 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - mesh uv painting
|
||||
*
|
||||
* Example demonstrates painting directly onto a mesh's texture: a ray is cast from the
|
||||
* mouse into the scene, the hit triangle is found, and the hit point is converted into
|
||||
* UV space using barycentric interpolation so a brush stroke can be drawn on the texture
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by PanicTitan (@PanicTitan) 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) 2025 PanicTitan (@PanicTitan)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
|
||||
#include <math.h> // Required for: fabsf(), floorf()
|
||||
#include <stddef.h> // Required for: NULL
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global Definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define CANVAS_SIZE 512
|
||||
#define PALETTE_COUNT 8
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//--------------------------------------------------------------------------------------
|
||||
typedef enum { TOOL_PAINT = 0, TOOL_PICKER } ToolMode;
|
||||
typedef enum { SHAPE_SPHERE = 0, SHAPE_CUBE, SHAPE_CYLINDER, SHAPE_TORUS } ShapeType;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static void ChangeShape(Model *model, BoundingBox *bbox, ShapeType *currentShape, ShapeType newShape, Texture2D canvasTexture);
|
||||
static bool GetMeshHitUV(Ray ray, Model model, BoundingBox bbox, Vector2 *outUV);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh uv painting");
|
||||
|
||||
Camera3D camera = { 0 };
|
||||
camera.position = (Vector3){ 0.0f, 3.5f, 6.5f };
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
// CPU-side canvas plus the GPU texture it gets pushed to after every stroke
|
||||
Image canvasImage = GenImageColor(CANVAS_SIZE, CANVAS_SIZE, RAYWHITE);
|
||||
Texture2D canvasTexture = LoadTextureFromImage(canvasImage);
|
||||
SetTextureFilter(canvasTexture, TEXTURE_FILTER_BILINEAR);
|
||||
|
||||
Model model = { 0 };
|
||||
BoundingBox modelBBox = { 0 };
|
||||
ShapeType currentShape = SHAPE_SPHERE;
|
||||
ChangeShape(&model, &modelBBox, ¤tShape, SHAPE_SPHERE, canvasTexture);
|
||||
|
||||
ToolMode currentTool = TOOL_PAINT;
|
||||
Color activeColor = RED;
|
||||
int brushRadius = 12;
|
||||
Vector2 lastHitUV = { 0 };
|
||||
bool hasLastHit = false;
|
||||
|
||||
Color palette[PALETTE_COUNT] = { RED, ORANGE, GOLD, LIME, SKYBLUE, PURPLE, DARKGRAY, WHITE };
|
||||
Rectangle uiPanelRec = { 10.0f, 10.0f, 230.0f, 490.0f };
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
bool isMouseOverUI = CheckCollisionPointRec(mousePos, uiPanelRec);
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
|
||||
if (!isMouseOverUI && IsMouseButtonDown(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
Ray ray = GetScreenToWorldRay(mousePos, camera);
|
||||
Vector2 hitUV = { 0 };
|
||||
|
||||
if (GetMeshHitUV(ray, model, modelBBox, &hitUV))
|
||||
{
|
||||
int px = (int)(hitUV.x * CANVAS_SIZE);
|
||||
int py = (int)(hitUV.y * CANVAS_SIZE);
|
||||
|
||||
if (currentTool == TOOL_PAINT)
|
||||
{
|
||||
// Stroke from the last hit to this one, guarding against jumps across a UV seam
|
||||
if (hasLastHit && (fabsf(hitUV.x - lastHitUV.x) < 0.25f) && (fabsf(hitUV.y - lastHitUV.y) < 0.25f))
|
||||
{
|
||||
int lastPx = (int)(lastHitUV.x * CANVAS_SIZE);
|
||||
int lastPy = (int)(lastHitUV.y * CANVAS_SIZE);
|
||||
float dist = Vector2Distance((Vector2){ (float)lastPx, (float)lastPy }, (Vector2){ (float)px, (float)py });
|
||||
int steps = (int)(dist / 2.0f) + 1;
|
||||
|
||||
for (int i = 0; i <= steps; i++)
|
||||
{
|
||||
float t = (float)i / (float)steps;
|
||||
ImageDrawCircle(&canvasImage, (int)Lerp((float)lastPx, (float)px, t),
|
||||
(int)Lerp((float)lastPy, (float)py, t), brushRadius, activeColor);
|
||||
}
|
||||
}
|
||||
else ImageDrawCircle(&canvasImage, px, py, brushRadius, activeColor);
|
||||
|
||||
UpdateTexture(canvasTexture, canvasImage.data);
|
||||
lastHitUV = hitUV;
|
||||
hasLastHit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeColor = GetImageColor(canvasImage, px, py);
|
||||
currentTool = TOOL_PAINT;
|
||||
hasLastHit = false;
|
||||
}
|
||||
}
|
||||
else hasLastHit = false;
|
||||
}
|
||||
else hasLastHit = false;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground((Color){ 30, 32, 40, 255 });
|
||||
|
||||
BeginMode3D(camera);
|
||||
DrawModel(model, Vector3Zero(), 1.0f, WHITE);
|
||||
DrawGrid(10, 1.0f);
|
||||
EndMode3D();
|
||||
|
||||
// Side panel
|
||||
DrawRectangleRec(uiPanelRec, Fade(BLACK, 0.8f));
|
||||
DrawRectangleLinesEx(uiPanelRec, 2.0f, DARKGRAY);
|
||||
DrawText("MESH UV PAINTER", 25, 22, 20, GOLD);
|
||||
|
||||
// Tool selection toggles
|
||||
bool paintActive = (currentTool == TOOL_PAINT);
|
||||
bool pickerActive = (currentTool == TOOL_PICKER);
|
||||
if (GuiToggle((Rectangle){ 25, 55, 95, 32 }, "PAINT", &paintActive)) currentTool = TOOL_PAINT;
|
||||
if (GuiToggle((Rectangle){ 125, 55, 95, 32 }, "PICKER", &pickerActive)) currentTool = TOOL_PICKER;
|
||||
|
||||
// Shape selection toggles
|
||||
DrawText("Mesh Shape:", 25, 100, 10, LIGHTGRAY);
|
||||
bool sphereActive = (currentShape == SHAPE_SPHERE);
|
||||
bool cubeActive = (currentShape == SHAPE_CUBE);
|
||||
bool cylinderActive = (currentShape == SHAPE_CYLINDER);
|
||||
bool torusActive = (currentShape == SHAPE_TORUS);
|
||||
|
||||
if (GuiToggle((Rectangle){ 25, 120, 95, 28 }, "SPHERE", &sphereActive))
|
||||
ChangeShape(&model, &modelBBox, ¤tShape, SHAPE_SPHERE, canvasTexture);
|
||||
if (GuiToggle((Rectangle){ 125, 120, 95, 28 }, "CUBE", &cubeActive))
|
||||
ChangeShape(&model, &modelBBox, ¤tShape, SHAPE_CUBE, canvasTexture);
|
||||
if (GuiToggle((Rectangle){ 25, 153, 95, 28 }, "CYLINDER", &cylinderActive))
|
||||
ChangeShape(&model, &modelBBox, ¤tShape, SHAPE_CYLINDER, canvasTexture);
|
||||
if (GuiToggle((Rectangle){ 125, 153, 95, 28 }, "TORUS", &torusActive))
|
||||
ChangeShape(&model, &modelBBox, ¤tShape, SHAPE_TORUS, canvasTexture);
|
||||
|
||||
// Color display
|
||||
DrawText("Active Color:", 25, 195, 10, LIGHTGRAY);
|
||||
DrawRectangle(125, 193, 95, 20, activeColor);
|
||||
DrawRectangleLines(125, 193, 95, 20, WHITE);
|
||||
|
||||
// Color swatches
|
||||
DrawText("Palette Swatches:", 25, 225, 10, LIGHTGRAY);
|
||||
for (int i = 0; i < PALETTE_COUNT; i++)
|
||||
{
|
||||
Rectangle swatchRec = { 25.0f + (i%4)*48, 245.0f + (i/4)*45, 40.0f, 38.0f };
|
||||
DrawRectangleRec(swatchRec, palette[i]);
|
||||
DrawRectangleLinesEx(swatchRec, 1.0f, WHITE);
|
||||
if (CheckCollisionPointRec(mousePos, swatchRec) && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) activeColor = palette[i];
|
||||
}
|
||||
|
||||
// Brush size buttons
|
||||
DrawText(TextFormat("Brush Size: %dpx", brushRadius), 25, 345, 10, LIGHTGRAY);
|
||||
if (GuiButton((Rectangle){ 25, 365, 95, 30 }, "SIZE -") && (brushRadius > 2)) brushRadius -= 2;
|
||||
if (GuiButton((Rectangle){ 125, 365, 95, 30 }, "SIZE +") && (brushRadius < 64)) brushRadius += 2;
|
||||
|
||||
// Canvas action buttons
|
||||
if (GuiButton((Rectangle){ 25, 410, 95, 30 }, "CLEAR"))
|
||||
{
|
||||
ImageClearBackground(&canvasImage, RAYWHITE);
|
||||
UpdateTexture(canvasTexture, canvasImage.data);
|
||||
}
|
||||
if (GuiButton((Rectangle){ 125, 410, 95, 30 }, "FILL"))
|
||||
{
|
||||
ImageClearBackground(&canvasImage, activeColor);
|
||||
UpdateTexture(canvasTexture, canvasImage.data);
|
||||
}
|
||||
|
||||
DrawText("Left click: paint / pick color | Right drag: orbit camera", 260, screenHeight - 25, 10, RAYWHITE);
|
||||
DrawFPS(screenWidth - 90, 15);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModel(model);
|
||||
UnloadImage(canvasImage);
|
||||
UnloadTexture(canvasTexture);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Unloads the current model and builds a new primitive shape in its place, sharing the
|
||||
// same canvas texture, and recomputes the transformed bounding box used for ray testing
|
||||
static void ChangeShape(Model *model, BoundingBox *bbox, ShapeType *currentShape, ShapeType newShape, Texture2D canvasTexture)
|
||||
{
|
||||
UnloadModel(*model);
|
||||
|
||||
Mesh mesh = { 0 };
|
||||
|
||||
switch (newShape)
|
||||
{
|
||||
case SHAPE_SPHERE: mesh = GenMeshSphere(1.5f, 32, 32); break;
|
||||
case SHAPE_CUBE: mesh = GenMeshCube(2.2f, 2.2f, 2.2f); break;
|
||||
case SHAPE_CYLINDER: mesh = GenMeshCylinder(1.2f, 2.5f, 24); break;
|
||||
case SHAPE_TORUS: mesh = GenMeshTorus(0.6f, 1.6f, 24, 36); break;
|
||||
default: mesh = GenMeshSphere(1.5f, 32, 32); break;
|
||||
}
|
||||
|
||||
*model = LoadModelFromMesh(mesh);
|
||||
|
||||
// GenMeshCylinder builds upward from y = 0; shift it down to center on the origin
|
||||
if (newShape == SHAPE_CYLINDER) model->transform = MatrixTranslate(0.0f, -1.25f, 0.0f);
|
||||
|
||||
model->materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = canvasTexture;
|
||||
|
||||
BoundingBox box = GetMeshBoundingBox(model->meshes[0]);
|
||||
box.min = Vector3Transform(box.min, model->transform);
|
||||
box.max = Vector3Transform(box.max, model->transform);
|
||||
*bbox = box;
|
||||
|
||||
*currentShape = newShape;
|
||||
}
|
||||
|
||||
// Raycasts against the model's mesh triangles and returns the UV coordinate of the
|
||||
// closest hit, interpolated from the hit triangle's vertices with barycentric weights
|
||||
static bool GetMeshHitUV(Ray ray, Model model, BoundingBox bbox, Vector2 *outUV)
|
||||
{
|
||||
if (!GetRayCollisionBox(ray, bbox).hit) return false; // Fast reject
|
||||
|
||||
Mesh mesh = model.meshes[0];
|
||||
float closestDistance = 1e9f;
|
||||
bool found = false;
|
||||
Vector2 hitUV = { 0 };
|
||||
|
||||
for (int tri = 0; tri < mesh.triangleCount; tri++)
|
||||
{
|
||||
int i0, i1, i2;
|
||||
|
||||
if (mesh.indices != NULL)
|
||||
{
|
||||
i0 = mesh.indices[3*tri + 0];
|
||||
i1 = mesh.indices[3*tri + 1];
|
||||
i2 = mesh.indices[3*tri + 2];
|
||||
}
|
||||
else { i0 = 3*tri; i1 = 3*tri + 1; i2 = 3*tri + 2; }
|
||||
|
||||
Vector3 a = Vector3Transform((Vector3){ mesh.vertices[3*i0], mesh.vertices[3*i0 + 1], mesh.vertices[3*i0 + 2] }, model.transform);
|
||||
Vector3 b = Vector3Transform((Vector3){ mesh.vertices[3*i1], mesh.vertices[3*i1 + 1], mesh.vertices[3*i1 + 2] }, model.transform);
|
||||
Vector3 c = Vector3Transform((Vector3){ mesh.vertices[3*i2], mesh.vertices[3*i2 + 1], mesh.vertices[3*i2 + 2] }, model.transform);
|
||||
|
||||
RayCollision hit = GetRayCollisionTriangle(ray, a, b, c);
|
||||
|
||||
if (hit.hit && (hit.distance < closestDistance))
|
||||
{
|
||||
closestDistance = hit.distance;
|
||||
found = true;
|
||||
|
||||
Vector2 uvA = { mesh.texcoords[2*i0], mesh.texcoords[2*i0 + 1] };
|
||||
Vector2 uvB = { mesh.texcoords[2*i1], mesh.texcoords[2*i1 + 1] };
|
||||
Vector2 uvC = { mesh.texcoords[2*i2], mesh.texcoords[2*i2 + 1] };
|
||||
|
||||
Vector3 w = Vector3Barycenter(hit.point, a, b, c);
|
||||
|
||||
hitUV.x = w.x*uvA.x + w.y*uvB.x + w.z*uvC.x;
|
||||
hitUV.y = w.x*uvA.y + w.y*uvB.y + w.z*uvC.y;
|
||||
|
||||
// Wrap into [0, 1] in case of minor floating point drift at UV seams
|
||||
hitUV.x -= floorf(hitUV.x);
|
||||
hitUV.y -= floorf(hitUV.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (found && (outUV != NULL)) *outUV = hitUV;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 31 KiB |
@ -1,504 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - procedural decals
|
||||
*
|
||||
* Example demonstrates projecting decals onto a 3D mesh surface by transforming the
|
||||
* mesh's own triangles into the decal's local space and clipping them against a box,
|
||||
* using only procedurally generated geometry and textures (no external resource files)
|
||||
*
|
||||
* NOTE: This is the same clip-space decal projection idea used by models_decals.c
|
||||
* (in turn based on three.js' DecalGeometry), applied here to a generated mesh and
|
||||
* generated textures instead of a loaded model, so the example is fully self-contained
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by PanicTitan (@PanicTitan) 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) 2025 PanicTitan (@PanicTitan)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#include <stddef.h> // Required for: NULL
|
||||
#include <string.h> // Required for: memcpy()
|
||||
#include <math.h> // Required for: fabsf(), fminf()
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global Definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define MAX_DECALS 256
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Growable triangle-soup buffer used while building a clipped decal mesh
|
||||
typedef struct MeshBuilder {
|
||||
int vertexCount;
|
||||
int vertexCapacity;
|
||||
Vector3 *vertices;
|
||||
Vector2 *uvs;
|
||||
} MeshBuilder;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 v0, Vector3 v1, Vector3 v2);
|
||||
static void FreeMeshBuilder(MeshBuilder *mb);
|
||||
static Mesh BuildMesh(MeshBuilder *mb);
|
||||
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
|
||||
static Mesh GenMeshDecal(Model model, Matrix projection, float decalSize, float decalOffset);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - procedural decals");
|
||||
|
||||
Camera3D camera = { 0 };
|
||||
camera.position = (Vector3){ 0.0f, 2.5f, 5.0f };
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
// Target model: a procedurally generated knot with a checkerboard skin
|
||||
Model model = LoadModelFromMesh(GenMeshTorus(0.8f, 1.8f, 32, 64));
|
||||
|
||||
Image checkerImage = GenImageChecked(512, 512, 32, 32, LIGHTGRAY, GRAY);
|
||||
Texture2D modelTexture = LoadTextureFromImage(checkerImage);
|
||||
UnloadImage(checkerImage);
|
||||
SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR);
|
||||
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture;
|
||||
|
||||
BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]);
|
||||
camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f);
|
||||
|
||||
float modelSize = fminf(fminf(fabsf(modelBBox.max.x - modelBBox.min.x),
|
||||
fabsf(modelBBox.max.y - modelBBox.min.y)), fabsf(modelBBox.max.z - modelBBox.min.z));
|
||||
|
||||
float decalSize = modelSize*0.35f;
|
||||
float decalOffset = 0.01f;
|
||||
|
||||
// Translucent cube previewing where the next decal will land
|
||||
Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize));
|
||||
placementCube.materials[0].maps[0].color = LIME;
|
||||
|
||||
// Decal texture: a procedurally drawn target/bullseye, no image file needed
|
||||
Image decalImage = GenImageColor(128, 128, BLANK);
|
||||
ImageDrawCircle(&decalImage, 64, 64, 60, RED);
|
||||
ImageDrawCircle(&decalImage, 64, 64, 45, WHITE);
|
||||
ImageDrawCircle(&decalImage, 64, 64, 30, RED);
|
||||
ImageDrawCircle(&decalImage, 64, 64, 15, YELLOW);
|
||||
|
||||
Texture2D decalTexture = LoadTextureFromImage(decalImage);
|
||||
UnloadImage(decalImage);
|
||||
SetTextureFilter(decalTexture, TEXTURE_FILTER_BILINEAR);
|
||||
|
||||
Material decalMaterial = LoadMaterialDefault();
|
||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture;
|
||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
||||
|
||||
bool showModel = true;
|
||||
Model decals[MAX_DECALS] = { 0 };
|
||||
int decalCount = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
|
||||
// Cast a ray from the mouse and keep the closest point it hits on the model
|
||||
Ray ray = GetScreenToWorldRay(GetMousePosition(), camera);
|
||||
RayCollision collision = { 0 };
|
||||
|
||||
if (GetRayCollisionBox(ray, modelBBox).hit && (decalCount < MAX_DECALS))
|
||||
{
|
||||
for (int m = 0; m < model.meshCount; m++)
|
||||
{
|
||||
RayCollision meshHit = GetRayCollisionMesh(ray, model.meshes[m], model.transform);
|
||||
if (meshHit.hit && (!collision.hit || (meshHit.distance < collision.distance))) collision = meshHit;
|
||||
}
|
||||
}
|
||||
|
||||
// Project a new decal at the hit point, facing along the surface normal
|
||||
if (collision.hit && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (decalCount < MAX_DECALS))
|
||||
{
|
||||
Vector3 lookTarget = Vector3Add(collision.point, collision.normal);
|
||||
Matrix splat = MatrixLookAt(collision.point, lookTarget, (Vector3){ 0.0f, 1.0f, 0.0f });
|
||||
splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*(float)GetRandomValue(-180, 180)));
|
||||
|
||||
Mesh decalMesh = GenMeshDecal(model, splat, decalSize, decalOffset);
|
||||
|
||||
if (decalMesh.vertexCount > 0)
|
||||
{
|
||||
decals[decalCount] = LoadModelFromMesh(decalMesh);
|
||||
decals[decalCount].materials[0].maps[0] = decalMaterial.maps[0];
|
||||
decalCount++;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
if (showModel) DrawModel(model, Vector3Zero(), 1.0f, WHITE);
|
||||
|
||||
for (int i = 0; i < decalCount; i++) DrawModel(decals[i], Vector3Zero(), 1.0f, WHITE);
|
||||
|
||||
// Preview cube at the surface point currently under the mouse
|
||||
if (collision.hit)
|
||||
{
|
||||
Vector3 lookTarget = Vector3Add(collision.point, collision.normal);
|
||||
Matrix splat = MatrixLookAt(collision.point, lookTarget, (Vector3){ 0.0f, 1.0f, 0.0f });
|
||||
placementCube.transform = MatrixInvert(splat);
|
||||
DrawModel(placementCube, Vector3Zero(), 1.0f, Fade(WHITE, 0.5f));
|
||||
}
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Vertex/triangle counts: base model vs total once decal geometry is added
|
||||
int baseVertices = 0, baseTriangles = 0;
|
||||
for (int i = 0; i < model.meshCount; i++)
|
||||
{
|
||||
baseVertices += model.meshes[i].vertexCount;
|
||||
baseTriangles += model.meshes[i].triangleCount;
|
||||
}
|
||||
|
||||
int totalVertices = baseVertices, totalTriangles = baseTriangles;
|
||||
for (int i = 0; i < decalCount; i++)
|
||||
{
|
||||
totalVertices += decals[i].meshes[0].vertexCount;
|
||||
totalTriangles += decals[i].meshes[0].triangleCount;
|
||||
}
|
||||
|
||||
int statX = screenWidth - 280;
|
||||
DrawText("Vertices", statX + 90, 10, 10, LIME);
|
||||
DrawText("Triangles", statX + 180, 10, 10, LIME);
|
||||
DrawText("Base Model", statX, 25, 10, LIME);
|
||||
DrawText(TextFormat("%d", baseVertices), statX + 90, 25, 10, LIME);
|
||||
DrawText(TextFormat("%d", baseTriangles), statX + 180, 25, 10, LIME);
|
||||
DrawText("TOTAL", statX, 40, 10, LIME);
|
||||
DrawText(TextFormat("%d", totalVertices), statX + 90, 40, 10, LIME);
|
||||
DrawText(TextFormat("%d", totalTriangles), statX + 180, 40, 10, LIME);
|
||||
|
||||
if (GuiButton((Rectangle){ 10, screenHeight - 80.0f, 100, 40 }, showModel ? "Hide Model" : "Show Model"))
|
||||
showModel = !showModel;
|
||||
|
||||
if (GuiButton((Rectangle){ 120, screenHeight - 80.0f, 100, 40 }, "Clear Decals"))
|
||||
{
|
||||
for (int i = 0; i < decalCount; i++) UnloadModel(decals[i]);
|
||||
decalCount = 0;
|
||||
}
|
||||
|
||||
DrawText("Left click: place decal | Right drag: orbit camera", 10, screenHeight - 25, 10, DARKGRAY);
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < decalCount; i++) UnloadModel(decals[i]);
|
||||
|
||||
UnloadModel(placementCube);
|
||||
UnloadTexture(decalTexture);
|
||||
UnloadTexture(modelTexture);
|
||||
UnloadModel(model);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Appends a triangle to a growable mesh builder buffer, growing it in fixed-size chunks
|
||||
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 v0, Vector3 v1, Vector3 v2)
|
||||
{
|
||||
if (mb->vertexCapacity <= (mb->vertexCount + 3))
|
||||
{
|
||||
int newVertexCapacity = (1 + (mb->vertexCapacity/256))*256;
|
||||
Vector3 *newVertices = (Vector3 *)MemAlloc(newVertexCapacity*sizeof(Vector3));
|
||||
|
||||
if (mb->vertexCapacity > 0)
|
||||
{
|
||||
memcpy(newVertices, mb->vertices, mb->vertexCount*sizeof(Vector3));
|
||||
MemFree(mb->vertices);
|
||||
}
|
||||
|
||||
mb->vertices = newVertices;
|
||||
mb->vertexCapacity = newVertexCapacity;
|
||||
}
|
||||
|
||||
int index = mb->vertexCount;
|
||||
mb->vertexCount += 3;
|
||||
|
||||
mb->vertices[index + 0] = v0;
|
||||
mb->vertices[index + 1] = v1;
|
||||
mb->vertices[index + 2] = v2;
|
||||
}
|
||||
|
||||
// Frees a mesh builder's backing buffers
|
||||
static void FreeMeshBuilder(MeshBuilder *mb)
|
||||
{
|
||||
if (mb->vertices != NULL) MemFree(mb->vertices);
|
||||
if (mb->uvs != NULL) MemFree(mb->uvs);
|
||||
*mb = (MeshBuilder){ 0 };
|
||||
}
|
||||
|
||||
// Converts a mesh builder's triangle soup into a standard uploaded raylib Mesh
|
||||
static Mesh BuildMesh(MeshBuilder *mb)
|
||||
{
|
||||
Mesh outMesh = { 0 };
|
||||
|
||||
outMesh.vertexCount = mb->vertexCount;
|
||||
outMesh.triangleCount = mb->vertexCount/3;
|
||||
outMesh.vertices = (float *)MemAlloc(outMesh.vertexCount*3*sizeof(float));
|
||||
if (mb->uvs != NULL) outMesh.texcoords = (float *)MemAlloc(outMesh.vertexCount*2*sizeof(float));
|
||||
|
||||
for (int i = 0; i < mb->vertexCount; i++)
|
||||
{
|
||||
outMesh.vertices[3*i + 0] = mb->vertices[i].x;
|
||||
outMesh.vertices[3*i + 1] = mb->vertices[i].y;
|
||||
outMesh.vertices[3*i + 2] = mb->vertices[i].z;
|
||||
|
||||
if (mb->uvs != NULL)
|
||||
{
|
||||
outMesh.texcoords[2*i + 0] = mb->uvs[i].x;
|
||||
outMesh.texcoords[2*i + 1] = mb->uvs[i].y;
|
||||
}
|
||||
}
|
||||
|
||||
UploadMesh(&outMesh, false);
|
||||
|
||||
return outMesh;
|
||||
}
|
||||
|
||||
// Clips the segment [v0, v1] against the plane p.x = s, returning the intersection point
|
||||
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s)
|
||||
{
|
||||
float d0 = Vector3DotProduct(v0, p) - s;
|
||||
float d1 = Vector3DotProduct(v1, p) - s;
|
||||
float t = d0/(d0 - d1);
|
||||
|
||||
return Vector3Lerp(v0, v1, t);
|
||||
}
|
||||
|
||||
// Builds a decal mesh: the model's triangles are transformed into the decal's local space
|
||||
// (so the decal sits at the origin, facing +Z) and clipped against a decalSize-sided box,
|
||||
// following the same clip-space projection idea used by engines' decal systems (and by
|
||||
// three.js' DecalGeometry, which the technique is commonly traced back to). What's left
|
||||
// after clipping becomes the decal's own small mesh, UV-mapped from its local coordinates
|
||||
static Mesh GenMeshDecal(Model model, Matrix projection, float decalSize, float decalOffset)
|
||||
{
|
||||
Matrix invProj = MatrixInvert(projection);
|
||||
MeshBuilder meshBuilders[2] = { 0 };
|
||||
int mbIndex = 0;
|
||||
|
||||
// Gather triangles that land anywhere near the decal box; this is a loose, cheap
|
||||
// pre-filter meant to skip most of the model, the precise clip happens below
|
||||
for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++)
|
||||
{
|
||||
Mesh mesh = model.meshes[meshIndex];
|
||||
|
||||
for (int tri = 0; tri < mesh.triangleCount; tri++)
|
||||
{
|
||||
Vector3 vertices[3] = { 0 };
|
||||
|
||||
if (mesh.indices == NULL)
|
||||
{
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
vertices[v] = (Vector3){
|
||||
mesh.vertices[3*3*tri + 3*v + 0],
|
||||
mesh.vertices[3*3*tri + 3*v + 1],
|
||||
mesh.vertices[3*3*tri + 3*v + 2]
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int v = 0; v < 3; v++)
|
||||
{
|
||||
int idx = mesh.indices[3*tri + v];
|
||||
vertices[v] = (Vector3){
|
||||
mesh.vertices[3*idx + 0],
|
||||
mesh.vertices[3*idx + 1],
|
||||
mesh.vertices[3*idx + 2]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
int insideCount = 0;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Vector3 v = Vector3Transform(vertices[i], projection);
|
||||
if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++;
|
||||
vertices[i] = v;
|
||||
}
|
||||
|
||||
if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices[0], vertices[1], vertices[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// Clip the surviving triangles against each of the decal box's 6 faces in turn
|
||||
Vector3 planes[6] = {
|
||||
{ 1, 0, 0 }, { -1, 0, 0 },
|
||||
{ 0, 1, 0 }, { 0, -1, 0 },
|
||||
{ 0, 0, 1 }, { 0, 0, -1 }
|
||||
};
|
||||
|
||||
for (int face = 0; face < 6; face++)
|
||||
{
|
||||
mbIndex = 1 - mbIndex;
|
||||
|
||||
MeshBuilder *inMesh = &meshBuilders[1 - mbIndex];
|
||||
MeshBuilder *outMesh = &meshBuilders[mbIndex];
|
||||
|
||||
outMesh->vertexCount = 0;
|
||||
float s = 0.5f*decalSize;
|
||||
|
||||
for (int i = 0; i < inMesh->vertexCount; i += 3)
|
||||
{
|
||||
Vector3 nV1, nV2, nV3, nV4;
|
||||
|
||||
float d1 = Vector3DotProduct(inMesh->vertices[i + 0], planes[face]) - s;
|
||||
float d2 = Vector3DotProduct(inMesh->vertices[i + 1], planes[face]) - s;
|
||||
float d3 = Vector3DotProduct(inMesh->vertices[i + 2], planes[face]) - s;
|
||||
|
||||
int v1Out = (d1 > 0);
|
||||
int v2Out = (d2 > 0);
|
||||
int v3Out = (d3 > 0);
|
||||
int total = v1Out + v2Out + v3Out;
|
||||
|
||||
switch (total)
|
||||
{
|
||||
case 0:
|
||||
// Whole triangle is inside this face, keep it as-is
|
||||
AddTriangleToMeshBuilder(outMesh, inMesh->vertices[i], inMesh->vertices[i + 1], inMesh->vertices[i + 2]);
|
||||
break;
|
||||
case 1:
|
||||
// One corner is outside; clip it off, turning the triangle into a quad
|
||||
if (v1Out)
|
||||
{
|
||||
nV1 = inMesh->vertices[i + 1];
|
||||
nV2 = inMesh->vertices[i + 2];
|
||||
nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s);
|
||||
nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s);
|
||||
}
|
||||
|
||||
if (v2Out)
|
||||
{
|
||||
nV1 = inMesh->vertices[i];
|
||||
nV2 = inMesh->vertices[i + 2];
|
||||
nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s);
|
||||
nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s);
|
||||
|
||||
AddTriangleToMeshBuilder(outMesh, nV3, nV2, nV1);
|
||||
AddTriangleToMeshBuilder(outMesh, nV2, nV3, nV4);
|
||||
break;
|
||||
}
|
||||
|
||||
if (v3Out)
|
||||
{
|
||||
nV1 = inMesh->vertices[i];
|
||||
nV2 = inMesh->vertices[i + 1];
|
||||
nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s);
|
||||
nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s);
|
||||
}
|
||||
|
||||
AddTriangleToMeshBuilder(outMesh, nV1, nV2, nV3);
|
||||
AddTriangleToMeshBuilder(outMesh, nV4, nV3, nV2);
|
||||
break;
|
||||
case 2:
|
||||
// Two corners are outside; only the small corner near the surviving vertex remains
|
||||
if (!v1Out)
|
||||
{
|
||||
nV1 = inMesh->vertices[i];
|
||||
nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
||||
nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
||||
AddTriangleToMeshBuilder(outMesh, nV1, nV2, nV3);
|
||||
}
|
||||
|
||||
if (!v2Out)
|
||||
{
|
||||
nV1 = inMesh->vertices[i + 1];
|
||||
nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
||||
nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
||||
AddTriangleToMeshBuilder(outMesh, nV1, nV2, nV3);
|
||||
}
|
||||
|
||||
if (!v3Out)
|
||||
{
|
||||
nV1 = inMesh->vertices[i + 2];
|
||||
nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
||||
nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
||||
AddTriangleToMeshBuilder(outMesh, nV1, nV2, nV3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// All 3 corners are outside this face, the triangle is fully clipped away
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MeshBuilder *finalMesh = &meshBuilders[mbIndex];
|
||||
Mesh decalMesh = { 0 };
|
||||
|
||||
if (finalMesh->vertexCount > 0)
|
||||
{
|
||||
finalMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*finalMesh->vertexCount);
|
||||
|
||||
for (int i = 0; i < finalMesh->vertexCount; i++)
|
||||
{
|
||||
// Clipped coordinates run roughly (-decalSize/2 .. decalSize/2); remap to (0..1)
|
||||
finalMesh->uvs[i].x = (finalMesh->vertices[i].x/decalSize + 0.5f);
|
||||
finalMesh->uvs[i].y = (finalMesh->vertices[i].y/decalSize + 0.5f);
|
||||
|
||||
// Nudge slightly along the normal so the decal doesn't z-fight with the surface
|
||||
finalMesh->vertices[i].z -= decalOffset;
|
||||
finalMesh->vertices[i] = Vector3Transform(finalMesh->vertices[i], invProj);
|
||||
}
|
||||
|
||||
decalMesh = BuildMesh(finalMesh);
|
||||
}
|
||||
|
||||
FreeMeshBuilder(&meshBuilders[0]);
|
||||
FreeMeshBuilder(&meshBuilders[1]);
|
||||
|
||||
return decalMesh;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 48 KiB |
@ -180,8 +180,8 @@ int main(void)
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(skybox.materials[0].shader);
|
||||
UnloadTexture(skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture);
|
||||
|
||||
UnloadModel(skybox); // Unload skybox model
|
||||
UnloadShader(shdrCubemap);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -1,153 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [others] example - scissor shapes
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 6.0
|
||||
*
|
||||
* Example contributed by David Buzatto (@davidbuzatto) 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) 2026 David Buzatto (@davidbuzatto)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "rlgl.h"
|
||||
|
||||
#include <math.h> // Required for: sinf()
|
||||
|
||||
// BeginScissorMode() only clips to an axis-aligned rectangle, since it maps
|
||||
// directly to glScissor. Clipping to an arbitrary shape (the same idea as
|
||||
// Graphics2D.setClip(Shape) in Java2D) needs the stencil buffer instead:
|
||||
// the clip shape is rasterized into the stencil buffer first, then further
|
||||
// draws are only let through where the stencil was written.
|
||||
//
|
||||
// rlgl has no stencil wrapper (see raysan5/raylib discussion #2964), so this
|
||||
// example calls the handful of OpenGL 1.0 stencil functions directly - they
|
||||
// don't need glad/extension loading, same as glScissor doesn't.
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#if !defined(APIENTRY)
|
||||
#if defined(_WIN32)
|
||||
#define APIENTRY __stdcall
|
||||
#else
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(WINGDIAPI) && defined(_WIN32)
|
||||
#define WINGDIAPI __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// mask is a callback instead of a fixed shape, so the clip region can be any
|
||||
// combination of Draw* calls (circle, polygon, text, several shapes together)
|
||||
typedef void (*ScissorMaskDrawFunc)(void *userData);
|
||||
|
||||
static void BeginScissorModeShape(ScissorMaskDrawFunc mask, void *userData)
|
||||
{
|
||||
rlDrawRenderBatchActive(); // Flush before touching stencil state
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilMask(0xFF);
|
||||
|
||||
// Pass 1: rasterize the mask into the stencil buffer only, no color write
|
||||
rlColorMask(false, false, false, false);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
mask(userData);
|
||||
rlDrawRenderBatchActive(); // Flush the mask draw
|
||||
|
||||
// Pass 2: subsequent draws only survive where the stencil was written
|
||||
rlColorMask(true, true, true, true);
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
}
|
||||
|
||||
static void EndScissorModeShape(void)
|
||||
{
|
||||
rlDrawRenderBatchActive();
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
// Two example mask shapes, drawn in WHITE (the color is irrelevant here,
|
||||
// only the stencil write from pass 1 matters)
|
||||
typedef struct { Vector2 center; float radius; } CircleMask;
|
||||
static void DrawCircleMask(void *userData)
|
||||
{
|
||||
CircleMask *m = (CircleMask *)userData;
|
||||
DrawCircleV(m->center, m->radius, WHITE);
|
||||
}
|
||||
|
||||
typedef struct { Vector2 center; float radius; int sides; } PolyMask;
|
||||
static void DrawPolyMask(void *userData)
|
||||
{
|
||||
PolyMask *m = (PolyMask *)userData;
|
||||
DrawPoly(m->center, m->sides, m->radius, 0.0f, WHITE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [others] example - scissor shapes");
|
||||
|
||||
Vector2 circleCenter = { screenWidth/2.0f - 120, screenHeight/2.0f };
|
||||
Vector2 hexCenter = { screenWidth/2.0f + 120, screenHeight/2.0f };
|
||||
float maskRadius = 100.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
circleCenter.y = screenHeight/2.0f + sinf((float)GetTime())*40.0f;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Circle-shaped clip: the full-screen rectangle only shows inside the circle
|
||||
CircleMask circleMask = { circleCenter, maskRadius };
|
||||
BeginScissorModeShape(DrawCircleMask, &circleMask);
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, BLUE);
|
||||
EndScissorModeShape();
|
||||
|
||||
// Hexagon-shaped clip: same mechanism, a different mask shape
|
||||
PolyMask hexMask = { hexCenter, maskRadius, 6 };
|
||||
BeginScissorModeShape(DrawPolyMask, &hexMask);
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, ORANGE);
|
||||
EndScissorModeShape();
|
||||
|
||||
DrawText("BeginScissorMode() only clips to a rectangle (glScissor)", 10, 10, 10, DARKGRAY);
|
||||
DrawText("This clips to arbitrary shapes instead, using the stencil buffer", 10, 25, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 16 KiB |
@ -24,7 +24,7 @@
|
||||
*
|
||||
* APPLE COMPILATION:
|
||||
* gcc -o rlgl_standalone rlgl_standalone.c -I../../src -Iexternal/include -Lexternal/lib \
|
||||
* -lglfw3 -framework CoreVideo -framework OpenGL -framework IOKit -framework Cocoa -framework QuartzCore
|
||||
* -lglfw3 -framework CoreVideo -framework OpenGL -framework IOKit -framework Cocoa
|
||||
* -Wno-deprecated-declarations -std=c99 -DGRAPHICS_API_OPENGL_33
|
||||
*
|
||||
*
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input values from vertex shader
|
||||
varying vec3 fragPosition;
|
||||
varying vec3 fragNormal;
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec3 viewPos;
|
||||
uniform vec3 lightPositions[8];
|
||||
uniform vec3 lightColors[8];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = texture2D(texture0, fragTexCoord);
|
||||
vec3 norm = normalize(fragNormal);
|
||||
vec3 viewDir = normalize(viewPos - fragPosition);
|
||||
|
||||
vec3 ambient = 0.05*texColor.rgb;
|
||||
vec3 totalDiffuse = vec3(0.0);
|
||||
vec3 totalSpecular = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vec3 lightDir = normalize(lightPositions[i] - fragPosition);
|
||||
float dist = length(lightPositions[i] - fragPosition);
|
||||
float attenuation = 1.0/(1.0 + 0.8*dist + 0.4*dist*dist);
|
||||
|
||||
// Diffuse shading
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
totalDiffuse += diff*lightColors[i]*attenuation*1.2;
|
||||
|
||||
// Blinn-Phong specular
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(norm, halfwayDir), 0.0), 32.0);
|
||||
totalSpecular += spec*lightColors[i]*attenuation*0.8;
|
||||
}
|
||||
|
||||
vec3 result = ambient + (totalDiffuse*texColor.rgb) + totalSpecular;
|
||||
gl_FragColor = vec4(result, texColor.a);
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
#version 100
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
|
||||
// Output values to fragment shader
|
||||
varying vec3 fragPosition;
|
||||
varying vec3 fragNormal;
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
fragNormal = normalize(vec3(matModel*vec4(vertexNormal, 0.0)));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(texture0, fragTexCoord);
|
||||
|
||||
// High-pass threshold blur: only pixels brighter than 0.75 in any channel contribute
|
||||
vec4 bloom = vec4(0.0);
|
||||
vec2 texel = vec2(1.0/1280.0, 1.0/720.0)*2.5;
|
||||
|
||||
for (int x = -2; x <= 2; x++)
|
||||
{
|
||||
for (int y = -2; y <= 2; y++)
|
||||
{
|
||||
vec4 smp = texture2D(texture0, fragTexCoord + vec2(float(x), float(y))*texel);
|
||||
float brightness = max(smp.r, max(smp.g, smp.b));
|
||||
if (brightness > 0.75) bloom += smp;
|
||||
}
|
||||
}
|
||||
bloom /= 25.0;
|
||||
|
||||
// Combine original with the bloom glow, then Reinhard tone-map back to [0, 1]
|
||||
vec3 hdr = color.rgb + bloom.rgb*1.2;
|
||||
vec3 ldr = hdr/(hdr + vec3(1.0));
|
||||
|
||||
gl_FragColor = vec4(ldr, color.a);
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
#version 330
|
||||
|
||||
// Input values from vertex shader
|
||||
in vec3 fragPosition;
|
||||
in vec3 fragNormal;
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec3 viewPos;
|
||||
uniform vec3 lightPositions[8];
|
||||
uniform vec3 lightColors[8];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = texture(texture0, fragTexCoord);
|
||||
vec3 norm = normalize(fragNormal);
|
||||
vec3 viewDir = normalize(viewPos - fragPosition);
|
||||
|
||||
vec3 ambient = 0.05*texColor.rgb;
|
||||
vec3 totalDiffuse = vec3(0.0);
|
||||
vec3 totalSpecular = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
vec3 lightDir = normalize(lightPositions[i] - fragPosition);
|
||||
float dist = length(lightPositions[i] - fragPosition);
|
||||
float attenuation = 1.0/(1.0 + 0.8*dist + 0.4*dist*dist);
|
||||
|
||||
// Diffuse shading
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
totalDiffuse += diff*lightColors[i]*attenuation*1.2;
|
||||
|
||||
// Blinn-Phong specular
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
float spec = pow(max(dot(norm, halfwayDir), 0.0), 32.0);
|
||||
totalSpecular += spec*lightColors[i]*attenuation*0.8;
|
||||
}
|
||||
|
||||
vec3 result = ambient + (totalDiffuse*texColor.rgb) + totalSpecular;
|
||||
finalColor = vec4(result, texColor.a);
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
|
||||
// Output values to fragment shader
|
||||
out vec3 fragPosition;
|
||||
out vec3 fragNormal;
|
||||
out vec2 fragTexCoord;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
fragNormal = normalize(vec3(matModel*vec4(vertexNormal, 0.0)));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(texture0, fragTexCoord);
|
||||
|
||||
// High-pass threshold blur: only pixels brighter than 0.75 in any channel contribute
|
||||
vec4 bloom = vec4(0.0);
|
||||
vec2 texel = vec2(1.0/1280.0, 1.0/720.0)*2.5;
|
||||
|
||||
for (int x = -2; x <= 2; x++)
|
||||
{
|
||||
for (int y = -2; y <= 2; y++)
|
||||
{
|
||||
vec4 smp = texture(texture0, fragTexCoord + vec2(float(x), float(y))*texel);
|
||||
float brightness = max(smp.r, max(smp.g, smp.b));
|
||||
if (brightness > 0.75) bloom += smp;
|
||||
}
|
||||
}
|
||||
bloom /= 25.0;
|
||||
|
||||
// Combine original with the bloom glow, then Reinhard tone-map back to [0, 1]
|
||||
vec3 hdr = color.rgb + bloom.rgb*1.2;
|
||||
vec3 ldr = hdr/(hdr + vec3(1.0));
|
||||
|
||||
finalColor = vec4(ldr, color.a);
|
||||
}
|
||||
@ -9,8 +9,6 @@
|
||||
*
|
||||
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3)
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Gleb A (@ggrizzly) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
|
||||
@ -168,7 +168,6 @@ int main(void)
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadTexture(light); // Unload texture
|
||||
UnloadRenderTexture(lightmap); // Unload lightmap render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -1,185 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shaders] example - lights bloom
|
||||
*
|
||||
* Example demonstrates forward multi-point lighting (8 point lights, attenuation and
|
||||
* Blinn-Phong specular) combined with a threshold-based bloom pass and Reinhard tone
|
||||
* mapping, applied as a full-screen post-process pass
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example uses resources/shaders/glsl100 and resources/shaders/glsl330, shared with the
|
||||
* rest of the shaders examples
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by PanicTitan (@PanicTitan) 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) 2025 PanicTitan (@PanicTitan)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
#include "rlgl.h"
|
||||
|
||||
#include <math.h> // Required for: sinf(), cosf()
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global Definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - lights bloom");
|
||||
|
||||
Camera3D camera = { 0 };
|
||||
camera.position = (Vector3){ 0.0f, 5.0f, 9.0f };
|
||||
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||
|
||||
// Forward multi-light shader and bloom post-process shader, both loaded from the
|
||||
// resources folder shared with the rest of the shaders examples. If the GLSL version
|
||||
// guessed from the PLATFORM_DESKTOP build flag turns out to be wrong for whatever
|
||||
// raylib was built against, linking fails and silently falls back to the default
|
||||
// shader - so this retries once with the other version, and either way the result
|
||||
// is checked explicitly and reported on screen rather than staying silently wrong
|
||||
Shader lightShader = LoadShader(TextFormat("resources/shaders/glsl%i/lights_bloom.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/lights_bloom.fs", GLSL_VERSION));
|
||||
Shader bloomShader = LoadShader(0, TextFormat("resources/shaders/glsl%i/lights_bloom_post.fs", GLSL_VERSION));
|
||||
|
||||
// Load models from generated cube mesh and plane
|
||||
// NOTE: Meshes are automatically unloaded on UnloadModel()
|
||||
Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 2.0f, 2.0f));
|
||||
Model floor = LoadModelFromMesh(GenMeshPlane(14.0f, 14.0f, 1, 1));
|
||||
cube.materials[0].shader = lightShader;
|
||||
floor.materials[0].shader = lightShader;
|
||||
|
||||
int lightPosLoc = GetShaderLocation(lightShader, "lightPositions");
|
||||
int lightColLoc = GetShaderLocation(lightShader, "lightColors");
|
||||
int viewPosLoc = GetShaderLocation(lightShader, "viewPos");
|
||||
|
||||
Vector3 lightPositions[MAX_LIGHTS] = { 0 };
|
||||
Vector3 lightColors[MAX_LIGHTS] = {
|
||||
{ 1.0f, 0.2f, 0.2f }, // Red
|
||||
{ 0.2f, 1.0f, 0.3f }, // Green
|
||||
{ 0.2f, 0.5f, 1.0f }, // Blue
|
||||
{ 1.0f, 0.8f, 0.1f }, // Yellow
|
||||
{ 1.0f, 0.1f, 0.8f }, // Magenta
|
||||
{ 0.1f, 1.0f, 1.0f }, // Cyan
|
||||
{ 1.0f, 0.4f, 0.1f }, // Orange
|
||||
{ 0.7f, 0.2f, 1.0f }, // Purple
|
||||
};
|
||||
|
||||
SetShaderValueV(lightShader, lightColLoc, lightColors, SHADER_UNIFORM_VEC3, MAX_LIGHTS);
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
float time = (float)GetTime();
|
||||
|
||||
// Orbital path for each point light, its own radius/height offset by index
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
float angle = (i/(float)MAX_LIGHTS)*2.0f*PI + time*0.6f;
|
||||
float radius = 4.2f + sinf(time*1.2f + i)*0.4f;
|
||||
float height = 1.0f + sinf(time*1.8f + i)*0.6f;
|
||||
|
||||
lightPositions[i] = (Vector3){ sinf(angle)*radius, height, cosf(angle)*radius };
|
||||
}
|
||||
|
||||
SetShaderValueV(lightShader, lightPosLoc, lightPositions, SHADER_UNIFORM_VEC3, MAX_LIGHTS);
|
||||
SetShaderValue(lightShader, viewPosLoc, &camera.position, SHADER_UNIFORM_VEC3);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Render the lit scene to an offscreen texture
|
||||
BeginTextureMode(target);
|
||||
|
||||
ClearBackground((Color){ 12, 12, 18, 255 });
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawModel(cube, (Vector3){ 0.0f, 1.0f, 0.0f }, 1.0f, GRAY);
|
||||
DrawModel(floor, (Vector3){ 0.0f, 0.0f, 0.0f }, 1.0f, DARKGRAY);
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
// Glowing bulbs mark each light's position
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
Color bulbColor = (Color){
|
||||
(unsigned char)(lightColors[i].x*255),
|
||||
(unsigned char)(lightColors[i].y*255),
|
||||
(unsigned char)(lightColors[i].z*255),
|
||||
255 };
|
||||
|
||||
DrawSphere(lightPositions[i], 0.15f, bulbColor);
|
||||
}
|
||||
|
||||
EndMode3D();
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
// Present the offscreen texture through the bloom + tone mapping shader
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
Rectangle srcRec = { 0, 0, (float)target.texture.width, (float)-target.texture.height };
|
||||
|
||||
BeginShaderMode(bloomShader);
|
||||
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
||||
DrawTextureRec(target.texture, srcRec, (Vector2){ 0, 0 }, WHITE);
|
||||
EndShaderMode();
|
||||
|
||||
DrawText("BALANCED MULTI-LIGHT + REINHARD TONE MAPPED BLOOM", 20, 20, 20, GREEN);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModel(cube);
|
||||
UnloadModel(floor);
|
||||
UnloadShader(lightShader);
|
||||
UnloadShader(bloomShader);
|
||||
UnloadRenderTexture(target);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 203 KiB |
@ -139,9 +139,6 @@ int main(void)
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
RL_FREE(transforms); // Free transforms
|
||||
UnloadMaterial(matInstances); // Also unloads the instancing shader
|
||||
UnloadMaterial(matDefault); // Unload default material
|
||||
UnloadMesh(cube); // Unload cube mesh
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -91,8 +91,6 @@ int main(void)
|
||||
Image whiteImage = GenImageColor(GOL_WIDTH, GOL_WIDTH, WHITE);
|
||||
Texture whiteTex = LoadTextureFromImage(whiteImage);
|
||||
UnloadImage(whiteImage);
|
||||
|
||||
SetTargetFPS(0); // Set our game to run with an uncapped framerate
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
|
||||
@ -68,7 +68,7 @@ int main(void)
|
||||
SetShaderValue(shadowShader, lightDirLoc, &lightDir, SHADER_UNIFORM_VEC3);
|
||||
SetShaderValue(shadowShader, lightColLoc, &lightColorNormalized, SHADER_UNIFORM_VEC4);
|
||||
int ambientLoc = GetShaderLocation(shadowShader, "ambient");
|
||||
float ambient[4] = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
float ambient[4] = {0.1f, 0.1f, 0.1f, 1.0f};
|
||||
SetShaderValue(shadowShader, ambientLoc, ambient, SHADER_UNIFORM_VEC4);
|
||||
int lightVPLoc = GetShaderLocation(shadowShader, "lightVP");
|
||||
int shadowMapLoc = GetShaderLocation(shadowShader, "shadowMap");
|
||||
@ -81,7 +81,7 @@ int main(void)
|
||||
for (int i = 0; i < robot.materialCount; i++) robot.materials[i].shader = shadowShader;
|
||||
|
||||
int animCount = 0;
|
||||
ModelAnimation* anims = LoadModelAnimations("resources/models/robot.glb", &animCount);
|
||||
ModelAnimation *anims = LoadModelAnimations("resources/models/robot.glb", &animCount);
|
||||
|
||||
RenderTexture2D shadowMap = LoadShadowmapRenderTexture(SHADOWMAP_RESOLUTION, SHADOWMAP_RESOLUTION);
|
||||
|
||||
@ -111,11 +111,9 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
float deltaTime = GetFrameTime();
|
||||
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
// send the updated camera position to the shader so that it can calculate the correct lighting for the scene
|
||||
Vector3 cameraPos = camera.position;
|
||||
SetShaderValue(shadowShader, shadowShader.locs[SHADER_LOC_VECTOR_VIEW], &cameraPos, SHADER_UNIFORM_VEC3);
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
frameCounter++;
|
||||
frameCounter %= (anims[0].keyframeCount);
|
||||
@ -162,7 +160,6 @@ int main(void)
|
||||
EndMode3D();
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
lightViewProj = MatrixMultiply(lightView, lightProj);
|
||||
|
||||
// PASS 02: Draw the scene into main framebuffer, using the generated shadowmap
|
||||
@ -180,9 +177,6 @@ int main(void)
|
||||
DrawScene(cube, robot); // Draw the same exact things as we drew in the shadowmap!
|
||||
EndMode3D();
|
||||
|
||||
rlActiveTextureSlot(textureActiveSlot);
|
||||
rlDisableTexture();
|
||||
|
||||
DrawText("Use the arrow keys to rotate the light!", 10, 10, 30, RED);
|
||||
DrawText("Shadows in raylib using the shadowmapping algorithm!", screenWidth - 280, screenHeight - 20, 10, GRAY);
|
||||
|
||||
|
||||
@ -1,164 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - drag puzzle
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Gabriel Piangers (@gabriel-piangers) 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) 2026 Gabriel Piangers (@gabriel-piangers)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Vector2 center;
|
||||
float radius;
|
||||
} Circle;
|
||||
|
||||
typedef struct {
|
||||
Vector2 v1;
|
||||
Vector2 v2;
|
||||
Vector2 v3;
|
||||
} Triangle;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - drag puzzle");
|
||||
|
||||
// Rectangle
|
||||
Rectangle rec = { screenWidth/2 - 250, screenHeight/2 + 50, 100.0f, 100.0f };
|
||||
Rectangle recArea = { screenWidth/2 - 60, screenHeight/2 - 110, 110.0f, 110.0f };
|
||||
bool recPickedUp = false;
|
||||
|
||||
// Circle
|
||||
Circle circ = { screenWidth/2, screenHeight/2 + 100, 50.0f };
|
||||
Circle circArea = { screenWidth/2 - 195, screenHeight/2 - 55, 55.0f };
|
||||
bool circPickedUp = false;
|
||||
|
||||
// Triangle
|
||||
Triangle tri = { { 600, 282 }, { 550, 369 }, { 650, 369 } };
|
||||
Triangle triArea = { { 600, 115 }, { 540, 222 }, { 660, 222 } };
|
||||
bool triPickedUp = false;
|
||||
|
||||
Vector2 mouseOffset = { 0.0f, 0.0f }; // Stores the offset of the mouse relative to the object's pivot point
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
bool recPlaced = false;
|
||||
bool circPlaced = false;
|
||||
bool triPlaced = false;
|
||||
|
||||
// Detect object pickup input
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, rec))
|
||||
{
|
||||
recPickedUp = true;
|
||||
mouseOffset = (Vector2) { rec.x - mousePosition.x, rec.y - mousePosition.y };
|
||||
}
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointCircle(mousePosition, circ.center, circ.radius))
|
||||
{
|
||||
circPickedUp = true;
|
||||
mouseOffset = (Vector2) { circ.center.x - mousePosition.x, circ.center.y - mousePosition.y };
|
||||
}
|
||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointTriangle(mousePosition, tri.v1, tri.v2, tri.v3))
|
||||
{
|
||||
triPickedUp = true;
|
||||
mouseOffset = (Vector2) { tri.v1.x - mousePosition.x, tri.v1.y - mousePosition.y }; // Uses v1 as the pivot point
|
||||
}
|
||||
|
||||
// Detect object drop input
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && recPickedUp) recPickedUp = false;
|
||||
else if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && circPickedUp) circPickedUp = false;
|
||||
else if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && triPickedUp) triPickedUp = false;
|
||||
|
||||
// Rectangle update
|
||||
if (recPickedUp)
|
||||
{
|
||||
rec.x = mousePosition.x + mouseOffset.x;
|
||||
rec.y = mousePosition.y + mouseOffset.y;
|
||||
}
|
||||
Rectangle RecCol = GetCollisionRec(recArea, rec);
|
||||
if (RecCol.width == rec.width && RecCol.height == rec.height) recPlaced = true;
|
||||
|
||||
// Circle update
|
||||
if (circPickedUp)
|
||||
{
|
||||
circ.center.x = mousePosition.x + mouseOffset.x;
|
||||
circ.center.y = mousePosition.y + mouseOffset.y;
|
||||
}
|
||||
if (Vector2Distance(circ.center, circArea.center) < circArea.radius - circ.radius) circPlaced = true;
|
||||
|
||||
// Triangle update
|
||||
if (triPickedUp)
|
||||
{
|
||||
Vector2 v2Offset = { tri.v2.x - tri.v1.x, tri.v2.y - tri.v1.y };
|
||||
Vector2 v3Offset = { tri.v3.x - tri.v1.x, tri.v3.y - tri.v1.y };
|
||||
|
||||
tri.v1 = (Vector2) { mousePosition.x + mouseOffset.x, mousePosition.y + mouseOffset.y };
|
||||
tri.v2 = (Vector2) { tri.v1.x + v2Offset.x, tri.v1.y + v2Offset.y };
|
||||
tri.v3 = (Vector2) { tri.v1.x + v3Offset.x, tri.v1.y + v3Offset.y };
|
||||
}
|
||||
if (
|
||||
CheckCollisionPointTriangle(tri.v1, triArea.v1, triArea.v2, triArea.v3) &&
|
||||
CheckCollisionPointTriangle(tri.v2, triArea.v1, triArea.v2, triArea.v3) &&
|
||||
CheckCollisionPointTriangle(tri.v2, triArea.v1, triArea.v2, triArea.v3)
|
||||
) triPlaced = true;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangleLinesEx(recArea, 2.0f, recPlaced ? GREEN : RED);
|
||||
DrawCircleLinesEx(circArea.center, circArea.radius, 2.0f, circPlaced ? GREEN : RED);
|
||||
DrawTriangleLinesEx(triArea.v1, triArea.v2, triArea.v3, 2.0f, triPlaced ? GREEN : RED);
|
||||
|
||||
// Draws objects that are not picked up first
|
||||
if (!triPickedUp) DrawTriangle(tri.v1, tri.v2, tri.v3, VIOLET);
|
||||
if (!circPickedUp) DrawCircleV(circ.center, circ.radius, BLUE);
|
||||
if (!recPickedUp) DrawRectangleRec(rec, ORANGE);
|
||||
|
||||
// Draws the object that is being dragged on top of others
|
||||
if (triPickedUp) DrawTriangle(tri.v1, tri.v2, tri.v3, VIOLET);
|
||||
if (circPickedUp) DrawCircleV(circ.center, circ.radius, BLUE);
|
||||
if (recPickedUp) DrawRectangleRec(rec, ORANGE);
|
||||
|
||||
DrawText("Use mouse to drag and drop the objects into the right spot!", 10, 10, 20, GRAY);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 7.9 KiB |
@ -59,7 +59,7 @@ int main(void)
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ellipse collision");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - collision ellipses");
|
||||
SetTargetFPS(60);
|
||||
|
||||
Vector2 ellipseACenter = { (float)screenWidth/4, (float)screenHeight/2 };
|
||||
|
||||
@ -56,7 +56,7 @@ int main(void)
|
||||
Vector2 mousePos = { 0 };
|
||||
Vector2 prevMousePos = { 0 };
|
||||
Vector2 scaleVector = { 1.0f, -1.0f };
|
||||
Vector2 offset = { GetRenderWidth()/2.0f, GetRenderHeight()/2.0f };
|
||||
Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
|
||||
|
||||
Camera2D camera = { 0 };
|
||||
camera.target = (Vector2){ 0 };
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 6.0
|
||||
* Example originally created with raylib 5.6
|
||||
*
|
||||
* Example contributed by Balamurugan R (@Bala050814) and reviewed by Ramon Santamaria (@raysan5)
|
||||
* Example contributed by Balamurugan R (@Bala050814]) 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
|
||||
|
||||
@ -1,407 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - outlines testbed
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 6.1, last time updated with raylib 6.1
|
||||
*
|
||||
* Example contributed by Matthew Roush (@MatthewRoush) 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) 2026 Matthew Roush (@MatthewRoush)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define COLOR_FILLED DARKBLUE
|
||||
#define COLOR_OUTLINE YELLOW
|
||||
|
||||
#define SHAPE_SPACING 14.0f
|
||||
#define SHAPE_SIZE 46.0f
|
||||
#define BOX_SPACING 10.0f
|
||||
|
||||
#define MOUSE_CAMERA_ZOOM_SPEED 0.3f
|
||||
#define KEYBOARD_CAMERA_MOVE_SPEED 10.0f
|
||||
#define KEYBOARD_CAMERA_ZOOM_SPEED 0.1f
|
||||
|
||||
#define CAMERA_ZOOM_MIN 0.1f
|
||||
#define CAMERA_ZOOM_MAX 1000.0f
|
||||
|
||||
// The shapes are ordered according to their order in this enum, left to right
|
||||
enum {
|
||||
ORDER_RECTANGLE = 0,
|
||||
ORDER_RECTANGLE_ROUNDED,
|
||||
ORDER_CIRCLE,
|
||||
ORDER_ELLIPSE,
|
||||
ORDER_CIRCLE_SECTOR,
|
||||
ORDER_RING,
|
||||
ORDER_TRIANGLE,
|
||||
ORDER_POLYGON,
|
||||
COUNT_SHAPES
|
||||
};
|
||||
|
||||
// The line style groups are ordered according to their order in this enum, top to bottom
|
||||
enum {
|
||||
ORDER_LINES = 0,
|
||||
ORDER_LINES_EX_WORLD,
|
||||
ORDER_LINES_EX_SCREEN,
|
||||
};
|
||||
|
||||
#define BOX_WIDTH (SHAPE_SIZE*COUNT_SHAPES + SHAPE_SPACING*(COUNT_SHAPES - 1) + BOX_SPACING*2.0f)
|
||||
#define BOX_HEIGHT (SHAPE_SIZE + BOX_SPACING*2.0f)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - outlines testbed");
|
||||
|
||||
Camera2D camera = { .zoom = 1 };
|
||||
|
||||
// User configurable options while running the program.
|
||||
float lineOpacity = 130;
|
||||
float lineThickness = 4.0f;
|
||||
float rectangleRoundness = 0.4f;
|
||||
float rectangleSegments = 9;
|
||||
float ellipseRadiusY = 0.5f;
|
||||
float circleStartAngle = 20.0f;
|
||||
float circleEndAngle = 270.0f;
|
||||
float circleSegments = 36;
|
||||
float ringInnerRadiusScale = 0.3f;
|
||||
float polygonSides = 6;
|
||||
|
||||
bool disableMouseControl = false;
|
||||
|
||||
const Rectangle optionsBackground = { 510, 0, 290, 450 };
|
||||
|
||||
const Vector2 zoomPoint = {((float)screenWidth - optionsBackground.width)/2.0f, (float)screenHeight/2.0f};
|
||||
|
||||
GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(WHITE));
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
const Vector2 mousePosScreen = GetMousePosition();
|
||||
const Vector2 mouseWheelVec = GetMouseWheelMoveV();
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosScreen, optionsBackground)) disableMouseControl = true;
|
||||
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) disableMouseControl = false;
|
||||
|
||||
if (!disableMouseControl) {
|
||||
if (mouseWheelVec.y != 0.0f) {
|
||||
const Vector2 prevWorldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
|
||||
camera.zoom *= exp2f(MOUSE_CAMERA_ZOOM_SPEED*mouseWheelVec.y); // Constant zoom rate
|
||||
camera.zoom = Clamp(camera.zoom, CAMERA_ZOOM_MIN, CAMERA_ZOOM_MAX);
|
||||
|
||||
const Vector2 worldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
camera.target = Vector2Add(camera.target, Vector2Subtract(prevWorldZoomPoint, worldZoomPoint));
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
|
||||
const Vector2 mouseDelta = GetMouseDelta();
|
||||
camera.target.x -= mouseDelta.x/camera.zoom;
|
||||
camera.target.y -= mouseDelta.y/camera.zoom;
|
||||
|
||||
const int mouseMaxX = (int)optionsBackground.x;
|
||||
const int mouseMaxY = screenHeight;
|
||||
|
||||
int newX = (int)mousePosScreen.x;
|
||||
int newY = (int)mousePosScreen.y;
|
||||
|
||||
// In C, the '%' operator computes the remainder, we want the modulus
|
||||
newX = (newX%mouseMaxX + mouseMaxX)%mouseMaxX;
|
||||
newY = (newY%mouseMaxY + mouseMaxY)%mouseMaxY;
|
||||
|
||||
if ((newX != (int)mousePosScreen.x) || (newY != (int)mousePosScreen.y)) SetMousePosition(newX, newY);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_A)) camera.target.x -= KEYBOARD_CAMERA_MOVE_SPEED/camera.zoom;
|
||||
if (IsKeyDown(KEY_D)) camera.target.x += KEYBOARD_CAMERA_MOVE_SPEED/camera.zoom;
|
||||
if (IsKeyDown(KEY_W)) camera.target.y -= KEYBOARD_CAMERA_MOVE_SPEED/camera.zoom;
|
||||
if (IsKeyDown(KEY_S)) camera.target.y += KEYBOARD_CAMERA_MOVE_SPEED/camera.zoom;
|
||||
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
const Vector2 prevWorldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
|
||||
camera.zoom *= exp2f(KEYBOARD_CAMERA_ZOOM_SPEED);
|
||||
camera.zoom = Clamp(camera.zoom, CAMERA_ZOOM_MIN, CAMERA_ZOOM_MAX);
|
||||
|
||||
const Vector2 worldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
camera.target = Vector2Add(camera.target, Vector2Subtract(prevWorldZoomPoint, worldZoomPoint));
|
||||
}
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
const Vector2 prevWorldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
|
||||
camera.zoom *= exp2f(-KEYBOARD_CAMERA_ZOOM_SPEED);
|
||||
camera.zoom = Clamp(camera.zoom, CAMERA_ZOOM_MIN, CAMERA_ZOOM_MAX);
|
||||
|
||||
const Vector2 worldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
camera.target = Vector2Add(camera.target, Vector2Subtract(prevWorldZoomPoint, worldZoomPoint));
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_Z))
|
||||
{
|
||||
const Vector2 zoomPoint = {((float)screenWidth - optionsBackground.width)/2.0f, (float)screenHeight/2.0f};
|
||||
const Vector2 prevWorldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
const Vector2 worldZoomPoint = GetScreenToWorld2D(zoomPoint, camera);
|
||||
camera.target = Vector2Add(camera.target, Vector2Subtract(prevWorldZoomPoint, worldZoomPoint));
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_C)) camera.target = (Vector2){ 0 };
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground((Color){ 50, 50, 55, 255 });
|
||||
|
||||
Color colorOutline = COLOR_OUTLINE;
|
||||
colorOutline.a = (unsigned char)lineOpacity;
|
||||
|
||||
BeginMode2D(camera);
|
||||
|
||||
const float shapeOffset = BOX_SPACING*2.0f;
|
||||
const float shapePaddingX = SHAPE_SIZE + SHAPE_SPACING;
|
||||
const float shapePaddingY = SHAPE_SIZE + SHAPE_SPACING + BOX_SPACING*2.0f;
|
||||
|
||||
const float radiusX = SHAPE_SIZE/2.0f;
|
||||
const float radiusY = radiusX*ellipseRadiusY;
|
||||
|
||||
const float ringOuterRadius = SHAPE_SIZE/2.0f;
|
||||
const float ringInnerRadius = ringOuterRadius*ringInnerRadiusScale;
|
||||
|
||||
const Vector2 triangleVertex0Offset = { 0.0f, SHAPE_SIZE*0.8f };
|
||||
const Vector2 triangleVertex1Offset = { SHAPE_SIZE*0.6f, SHAPE_SIZE };
|
||||
const Vector2 triangleVertex2Offset = { SHAPE_SIZE, 0.0f };
|
||||
|
||||
// ----------------------------------------
|
||||
// Draw*Lines()
|
||||
float posY = shapeOffset + shapePaddingY*ORDER_LINES;
|
||||
|
||||
// Rectangle
|
||||
float posX = shapeOffset + shapePaddingX*ORDER_RECTANGLE;
|
||||
DrawRectangleRec((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, COLOR_FILLED);
|
||||
DrawRectangleLines(posX, posY, SHAPE_SIZE, SHAPE_SIZE, colorOutline);
|
||||
|
||||
// Rectangle Rounded
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RECTANGLE_ROUNDED;
|
||||
DrawRectangleRounded((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, rectangleRoundness, (int)rectangleSegments, COLOR_FILLED);
|
||||
DrawRectangleRoundedLines((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, rectangleRoundness, (int)rectangleSegments, colorOutline);
|
||||
|
||||
// Circle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_CIRCLE;
|
||||
DrawCircleV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, COLOR_FILLED);
|
||||
DrawCircleLinesV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, colorOutline);
|
||||
|
||||
// Ellipse
|
||||
posX = shapeOffset + shapePaddingX*ORDER_ELLIPSE;
|
||||
DrawEllipseV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, radiusY, COLOR_FILLED);
|
||||
DrawEllipseLinesV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, radiusY, colorOutline);
|
||||
|
||||
// Circle Sector
|
||||
posX = shapeOffset + shapePaddingX*ORDER_CIRCLE_SECTOR;
|
||||
DrawCircleSector((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, circleStartAngle, circleEndAngle, (int)circleSegments, COLOR_FILLED);
|
||||
DrawCircleSectorLines((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, circleStartAngle, circleEndAngle, (int)circleSegments, colorOutline);
|
||||
|
||||
// Ring
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RING;
|
||||
DrawRing((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, ringInnerRadius, ringOuterRadius, circleStartAngle, circleEndAngle, (int)circleSegments, COLOR_FILLED);
|
||||
DrawRingLines((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, ringInnerRadius, ringOuterRadius, circleStartAngle, circleEndAngle, (int)circleSegments, colorOutline);
|
||||
|
||||
// Triangle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_TRIANGLE;
|
||||
DrawTriangle((Vector2){ posX + triangleVertex0Offset.x, posY + triangleVertex0Offset.y },
|
||||
(Vector2){ posX + triangleVertex1Offset.x, posY + triangleVertex1Offset.y },
|
||||
(Vector2){ posX + triangleVertex2Offset.x, posY + triangleVertex2Offset.y },
|
||||
COLOR_FILLED);
|
||||
DrawTriangleLines((Vector2){ posX + triangleVertex0Offset.x, posY + triangleVertex0Offset.y },
|
||||
(Vector2){ posX + triangleVertex1Offset.x, posY + triangleVertex1Offset.y },
|
||||
(Vector2){ posX + triangleVertex2Offset.x, posY + triangleVertex2Offset.y },
|
||||
colorOutline);
|
||||
|
||||
// Polygon
|
||||
posX = shapeOffset + shapePaddingX*ORDER_POLYGON;
|
||||
DrawPoly((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, (int)polygonSides, radiusX, 0.0f, COLOR_FILLED);
|
||||
DrawPolyLines((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, (int)polygonSides, radiusX, 0.0f, colorOutline);
|
||||
|
||||
// Group the shapes
|
||||
GuiGroupBox((Rectangle){ shapeOffset - BOX_SPACING, posY - BOX_SPACING, BOX_WIDTH, BOX_HEIGHT }, "Draw*Lines()");
|
||||
// ----------------------------------------
|
||||
|
||||
// ----------------------------------------
|
||||
// Draw*LinesEx() with world space pixel thickness
|
||||
posY = shapeOffset + shapePaddingY*ORDER_LINES_EX_WORLD;
|
||||
|
||||
// Rectangle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RECTANGLE;
|
||||
DrawRectangleRec((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, COLOR_FILLED);
|
||||
DrawRectangleLinesEx((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, lineThickness, colorOutline);
|
||||
|
||||
// Rectangle Rounded
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RECTANGLE_ROUNDED;
|
||||
DrawRectangleRounded((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, rectangleRoundness, (int)rectangleSegments, COLOR_FILLED);
|
||||
DrawRectangleRoundedLinesEx((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, rectangleRoundness, (int)rectangleSegments, lineThickness, colorOutline);
|
||||
|
||||
// Circle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_CIRCLE;
|
||||
DrawCircleV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, COLOR_FILLED);
|
||||
DrawCircleLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, lineThickness, colorOutline);
|
||||
|
||||
// Ellipse
|
||||
posX = shapeOffset + shapePaddingX*ORDER_ELLIPSE;
|
||||
DrawEllipseV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, radiusY, COLOR_FILLED);
|
||||
DrawEllipseLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, radiusY, lineThickness, colorOutline);
|
||||
|
||||
// Circle Sector
|
||||
posX = shapeOffset + shapePaddingX*ORDER_CIRCLE_SECTOR;
|
||||
DrawCircleSector((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, circleStartAngle, circleEndAngle, (int)circleSegments, COLOR_FILLED);
|
||||
DrawCircleSectorLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, circleStartAngle, circleEndAngle, (int)circleSegments, lineThickness, colorOutline);
|
||||
|
||||
// Ring
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RING;
|
||||
DrawRing((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, ringInnerRadius, ringOuterRadius, circleStartAngle, circleEndAngle, (int)circleSegments, COLOR_FILLED);
|
||||
DrawRingLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, ringInnerRadius, ringOuterRadius, circleStartAngle, circleEndAngle, (int)circleSegments, lineThickness, colorOutline);
|
||||
|
||||
// Triangle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_TRIANGLE;
|
||||
DrawTriangle((Vector2){ posX + triangleVertex0Offset.x, posY + triangleVertex0Offset.y },
|
||||
(Vector2){ posX + triangleVertex1Offset.x, posY + triangleVertex1Offset.y },
|
||||
(Vector2){ posX + triangleVertex2Offset.x, posY + triangleVertex2Offset.y },
|
||||
COLOR_FILLED);
|
||||
DrawTriangleLinesEx((Vector2){ posX + triangleVertex0Offset.x, posY + triangleVertex0Offset.y },
|
||||
(Vector2){ posX + triangleVertex1Offset.x, posY + triangleVertex1Offset.y },
|
||||
(Vector2){ posX + triangleVertex2Offset.x, posY + triangleVertex2Offset.y },
|
||||
lineThickness, colorOutline);
|
||||
|
||||
// Polygon
|
||||
posX = shapeOffset + shapePaddingX*ORDER_POLYGON;
|
||||
DrawPoly((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, (int)polygonSides, radiusX, 0.0f, COLOR_FILLED);
|
||||
DrawPolyLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, (int)polygonSides, radiusX, 0.0f, lineThickness, colorOutline);
|
||||
|
||||
// Group the shapes
|
||||
GuiGroupBox((Rectangle){ shapeOffset - BOX_SPACING, posY - BOX_SPACING, BOX_WIDTH, BOX_HEIGHT }, "Draw*LinesEx() with *world space* pixel thickness");
|
||||
// ----------------------------------------
|
||||
|
||||
// ----------------------------------------
|
||||
// Draw*LinesEx() with screen space pixel thickness
|
||||
posY = shapeOffset + shapePaddingY*ORDER_LINES_EX_SCREEN;
|
||||
|
||||
float constantThickness = lineThickness/camera.zoom;
|
||||
|
||||
// Rectangle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RECTANGLE;
|
||||
DrawRectangleRec((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, COLOR_FILLED);
|
||||
DrawRectangleLinesEx((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, constantThickness, colorOutline);
|
||||
|
||||
// Rectangle Rounded
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RECTANGLE_ROUNDED;
|
||||
DrawRectangleRounded((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, rectangleRoundness, (int)rectangleSegments, COLOR_FILLED);
|
||||
DrawRectangleRoundedLinesEx((Rectangle){ posX, posY, SHAPE_SIZE, SHAPE_SIZE }, rectangleRoundness, (int)rectangleSegments, constantThickness, colorOutline);
|
||||
|
||||
// Circle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_CIRCLE;
|
||||
DrawCircleV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, COLOR_FILLED);
|
||||
DrawCircleLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, constantThickness, colorOutline);
|
||||
|
||||
// Ellipse
|
||||
posX = shapeOffset + shapePaddingX*ORDER_ELLIPSE;
|
||||
DrawEllipseV((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, radiusY, COLOR_FILLED);
|
||||
DrawEllipseLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, radiusY, constantThickness, colorOutline);
|
||||
|
||||
// Circle Sector
|
||||
posX = shapeOffset + shapePaddingX*ORDER_CIRCLE_SECTOR;
|
||||
DrawCircleSector((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, circleStartAngle, circleEndAngle, (int)circleSegments, COLOR_FILLED);
|
||||
DrawCircleSectorLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, radiusX, circleStartAngle, circleEndAngle, (int)circleSegments, constantThickness, colorOutline);
|
||||
|
||||
// Ring
|
||||
posX = shapeOffset + shapePaddingX*ORDER_RING;
|
||||
DrawRing((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, ringInnerRadius, ringOuterRadius, circleStartAngle, circleEndAngle, (int)circleSegments, COLOR_FILLED);
|
||||
DrawRingLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, ringInnerRadius, ringOuterRadius, circleStartAngle, circleEndAngle, (int)circleSegments, constantThickness, colorOutline);
|
||||
|
||||
// Triangle
|
||||
posX = shapeOffset + shapePaddingX*ORDER_TRIANGLE;
|
||||
DrawTriangle((Vector2){ posX + triangleVertex0Offset.x, posY + triangleVertex0Offset.y },
|
||||
(Vector2){ posX + triangleVertex1Offset.x, posY + triangleVertex1Offset.y },
|
||||
(Vector2){ posX + triangleVertex2Offset.x, posY + triangleVertex2Offset.y },
|
||||
COLOR_FILLED);
|
||||
DrawTriangleLinesEx((Vector2){ posX + triangleVertex0Offset.x, posY + triangleVertex0Offset.y },
|
||||
(Vector2){ posX + triangleVertex1Offset.x, posY + triangleVertex1Offset.y },
|
||||
(Vector2){ posX + triangleVertex2Offset.x, posY + triangleVertex2Offset.y },
|
||||
constantThickness, colorOutline);
|
||||
|
||||
// Polygon
|
||||
posX = shapeOffset + shapePaddingX*ORDER_POLYGON;
|
||||
DrawPoly((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, (int)polygonSides, radiusX, 0.0f, COLOR_FILLED);
|
||||
DrawPolyLinesEx((Vector2){ posX + SHAPE_SIZE/2.0f, posY + SHAPE_SIZE/2.0f }, (int)polygonSides, radiusX, 0.0f, constantThickness, colorOutline);
|
||||
|
||||
// Group the shapes
|
||||
GuiGroupBox((Rectangle){ shapeOffset - BOX_SPACING, posY - BOX_SPACING, BOX_WIDTH, BOX_HEIGHT }, "Draw*LinesEx() with *screen space* pixel thickness");
|
||||
// ----------------------------------------
|
||||
|
||||
EndMode2D();
|
||||
|
||||
DrawRectangleRec(optionsBackground, Fade(DARKGRAY, 0.75f));
|
||||
|
||||
DrawRectangleRec((Rectangle){ optionsBackground.x, 360, optionsBackground.width, 90 }, Fade(BLACK, 0.4f));
|
||||
DrawLineEx((Vector2){ optionsBackground.x, 360 }, (Vector2){ optionsBackground.x + optionsBackground.width, 360 }, 1.0f, BLACK);
|
||||
|
||||
DrawText("Move with the mouse or WASD keys", (int)optionsBackground.x + 10, 370, 10, ORANGE);
|
||||
DrawText("Zoom with the mouse or UP and DOWN keys", (int)optionsBackground.x + 10, 390, 10, ORANGE);
|
||||
DrawText("Press C to reset position", (int)optionsBackground.x + 10, 410, 10, ORANGE);
|
||||
DrawText("Press Z to reset zoom", (int)optionsBackground.x + 10, 430, 10, ORANGE);
|
||||
|
||||
DrawLineEx((Vector2){ optionsBackground.x, optionsBackground.y }, (Vector2){ optionsBackground.x, optionsBackground.y + optionsBackground.height }, 1.0f, BLACK);
|
||||
|
||||
GuiSliderBar((Rectangle){ 605, 10, 150, 25 }, "Line Opacity" , TextFormat("%d" , (int)lineOpacity) , &lineOpacity , 0 , 255);
|
||||
GuiSliderBar((Rectangle){ 605, 45, 150, 25 }, "Thickness" , TextFormat("%.2f", lineThickness) , &lineThickness , -20.0f , 40.0f);
|
||||
GuiSliderBar((Rectangle){ 605, 80, 150, 25 }, "Rect Roundness" , TextFormat("%.2f", rectangleRoundness) , &rectangleRoundness , -1.0f , 2.0f);
|
||||
GuiSliderBar((Rectangle){ 605, 115, 150, 25 }, "Rect Segments" , TextFormat("%d" , (int)rectangleSegments), &rectangleSegments , -1 , 100);
|
||||
GuiSliderBar((Rectangle){ 605, 150, 150, 25 }, "Ellipse Radius Y", TextFormat("%.2f", ellipseRadiusY) , &ellipseRadiusY , 0.0f , 1.25f);
|
||||
GuiSliderBar((Rectangle){ 605, 185, 150, 25 }, "Start Angle" , TextFormat("%.2f", circleStartAngle) , &circleStartAngle , -360.0f, 360.0f);
|
||||
GuiSliderBar((Rectangle){ 605, 220, 150, 25 }, "End Angle" , TextFormat("%.2f", circleEndAngle) , &circleEndAngle , -360.0f, 360.0f);
|
||||
GuiSliderBar((Rectangle){ 605, 255, 150, 25 }, "Circle Segments" , TextFormat("%d" , (int)circleSegments) , &circleSegments , -1 , 100);
|
||||
GuiSliderBar((Rectangle){ 605, 290, 150, 25 }, "Ring Radius" , TextFormat("%.2f", ringInnerRadiusScale) , &ringInnerRadiusScale, -1.0f , 2.0f);
|
||||
GuiSliderBar((Rectangle){ 605, 325, 150, 25 }, "Poly Sides" , TextFormat("%d" , (int)polygonSides) , &polygonSides , -1 , 100);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 24 KiB |
@ -1,78 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - outlines thickness
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 6.1, last time updated with raylib 6.1
|
||||
*
|
||||
* Example contributed by Matthew Roush (@MatthewRoush) 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) 2026 Matthew Roush (@MatthewRoush)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - outlines thickness");
|
||||
|
||||
float thick = 5.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update variables / Implement example logic at this point
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
GuiSliderBar((Rectangle){ 290, 50, 220, 24 }, "Thickness", TextFormat("%.2f", thick), &thick, -30.0f, 30.0f);
|
||||
|
||||
DrawRectangle(35, 180, 220, 220, LIGHTGRAY);
|
||||
DrawRectangleLinesEx((Rectangle){ 35, 180, 220, 220 }, thick, BLUE);
|
||||
DrawText("DrawRectangleLinesEx()", 35, 160, 10, BLACK);
|
||||
|
||||
DrawRectangleRounded((Rectangle){ 290, 180, 220, 220 }, 0.2f, 9, LIGHTGRAY);
|
||||
DrawRectangleRoundedLinesEx((Rectangle){ 290, 180, 220, 220 }, 0.2f, 9, thick, BLUE);
|
||||
DrawText("DrawRectangleRoundedLinesEx()", 290, 160, 10, BLACK);
|
||||
|
||||
DrawCircle(655, 290, 110, LIGHTGRAY);
|
||||
DrawCircleLinesEx((Vector2){ 655, 290 }, 110, thick, BLUE);
|
||||
DrawText("DrawCircleLinesEx()", 545, 160, 10, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 17 KiB |
@ -16,13 +16,12 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_PIE_SLICES 10 // Max pie slices
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -40,8 +39,12 @@ int main(void)
|
||||
int sliceCount = 7;
|
||||
float donutInnerRadius = 25.0f;
|
||||
float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
|
||||
char labels[MAX_PIE_SLICES][32] = { 0 };
|
||||
bool editingLabel[MAX_PIE_SLICES] = { 0 };
|
||||
|
||||
for (int i = 0; i < MAX_PIE_SLICES; i++)
|
||||
snprintf(labels[i], 32, "Slice %02i", i + 1);
|
||||
|
||||
bool showValues = true;
|
||||
bool showPercentages = false;
|
||||
bool showDonut = false;
|
||||
@ -56,7 +59,7 @@ int main(void)
|
||||
|
||||
// UI Panel top-left anchor
|
||||
const Vector2 panelPos = {
|
||||
(float)screenWidth - panelMargin - panelWidth,
|
||||
(float)screenWidth - panelMargin - panelWidth,
|
||||
(float)panelMargin
|
||||
};
|
||||
|
||||
@ -69,7 +72,7 @@ int main(void)
|
||||
|
||||
// Pie chart geometry
|
||||
const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
|
||||
const Vector2 center = { canvas.width/2.0f, canvas.height/2.0f };
|
||||
const Vector2 center = { canvas.width/2.0f, canvas.height/2.0f};
|
||||
const float radius = 205.0f;
|
||||
|
||||
// Total value for percentage calculations
|
||||
@ -90,7 +93,6 @@ int main(void)
|
||||
// Check for mouse hover over slices
|
||||
hoveredSlice = -1; // Reset hovered slice
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointRec(mousePos, canvas)) // Only check if mouse is inside the canvas
|
||||
{
|
||||
float dx = mousePos.x - center.x;
|
||||
@ -174,7 +176,7 @@ int main(void)
|
||||
|
||||
if (showDonut) GuiDisable();
|
||||
GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
|
||||
"Inner Radius", NULL, & donutInnerRadius, 5.0f, radius - 10.0f);
|
||||
"Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
|
||||
GuiEnable();
|
||||
|
||||
GuiLine((Rectangle){ panelPos.x + 10, (float)panelPos.y + 12 + 170, panelRect.width - 20, 1 }, NULL);
|
||||
@ -188,7 +190,8 @@ int main(void)
|
||||
};
|
||||
int contentHeight = sliceCount*35;
|
||||
|
||||
GuiScrollPanel(scrollPanelBounds, NULL, (Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
|
||||
GuiScrollPanel(scrollPanelBounds, NULL,
|
||||
(Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
|
||||
&scrollContentOffset, &view);
|
||||
|
||||
const float contentX = view.x + scrollContentOffset.x; // Left of content
|
||||
@ -205,8 +208,7 @@ int main(void)
|
||||
DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
|
||||
|
||||
// Label textbox
|
||||
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, TextFormat("Slice %02i", i + 1), 32, editingLabel[i]))
|
||||
editingLabel[i] = !editingLabel[i];
|
||||
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, labels[i], 32, editingLabel[i])) editingLabel[i] = !editingLabel[i];
|
||||
|
||||
GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
|
||||
}
|
||||
|
||||
@ -1,118 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - polygon lines
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 6.1, last time updated with raylib 6.1
|
||||
*
|
||||
* Example contributed by Matthew Roush (@MatthewRoush) 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) 2026 Matthew Roush (@MatthewRoush)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - polygon lines");
|
||||
|
||||
int thick = 2;
|
||||
float rotation = 0.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_UP)) thick = thick + 1;
|
||||
if (IsKeyPressed(KEY_DOWN)) thick = thick - 1;
|
||||
|
||||
thick = (thick < 1) ? 1 : (thick > 60) ? 60 : thick;
|
||||
|
||||
rotation += (360.0f/10.0f)*GetFrameTime();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText(TextFormat("thick = %d", thick), 10, 280, 20, LIME);
|
||||
|
||||
// The square and circle outlines in the top left should match
|
||||
// The fist pair of outlines are drawn using `DrawRectangleLinesEx()` and `DrawCircleLinesEx()`
|
||||
// The second pair are drawn using `DrawPolyLinesEx()` with parameters that should visually match the first pair
|
||||
|
||||
DrawText("These should look identical!", 10, 10, 20, MAROON);
|
||||
|
||||
// Outline pair 1
|
||||
DrawRectangle(10, 40, 50, 50, LIGHTGRAY);
|
||||
DrawRectangleLinesEx((Rectangle){ 10, 40, 50, 50 }, (float)thick, RED);
|
||||
|
||||
DrawCircle(95, 65, 25, LIGHTGRAY);
|
||||
DrawCircleLinesEx((Vector2){ 95, 65 }, 25, (float)thick, RED);
|
||||
|
||||
DrawText("DrawRectangleLinesEx() and DrawCircleLinesEx()", 130, 60, 10, BLACK);
|
||||
|
||||
// Outline pair 2
|
||||
DrawPoly((Vector2){ 35, 125 }, 4, 35.355f, 45, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 35, 125 }, 4, 35.355f, 45, (float)thick, RED);
|
||||
|
||||
DrawPoly((Vector2){ 95, 125 }, 36, 25, 0, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 95, 125 }, 36, 25, 0, (float)thick, RED);
|
||||
|
||||
DrawText("DrawPolyLinesEx()", 130, 120, 10, BLACK);
|
||||
|
||||
// Some other shapes, all of these outlines should have the same looking thickness
|
||||
DrawPoly((Vector2){ 290, 220 }, 3, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 290, 220 }, 3, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 430, 220 }, 4, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 430, 220 }, 4, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 570, 220 }, 5, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 570, 220 }, 5, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 710, 220 }, 6, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 710, 220 }, 6, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 290, 360 }, 7, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 290, 360 }, 7, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 430, 360 }, 8, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 430, 360 }, 8, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 570, 360 }, 9, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 570, 360 }, 9, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
DrawPoly((Vector2){ 710, 360 }, 10, 60, rotation, LIGHTGRAY);
|
||||
DrawPolyLinesEx((Vector2){ 710, 360 }, 10, 60, rotation, (float)thick, BLUE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 20 KiB |
@ -442,7 +442,6 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(alphaDiscard);
|
||||
UnloadFont(font);
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -135,7 +135,7 @@ int main(void)
|
||||
// Module Functions Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
// Remove codepoint duplicates if requested
|
||||
// WARNING: This process could be a bit slow if the text to process is very long
|
||||
// WARNING: This process could be a bit slow if there text to process is very long
|
||||
static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount)
|
||||
{
|
||||
int codepointsNoDupsCount = codepointCount;
|
||||
@ -149,7 +149,7 @@ static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *
|
||||
{
|
||||
if (codepointsNoDups[i] == codepointsNoDups[j])
|
||||
{
|
||||
for (int k = j; k < codepointsNoDupsCount - 1; k++) codepointsNoDups[k] = codepointsNoDups[k + 1];
|
||||
for (int k = j; k < codepointsNoDupsCount; k++) codepointsNoDups[k] = codepointsNoDups[k + 1];
|
||||
|
||||
codepointsNoDupsCount--;
|
||||
j--;
|
||||
|
||||
@ -31,7 +31,7 @@ int main(void)
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - font filters");
|
||||
|
||||
const char *msg = "Loaded Font";
|
||||
const char msg[50] = "Loaded Font";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ int main(void)
|
||||
|
||||
// Define characters to draw
|
||||
// NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally
|
||||
const char *msg = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm\nnopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒ\nÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö\n÷øùúûüýþÿ";
|
||||
const char msg[256] = "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ int main(void)
|
||||
|
||||
bool paused = false;
|
||||
|
||||
SetTargetFPS(0); // Set our game to run with an uncapped framerate
|
||||
//SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
|
||||
@ -82,8 +82,8 @@ int main(void)
|
||||
if (IsTextureValid(collection[i].texture))
|
||||
{
|
||||
DrawTexturePro(collection[i].texture,
|
||||
(Rectangle){0,0,(float)collection[i].texture.width, (float)collection[i].texture.height},
|
||||
(Rectangle){collection[i].position.x,collection[i].position.y, (float)collection[i].texture.width, (float)collection[i].texture.height},
|
||||
(Rectangle){0,0,collection[i].texture.width, collection[i].texture.height},
|
||||
(Rectangle){collection[i].position.x,collection[i].position.y,collection[i].texture.width, collection[i].texture.height},
|
||||
(Vector2){collection[i].texture.width*0.5f, collection[i].texture.height*0.5f},
|
||||
0.0f, WHITE);
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ int main(void)
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawRectangleLines((int)((subjectTarget.texture.width - captureSize)/2.0f), (int)((subjectTarget.texture.height - captureSize)/2.0f), (int)captureSize, (int)captureSize, GREEN);
|
||||
DrawRectangleLines((int)((subjectTarget.texture.width - captureSize)/2.0f), (int)((subjectTarget.texture.height - captureSize)/2.0f), captureSize, captureSize, GREEN);
|
||||
DrawText("Subject View", 10, subjectTarget.texture.height - 30, 20, BLACK);
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
@ -109,7 +109,7 @@ int main(void)
|
||||
else if (IsKeyPressed(KEY_UP))
|
||||
{
|
||||
currentProcess--;
|
||||
if (currentProcess < 0) currentProcess = (NUM_PROCESSES - 1);
|
||||
if (currentProcess < 0) currentProcess = 7;
|
||||
textureReload = true;
|
||||
}
|
||||
|
||||
|
||||
@ -44,10 +44,6 @@ int main(void)
|
||||
textures[1] = LoadTextureFromImage(image90);
|
||||
textures[2] = LoadTextureFromImage(imageNeg90);
|
||||
|
||||
UnloadImage(image45);
|
||||
UnloadImage(image90);
|
||||
UnloadImage(imageNeg90);
|
||||
|
||||
int currentTexture = 0;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
@ -29,14 +29,8 @@ int main(void)
|
||||
|
||||
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
||||
|
||||
// When no codepoints are provided, LoadFontEx() loads a default set of codepoints
|
||||
// This set includes '@', which "KAISG.ttf" doesn't have a glyph for, causing a warning to be logged
|
||||
// We avoid this by just excluding it from the list of codepoints we load
|
||||
int codepointCount = 0;
|
||||
int *codepoints = LoadCodepoints(" !\"#$%&'()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", &codepointCount);
|
||||
// TTF Font loading with custom generation parameters
|
||||
Font font = LoadFontEx("resources/KAISG.ttf", 64, codepoints, codepointCount);
|
||||
UnloadCodepoints(codepoints);
|
||||
Font font = LoadFontEx("resources/KAISG.ttf", 64, 0, 0);
|
||||
|
||||
// Draw over image using custom font
|
||||
ImageDrawTextEx(&parrots, font, "[Parrots font drawing]", (Vector2){ 20.0f, 20.0f }, (float)font.baseSize, 0.0f, RED);
|
||||
@ -75,21 +69,7 @@ int main(void)
|
||||
DrawTextEx(font, "[Parrots font drawing]", (Vector2){ position.x + 20,
|
||||
position.y + 20 + 280 }, (float)font.baseSize, 0.0f, WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make the font atlas texture fit the screen, so we can see the whole thing
|
||||
float scale = 1.0f;
|
||||
|
||||
float atlasRatio = (float)font.texture.width/(float)font.texture.height;
|
||||
float screenRatio = (float)screenWidth/(float)screenHeight;
|
||||
if (atlasRatio >= screenRatio) scale = (float)screenWidth/(float)font.texture.width;
|
||||
else scale = (float)screenHeight/(float)font.texture.height;
|
||||
|
||||
float width = (float)font.texture.width * scale;
|
||||
float height = (float)font.texture.height * scale;
|
||||
|
||||
DrawTextureEx(font.texture, (Vector2){ ((float)screenWidth - width)/2, ((float)screenHeight - height)/2 }, 0, scale, BLACK);
|
||||
}
|
||||
else DrawTexture(font.texture, screenWidth/2 - font.texture.width/2, 50, BLACK);
|
||||
|
||||
DrawText("PRESS SPACE to SHOW FONT ATLAS USED", 290, 420, 10, DARKGRAY);
|
||||
|
||||
|
||||
@ -16,9 +16,7 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "rlgl.h" // Required for: rlSetBlendFactorsSeparate()
|
||||
#include "raymath.h" // Required for: Vector2Multiply()
|
||||
#include "rlgl.h" // for rlSetBlendFactorsSeparate()
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
@ -47,7 +45,8 @@ int main(void)
|
||||
// Set magnifying glass zoom
|
||||
camera.zoom = 2;
|
||||
// Offset by half the size of the magnifying glass to counteract drawing the texture centered on the mouse position
|
||||
camera.offset = Vector2Multiply((Vector2){ 128, 128 }, GetWindowScaleDPI());
|
||||
camera.offset = (Vector2){128, 128};
|
||||
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 3.0, last time updated with raylib 6.0
|
||||
* Example originally created with raylib 3.0, last time updated with raylib 3.0
|
||||
*
|
||||
* Example contributed by Chris Dill (@MysteriousSpace) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
@ -114,7 +114,7 @@ int main(void)
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsGestureDetected(GESTURE_DRAG))
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || (GetGestureDetected() == GESTURE_DRAG))
|
||||
{
|
||||
// Paint circle into render texture
|
||||
// NOTE: To avoid discontinuous circles, we could store
|
||||
|
||||
@ -1,242 +0,0 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - portal window
|
||||
*
|
||||
* Example demonstrates rendering a second scene to a texture and projecting it onto a
|
||||
* quad to create the illusion of a portal window looking into another place. The second
|
||||
* scene is rendered with an off-axis ("oblique frustum") projection matched to the
|
||||
* viewer's actual position relative to the window, so the illusion holds up correctly
|
||||
* as the player moves and looks around, rather than only looking right from one spot
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by PanicTitan (@PanicTitan) 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) 2025 PanicTitan (@PanicTitan)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
#include "rlgl.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
// Begin portal mode 3D view
|
||||
static void BeginPortalMode3D(Vector3 eye, Vector3 bottomLeft, Vector3 bottomRight, Vector3 topLeft, float nearPlane, float farPlane);
|
||||
// End portal 3D mode and returns to default 2D orthographic mode
|
||||
static void EndPortalMode3D(void);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - portal window");
|
||||
|
||||
// Camera to navigate the "real world" (Dimension A)
|
||||
Camera3D camera = { 0 };
|
||||
camera.position = (Vector3){ 0.0f, 2.5f, 7.0f };
|
||||
camera.target = (Vector3){ 0.0f, 1.8f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
// The archway opening, in Dimension A world space (used both to draw the frame and
|
||||
// as the window rectangle the oblique projection is built from)
|
||||
Vector3 archBottomLeft = { -1.5f, 0.0f, 0.0f };
|
||||
Vector3 archBottomRight = { 1.5f, 0.0f, 0.0f };
|
||||
Vector3 archTopLeft = { -1.5f, 4.0f, 0.0f };
|
||||
|
||||
// The archway sits at portalA and looks out onto portalB, far away in world space.
|
||||
// Every frame, Dimension B gets rendered to a texture using the same relative eye
|
||||
// and window position, shifted by the offset between the two portals
|
||||
Vector3 portalA = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 portalB = { 0.0f, 0.0f, -60.0f };
|
||||
RenderTexture2D portalView = LoadRenderTexture(480, 640);
|
||||
|
||||
DisableCursor(); // Lock cursor for first-person free camera controls
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_FREE);
|
||||
float time = (float)GetTime();
|
||||
|
||||
// Eye and window corners, shifted into Dimension B so they match the player's
|
||||
// actual position and viewing angle relative to the archway
|
||||
Vector3 offset = Vector3Subtract(portalB, portalA);
|
||||
Vector3 eyeInB = Vector3Add(camera.position, offset);
|
||||
Vector3 blInB = Vector3Add(archBottomLeft, offset);
|
||||
Vector3 brInB = Vector3Add(archBottomRight, offset);
|
||||
Vector3 tlInB = Vector3Add(archTopLeft, offset);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Render Dimension B into an offscreen texture, using an oblique projection so
|
||||
// its perspective lines up with the archway exactly as the real camera sees it
|
||||
BeginTextureMode(portalView);
|
||||
|
||||
ClearBackground((Color){ 10, 5, 20, 255 });
|
||||
|
||||
BeginPortalMode3D(eyeInB, blInB, brInB, tlInB, 0.05f, 100.0f);
|
||||
|
||||
DrawGrid(30, 0.8f);
|
||||
|
||||
// Floating pulsing core sphere
|
||||
Vector3 corePos = Vector3Add(portalB, (Vector3){ 0.0f, 2.0f + sinf(time * 2.5f) * 0.4f, -4.0f });
|
||||
DrawSphere(corePos, 1.2f, PURPLE);
|
||||
DrawSphereWires(corePos, 1.25f, 16, 16, MAGENTA);
|
||||
|
||||
// Orbiting cubes
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float angle = time * 1.5f + i * (PI / 2.0f);
|
||||
Vector3 pos = Vector3Add(portalB, (Vector3){
|
||||
sinf(angle) * 2.5f,
|
||||
2.0f + cosf(time * 3.0f + i) * 0.5f,
|
||||
-4.0f + cosf(angle) * 2.5f });
|
||||
|
||||
DrawCube(pos, 0.5f, 0.5f, 0.5f, LIME);
|
||||
DrawCubeWires(pos, 0.52f, 0.52f, 0.52f, DARKGREEN);
|
||||
}
|
||||
|
||||
EndPortalMode3D();
|
||||
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawGrid(20, 1.0f);
|
||||
|
||||
// Side pillars
|
||||
DrawCube((Vector3){ -3.5f, 2.0f, 0.0f }, 0.8f, 4.0f, 0.8f, DARKGRAY);
|
||||
DrawCubeWires((Vector3){ -3.5f, 2.0f, 0.0f }, 0.8f, 4.0f, 0.8f, ORANGE);
|
||||
DrawCube((Vector3){ 3.5f, 2.0f, 0.0f }, 0.8f, 4.0f, 0.8f, DARKGRAY);
|
||||
DrawCubeWires((Vector3){ 3.5f, 2.0f, 0.0f }, 0.8f, 4.0f, 0.8f, ORANGE);
|
||||
|
||||
// Golden archway frame and solid base
|
||||
DrawCubeWires((Vector3){ 0.0f, 2.0f, 0.0f }, 3.2f, 4.2f, 0.2f, GOLD);
|
||||
DrawCube((Vector3){ 0.0f, 0.05f, 0.0f }, 3.4f, 0.1f, 0.6f, MAROON);
|
||||
|
||||
// Solid backing wall, only ever seen if looking at the archway from behind
|
||||
DrawCube((Vector3){ 0.0f, 2.0f, -0.05f }, 3.1f, 4.1f, 0.05f, MAROON);
|
||||
|
||||
// The portal opening itself: a plain quad textured with the Dimension B
|
||||
// render, filling the archway exactly, so nothing "leaks" outside its shape
|
||||
rlSetTexture(portalView.texture.id);
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(255, 255, 255, 255);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f);
|
||||
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(archBottomLeft.x, archBottomLeft.y, archBottomLeft.z);
|
||||
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(archBottomRight.x, archBottomRight.y, archBottomRight.z);
|
||||
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(archBottomRight.x, 4.0f, archBottomRight.z);
|
||||
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(archTopLeft.x, archTopLeft.y, archTopLeft.z);
|
||||
rlEnd();
|
||||
rlSetTexture(0);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// HUD overlay
|
||||
DrawRectangle(15, 15, 520, 100, Fade(BLACK, 0.75f));
|
||||
DrawRectangleLines(15, 15, 520, 100, GOLD);
|
||||
DrawText("PORTAL WINDOW", 28, 25, 20, GOLD);
|
||||
DrawText("Look through the golden arch into Dimension B", 28, 52, 20, RAYWHITE);
|
||||
DrawText("Controls: Mouse to look | WASD to move", 28, 80, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(portalView);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Starts a 3D mode using an off-axis ("oblique frustum") projection, built directly from
|
||||
// an eye point and 3 corners of a rectangular window, instead of a fovy centered straight
|
||||
// ahead of the camera. This is the standard technique for rendering a scene as seen through
|
||||
// a window that isn't necessarily faced head-on (also used for multi-monitor and VR
|
||||
// rendering) - the key difference from a normal Camera3D is that the frustum is allowed
|
||||
// to be asymmetric, so perspective lines through the window line up correctly from any
|
||||
// eye position, instead of behaving like a flat image pasted onto the window
|
||||
static void BeginPortalMode3D(Vector3 eye, Vector3 bottomLeft, Vector3 bottomRight, Vector3 topLeft, float nearPlane, float farPlane)
|
||||
{
|
||||
Vector3 right = Vector3Normalize(Vector3Subtract(bottomRight, bottomLeft));
|
||||
Vector3 up = Vector3Normalize(Vector3Subtract(topLeft, bottomLeft));
|
||||
Vector3 normal = Vector3Normalize(Vector3CrossProduct(right, up));
|
||||
|
||||
// Vectors from the eye to 3 corners of the window, used to project the window onto
|
||||
// the near plane and read off how far it extends left/right/bottom/top of the eye
|
||||
Vector3 toBL = Vector3Subtract(bottomLeft, eye);
|
||||
Vector3 toBR = Vector3Subtract(bottomRight, eye);
|
||||
Vector3 toTL = Vector3Subtract(topLeft, eye);
|
||||
|
||||
float dist = -Vector3DotProduct(toBL, normal);
|
||||
if (dist < 0.01f) dist = 0.01f; // Keep the eye from crossing the window plane
|
||||
|
||||
float scale = nearPlane/dist;
|
||||
|
||||
rlDrawRenderBatchActive();
|
||||
|
||||
rlMatrixMode(RL_PROJECTION);
|
||||
rlPushMatrix();
|
||||
rlSetMatrixProjection(MatrixFrustum(
|
||||
Vector3DotProduct(right, toBL)*scale, Vector3DotProduct(right, toBR)*scale,
|
||||
Vector3DotProduct(up, toBL)*scale, Vector3DotProduct(up, toTL)*scale,
|
||||
nearPlane, farPlane));
|
||||
|
||||
// View orientation is fixed to the window's own plane (looking straight through it
|
||||
// along its normal), NOT aimed at any target - that's what the asymmetric frustum
|
||||
// above is for, and is what lets the eye move off to one side without distorting
|
||||
rlMatrixMode(RL_MODELVIEW);
|
||||
rlLoadIdentity();
|
||||
rlMultMatrixf(MatrixToFloat(MatrixLookAt(eye, Vector3Subtract(eye, normal), up)));
|
||||
|
||||
rlEnableDepthTest();
|
||||
}
|
||||
|
||||
// End portal 3D mode and returns to default 2D orthographic mode
|
||||
// NOTE: Similar implementation to EndMode3D()
|
||||
static void EndPortalMode3D(void)
|
||||
{
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||
rlPopMatrix(); // Restore previous matrix (projection) from matrix stack
|
||||
|
||||
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
||||
rlLoadIdentity(); // Reset current matrix (modelview)
|
||||
|
||||
rlDisableDepthTest(); // Disable DEPTH_TEST for 2D
|
||||
}
|
||||
|
Before Width: | Height: | Size: 26 KiB |
401
projects/4coder/Makefile
Normal file
@ -0,0 +1,401 @@
|
||||
#**************************************************************************************************
|
||||
#
|
||||
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
|
||||
#
|
||||
# Copyright (c) 2013-2026 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 raylib variables
|
||||
PROJECT_NAME ?= game
|
||||
RAYLIB_VERSION ?= 4.2.0
|
||||
RAYLIB_PATH ?= ..\..
|
||||
|
||||
# Define default options
|
||||
|
||||
# One of PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# Locations of your newly installed library and associated headers. See ../src/Makefile
|
||||
# On Linux, if you have installed raylib but cannot compile the examples, check that
|
||||
# the *_INSTALL_PATH values here are the same as those in src/Makefile or point to known locations.
|
||||
# To enable system-wide compile-time and runtime linking to libraylib.so, run ../src/$ sudo make install RAYLIB_LIBTYPE_SHARED.
|
||||
# To enable compile-time linking to a special version of libraylib.so, change these variables here.
|
||||
# To enable runtime linking to a special version of libraylib.so, see EXAMPLE_RUNTIME_PATH below.
|
||||
# If there is a libraylib in both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH, at runtime,
|
||||
# the library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over the one at RAYLIB_INSTALL_PATH.
|
||||
# RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths.
|
||||
DESTDIR ?= /usr/local
|
||||
RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib
|
||||
# RAYLIB_H_INSTALL_PATH locates the installed raylib header and associated source files.
|
||||
RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include
|
||||
|
||||
# Library type used for raylib: 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
|
||||
# TODO: Review usage on Linux. Target version of choice. Switch on -lglfw or -lglfw3
|
||||
USE_EXTERNAL_GLFW ?= FALSE
|
||||
|
||||
# Use Wayland display server protocol on Linux desktop
|
||||
# by default it uses X11 windowing system
|
||||
USE_WAYLAND_DISPLAY ?= FALSE
|
||||
|
||||
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# 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 ($(PLATFORM),PLATFORM_RPI)
|
||||
UNAMEOS=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
endif
|
||||
endif
|
||||
|
||||
# RAYLIB_PATH adjustment for different platforms.
|
||||
# If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
|
||||
# Required for ldconfig or other tools that do not perform path expansion.
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
RAYLIB_PREFIX ?= ..
|
||||
RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
|
||||
endif
|
||||
endif
|
||||
# Default path for raylib on Raspberry Pi, if installed in different path, update it!
|
||||
# This is not currently used by src/Makefile. Not sure of its origin or usage. Refer to wiki.
|
||||
# TODO: update install: target in src/Makefile for RPI, consider relation to LINUX.
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
RAYLIB_PATH ?= /home/pi/raylib
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# 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.13.3_64bit
|
||||
NODE_PATH = $(EMSDK_PATH)/node/22.16.0_64bit/bin
|
||||
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:\raylib\MinGW\bin:$$(PATH)
|
||||
endif
|
||||
|
||||
# Define raylib release directory for compiled library.
|
||||
# RAYLIB_RELEASE_PATH points to provided binaries or your freshly built version
|
||||
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
|
||||
|
||||
# EXAMPLE_RUNTIME_PATH embeds a custom runtime location of libraylib.so or other desired libraries
|
||||
# into each example binary compiled with RAYLIB_LIBTYPE=SHARED. It defaults to RAYLIB_RELEASE_PATH
|
||||
# so that these examples link at runtime with your version of libraylib.so in ../release/libs/linux
|
||||
# without formal installation from ../src/Makefile. It aids portability and is useful if you have
|
||||
# multiple versions of raylib, have raylib installed to a non-standard location, or want to
|
||||
# bundle libraylib.so with your game. Change it to your liking.
|
||||
# NOTE: If, at runtime, there is a libraylib.so at both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH,
|
||||
# The library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over RAYLIB_INSTALL_PATH,
|
||||
# Implemented for LINUX below with CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
|
||||
# To see the result, run readelf -d core/core_basic_window; looking at the RPATH or RUNPATH attribute.
|
||||
# To see which libraries a built example is linking to, ldd core/core_basic_window;
|
||||
# Look for libraylib.so.1 => $(RAYLIB_INSTALL_PATH)/libraylib.so.1 or similar listing.
|
||||
EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH)
|
||||
|
||||
# Define default C compiler: gcc
|
||||
# NOTE: define g++ compiler if using C++
|
||||
CC = gcc
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
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 ($(PLATFORM),PLATFORM_RPI)
|
||||
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
|
||||
# Define RPI cross-compiler
|
||||
#CC = armv6j-hardfloat-linux-gnueabi-gcc
|
||||
CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
|
||||
endif
|
||||
endif
|
||||
ifeq ($(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: Mingw32-make
|
||||
MAKE = mingw32-make
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
MAKE = make
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
MAKE = make
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define compiler flags:
|
||||
# -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)
|
||||
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
|
||||
CFLAGS += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
|
||||
|
||||
ifeq ($(BUILD_MODE),DEBUG)
|
||||
CFLAGS += -g
|
||||
endif
|
||||
|
||||
# Additional flags for compiler (if desired)
|
||||
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# resource file contains windows executable icon and properties
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
CFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data -Wl,--subsystem,windows
|
||||
endif
|
||||
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,$(EXAMPLE_RUNTIME_PATH)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS += -std=gnu99
|
||||
endif
|
||||
ifeq ($(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)
|
||||
# -sMINIFY_HTML=0 # minify generated html from shell.html
|
||||
# --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
|
||||
# --shell-file shell.html # define a custom shell .html and output extension
|
||||
CFLAGS += -Os -sUSE_GLFW=3 -sTOTAL_MEMORY=16777216 --preload-file resources -sMINIFY_HTML=0
|
||||
ifeq ($(BUILD_MODE), DEBUG)
|
||||
CFLAGS += -sASSERTIONS=1 --profiling
|
||||
endif
|
||||
|
||||
# Define a custom shell .html and output extension
|
||||
CFLAGS += --shell-file $(RAYLIB_PATH)/src/shell.html
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# Define include paths for required headers
|
||||
# NOTE: Several external required libraries (stb and others)
|
||||
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
|
||||
|
||||
# Define additional directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# RPI required libraries
|
||||
INCLUDE_PATHS += -I/opt/vc/include
|
||||
INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux
|
||||
INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
# Consider -L$(RAYLIB_H_INSTALL_PATH)
|
||||
INCLUDE_PATHS += -I/usr/local/include
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# Reset everything.
|
||||
# Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
|
||||
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external
|
||||
endif
|
||||
endif
|
||||
|
||||
# Define library paths containing required libs.
|
||||
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
# Consider -L$(RAYLIB_INSTALL_PATH)
|
||||
LDFLAGS += -L. -Lsrc -L/usr/local/lib
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# Reset everything.
|
||||
# Precedence: immediately local, installed version, raysan5 provided libs
|
||||
LDFLAGS = -L. -L$(RAYLIB_INSTALL_PATH) -L$(RAYLIB_RELEASE_PATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LDFLAGS += -L/opt/vc/lib
|
||||
endif
|
||||
|
||||
# Define any libraries required on linking
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
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
|
||||
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 OpenAL -framework Cocoa
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),BSD)
|
||||
# Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling
|
||||
# NOTE: Required packages: mesa-libs
|
||||
LDLIBS = -lraylib -lGL -lpthread -lm
|
||||
|
||||
# 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 ($(PLATFORM),PLATFORM_RPI)
|
||||
# Libraries for Raspberry Pi compiling
|
||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||
LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# Libraries for web (HTML5) compiling
|
||||
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
|
||||
endif
|
||||
|
||||
# Define a recursive wildcard function
|
||||
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||
|
||||
# Define all source files required
|
||||
SRC_DIR = src
|
||||
OBJ_DIR = obj
|
||||
|
||||
# Define all object files from source files
|
||||
SRC = $(call rwildcard, *.c, *.h)
|
||||
#OBJS = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||
OBJS = main.c
|
||||
|
||||
# For Android platform we call a custom Makefile.Android
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
MAKEFILE_PARAMS = -f Makefile.Android
|
||||
export PROJECT_NAME
|
||||
export SRC_DIR
|
||||
else
|
||||
MAKEFILE_PARAMS = $(PROJECT_NAME)
|
||||
endif
|
||||
|
||||
# Default target entry
|
||||
# NOTE: We call this Makefile target or Makefile.Android target
|
||||
all:
|
||||
$(MAKE) $(MAKEFILE_PARAMS)
|
||||
|
||||
# Project target defined by PROJECT_NAME
|
||||
$(PROJECT_NAME): $(OBJS)
|
||||
$(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
# Compile source files
|
||||
# NOTE: This pattern will compile every module defined on $(OBJS)
|
||||
#%.o: %.c
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
||||
|
||||
# Clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
del *.o *.exe /s
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -fv
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -fv *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
300
projects/4coder/Makefile.Android
Normal file
@ -0,0 +1,300 @@
|
||||
#**************************************************************************************************
|
||||
#
|
||||
# raylib makefile for Android project (APK building)
|
||||
#
|
||||
# Copyright (c) 2017 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
|
||||
ANDROID_ARCH ?= ARM
|
||||
ANDROID_API_VERSION = 21
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
ANDROID_ARCH_NAME = armeabi-v7a
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
ANDROID_ARCH_NAME = arm64-v8a
|
||||
endif
|
||||
|
||||
# Required path variables
|
||||
# NOTE: JAVA_HOME must be set to JDK
|
||||
JAVA_HOME ?= C:/JavaJDK
|
||||
ANDROID_HOME = C:/android-sdk
|
||||
ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
|
||||
ANDROID_BUILD_TOOLS = $(ANDROID_HOME)/build-tools/28.0.1
|
||||
ANDROID_PLATFORM_TOOLS = $(ANDROID_HOME)/platform-tools
|
||||
|
||||
# Android project configuration variables
|
||||
PROJECT_NAME ?= raylib_game
|
||||
PROJECT_LIBRARY_NAME ?= main
|
||||
PROJECT_BUILD_PATH ?= android.$(PROJECT_NAME)
|
||||
PROJECT_RESOURCES_PATH ?= resources
|
||||
PROJECT_SOURCE_FILES ?= raylib_game.c
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
# NOTE: GCC is being deprecated in Android NDK r16
|
||||
ifeq ($(ANDROID_ARCH),ARM)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
|
||||
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-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 -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$(RAYLIB_PATH)/src/external/android/native_app_glue
|
||||
|
||||
# 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',
|
||||
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
|
||||
|
||||
# Create required temp directories for APK building
|
||||
create_temp_project_dirs:
|
||||
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)\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
|
||||
$(foreach dir, $(PROJECT_SOURCE_DIRS), $(call create_dir, $(dir)))
|
||||
|
||||
define create_dir
|
||||
if not exist $(PROJECT_BUILD_PATH)\obj\$(1) mkdir $(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 /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME)\libraylib.so
|
||||
endif
|
||||
ifeq ($(RAYLIB_LIBTYPE),STATIC)
|
||||
copy /Y $(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
|
||||
# TODO: Review xcopy usage, it can not be found in some systems!
|
||||
copy_project_resources:
|
||||
copy $(APP_ICON_LDPI) $(PROJECT_BUILD_PATH)\res\drawable-ldpi\icon.png /Y
|
||||
copy $(APP_ICON_MDPI) $(PROJECT_BUILD_PATH)\res\drawable-mdpi\icon.png /Y
|
||||
copy $(APP_ICON_HDPI) $(PROJECT_BUILD_PATH)\res\drawable-hdpi\icon.png /Y
|
||||
@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
|
||||
|
||||
# Generate NativeLoader.java to load required shared libraries
|
||||
# NOTE: Probably not the bet way to generate this file... but it works.
|
||||
generate_loader_script:
|
||||
@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
|
||||
|
||||
# Generate AndroidManifest.xml with all the required options
|
||||
# NOTE: Probably not the bet way to generate this file... but it works.
|
||||
generate_android_manifest:
|
||||
@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
|
||||
|
||||
# Generate storekey for APK signing: $(PROJECT_NAME).keystore
|
||||
# NOTE: Configure here your Distinguished Names (-dname) if required!
|
||||
generate_apk_keystore:
|
||||
if not exist $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore $(JAVA_HOME)/bin/keytool -genkeypair -validity 1000 -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
|
||||
|
||||
# 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 $(RAYLIB_PATH)/src/external/android/native_app_glue/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;$(PROJECT_BUILD_PATH)/obj -sourcepath $(PROJECT_BUILD_PATH)/src $(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 --abi $(ANDROID_ARCH_NAME) -rds $(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 -r $(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:
|
||||
del $(PROJECT_BUILD_PATH)\* /f /s /q
|
||||
rmdir $(PROJECT_BUILD_PATH) /s /q
|
||||
@echo Cleaning done
|
||||
40
projects/4coder/main.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <math.h>
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib");
|
||||
|
||||
Camera cam;
|
||||
cam.position = (Vector3){ 0.0f, 10.0f, 8.f };
|
||||
cam.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||
cam.up = (Vector3){ 0.0f, 1.f, 0.0f };
|
||||
cam.fovy = 60.0f;
|
||||
|
||||
Vector3 cubePos = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
SetTargetFPS(60);
|
||||
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
cam.position.x = sin(GetTime())*10.0f;
|
||||
cam.position.z = cos(GetTime())*10.0f;
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginMode3D(cam);
|
||||
DrawCube(cubePos, 2.f, 2.f, 2.f, RED);
|
||||
DrawCubeWires(cubePos, 2.f, 2.f, 2.f, MAROON);
|
||||
DrawGrid(10, 1.f);
|
||||
EndMode3D();
|
||||
DrawText("This is a raylib example", 10, 40, 20, DARKGRAY);
|
||||
DrawFPS(10, 10);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
CloseWindow();
|
||||
return 0;
|
||||
}
|
||||
54
projects/4coder/project.4coder
Normal file
@ -0,0 +1,54 @@
|
||||
version(1);
|
||||
|
||||
project_name = "raylib-example";
|
||||
|
||||
patterns = {
|
||||
"*.cpp",
|
||||
"*.c",
|
||||
"*.h",
|
||||
"*.bat",
|
||||
"*.sh",
|
||||
"*.4coder",
|
||||
"Makefile",
|
||||
};
|
||||
|
||||
blacklist_patterns = {
|
||||
".*",
|
||||
};
|
||||
|
||||
load_paths = {
|
||||
{ { {".", .relative = true, .recursive = true, } }, .os = "win" },
|
||||
{ { {".", .relative = true, .recursive = true, } }, .os = "linux" },
|
||||
{ { {".", .relative = true, .recursive = true, } }, .os = "mac" },
|
||||
};
|
||||
|
||||
command_list = {
|
||||
{ .name = "clean",
|
||||
.out = "*clean*", .footer_panel = true, .save_dirty_files = false, .cursor_at_end = true,
|
||||
.cmd = {
|
||||
{"mingw32-make clean", .os = "win"},
|
||||
{"make clean", .os = "linux"},
|
||||
{"make clean", .os = "mac"},
|
||||
},
|
||||
},
|
||||
{ .name = "build",
|
||||
.out = "*compile*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false,
|
||||
.cmd = {
|
||||
{"mingw32-make", .os = "win"},
|
||||
{"make", .os = "linux"},
|
||||
{"make", .os = "mac"},
|
||||
},
|
||||
},
|
||||
{ .name = "run",
|
||||
.out = "*run*", .footer_panel = true, .save_dirty_files = false, .cursor_at_end = true,
|
||||
.cmd = {
|
||||
{".\game.exe", .os = "win"},
|
||||
{"./game", .os = "linux"},
|
||||
{"./game", .os = "mac"},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
fkey_command[3] = "clean";
|
||||
fkey_command[4] = "build";
|
||||
fkey_command[5] = "run";
|
||||
@ -38,5 +38,4 @@ if (APPLE)
|
||||
target_link_libraries(${PROJECT_NAME} "-framework IOKit")
|
||||
target_link_libraries(${PROJECT_NAME} "-framework Cocoa")
|
||||
target_link_libraries(${PROJECT_NAME} "-framework OpenGL")
|
||||
target_link_libraries(${PROJECT_NAME} "-framework QuartzCore")
|
||||
endif()
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
<Add option="-framework IOKit" />
|
||||
<Add option="-framework CoreAudio" />
|
||||
<Add option="-framework CoreVideo" />
|
||||
<Add option="-framework QuartzCore" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Release (Mac)">
|
||||
@ -45,7 +44,6 @@
|
||||
<Add option="-framework IOKit" />
|
||||
<Add option="-framework CoreAudio" />
|
||||
<Add option="-framework CoreVideo" />
|
||||
<Add option="-framework QuartzCore" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Debug (Linux)">
|
||||
|
||||
@ -4,11 +4,12 @@ This folder contains raylib templates for some common IDEs.
|
||||
|
||||
IDE | Platform(s) | Source | Example(s)
|
||||
----| ------------| :-------: | :-----:
|
||||
[4coder](http://4coder.net/) | Windows | ❌ | ✔️
|
||||
[Builder](https://wiki.gnome.org/Apps/Builder) | Linux | ❌ | ✔️
|
||||
[CMake](https://cmake.org/) | Windows, Linux, macOS, Web | ✔️ | ✔️
|
||||
[CodeBlocks](http://www.codeblocks.org/) | Windows, Linux, macOS | ❌ | ✔️
|
||||
[Geany](https://www.geany.org/) | Windows, Linux | ✔️ | ✔️
|
||||
[Notepad++](https://notepad-plus-plus.org/) | Windows, Web | ✔️ | ✔️
|
||||
[Notepad++](https://notepad-plus-plus.org/) | Windows Web | ✔️ | ✔️
|
||||
[SublimeText](https://www.sublimetext.com/) | Windows, Linux, macOS | ✔️ | ✔️
|
||||
[VS2022](https://www.visualstudio.com) | Windows | ✔️ | ✔️
|
||||
[VSCode](https://code.visualstudio.com/) | Windows, Linux, macOS | ❌ | ✔️
|
||||
|
||||
75
projects/VS2019-Android/raylib_android.sln
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31702.278
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "raylib_android", "raylib_android", "{5C24BC76-8848-40EA-9BBB-A544648D8D5B}"
|
||||
EndProject
|
||||
Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "raylib_android.Packaging", "raylib_android\raylib_android.Packaging\raylib_android.Packaging.androidproj", "{B2231F0D-52DA-4C55-8998-5886F766553C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib_android.NativeActivity", "raylib_android\raylib_android.NativeActivity\raylib_android.NativeActivity.vcxproj", "{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.Build.0 = Debug|x64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.Build.0 = Debug|x86
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.Build.0 = Release|ARM
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.ActiveCfg = Release|x64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.Build.0 = Release|x64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.Deploy.0 = Release|x64
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.ActiveCfg = Release|x86
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.Build.0 = Release|x86
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.Deploy.0 = Release|x86
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x64.Build.0 = Debug|x64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x86.Build.0 = Debug|x86
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM.Build.0 = Release|ARM
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x64.ActiveCfg = Release|x64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x64.Build.0 = Release|x64
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x86.ActiveCfg = Release|x86
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{B2231F0D-52DA-4C55-8998-5886F766553C} = {5C24BC76-8848-40EA-9BBB-A544648D8D5B}
|
||||
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2} = {5C24BC76-8848-40EA-9BBB-A544648D8D5B}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B7ED0AA6-6B00-40AC-BF71-526D5BEEFC78}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||