Compare commits
372 commits
raylib/v0.
...
master
Author | SHA1 | Date | |
---|---|---|---|
1468af2636 | |||
d63f1b19df | |||
45473d7240 | |||
3df816e2bf | |||
d707d9e51c | |||
bc3da009ef | |||
|
eddd038123 | ||
|
6039070d78 | ||
|
9a87dd6d60 | ||
|
7e9246c069 | ||
|
5d704708c4 | ||
|
3327fcaf9f | ||
|
e08c4cd054 | ||
|
fca3bf26c5 | ||
|
1d42dc5846 | ||
|
0380afdf21 | ||
|
e6017e5fc4 | ||
|
5ca0e770e3 | ||
|
761bde1e61 | ||
|
a4292f0f04 | ||
|
ce20f0c639 | ||
|
b542022337 | ||
|
705f704ecf | ||
|
db8e47f0e5 | ||
|
3fd9012394 | ||
|
960a135c15 | ||
|
6dbba4f81a | ||
|
e31988d117 | ||
|
d58ffe1a3a | ||
|
ff0ecd0e76 | ||
|
8e035f761c | ||
|
453bad2769 | ||
|
2040136e38 | ||
|
edb2c107b3 | ||
|
078d0bec34 | ||
|
5dad257e8d | ||
|
8490a60f72 | ||
|
5868292fd5 | ||
|
7a899c5e3a | ||
|
c301540ef5 | ||
|
041142d30c | ||
|
46524a8c46 | ||
|
533c35110b | ||
|
dce94f509d | ||
|
98ce816ab8 | ||
|
a9ad86d501 | ||
|
659b0700ba | ||
|
3b89a24e68 | ||
|
28ef2a891c | ||
|
b6bb8ec528 | ||
|
ea071de5c2 | ||
|
5df9325f63 | ||
|
aef24a2104 | ||
|
c4ef7b53e9 | ||
|
b6d58c5ba6 | ||
|
db948137ee | ||
|
04c9cea61b | ||
|
8b5f8fe6bb | ||
|
a7ac43847a | ||
|
4c05c52a4b | ||
|
5d50abe7c6 | ||
|
5ed790526c | ||
|
c3489ebef8 | ||
|
4c9f2e5dd7 | ||
|
574299012d | ||
|
de01649968 | ||
|
e5537960f0 | ||
|
f10c42c14e | ||
|
5d9fdd5313 | ||
|
692079f471 | ||
|
d054bd9043 | ||
|
ffc0ab4fc6 | ||
|
9e7c7db0ec | ||
|
aee70123d7 | ||
|
ccc9ef8662 | ||
|
b922049f3b | ||
|
24323485a0 | ||
|
0c2506a3cd | ||
|
3282ea28f2 | ||
|
f3553fea29 | ||
|
b09e22b6ad | ||
|
493260d376 | ||
|
c9a7c5c130 | ||
|
22bfaf1652 | ||
|
47bd3b9420 | ||
|
1d2d8d9350 | ||
|
9d16da4548 | ||
|
090dbf62ef | ||
|
36259e95a7 | ||
|
8d97c05afb | ||
|
dbf9ed2bff | ||
|
d81d956c18 | ||
|
07d2a6efde | ||
|
19bdd59547 | ||
|
bf03596ee4 | ||
|
23f1ab19b7 | ||
|
4da4ec54eb | ||
|
77b59b8ebe | ||
|
873552f31a | ||
|
05860b8650 | ||
|
cb6615f05b | ||
|
24c48cde91 | ||
|
c364e5b3f5 | ||
|
1b93816b90 | ||
|
1ad4e58c4f | ||
|
0f95293831 | ||
|
ff18bb497b | ||
|
972563ca1f | ||
|
7275646a1d | ||
|
52954882a0 | ||
|
886e44de9c | ||
|
31abcc5ee4 | ||
|
13942ea31b | ||
|
76be48cc11 | ||
|
d7cae48c5a | ||
|
7faf6e22e7 | ||
|
15e71af9da | ||
|
11a0342061 | ||
|
a0882a5b81 | ||
|
2ad5a4babf | ||
|
724c790ff7 | ||
|
fc50e055c0 | ||
|
614ed9f942 | ||
|
e184faa15c | ||
|
c59907eea6 | ||
|
4738b1467e | ||
|
37fd299f2a | ||
|
466f3e0804 | ||
|
3af3eea92a | ||
|
69cf3d30a4 | ||
|
3e01b50698 | ||
|
f293ef1482 | ||
|
3b4a7104e2 | ||
|
b1792a31d9 | ||
|
c77be99ddc | ||
|
8d54e15dc2 | ||
|
bc9182ac34 | ||
|
af2e6d755e | ||
|
5b33862cc1 | ||
|
01864c04b8 | ||
|
b6c8a8e892 | ||
|
5eb8d9ded7 | ||
|
9782760778 | ||
|
f465c30447 | ||
|
acf83f1ff9 | ||
|
e9aa553ec6 | ||
|
0ce1777bf3 | ||
|
60446bce15 | ||
|
4983e462e3 | ||
|
bb09313fb5 | ||
|
441f7fa504 | ||
|
4b3433a06d | ||
|
de1c5d32ef | ||
|
0e82ab3a0d | ||
|
6de5b09c62 | ||
|
1073c97df9 | ||
|
cac9dee8dd | ||
|
3f8ab9718f | ||
|
7e465e47e2 | ||
|
9108b3b7b0 | ||
|
a1df2e388e | ||
|
5e9516b94f | ||
|
382cbda3de | ||
|
553871567e | ||
|
ac16a0b3b6 | ||
|
7a92d50d28 | ||
|
afc255d0ca | ||
|
52946ea71d | ||
|
e171bb3751 | ||
|
b7ac6957d3 | ||
|
5100377cde | ||
|
3158dca464 | ||
|
44e76696cc | ||
|
8c4ce9e206 | ||
|
549dbcf4d8 | ||
|
735af12e7f | ||
|
893dfa5f85 | ||
|
8ea76a8e09 | ||
|
ab0d3a3fb2 | ||
|
87d0d7185f | ||
|
c3e8a0f84a | ||
|
8d78eefeee | ||
|
8a6b23b2ed | ||
|
f8147233ca | ||
|
1f7ddfca09 | ||
|
bd66c8b623 | ||
|
6807b5cc47 | ||
|
f2ab1b0c35 | ||
|
20a76b285d | ||
|
d4e03b2d75 | ||
|
bb20d2da3e | ||
|
badf94c433 | ||
|
5c0fc5c528 | ||
|
5268babfe0 | ||
|
f9b5993843 | ||
|
da901b89c1 | ||
|
d6c07f1bbf | ||
|
b7833eeae8 | ||
|
ec8840cdae | ||
|
f84ecd5b63 | ||
|
0975c91121 | ||
|
077c9b9f63 | ||
|
eb60c30db1 | ||
|
220865147a | ||
|
e9d222595d | ||
|
1eacaf732c | ||
|
42a2d9159c | ||
|
8f5a54a530 | ||
|
3c0d4bcab6 | ||
|
535ef37449 | ||
|
5c8466e15f | ||
|
f1236640f9 | ||
|
cf5c9f8b9a | ||
|
274a0b5854 | ||
|
a9a0a28119 | ||
|
5bed8af6d4 | ||
|
81eae2921a | ||
|
0a5dd6e49b | ||
|
d7bd66f339 | ||
|
1ff1eefdf1 | ||
|
c2b8b9ee3a | ||
|
10a7b71ee0 | ||
|
4e4f18a37c | ||
|
afe70ad4c8 | ||
|
bf5ef18350 | ||
|
a33e6f490b | ||
|
5bf50a5c5b | ||
|
3039b26796 | ||
|
e43e388549 | ||
|
f4adffe016 | ||
|
54b89f5a68 | ||
|
c66f9e2942 | ||
|
c2c8150de9 | ||
|
6bc3d79c96 | ||
|
2053879bfb | ||
|
123ec7ae6b | ||
|
6c2499adff | ||
|
b4d0c52dc9 | ||
|
287f319ecb | ||
|
26bdccfe6f | ||
|
d374f90b45 | ||
|
a30a52c553 | ||
|
afca9ac4b5 | ||
|
8861ee437d | ||
|
64b25f38d9 | ||
|
62016ee92f | ||
|
ded439d849 | ||
|
49d7e62303 | ||
|
6c3961f894 | ||
|
f529bc2897 | ||
|
a997a44fb9 | ||
|
b7c9eeec1b | ||
|
d86638ae10 | ||
|
6c4349fd5c | ||
|
b1a49c28b6 | ||
|
4a4f1ef82e | ||
|
7430a4e0ef | ||
|
9fe64ac4bd | ||
|
86d08a7b86 | ||
|
426bcb3529 | ||
|
b56bfca1e8 | ||
|
5314a4a209 | ||
|
a158bd444e | ||
|
2915c1c582 | ||
|
7c239d1050 | ||
|
c212c33886 | ||
|
e824a9b663 | ||
|
4c0391d217 | ||
|
fa7e76c6a6 | ||
|
6fd7907d31 | ||
|
ac27873749 | ||
|
49242a59c9 | ||
|
da79f1d8b6 | ||
|
032352a5ba | ||
|
f68049cf26 | ||
|
4b3ab504c8 | ||
|
9b53342ac0 | ||
|
c09c9462b4 | ||
|
28722bb71f | ||
|
48e419d11f | ||
|
21775d2dee | ||
|
451c14ce9f | ||
|
64a63d5914 | ||
|
45279d6d25 | ||
|
6031600b18 | ||
|
7c4c1eed60 | ||
|
54ab84ca0c | ||
|
8a207901da | ||
|
6fa153fa53 | ||
|
7810550d63 | ||
|
266797ff04 | ||
|
74d0b22ad1 | ||
|
1a0035bfed | ||
|
a7fccc35a1 | ||
|
db4aa35b12 | ||
|
65392e706d | ||
|
95c2f5679a | ||
|
18035cee69 | ||
|
1868520849 | ||
|
2a66186c7d | ||
|
0b93fbfb6f | ||
|
19429cd00d | ||
|
1c9f65903d | ||
|
f406ea403b | ||
|
4523bcd71d | ||
|
278df68f40 | ||
|
8545220e18 | ||
|
9548fadb54 | ||
|
e717485867 | ||
|
39b56ef013 | ||
|
53f26d8a08 | ||
|
0b4f8b1cc0 | ||
|
c3665eb9ab | ||
|
00f5f785e6 | ||
|
069b39e688 | ||
|
468523fda4 | ||
|
3889376dd3 | ||
|
cc776abd3b | ||
|
caf96ad1c0 | ||
|
83c4beb421 | ||
|
5abcc8b79c | ||
|
8596a5db72 | ||
|
ce43cc1f10 | ||
|
9a0e172ca7 | ||
|
0b7f0bb776 | ||
|
a870a09894 | ||
|
a490f10c86 | ||
|
83d871a38f | ||
|
a5d0d71e50 | ||
|
0e9c277161 | ||
|
74450e33c1 | ||
|
3bc33ec8b7 | ||
|
2a08e83ca4 | ||
|
0b58bcbe1b | ||
|
5cc3226b35 | ||
|
5c31cc3104 | ||
|
49aab27a9b | ||
|
1f80c1e4c2 | ||
|
509ad7da5c | ||
|
483e94e4d9 | ||
|
b63c9257c5 | ||
|
b32467e017 | ||
|
381d68b2a3 | ||
|
17ce081452 | ||
|
48241c48d2 | ||
|
9553e2fd26 | ||
|
6f8b5ec246 | ||
|
6656db4829 | ||
|
5c6d0848aa | ||
|
1cee1d0534 | ||
|
656b4a4a8d | ||
|
6c3c38896e | ||
|
ac28b4b4f1 | ||
|
03d38e920f | ||
|
4bb9631420 | ||
|
cf285a20a1 | ||
|
69512c77d6 | ||
|
2bee857547 | ||
|
19dc46f86c | ||
|
48309e2407 | ||
|
7ef92adf08 | ||
|
34ea0cc7f5 | ||
|
a5d2760b16 | ||
|
f537de6ed9 | ||
|
f239fe2f67 | ||
|
a9659ea9c9 | ||
|
db3e0be60e | ||
|
43d0a14b92 | ||
|
2be56088ed | ||
|
fdd3d616da | ||
|
79286ba625 | ||
|
251b88bcb4 |
415 changed files with 57463 additions and 44535 deletions
121
.github/workflows/build.yml
vendored
121
.github/workflows/build.yml
vendored
|
@ -1,121 +0,0 @@
|
||||||
on: [push, pull_request]
|
|
||||||
name: Build
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.21.x]
|
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install package
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
- name: Build
|
|
||||||
run: go build ./...
|
|
||||||
working-directory: raylib
|
|
||||||
- name: Verify dependencies
|
|
||||||
run: go mod verify
|
|
||||||
working-directory: raylib
|
|
||||||
- name: Build
|
|
||||||
run: go build -v ./...
|
|
||||||
working-directory: raylib
|
|
||||||
- name: Run go vet
|
|
||||||
run: go vet ./...
|
|
||||||
working-directory: raylib
|
|
||||||
- name: Install staticcheck
|
|
||||||
run: go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
||||||
working-directory: raylib
|
|
||||||
- name: Run staticcheck
|
|
||||||
run: staticcheck ./...
|
|
||||||
working-directory: raylib
|
|
||||||
- name: Run tests
|
|
||||||
run: go test -race -vet=off ./...
|
|
||||||
working-directory: raylib
|
|
||||||
|
|
||||||
test-drm:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.21.x]
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install package
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y; sudo apt-get -y install libegl1-mesa-dev libdrm-dev
|
|
||||||
- name: Build
|
|
||||||
run: go build -tags drm
|
|
||||||
working-directory: raylib
|
|
||||||
|
|
||||||
test-sdl:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.21.x]
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install package
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y; sudo apt-get -y install libgl1-mesa-dev libsdl2-dev
|
|
||||||
- name: Build
|
|
||||||
run: go build -tags sdl
|
|
||||||
working-directory: raylib
|
|
||||||
|
|
||||||
test-wayland:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.21.x]
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install package
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y; sudo apt-get -y install libgl1-mesa-dev libwayland-dev libxkbcommon-dev
|
|
||||||
- name: Build
|
|
||||||
run: go build -tags wayland
|
|
||||||
working-directory: raylib
|
|
||||||
|
|
||||||
test-examples:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.21.x]
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install package
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y; sudo apt-get -y install libxi-dev libxinerama-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev
|
|
||||||
- name: Build
|
|
||||||
run: go build ./...
|
|
||||||
working-directory: examples
|
|
62
README.md
62
README.md
|
@ -1,12 +1,14 @@
|
||||||

|

|
||||||
## raylib-go
|
## raylib-go
|
||||||
[](https://github.com/gen2brain/raylib-go/actions)
|
[](https://git.terah.dev/UnrealXR/raylib-go/actions)
|
||||||
[](https://godoc.org/github.com/gen2brain/raylib-go/raylib)
|
[](https://godoc.org/git.terah.dev/UnrealXR/raylib-go/raylib)
|
||||||
[](https://goreportcard.com/report/github.com/gen2brain/raylib-go/raylib)
|
[](https://goreportcard.com/report/git.terah.dev/UnrealXR/raylib-go/raylib)
|
||||||
[](https://github.com/gen2brain/raylib-go/tree/master/examples)
|
[](https://git.terah.dev/UnrealXR/raylib-go/src/branch/master/examples)
|
||||||
|
|
||||||
Golang bindings for [raylib](http://www.raylib.com/), a simple and easy-to-use library to enjoy videogames programming.
|
Golang bindings for [raylib](http://www.raylib.com/), a simple and easy-to-use library to enjoy videogames programming.
|
||||||
|
|
||||||
|
This is a fork of [gen2brain's `raylib-go` bindings](https://github.com/gen2brain/raylib-go) to add [DRM leasing](https://wayland.app/protocols/drm-lease-v1) support.
|
||||||
|
|
||||||
raylib C source code is included and compiled together with bindings. Note that the first build can take a few minutes.
|
raylib C source code is included and compiled together with bindings. Note that the first build can take a few minutes.
|
||||||
|
|
||||||
It is also possible to use raylib-go without cgo (Windows only; see requirements below).
|
It is also possible to use raylib-go without cgo (Windows only; see requirements below).
|
||||||
|
@ -15,27 +17,15 @@ It is also possible to use raylib-go without cgo (Windows only; see requirements
|
||||||
|
|
||||||
##### Ubuntu
|
##### Ubuntu
|
||||||
|
|
||||||
###### X11
|
apt-get install libgl1-mesa-dev libxi-dev libxcursor-dev libxrandr-dev libxinerama-dev libwayland-dev libxkbcommon-dev
|
||||||
|
|
||||||
apt-get install libgl1-mesa-dev libxi-dev libxcursor-dev libxrandr-dev libxinerama-dev
|
|
||||||
|
|
||||||
###### Wayland
|
|
||||||
|
|
||||||
apt-get install libgl1-mesa-dev libwayland-dev libxkbcommon-dev
|
|
||||||
|
|
||||||
##### Fedora
|
##### Fedora
|
||||||
|
|
||||||
###### X11
|
dnf install mesa-libGL-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel wayland-devel libxkbcommon-devel
|
||||||
|
|
||||||
dnf install mesa-libGL-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel
|
|
||||||
|
|
||||||
###### Wayland
|
|
||||||
|
|
||||||
dnf install mesa-libGL-devel wayland-devel libxkbcommon-devel
|
|
||||||
|
|
||||||
##### macOS
|
##### macOS
|
||||||
|
|
||||||
On macOS you need Xcode or Command Line Tools for Xcode.
|
On macOS, you need Xcode or Command Line Tools for Xcode (if you have `brew` installed, you already have this).
|
||||||
|
|
||||||
##### Windows
|
##### Windows
|
||||||
|
|
||||||
|
@ -51,40 +41,48 @@ To remove console window, build with `-ldflags "-H=windowsgui"`.
|
||||||
Download the raylib.dll from the assets on the [releases page](https://github.com/raysan5/raylib/releases). It is contained in the `raylib-*_win64_msvc*.zip`.
|
Download the raylib.dll from the assets on the [releases page](https://github.com/raysan5/raylib/releases). It is contained in the `raylib-*_win64_msvc*.zip`.
|
||||||
Put the raylib.dll into the root folder of your project or copy it into `C:\Windows\System32` for a system-wide installation.
|
Put the raylib.dll into the root folder of your project or copy it into `C:\Windows\System32` for a system-wide installation.
|
||||||
|
|
||||||
As of November 15, 2023, raylib 5.0 is the required version.
|
It is also possible to build the DLL yourself. You can find more info at [raylib's wiki](https://github.com/raysan5/raylib/wiki/Working-on-Windows).
|
||||||
|
|
||||||
It is also possible build the dll yourself. You can find more infos at [raylib's wiki](https://github.com/raysan5/raylib/wiki/Working-on-Windows).
|
|
||||||
|
|
||||||
##### Android
|
##### Android
|
||||||
|
|
||||||
[Android example](https://github.com/gen2brain/raylib-go/tree/master/examples/others/android/example).
|
[Android example](https://git.terah.dev/UnrealXR/raylib-go/tree/master/examples/others/android/example).
|
||||||
|
|
||||||
|
##### Wasm
|
||||||
|
|
||||||
|
For web bindings, refer to [Raylib-Go-Wasm](https://github.com/BrownNPC/Raylib-Go-Wasm); it should be largely compatible with this repository.
|
||||||
|
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
go get -v -u github.com/gen2brain/raylib-go/raylib
|
go get -v -u git.terah.dev/UnrealXR/raylib-go/raylib
|
||||||
|
|
||||||
### Build tags
|
### Build tags
|
||||||
|
|
||||||
* `drm` - build for Linux native DRM mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM)
|
* `drm` - build for Linux native [DRM](https://en.wikipedia.org/wiki/Direct_Rendering_Manager) mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM)
|
||||||
* `sdl` - build for SDL backend instead of internal GLFW (PLATFORM_DESKTOP_SDL)
|
* `drm_disable_input` - disables keyboard input capabilities for the DRM backend. Requires the `drm` build tag as a prerequisite
|
||||||
* `wayland` - build against Wayland libraries (internal GLFW)
|
* `drm_leasing` - enables Wayland DRM leasing capabilties. Requires the `drm` build tag as a prerequisite
|
||||||
|
* `sdl` - build for [SDL](https://github.com/libsdl-org/SDL) backend (PLATFORM_DESKTOP_SDL)
|
||||||
|
* `sdl3` - build for [SDL3](https://github.com/libsdl-org/SDL) backend (PLATFORM_DESKTOP_SDL3)
|
||||||
|
* `rgfw` - build for [RGFW](https://github.com/ColleagueRiley/RGFW) backend (PLATFORM_DESKTOP_RGFW)
|
||||||
* `noaudio` - disables audio functions
|
* `noaudio` - disables audio functions
|
||||||
* `opengl43` - uses OpenGL 4.3 backend
|
* `opengl43` - uses OpenGL 4.3 backend
|
||||||
* `opengl21` - uses OpenGL 2.1 backend (default is 3.3 on desktop)
|
* `opengl21` - uses OpenGL 2.1 backend (default is 3.3 on desktop)
|
||||||
* `opengl11` - uses OpenGL 1.1 backend (pseudo OpenGL 1.1 style)
|
* `opengl11` - uses OpenGL 1.1 backend (pseudo OpenGL 1.1 style)
|
||||||
* `es2` - uses OpenGL ES 2.0 backend (can be used to link against [Google's ANGLE](https://github.com/google/angle))
|
* `es2` - uses OpenGL ES 2.0 backend (can be used to link against [Google's ANGLE](https://github.com/google/angle))
|
||||||
* `es3` - experimental support for OpenGL ES 3.0
|
* `es3` - experimental support for OpenGL ES 3.0
|
||||||
|
* `x11` - force X11 compatibility mode on Wayland (PLATFORM_DESKTOP/GLFW)
|
||||||
|
* `wayland` - force Wayland only mode (PLATFORM_DESKTOP/GLFW)
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
Documentation on [GoDoc](https://godoc.org/github.com/gen2brain/raylib-go/raylib). Also check raylib [cheatsheet](http://www.raylib.com/cheatsheet/cheatsheet.html).
|
Documentation on [GoDoc](https://godoc.org/git.terah.dev/UnrealXR/raylib-go/raylib). Also check raylib [cheatsheet](http://www.raylib.com/cheatsheet/cheatsheet.html). If you have problems or need assistance there is an active community in the #raylib-go channel of the [Raylib Discord Server](https://discord.gg/raylib) that can help.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import rl "github.com/gen2brain/raylib-go/raylib"
|
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl.InitWindow(800, 450, "raylib [core] example - basic window")
|
rl.InitWindow(800, 450, "raylib [core] example - basic window")
|
||||||
|
@ -103,7 +101,7 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Check more [examples](https://github.com/gen2brain/raylib-go/tree/master/examples) organized by raylib modules.
|
Check more [examples](https://git.terah.dev/UnrealXR/raylib-go/tree/master/examples) organized by raylib modules.
|
||||||
|
|
||||||
### Cross-compile (Linux)
|
### Cross-compile (Linux)
|
||||||
|
|
||||||
|
@ -133,4 +131,4 @@ basic_window: Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
|
||||||
raylib-go is licensed under an unmodified zlib/libpng license. View [LICENSE](https://github.com/gen2brain/raylib-go/blob/master/LICENSE).
|
raylib-go is licensed under an unmodified zlib/libpng license. View [LICENSE](https://git.terah.dev/UnrealXR/raylib-go/blob/master/LICENSE).
|
||||||
|
|
BIN
assets/raylib-go_256x256.png
Normal file
BIN
assets/raylib-go_256x256.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 KiB |
|
@ -1,4 +1,4 @@
|
||||||
## easings [](https://godoc.org/github.com/gen2brain/raylib-go/easings)
|
## easings [](https://godoc.org/git.terah.dev/UnrealXR/raylib-go/easings)
|
||||||
|
|
||||||
Useful easing functions for values animation.
|
Useful easing functions for values animation.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module github.com/gen2brain/raylib-go/easings
|
module git.terah.dev/UnrealXR/raylib-go/easings
|
||||||
|
|
||||||
go 1.21
|
go 1.21
|
||||||
|
|
BIN
examples/audio/mixed_processor/coin.wav
Normal file
BIN
examples/audio/mixed_processor/coin.wav
Normal file
Binary file not shown.
BIN
examples/audio/mixed_processor/country.mp3
Normal file
BIN
examples/audio/mixed_processor/country.mp3
Normal file
Binary file not shown.
155
examples/audio/mixed_processor/main.go
Normal file
155
examples/audio/mixed_processor/main.go
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [audio] example - Mixed audio processing
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||||
|
*
|
||||||
|
* Example contributed by hkc (@hatkidchan) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 hkc (@hatkidchan)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
var exponent float32 = 1.0 // Audio exponentiation value
|
||||||
|
var averageVolume [400]float32 // Average volume history
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output")
|
||||||
|
|
||||||
|
rl.InitAudioDevice() // Initialize audio device
|
||||||
|
rl.AttachAudioMixedProcessor(ProcessAudio)
|
||||||
|
|
||||||
|
music := rl.LoadMusicStream("country.mp3")
|
||||||
|
sound := rl.LoadSound("coin.wav")
|
||||||
|
|
||||||
|
rl.PlayMusicStream(music)
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
rl.UpdateMusicStream(music) // Update music buffer with new stream data
|
||||||
|
|
||||||
|
// Modify processing variables
|
||||||
|
if rl.IsKeyPressed(rl.KeyLeft) {
|
||||||
|
exponent -= 0.05
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyRight) {
|
||||||
|
exponent += 0.05
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyDown) {
|
||||||
|
exponent -= 0.25
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyUp) {
|
||||||
|
exponent += 0.25
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that exponent stays between 0.5 and 3
|
||||||
|
exponent = clamp(exponent, 0.5, 3)
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeySpace) {
|
||||||
|
rl.PlaySound(sound)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
|
rl.DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, rl.LightGray)
|
||||||
|
|
||||||
|
rl.DrawText(fmt.Sprintf("EXPONENT = %.2f", exponent), 215, 180, 20, rl.LightGray)
|
||||||
|
|
||||||
|
rl.DrawRectangle(199, 199, 402, 34, rl.LightGray)
|
||||||
|
for i := int32(0); i < 400; i++ {
|
||||||
|
rl.DrawLine(201+i, 232-int32(averageVolume[i]*32), 201+i, 232, rl.Maroon)
|
||||||
|
}
|
||||||
|
rl.DrawRectangleLines(199, 199, 402, 34, rl.Gray)
|
||||||
|
|
||||||
|
rl.DrawText("PRESS SPACE TO PLAY OTHER SOUND", 200, 250, 20, rl.LightGray)
|
||||||
|
rl.DrawText("USE LEFT AND RIGHT ARROWS TO ALTER DISTORTION", 140, 280, 20, rl.LightGray)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.UnloadMusicStream(music) // Unload music stream buffers from RAM
|
||||||
|
rl.DetachAudioMixedProcessor(ProcessAudio) // Disconnect audio processor
|
||||||
|
rl.CloseAudioDevice() // Close audio device (music streaming is automatically stopped)
|
||||||
|
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessAudio is the audio processing function
|
||||||
|
func ProcessAudio(buffer []float32, frames int) {
|
||||||
|
var average float32 // Temporary average volume
|
||||||
|
maxFrame := frames / 2
|
||||||
|
|
||||||
|
// Each frame has 2 samples (left and right),
|
||||||
|
// so we should loop `frames / 2` times
|
||||||
|
for frame := 0; frame < maxFrame; frame++ {
|
||||||
|
left := &buffer[frame*2+0] // Left channel
|
||||||
|
right := &buffer[frame*2+1] // Right channel
|
||||||
|
|
||||||
|
// Modify left and right channel samples with exponent
|
||||||
|
*left = pow(abs(*left), exponent) * sgn(*left)
|
||||||
|
*right = pow(abs(*right), exponent) * sgn(*right)
|
||||||
|
|
||||||
|
// Accumulating average volume
|
||||||
|
average += abs(*left) / float32(maxFrame)
|
||||||
|
average += abs(*right) / float32(maxFrame)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift average volume history buffer to the left
|
||||||
|
for i := 0; i < 399; i++ {
|
||||||
|
averageVolume[i] = averageVolume[i+1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new average value
|
||||||
|
averageVolume[399] = average
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions to make the code shorter
|
||||||
|
// (using less type conversions)
|
||||||
|
// (Golang: Please make the `math` package generic! This is ridiculous :-)
|
||||||
|
func abs(value float32) float32 {
|
||||||
|
return float32(math.Abs(float64(value)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func pow(value, exponent float32) float32 {
|
||||||
|
return float32(math.Pow(float64(value), float64(exponent)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func sgn(value float32) float32 {
|
||||||
|
if value < 0 {
|
||||||
|
return -1
|
||||||
|
} else if value > 0 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func clamp(value, min, max float32) float32 {
|
||||||
|
if value < min {
|
||||||
|
return min
|
||||||
|
}
|
||||||
|
if value > max {
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxCircles = 64
|
const maxCircles = 64
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl.InitWindow(800, 450, "raylib [audio] example - music playing (streaming)")
|
rl.InitWindow(800, 450, "raylib [audio] example - music playing (streaming)")
|
||||||
rl.InitAudioDevice()
|
rl.InitAudioDevice()
|
||||||
|
|
|
@ -1,71 +1,69 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxSamples = 22050
|
nSamples = 44000 * 10
|
||||||
maxSamplesPerUpdate = 4096
|
sampleRate = 6000
|
||||||
|
bufferSize = nSamples
|
||||||
|
frequency = 440
|
||||||
|
targetFPS = 240
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming")
|
rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming")
|
||||||
|
position := rl.NewVector2(0, 0)
|
||||||
|
|
||||||
|
rl.SetAudioStreamBufferSizeDefault(bufferSize)
|
||||||
|
|
||||||
rl.InitAudioDevice()
|
rl.InitAudioDevice()
|
||||||
|
|
||||||
// Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono)
|
// Init raw audio stream (sample rate: <nSamples>, sample size: 32bit-float, channels: 1-mono)
|
||||||
stream := rl.LoadAudioStream(22050, 32, 1)
|
stream := rl.LoadAudioStream(nSamples, 32, 1)
|
||||||
|
|
||||||
//// Fill audio stream with some samples (sine wave)
|
//// Create sine wave to play
|
||||||
data := make([]float32, maxSamples)
|
data := make([]float32, nSamples)
|
||||||
|
|
||||||
for i := 0; i < maxSamples; i++ {
|
for i := 0; i < nSamples; i++ {
|
||||||
data[i] = float32(math.Sin(float64((2*rl.Pi*float32(i))/2) * rl.Deg2rad))
|
t := float32(i) / float32(nSamples)
|
||||||
|
data[i] = float32(math.Sin(float64((2 * rl.Pi * frequency * t))))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop
|
// NOTE: The buffer can only be updated when it has been processed. Time between buffer processing and next load and causes clipping
|
||||||
// for that reason, there is a clip everytime audio stream is looped
|
|
||||||
rl.PlayAudioStream(stream)
|
rl.PlayAudioStream(stream)
|
||||||
|
|
||||||
totalSamples := int32(maxSamples)
|
startTime := time.Now()
|
||||||
samplesLeft := int32(totalSamples)
|
rl.SetTargetFPS(targetFPS)
|
||||||
|
|
||||||
position := rl.NewVector2(0, 0)
|
|
||||||
|
|
||||||
rl.SetTargetFPS(30)
|
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
// Refill audio stream if required
|
// Refill audio stream if buffer is processed
|
||||||
if rl.IsAudioStreamProcessed(stream) {
|
if rl.IsAudioStreamProcessed(stream) {
|
||||||
numSamples := int32(0)
|
elapsedTime := time.Since(startTime).Seconds()
|
||||||
if samplesLeft >= maxSamplesPerUpdate {
|
currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(nSamples)))
|
||||||
numSamples = maxSamplesPerUpdate
|
nextSampleIndex := currentSampleIndex + bufferSize
|
||||||
|
|
||||||
|
if nextSampleIndex > nSamples {
|
||||||
|
nextSampleIndex = bufferSize - (nSamples - currentSampleIndex)
|
||||||
|
rl.UpdateAudioStream(stream, append(data[currentSampleIndex:], data[:nextSampleIndex]...))
|
||||||
} else {
|
} else {
|
||||||
numSamples = samplesLeft
|
rl.UpdateAudioStream(stream, data[currentSampleIndex:nextSampleIndex])
|
||||||
}
|
|
||||||
|
|
||||||
rl.UpdateAudioStream(stream, data[totalSamples-samplesLeft:])
|
|
||||||
|
|
||||||
samplesLeft -= numSamples
|
|
||||||
|
|
||||||
// Reset samples feeding (loop audio)
|
|
||||||
if samplesLeft <= 0 {
|
|
||||||
samplesLeft = totalSamples
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
rl.DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, rl.LightGray)
|
rl.DrawText(fmt.Sprintf("%d Hz SINE WAVE SHOULD BE PLAYING!", frequency), 200, 140, 20, rl.LightGray)
|
||||||
|
|
||||||
// NOTE: Draw a part of the sine wave (only screen width)
|
// NOTE: Draw a part of the sine wave (only screen width)
|
||||||
for i := 0; i < int(rl.GetScreenWidth()); i++ {
|
for i := 0; i < int(rl.GetScreenWidth()); i++ {
|
||||||
position.X = float32(i)
|
position.X = float32(i)
|
||||||
position.Y = 250 + 50*data[i]
|
position.Y = 250 + 10*data[i*nSamples/int(20*rl.GetScreenWidth())]
|
||||||
|
|
||||||
rl.DrawPixelV(position, rl.Red)
|
rl.DrawPixelV(position, rl.Red)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
65
examples/audio/sound_multi/main.go
Normal file
65
examples/audio/sound_multi/main.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [audio] example - Playing sound multiple times
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 4.6
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Jeffery Myers (@JeffM2501)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
maxSounds = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
var soundArray [maxSounds]rl.Sound
|
||||||
|
var currentSound int32
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [audio] example - playing sound multiple times")
|
||||||
|
|
||||||
|
// Initialize audio device
|
||||||
|
rl.InitAudioDevice()
|
||||||
|
|
||||||
|
// Load WAV audio file into the first slot as the 'source' sound
|
||||||
|
// this sound owns the sample data
|
||||||
|
soundArray[0] = rl.LoadSound("sound.wav")
|
||||||
|
|
||||||
|
for i := 1; i < maxSounds; i++ {
|
||||||
|
// Load an alias of the sound into slots 1-9.
|
||||||
|
// These do not own the sound data, but can be played
|
||||||
|
soundArray[i] = rl.LoadSoundAlias(soundArray[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
if rl.IsKeyPressed(rl.KeySpace) {
|
||||||
|
rl.PlaySound(soundArray[currentSound]) // play the next open sound slot
|
||||||
|
currentSound++ // increment the sound slot
|
||||||
|
if currentSound >= maxSounds { // if the sound slot is out of bounds, go back to 0
|
||||||
|
currentSound = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: a better way would be to look at the list for the first sound that is not playing and use that slot
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.DrawText("Press SPACE to PLAY a WAV sound!", 200, 180, 20, rl.LightGray)
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.UnloadSound(soundArray[0]) // Unload source sound data
|
||||||
|
rl.CloseAudioDevice() // Close audio device
|
||||||
|
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
BIN
examples/audio/sound_multi/sound.wav
Normal file
BIN
examples/audio/sound_multi/sound.wav
Normal file
Binary file not shown.
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib [core] example - 2d camera mouse zoom
|
* raylib [core] example - 2d camera mouse zoom
|
||||||
|
|
261
examples/core/2d_camera_platformer/main.go
Normal file
261
examples/core/2d_camera_platformer/main.go
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
gravity = 400
|
||||||
|
playerJumpSpeed = 350.0
|
||||||
|
playerHORSpeed = 200.0
|
||||||
|
)
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
position rl.Vector2
|
||||||
|
speed float32
|
||||||
|
canJump bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnvironmentItem struct {
|
||||||
|
rect rl.Rectangle
|
||||||
|
blocking bool
|
||||||
|
color rl.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
type cameraUpdater func(*rl.Camera2D, *Player, []EnvironmentItem, float32)
|
||||||
|
|
||||||
|
// These 3 variables are used only for camera 4,
|
||||||
|
// but they need to be declared on module level
|
||||||
|
// for camera 4 to work (static in C)
|
||||||
|
var eveningOut = false
|
||||||
|
var evenOutSpeed float32 = 700
|
||||||
|
var evenOutTarget float32 = 0
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera platformer")
|
||||||
|
|
||||||
|
player := Player{
|
||||||
|
position: rl.NewVector2(400, 280),
|
||||||
|
speed: 0,
|
||||||
|
canJump: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
envItems := []EnvironmentItem{
|
||||||
|
{rect: rl.Rectangle{Width: 1000, Height: 400}, blocking: false, color: rl.LightGray},
|
||||||
|
{rect: rl.Rectangle{Y: 400, Width: 1000, Height: 200}, blocking: true, color: rl.Gray},
|
||||||
|
{rect: rl.Rectangle{X: 300, Y: 200, Width: 400, Height: 10}, blocking: true, color: rl.Gray},
|
||||||
|
{rect: rl.Rectangle{X: 250, Y: 300, Width: 100, Height: 10}, blocking: true, color: rl.Gray},
|
||||||
|
{rect: rl.Rectangle{X: 650, Y: 300, Width: 100, Height: 10}, blocking: true, color: rl.Gray},
|
||||||
|
}
|
||||||
|
|
||||||
|
camera := rl.Camera2D{
|
||||||
|
Offset: rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2},
|
||||||
|
Target: player.position,
|
||||||
|
Rotation: 0,
|
||||||
|
Zoom: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
cameraUpdaters := []cameraUpdater{
|
||||||
|
updateCameraCenter,
|
||||||
|
updateCameraCenterInsideMap,
|
||||||
|
updateCameraCenterSmoothFollow,
|
||||||
|
updateCameraEvenOutOnLanding,
|
||||||
|
updateCameraPlayerBoundsPush,
|
||||||
|
}
|
||||||
|
cameraDescriptions := []string{
|
||||||
|
"1. Follow player center",
|
||||||
|
"2. Follow player center, but clamp to map edges",
|
||||||
|
"3. Follow player center; smoothed",
|
||||||
|
"4. Follow player center horizontally; update player center vertically after landing",
|
||||||
|
"5. Player push camera on getting too close to screen edge",
|
||||||
|
}
|
||||||
|
|
||||||
|
cameraOption := 0
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
deltaTime := rl.GetFrameTime()
|
||||||
|
|
||||||
|
updatePlayer(&player, envItems, deltaTime)
|
||||||
|
|
||||||
|
camera.Zoom += rl.GetMouseWheelMove() * 0.05
|
||||||
|
|
||||||
|
camera.Zoom = clamp(camera.Zoom, 0.25, 3)
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyC) {
|
||||||
|
cameraOption = (cameraOption + 1) % len(cameraUpdaters)
|
||||||
|
}
|
||||||
|
// Call update camera function by its pointer
|
||||||
|
cameraUpdaters[cameraOption](&camera, &player, envItems, deltaTime)
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.BeginMode2D(camera)
|
||||||
|
|
||||||
|
for _, item := range envItems {
|
||||||
|
rl.DrawRectangleRec(item.rect, item.color)
|
||||||
|
}
|
||||||
|
|
||||||
|
playerRect := rl.Rectangle{
|
||||||
|
X: player.position.X - 20,
|
||||||
|
Y: player.position.Y - 40,
|
||||||
|
Width: 40,
|
||||||
|
Height: 40,
|
||||||
|
}
|
||||||
|
rl.DrawRectangleRec(playerRect, rl.Red)
|
||||||
|
rl.DrawCircleV(player.position, 5, rl.Gold)
|
||||||
|
|
||||||
|
rl.EndMode2D()
|
||||||
|
|
||||||
|
rl.DrawText("Controls:", 20, 20, 10, rl.Black)
|
||||||
|
rl.DrawText(" - Right/Left to move", 40, 40, 10, rl.DarkGray)
|
||||||
|
rl.DrawText(" - Space to jump", 40, 60, 10, rl.DarkGray)
|
||||||
|
rl.DrawText(" - Mouse Wheel to Zoom in-out, R to reset zoom", 40, 80, 10, rl.DarkGray)
|
||||||
|
rl.DrawText(" - C to change camera mode", 20, 100, 10, rl.Black)
|
||||||
|
rl.DrawText("Current Camera Mode:", 20, 120, 10, rl.DarkGray)
|
||||||
|
rl.DrawText(cameraDescriptions[cameraOption], 40, 140, 10, rl.DarkGray)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatePlayer(player *Player, envItems []EnvironmentItem, delta float32) {
|
||||||
|
if rl.IsKeyDown(rl.KeyLeft) {
|
||||||
|
player.position.X -= playerHORSpeed * delta
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(rl.KeyRight) {
|
||||||
|
player.position.X += playerHORSpeed * delta
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(rl.KeySpace) && player.canJump {
|
||||||
|
player.speed = -playerJumpSpeed
|
||||||
|
player.canJump = false
|
||||||
|
}
|
||||||
|
|
||||||
|
hitObstacle := false
|
||||||
|
for _, item := range envItems {
|
||||||
|
if item.blocking &&
|
||||||
|
item.rect.X <= player.position.X && item.rect.X+item.rect.Width >= player.position.X &&
|
||||||
|
item.rect.Y >= player.position.Y && item.rect.Y <= player.position.Y+player.speed*delta {
|
||||||
|
hitObstacle = true
|
||||||
|
player.speed = 0
|
||||||
|
player.position.Y = item.rect.Y
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hitObstacle {
|
||||||
|
player.position.Y += player.speed * delta
|
||||||
|
player.speed += gravity * delta
|
||||||
|
player.canJump = false
|
||||||
|
} else {
|
||||||
|
player.canJump = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCameraCenter(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, _ float32) {
|
||||||
|
camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2}
|
||||||
|
camera.Target = player.position
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCameraCenterInsideMap(camera *rl.Camera2D, player *Player, envItems []EnvironmentItem, _ float32) {
|
||||||
|
camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2}
|
||||||
|
camera.Target = player.position
|
||||||
|
|
||||||
|
var minX, minY, maxX, maxY float32 = 1000, 1000, -1000, -10000
|
||||||
|
|
||||||
|
for _, item := range envItems {
|
||||||
|
minX = min(item.rect.X, minX)
|
||||||
|
maxX = max(item.rect.X+item.rect.Width, maxX)
|
||||||
|
minY = min(item.rect.Y, minY)
|
||||||
|
maxY = max(item.rect.Y+item.rect.Height, maxY)
|
||||||
|
}
|
||||||
|
|
||||||
|
maxV := rl.GetWorldToScreen2D(rl.Vector2{X: maxX, Y: maxY}, *camera)
|
||||||
|
minV := rl.GetWorldToScreen2D(rl.Vector2{X: minX, Y: minY}, *camera)
|
||||||
|
|
||||||
|
if maxV.X < screenWidth {
|
||||||
|
camera.Offset.X = screenWidth - (maxV.X - screenWidth/2)
|
||||||
|
}
|
||||||
|
if maxV.Y < screenHeight {
|
||||||
|
camera.Offset.Y = screenHeight - (maxV.Y - screenHeight/2)
|
||||||
|
}
|
||||||
|
if minV.X > 0 {
|
||||||
|
camera.Offset.X = screenWidth/2 - minV.X
|
||||||
|
}
|
||||||
|
if minV.Y > 0 {
|
||||||
|
camera.Offset.Y = screenHeight/2 - minV.Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCameraCenterSmoothFollow(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, delta float32) {
|
||||||
|
var minSpeed, minEffectLength, fractionSpeed float32 = 30.0, 10.0, 0.8
|
||||||
|
|
||||||
|
camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2}
|
||||||
|
diff := rl.Vector2Subtract(player.position, camera.Target)
|
||||||
|
length := rl.Vector2Length(diff)
|
||||||
|
|
||||||
|
if length > minEffectLength {
|
||||||
|
speed := max(fractionSpeed*length, minSpeed)
|
||||||
|
camera.Target = rl.Vector2Add(camera.Target, rl.Vector2Scale(diff, speed*delta/length))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCameraEvenOutOnLanding(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, delta float32) {
|
||||||
|
camera.Offset = rl.Vector2{X: screenWidth / 2, Y: screenHeight / 2}
|
||||||
|
camera.Target.X = player.position.X
|
||||||
|
|
||||||
|
if eveningOut {
|
||||||
|
if evenOutTarget > camera.Target.Y {
|
||||||
|
camera.Target.Y += evenOutSpeed * delta
|
||||||
|
if camera.Target.Y > evenOutTarget {
|
||||||
|
camera.Target.Y = evenOutTarget
|
||||||
|
eveningOut = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
camera.Target.Y -= evenOutSpeed * delta
|
||||||
|
if camera.Target.Y < evenOutTarget {
|
||||||
|
camera.Target.Y = evenOutTarget
|
||||||
|
eveningOut = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if player.canJump && player.speed == 0 && player.position.Y != camera.Target.Y {
|
||||||
|
eveningOut = true
|
||||||
|
evenOutTarget = player.position.Y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateCameraPlayerBoundsPush(camera *rl.Camera2D, player *Player, _ []EnvironmentItem, _ float32) {
|
||||||
|
bbox := rl.Vector2{X: 0.2, Y: 0.2}
|
||||||
|
|
||||||
|
bboxWorldMin := rl.GetScreenToWorld2D(rl.Vector2{X: (1 - bbox.X) * 0.5 * screenWidth, Y: (1 - bbox.Y) * 0.5 * screenHeight}, *camera)
|
||||||
|
bboxWorldMax := rl.GetScreenToWorld2D(rl.Vector2{X: (1 + bbox.X) * 0.5 * screenWidth, Y: (1 + bbox.Y) * 0.5 * screenHeight}, *camera)
|
||||||
|
camera.Offset = rl.Vector2{X: (1 - bbox.X) * 0.5 * screenWidth, Y: (1 - bbox.Y) * 0.5 * screenHeight}
|
||||||
|
|
||||||
|
if player.position.X < bboxWorldMin.X {
|
||||||
|
camera.Target.X = player.position.X
|
||||||
|
}
|
||||||
|
if player.position.Y < bboxWorldMin.Y {
|
||||||
|
camera.Target.Y = player.position.Y
|
||||||
|
}
|
||||||
|
if player.position.X > bboxWorldMax.X {
|
||||||
|
camera.Target.X = bboxWorldMin.X + (player.position.X - bboxWorldMax.X)
|
||||||
|
}
|
||||||
|
if player.position.Y > bboxWorldMax.Y {
|
||||||
|
camera.Target.Y = bboxWorldMin.Y + (player.position.Y - bboxWorldMax.Y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func clamp(zoom float32, min float32, max float32) float32 {
|
||||||
|
if zoom < min {
|
||||||
|
return min
|
||||||
|
}
|
||||||
|
if zoom > max {
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
return zoom
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const colorCount = 23
|
const colorCount = 23
|
||||||
|
|
|
@ -1,22 +1,43 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
"fmt"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxColumns = 20
|
maxColumns = 20
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
False = 0
|
||||||
|
True = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
var camModes = map[rl.CameraMode]string{
|
||||||
rl.InitWindow(800, 450, "raylib [core] example - 3d camera first person")
|
rl.CameraFree: "FREE",
|
||||||
|
rl.CameraOrbital: "ORBITAL",
|
||||||
|
rl.CameraFirstPerson: "FIRST PERSON",
|
||||||
|
rl.CameraThirdPerson: "THIRD PERSON",
|
||||||
|
}
|
||||||
|
|
||||||
|
var camProjections = map[rl.CameraProjection]string{
|
||||||
|
rl.CameraPerspective: "PERSPECTIVE",
|
||||||
|
rl.CameraOrthographic: "ORTHOGRAPHIC",
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person")
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world (position, target, up vector)
|
||||||
camera := rl.Camera3D{}
|
camera := rl.Camera3D{}
|
||||||
camera.Position = rl.NewVector3(4.0, 2.0, 4.0)
|
camera.Position = rl.NewVector3(0.0, 2.0, 4.0) // Camera position
|
||||||
camera.Target = rl.NewVector3(0.0, 1.8, 0.0)
|
camera.Target = rl.NewVector3(0.0, 2.0, 0.0) // Camera looking at point
|
||||||
camera.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Camera up vector (rotation towards target)
|
||||||
camera.Fovy = 60.0
|
camera.Fovy = 60.0 // Camera field-of-view Y
|
||||||
camera.Projection = rl.CameraPerspective
|
camera.Projection = rl.CameraPerspective // Camera projection type
|
||||||
|
|
||||||
|
cameraMode := rl.CameraFirstPerson
|
||||||
|
|
||||||
// Generates some random columns
|
// Generates some random columns
|
||||||
heights := make([]float32, maxColumns)
|
heights := make([]float32, maxColumns)
|
||||||
|
@ -24,15 +45,81 @@ func main() {
|
||||||
colors := make([]rl.Color, maxColumns)
|
colors := make([]rl.Color, maxColumns)
|
||||||
|
|
||||||
for i := 0; i < maxColumns; i++ {
|
for i := 0; i < maxColumns; i++ {
|
||||||
heights[i] = float32(rl.GetRandomValue(1, 12))
|
heights[i] = rndF(1, 12)
|
||||||
positions[i] = rl.NewVector3(float32(rl.GetRandomValue(-15, 15)), heights[i]/2, float32(rl.GetRandomValue(-15, 15)))
|
positions[i] = rl.NewVector3(rndF(-15, 15), heights[i]/2, rndF(-15, 15))
|
||||||
colors[i] = rl.NewColor(uint8(rl.GetRandomValue(20, 255)), uint8(rl.GetRandomValue(10, 55)), 30, 255)
|
colors[i] = rl.NewColor(rndU(20, 255), rndU(10, 55), 30, 255)
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.SetTargetFPS(60)
|
rl.DisableCursor() // Limit cursor to relative movement inside the window
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
// Main game loop
|
||||||
rl.UpdateCamera(&camera, rl.CameraFirstPerson) // Update camera with first person mode
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Switch camera mode
|
||||||
|
if rl.IsKeyPressed(rl.KeyOne) {
|
||||||
|
cameraMode = rl.CameraFree
|
||||||
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyTwo) {
|
||||||
|
cameraMode = rl.CameraFirstPerson
|
||||||
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyThree) {
|
||||||
|
cameraMode = rl.CameraThirdPerson
|
||||||
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyFour) {
|
||||||
|
cameraMode = rl.CameraOrbital
|
||||||
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0) // Reset roll
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch camera projection
|
||||||
|
if rl.IsKeyPressed(rl.KeyP) {
|
||||||
|
cameraMode = rl.CameraThirdPerson
|
||||||
|
if camera.Projection == rl.CameraPerspective {
|
||||||
|
// Create isometric view
|
||||||
|
// Note: The target distance is related to the render distance in the orthographic projection
|
||||||
|
camera.Position = rl.NewVector3(0.0, 2.0, -100.0)
|
||||||
|
camera.Target = rl.NewVector3(0.0, 2.0, 0.0)
|
||||||
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
||||||
|
camera.Projection = rl.CameraOrthographic
|
||||||
|
camera.Fovy = 20.0 // near plane width in CAMERA_ORTHOGRAPHIC
|
||||||
|
rl.CameraYaw(&camera, -135*rl.Deg2rad, True)
|
||||||
|
rl.CameraPitch(&camera, -45*rl.Deg2rad, True, True, False)
|
||||||
|
} else if camera.Projection == rl.CameraOrthographic {
|
||||||
|
// Reset to default view
|
||||||
|
camera.Position = rl.NewVector3(0.0, 2.0, 10.0)
|
||||||
|
camera.Target = rl.NewVector3(0.0, 2.0, 0.0)
|
||||||
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
||||||
|
camera.Projection = rl.CameraPerspective
|
||||||
|
camera.Fovy = 60.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update camera computes movement internally depending on the camera mode.
|
||||||
|
// Some default standard keyboard/mouse inputs are hardcoded to simplify use.
|
||||||
|
// For advance camera controls, it's recommended to compute camera movement manually.
|
||||||
|
rl.UpdateCamera(&camera, cameraMode) // Update camera
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Camera PRO usage example (EXPERIMENTAL)
|
||||||
|
// This new camera function allows custom movement/rotation values to be directly provided
|
||||||
|
// as input parameters, with this approach, rcamera module is internally independent of raylib inputs
|
||||||
|
UpdateCameraPro(&camera,
|
||||||
|
(Vector3){
|
||||||
|
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
|
||||||
|
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
|
||||||
|
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
|
||||||
|
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
|
||||||
|
0.0f // Move up-down
|
||||||
|
},
|
||||||
|
(Vector3){
|
||||||
|
GetMouseDelta().x*0.05f, // Rotation: yaw
|
||||||
|
GetMouseDelta().y*0.05f, // Rotation: pitch
|
||||||
|
0.0f // Rotation: roll
|
||||||
|
},
|
||||||
|
GetMouseWheelMove()*2.0f); // Move to target (zoom)
|
||||||
|
*/
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
|
@ -51,17 +138,57 @@ func main() {
|
||||||
rl.DrawCubeWires(positions[i], 2.0, heights[i], 2.0, rl.Maroon)
|
rl.DrawCubeWires(positions[i], 2.0, heights[i], 2.0, rl.Maroon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw player cube
|
||||||
|
if cameraMode == rl.CameraThirdPerson {
|
||||||
|
rl.DrawCube(camera.Target, 0.5, 0.5, 0.5, rl.Purple)
|
||||||
|
rl.DrawCubeWires(camera.Target, 0.5, 0.5, 0.5, rl.DarkPurple)
|
||||||
|
}
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
|
||||||
rl.DrawRectangle(10, 10, 220, 70, rl.Fade(rl.SkyBlue, 0.5))
|
// Draw info boxes
|
||||||
rl.DrawRectangleLines(10, 10, 220, 70, rl.Blue)
|
rl.DrawRectangle(5, 5, 330, 100, rl.Fade(rl.SkyBlue, 0.5))
|
||||||
|
rl.DrawRectangleLines(5, 5, 330, 100, rl.Blue)
|
||||||
|
|
||||||
rl.DrawText("First person camera default controls:", 20, 20, 10, rl.Black)
|
rl.DrawText("Camera controls:", 15, 15, 10, rl.Black)
|
||||||
rl.DrawText("- Move with keys: W, A, S, D", 40, 40, 10, rl.DarkGray)
|
rl.DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, rl.Black)
|
||||||
rl.DrawText("- Mouse move to look around", 40, 60, 10, rl.DarkGray)
|
rl.DrawText("- Look around: arrow keys or mouse", 15, 45, 10, rl.Black)
|
||||||
|
rl.DrawText("- Camera mode keys: 1,2,3,4", 15, 60, 10, rl.Black)
|
||||||
|
rl.DrawText("- Zoom keys: num-plus, num-minus or mouse scroll", 15, 75, 10, rl.Black)
|
||||||
|
rl.DrawText("- Camera projection key: P", 15, 90, 10, rl.Black)
|
||||||
|
|
||||||
|
rl.DrawRectangle(600, 5, 195, 100, rl.Fade(rl.SkyBlue, 0.5))
|
||||||
|
rl.DrawRectangleLines(600, 5, 195, 100, rl.Blue)
|
||||||
|
|
||||||
|
rl.DrawText("Camera status:", 610, 15, 10, rl.Black)
|
||||||
|
rl.DrawText(s2T("Mode:", camModes[cameraMode]), 610, 30, 10, rl.Black)
|
||||||
|
rl.DrawText(s2T("Projection:", camProjections[camera.Projection]), 610, 45, 10, rl.Black)
|
||||||
|
rl.DrawText(s2T("Position:", v2T(camera.Position)), 610, 60, 10, rl.Black)
|
||||||
|
rl.DrawText(s2T("Target:", v2T(camera.Target)), 610, 75, 10, rl.Black)
|
||||||
|
rl.DrawText(s2T("Up:", v2T(camera.Up)), 610, 90, 10, rl.Black)
|
||||||
|
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.CloseWindow()
|
rl.CloseWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rndU generates a random uint8 value between min and max
|
||||||
|
func rndU(min, max int32) uint8 {
|
||||||
|
return uint8(rl.GetRandomValue(min, max))
|
||||||
|
}
|
||||||
|
|
||||||
|
// rndF generates a random float32 value between min and max
|
||||||
|
func rndF(min, max int32) float32 {
|
||||||
|
return float32(rl.GetRandomValue(min, max))
|
||||||
|
}
|
||||||
|
|
||||||
|
// s2t generates a Status item string from a name and value
|
||||||
|
func s2T(name, value string) string {
|
||||||
|
return fmt.Sprintf(" - %s %s", name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// v2T generates a string from a rl.Vector3
|
||||||
|
func v2T(v rl.Vector3) string {
|
||||||
|
return fmt.Sprintf("%6.3f, %6.3f, %6.3f", v.X, v.Y, v.Z)
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -44,8 +44,6 @@ func main() {
|
||||||
rl.DrawText("Free camera default controls:", 20, 20, 10, rl.Black)
|
rl.DrawText("Free camera default controls:", 20, 20, 10, rl.Black)
|
||||||
rl.DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, rl.DarkGray)
|
rl.DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, rl.DarkGray)
|
||||||
rl.DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, rl.DarkGray)
|
rl.DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, rl.DarkGray)
|
||||||
rl.DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 80, 10, rl.DarkGray)
|
|
||||||
rl.DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, rl.DarkGray)
|
|
||||||
rl.DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, rl.DarkGray)
|
rl.DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, rl.DarkGray)
|
||||||
|
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
screenW = int32(800)
|
screenW = int32(800)
|
||||||
screenH = int32(450)
|
screenH = int32(450)
|
||||||
playerSize = float32(40)
|
|
||||||
cam1, cam2 rl.Camera3D
|
cam1, cam2 rl.Camera3D
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,67 +14,63 @@ func main() {
|
||||||
|
|
||||||
rl.InitWindow(screenW, screenH, "raylib [core] example - 3d camera split screen")
|
rl.InitWindow(screenW, screenH, "raylib [core] example - 3d camera split screen")
|
||||||
|
|
||||||
|
// Setup player 1 camera and screen
|
||||||
cam1.Fovy = 45
|
cam1.Fovy = 45
|
||||||
cam1.Up.Y = 1
|
cam1.Up.Y = 1
|
||||||
cam1.Target.Y = 1
|
cam1.Target.Y = 1
|
||||||
cam1.Position.Z = -3
|
cam1.Position.Z = -3
|
||||||
cam1.Position.Y = 0.5
|
cam1.Position.Y = 1
|
||||||
|
|
||||||
cam2 = cam1
|
// Setup player two camera and screen
|
||||||
cam1.Position.Z = 3
|
cam2.Fovy = 45
|
||||||
|
cam2.Up.Y = 1
|
||||||
|
cam2.Target.Y = 3
|
||||||
|
cam2.Position.X = -3
|
||||||
|
cam2.Position.Y = 3
|
||||||
|
|
||||||
screenCam1 := rl.LoadRenderTexture(screenW/2, screenH)
|
screenCam1 := rl.LoadRenderTexture(screenW/2, screenH)
|
||||||
screenCam2 := rl.LoadRenderTexture(screenW/2, screenH)
|
screenCam2 := rl.LoadRenderTexture(screenW/2, screenH)
|
||||||
|
|
||||||
splitScreenRec := rl.NewRectangle(0, 0, float32(screenCam1.Texture.Width), -float32(screenCam1.Texture.Height))
|
splitScreenRec := rl.NewRectangle(0, 0, float32(screenCam1.Texture.Width), -float32(screenCam1.Texture.Height))
|
||||||
|
|
||||||
count := 5
|
count := float32(5)
|
||||||
spacing := float32(4)
|
spacing := float32(4)
|
||||||
|
|
||||||
rl.SetTargetFPS(60)
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
|
// If anyone moves this frame, how far will they move based on the time
|
||||||
|
// since the last frame this moves things at 10 world units per second,
|
||||||
|
// regardless of the actual FPS
|
||||||
frameOffset := 10 * rl.GetFrameTime()
|
frameOffset := 10 * rl.GetFrameTime()
|
||||||
|
|
||||||
|
// Move Player1 forward and backwards (no turning)
|
||||||
if rl.IsKeyDown(rl.KeyW) {
|
if rl.IsKeyDown(rl.KeyW) {
|
||||||
cam1.Position.Z -= frameOffset
|
|
||||||
cam1.Target.Z -= frameOffset
|
|
||||||
} else if rl.IsKeyDown(rl.KeyS) {
|
|
||||||
cam1.Position.Z += frameOffset
|
cam1.Position.Z += frameOffset
|
||||||
cam1.Target.Z += frameOffset
|
cam1.Target.Z += frameOffset
|
||||||
}
|
} else if rl.IsKeyDown(rl.KeyS) {
|
||||||
if rl.IsKeyDown(rl.KeyD) {
|
cam1.Position.Z -= frameOffset
|
||||||
cam1.Position.X += frameOffset
|
cam1.Target.Z -= frameOffset
|
||||||
cam1.Target.X += frameOffset
|
|
||||||
} else if rl.IsKeyDown(rl.KeyA) {
|
|
||||||
cam1.Position.X -= frameOffset
|
|
||||||
cam1.Target.X -= frameOffset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move Player2 forward and backwards (no turning)
|
||||||
if rl.IsKeyDown(rl.KeyUp) {
|
if rl.IsKeyDown(rl.KeyUp) {
|
||||||
cam2.Position.Z += frameOffset
|
|
||||||
cam2.Target.Z += frameOffset
|
|
||||||
} else if rl.IsKeyDown(rl.KeyDown) {
|
|
||||||
cam2.Position.Z -= frameOffset
|
|
||||||
cam2.Target.Z -= frameOffset
|
|
||||||
}
|
|
||||||
if rl.IsKeyDown(rl.KeyRight) {
|
|
||||||
cam2.Position.X -= frameOffset
|
|
||||||
cam2.Target.X -= frameOffset
|
|
||||||
} else if rl.IsKeyDown(rl.KeyLeft) {
|
|
||||||
cam2.Position.X += frameOffset
|
cam2.Position.X += frameOffset
|
||||||
cam2.Target.X += frameOffset
|
cam2.Target.X += frameOffset
|
||||||
|
} else if rl.IsKeyDown(rl.KeyDown) {
|
||||||
|
cam2.Position.X -= frameOffset
|
||||||
|
cam2.Target.X -= frameOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw Player1 view to the render texture
|
||||||
rl.BeginTextureMode(screenCam1)
|
rl.BeginTextureMode(screenCam1)
|
||||||
rl.ClearBackground(rl.SkyBlue)
|
rl.ClearBackground(rl.SkyBlue)
|
||||||
rl.BeginMode3D(cam1)
|
rl.BeginMode3D(cam1)
|
||||||
|
|
||||||
rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige)
|
rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige)
|
||||||
|
|
||||||
for x := -float32(count) * spacing; x <= float32(count)*spacing; x += spacing {
|
for x := -count * spacing; x <= count*spacing; x += spacing {
|
||||||
for z := -float32(count) * spacing; z <= float32(count)*spacing; z += spacing {
|
for z := -count * spacing; z <= count*spacing; z += spacing {
|
||||||
rl.DrawCube(rl.NewVector3(x-0.5, 1.5, z), 1, 1, 1, rl.Lime)
|
rl.DrawCube(rl.NewVector3(x-0.5, 1.5, z), 1, 1, 1, rl.Lime)
|
||||||
rl.DrawCube(rl.NewVector3(x-0.5, 0.5, z), 0.25, 1, 0.25, rl.Brown)
|
rl.DrawCube(rl.NewVector3(x-0.5, 0.5, z), 0.25, 1, 0.25, rl.Brown)
|
||||||
}
|
}
|
||||||
|
@ -87,17 +82,18 @@ func main() {
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
|
||||||
rl.DrawRectangle(0, 0, screenW/2, 40, rl.Fade(rl.RayWhite, 0.8))
|
rl.DrawRectangle(0, 0, screenW/2, 40, rl.Fade(rl.RayWhite, 0.8))
|
||||||
rl.DrawText("PLAYER 1 WASD KEYS", 10, 10, 20, rl.Maroon)
|
rl.DrawText("PLAYER1: W/S to move", 10, 10, 20, rl.Maroon)
|
||||||
rl.EndTextureMode()
|
rl.EndTextureMode()
|
||||||
|
|
||||||
|
// Draw Player2 view to the render texture
|
||||||
rl.BeginTextureMode(screenCam2)
|
rl.BeginTextureMode(screenCam2)
|
||||||
rl.ClearBackground(rl.SkyBlue)
|
rl.ClearBackground(rl.SkyBlue)
|
||||||
rl.BeginMode3D(cam2)
|
rl.BeginMode3D(cam2)
|
||||||
|
|
||||||
rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige)
|
rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige)
|
||||||
|
|
||||||
for x := -float32(count) * spacing; x <= float32(count)*spacing; x += spacing {
|
for x := -count * spacing; x <= count*spacing; x += spacing {
|
||||||
for z := -float32(count) * spacing; z <= float32(count)*spacing; z += spacing {
|
for z := -count * spacing; z <= count*spacing; z += spacing {
|
||||||
rl.DrawCube(rl.NewVector3(x, 1.5, z), 1, 1, 1, rl.Lime)
|
rl.DrawCube(rl.NewVector3(x, 1.5, z), 1, 1, 1, rl.Lime)
|
||||||
rl.DrawCube(rl.NewVector3(x, 0.5, z), 0.25, 1, 0.25, rl.Brown)
|
rl.DrawCube(rl.NewVector3(x, 0.5, z), 0.25, 1, 0.25, rl.Brown)
|
||||||
}
|
}
|
||||||
|
@ -109,9 +105,10 @@ func main() {
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
|
||||||
rl.DrawRectangle(0, 0, screenW/2, 40, rl.Fade(rl.RayWhite, 0.8))
|
rl.DrawRectangle(0, 0, screenW/2, 40, rl.Fade(rl.RayWhite, 0.8))
|
||||||
rl.DrawText("PLAYER 2 ARROW KEYS", 10, 10, 20, rl.Maroon)
|
rl.DrawText("PLAYER2: UP/DOWN to move", 10, 10, 20, rl.Maroon)
|
||||||
rl.EndTextureMode()
|
rl.EndTextureMode()
|
||||||
|
|
||||||
|
// Draw both views render textures to the screen side by side
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
rl.ClearBackground(rl.Black)
|
rl.ClearBackground(rl.Black)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/gen2brain/raylib-go/raylib"
|
import "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl.SetConfigFlags(rl.FlagVsyncHint)
|
rl.SetConfigFlags(rl.FlagVsyncHint)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const screenW = int32(1280)
|
const screenW = int32(1280)
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl.InitWindow(800, 450, "raylib [core] example - color selection (collision detection)")
|
rl.InitWindow(800, 450, "raylib [core] example - color selection (collision detection)")
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
|
|
131
examples/core/custom_frame_control/main.go
Normal file
131
examples/core/custom_frame_control/main.go
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - custom frame control
|
||||||
|
*
|
||||||
|
* NOTE: WARNING: This is an example for advanced users willing to have full control over
|
||||||
|
* the frame processes. By default, EndDrawing() calls the following processes:
|
||||||
|
* 1. Draw remaining batch data: rlDrawRenderBatchActive()
|
||||||
|
* 2. SwapScreenBuffer()
|
||||||
|
* 3. Frame time control: WaitTime()
|
||||||
|
* 4. PollInputEvents()
|
||||||
|
*
|
||||||
|
* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in
|
||||||
|
* config.h (it requires recompiling raylib). This way those steps are up to the user.
|
||||||
|
*
|
||||||
|
* Note that enabling this flag invalidates some functions:
|
||||||
|
* - GetFrameTime()
|
||||||
|
* - SetTargetFPS()
|
||||||
|
* - GetFPS()
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 4.0, last time updated with raylib 4.0
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Custom Frame Control")
|
||||||
|
|
||||||
|
previousTime := rl.GetTime()
|
||||||
|
currentTime := 0.0
|
||||||
|
updateDrawTime := 0.0
|
||||||
|
waitTime := 0.0
|
||||||
|
deltaTime := 0.0
|
||||||
|
|
||||||
|
timeCounter := 0.0
|
||||||
|
position := 0.0
|
||||||
|
pause := false
|
||||||
|
|
||||||
|
targetFPS := 60
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
rl.PollInputEvents() // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL)
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeySpace) {
|
||||||
|
pause = !pause
|
||||||
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyUp) {
|
||||||
|
targetFPS += 20
|
||||||
|
} else if rl.IsKeyPressed(rl.KeyDown) {
|
||||||
|
targetFPS -= 20
|
||||||
|
}
|
||||||
|
|
||||||
|
if targetFPS < 0 {
|
||||||
|
targetFPS = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pause {
|
||||||
|
position += 200 * deltaTime // We move at 200 pixels per second
|
||||||
|
if position >= float64(rl.GetScreenWidth()) {
|
||||||
|
position = 0
|
||||||
|
}
|
||||||
|
timeCounter += deltaTime // We count time (seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
|
for i := 0; i < rl.GetScreenWidth()/200; i++ {
|
||||||
|
rl.DrawRectangle(200*int32(i), 0, 1, int32(rl.GetScreenHeight()), rl.SkyBlue)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawCircle(int32(position), int32(rl.GetScreenHeight()/2-25), 50, rl.Red)
|
||||||
|
|
||||||
|
msg := fmt.Sprintf("%03.0f ms", timeCounter*1000)
|
||||||
|
rl.DrawText(msg, int32(position-40), int32(rl.GetScreenHeight()/2-100), 20, rl.Maroon)
|
||||||
|
msg = fmt.Sprintf("PosX: %03.0f", position)
|
||||||
|
rl.DrawText(msg, int32(position-50), int32(rl.GetScreenHeight()/2+40), 20, rl.Black)
|
||||||
|
|
||||||
|
msg = "Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate."
|
||||||
|
rl.DrawText(msg, 10, 10, 20, rl.DarkGray)
|
||||||
|
msg = "PRESS SPACE to PAUSE MOVEMENT"
|
||||||
|
rl.DrawText(msg, 10, int32(rl.GetScreenHeight()-60), 20, rl.Gray)
|
||||||
|
msg = "PRESS UP | DOWN to CHANGE TARGET FPS"
|
||||||
|
rl.DrawText(msg, 10, int32(rl.GetScreenHeight()-30), 20, rl.Gray)
|
||||||
|
msg = fmt.Sprintf("TARGET FPS: %d", targetFPS)
|
||||||
|
rl.DrawText(msg, int32(rl.GetScreenWidth()-220), 10, 20, rl.Lime)
|
||||||
|
msg = fmt.Sprintf("CURRENT FPS: %d", int(1/deltaTime))
|
||||||
|
rl.DrawText(msg, int32(rl.GetScreenWidth()-220), 40, 20, rl.Lime)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
|
||||||
|
// NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL,
|
||||||
|
// Events polling, screen buffer swap and frame time control must be managed by the user
|
||||||
|
|
||||||
|
rl.SwapScreenBuffer() // We want a fixed frame rate
|
||||||
|
|
||||||
|
currentTime = rl.GetTime()
|
||||||
|
updateDrawTime = currentTime - previousTime
|
||||||
|
|
||||||
|
if targetFPS > 0 { // We want a fixed frame rate
|
||||||
|
waitTime = (1 / float64(targetFPS)) - updateDrawTime
|
||||||
|
if waitTime > 0 {
|
||||||
|
rl.WaitTime(waitTime)
|
||||||
|
currentTime = rl.GetTime()
|
||||||
|
deltaTime = currentTime - previousTime
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deltaTime = updateDrawTime
|
||||||
|
}
|
||||||
|
|
||||||
|
previousTime = currentTime
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
49
examples/core/custom_logging/main.go
Normal file
49
examples/core/custom_logging/main.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Set custom logger
|
||||||
|
rl.SetTraceLogCallback(customLog)
|
||||||
|
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Custom Logging")
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.DrawText("Check the console output to see the custom logger in action!", 60, 200, 20, rl.LightGray)
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom logging function
|
||||||
|
func customLog(msgType int, text string) {
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
switch rl.TraceLogLevel(msgType) {
|
||||||
|
case rl.LogInfo:
|
||||||
|
fmt.Println("[INFO] : ", now, text)
|
||||||
|
case rl.LogError:
|
||||||
|
fmt.Println("[ERROR] : ", now, text)
|
||||||
|
case rl.LogWarning:
|
||||||
|
fmt.Println("[WARNING] : ", now, text)
|
||||||
|
case rl.LogDebug:
|
||||||
|
fmt.Println("[DEBUG] : ", now, text)
|
||||||
|
default:
|
||||||
|
fmt.Println("[UNKNOWN] : ", now, text)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(800)
|
screenWidth := int32(800)
|
||||||
screenHeight := int32(450)
|
screenHeight := int32(450)
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
maxGestureStrings int = 20
|
maxGestureStrings int = 20
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(800)
|
screenWidth := int32(800)
|
||||||
screenHeight := int32(450)
|
screenHeight := int32(450)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const screenW = int32(1280)
|
const screenW = int32(1280)
|
||||||
|
|
127
examples/core/storage_values/main.go
Normal file
127
examples/core/storage_values/main.go
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - Storage save/load values
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 1.4, last time updated with raylib 4.2
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
storageDataFile = "storage.data"
|
||||||
|
// NOTE: Storage positions must start with 0, directly related to file memory layout
|
||||||
|
storagePositionScore = 0
|
||||||
|
storagePositionHiscore = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - storage save/load values")
|
||||||
|
|
||||||
|
var score int32
|
||||||
|
var hiscore int32
|
||||||
|
var framesCounter int32
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Update
|
||||||
|
if rl.IsKeyPressed(rl.KeyR) {
|
||||||
|
score = rl.GetRandomValue(1000, 2000)
|
||||||
|
hiscore = rl.GetRandomValue(2000, 4000)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyEnter) {
|
||||||
|
_ = SaveStorageValue(storagePositionScore, score)
|
||||||
|
_ = SaveStorageValue(storagePositionHiscore, hiscore)
|
||||||
|
} else if rl.IsKeyPressed(rl.KeySpace) {
|
||||||
|
// NOTE: If requested position could not be found, value 0 is returned
|
||||||
|
score, _ = LoadStorageValue(storagePositionScore)
|
||||||
|
hiscore, _ = LoadStorageValue(storagePositionHiscore)
|
||||||
|
}
|
||||||
|
|
||||||
|
framesCounter++
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
|
rl.DrawText(fmt.Sprintf("SCORE: %d", score), 280, 130, 40, rl.Maroon)
|
||||||
|
rl.DrawText(fmt.Sprintf("HI-SCORE: %d", hiscore), 210, 200, 50, rl.Black)
|
||||||
|
|
||||||
|
rl.DrawText(fmt.Sprintf("frames: %d", framesCounter), 10, 10, 20, rl.Lime)
|
||||||
|
|
||||||
|
rl.DrawText("Press R to generate random numbers", 220, 40, 20, rl.LightGray)
|
||||||
|
rl.DrawText("Press ENTER to SAVE values", 250, 310, 20, rl.LightGray)
|
||||||
|
rl.DrawText("Press SPACE to LOAD values", 252, 350, 20, rl.LightGray)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveStorageValue saves an integer value to storage file (to defined position)
|
||||||
|
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
|
||||||
|
func SaveStorageValue(position uint32, value int32) error {
|
||||||
|
// Load the file data
|
||||||
|
fileData, err := os.ReadFile(storageDataFile)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("failed to load file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSize := len(fileData)
|
||||||
|
requiredSize := int((position + 1) * 4) // Each int32 is 4 bytes
|
||||||
|
newFileData := make([]byte, requiredSize)
|
||||||
|
|
||||||
|
// Copy existing file data to newFileData
|
||||||
|
if dataSize > 0 {
|
||||||
|
copy(newFileData, fileData)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the value at the specified position
|
||||||
|
binary.LittleEndian.PutUint32(newFileData[position*4:], uint32(value))
|
||||||
|
|
||||||
|
// Save the updated data back to the file
|
||||||
|
err = os.WriteFile(storageDataFile, newFileData, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to save file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadStorageValue loads an integer value from storage file (from defined position)
|
||||||
|
// NOTE: If requested position could not be found, value 0 is returned
|
||||||
|
func LoadStorageValue(position uint32) (int32, error) {
|
||||||
|
// Load the file data
|
||||||
|
fileData, err := os.ReadFile(storageDataFile)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to load file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSize := len(fileData)
|
||||||
|
if dataSize < int((position+1)*4) {
|
||||||
|
return 0, fmt.Errorf("position out of bounds")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the value at the specified position
|
||||||
|
value := int32(binary.LittleEndian.Uint32(fileData[position*4:]))
|
||||||
|
return value, nil
|
||||||
|
}
|
52
examples/core/vr_simulator/distortion100.fs
Normal file
52
examples/core/vr_simulator/distortion100.fs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
// NOTE: Add here your custom variables
|
||||||
|
uniform vec2 leftLensCenter;
|
||||||
|
uniform vec2 rightLensCenter;
|
||||||
|
uniform vec2 leftScreenCenter;
|
||||||
|
uniform vec2 rightScreenCenter;
|
||||||
|
uniform vec2 scale;
|
||||||
|
uniform vec2 scaleIn;
|
||||||
|
uniform vec4 deviceWarpParam;
|
||||||
|
uniform vec4 chromaAbParam;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Compute lens distortion
|
||||||
|
vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter;
|
||||||
|
vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter;
|
||||||
|
vec2 theta = (fragTexCoord - lensCenter)*scaleIn;
|
||||||
|
float rSq = theta.x*theta.x + theta.y*theta.y;
|
||||||
|
vec2 theta1 = theta*(deviceWarpParam.x + deviceWarpParam.y*rSq + deviceWarpParam.z*rSq*rSq + deviceWarpParam.w*rSq*rSq*rSq);
|
||||||
|
vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq);
|
||||||
|
vec2 tcBlue = lensCenter + scale*thetaBlue;
|
||||||
|
|
||||||
|
if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue)))
|
||||||
|
{
|
||||||
|
// Set black fragment for everything outside the lens border
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Compute color chroma aberration
|
||||||
|
float blue = texture2D(texture0, tcBlue).b;
|
||||||
|
vec2 tcGreen = lensCenter + scale*theta1;
|
||||||
|
float green = texture2D(texture0, tcGreen).g;
|
||||||
|
|
||||||
|
vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq);
|
||||||
|
vec2 tcRed = lensCenter + scale*thetaRed;
|
||||||
|
|
||||||
|
float red = texture2D(texture0, tcRed).r;
|
||||||
|
gl_FragColor = vec4(red, green, blue, 1.0);
|
||||||
|
}
|
||||||
|
}
|
53
examples/core/vr_simulator/distortion330.fs
Normal file
53
examples/core/vr_simulator/distortion330.fs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
// Output fragment color
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
// NOTE: Add here your custom variables
|
||||||
|
uniform vec2 leftLensCenter = vec2(0.288, 0.5);
|
||||||
|
uniform vec2 rightLensCenter = vec2(0.712, 0.5);
|
||||||
|
uniform vec2 leftScreenCenter = vec2(0.25, 0.5);
|
||||||
|
uniform vec2 rightScreenCenter = vec2(0.75, 0.5);
|
||||||
|
uniform vec2 scale = vec2(0.25, 0.45);
|
||||||
|
uniform vec2 scaleIn = vec2(4, 2.2222);
|
||||||
|
uniform vec4 deviceWarpParam = vec4(1, 0.22, 0.24, 0);
|
||||||
|
uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Compute lens distortion
|
||||||
|
vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter;
|
||||||
|
vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter;
|
||||||
|
vec2 theta = (fragTexCoord - lensCenter)*scaleIn;
|
||||||
|
float rSq = theta.x*theta.x + theta.y*theta.y;
|
||||||
|
vec2 theta1 = theta*(deviceWarpParam.x + deviceWarpParam.y*rSq + deviceWarpParam.z*rSq*rSq + deviceWarpParam.w*rSq*rSq*rSq);
|
||||||
|
vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq);
|
||||||
|
vec2 tcBlue = lensCenter + scale*thetaBlue;
|
||||||
|
|
||||||
|
if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue)))
|
||||||
|
{
|
||||||
|
// Set black fragment for everything outside the lens border
|
||||||
|
finalColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Compute color chroma aberration
|
||||||
|
float blue = texture(texture0, tcBlue).b;
|
||||||
|
vec2 tcGreen = lensCenter + scale*theta1;
|
||||||
|
float green = texture(texture0, tcGreen).g;
|
||||||
|
|
||||||
|
vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq);
|
||||||
|
vec2 tcRed = lensCenter + scale*thetaRed;
|
||||||
|
|
||||||
|
float red = texture(texture0, tcRed).r;
|
||||||
|
finalColor = vec4(red, green, blue, 1.0);
|
||||||
|
}
|
||||||
|
}
|
137
examples/core/vr_simulator/main.go
Normal file
137
examples/core/vr_simulator/main.go
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters)
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
glslVersion = 330 // Desktop
|
||||||
|
// glslVersion = 100 // Android, web
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// NOTE: screenWidth/screenHeight should match VR device aspect ratio
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator")
|
||||||
|
|
||||||
|
// VR device parameters definition
|
||||||
|
device := rl.VrDeviceInfo{
|
||||||
|
// Oculus Rift CV1 parameters for simulator
|
||||||
|
HResolution: 2160, // Horizontal resolution in pixels
|
||||||
|
VResolution: 1200, // Vertical resolution in pixels
|
||||||
|
HScreenSize: 0.133793, // Horizontal size in meters
|
||||||
|
VScreenSize: 0.0669, // Vertical size in meters
|
||||||
|
EyeToScreenDistance: 0.041, // Distance between eye and display in meters
|
||||||
|
LensSeparationDistance: 0.07, // Lens separation distance in meters
|
||||||
|
InterpupillaryDistance: 0.07, // IPD (distance between pupils) in meters
|
||||||
|
|
||||||
|
// NOTE: CV1 uses fresnel-hybrid-asymmetric lenses with specific compute shaders
|
||||||
|
// Following parameters are just an approximation to CV1 distortion stereo rendering
|
||||||
|
|
||||||
|
// Lens distortion constant parameters
|
||||||
|
LensDistortionValues: [4]float32{1.0, 0.22, 0.24, 0.0},
|
||||||
|
// Chromatic aberration correction parameters
|
||||||
|
ChromaAbCorrection: [4]float32{0.996, -0.004, 1.014, 0.0},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load VR stereo config for VR device parameters (Oculus Rift CV1 parameters)
|
||||||
|
config := rl.LoadVrStereoConfig(device)
|
||||||
|
|
||||||
|
// Distortion shader (uses device lens distortion and chroma)
|
||||||
|
fileName := fmt.Sprintf("distortion%d.fs", glslVersion)
|
||||||
|
distortion := rl.LoadShader("", fileName)
|
||||||
|
|
||||||
|
// Update distortion shader with lens and distortion-scale parameters
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "leftLensCenter"),
|
||||||
|
config.LeftLensCenter[:], rl.ShaderUniformVec2)
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "rightLensCenter"),
|
||||||
|
config.RightLensCenter[:], rl.ShaderUniformVec2)
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "leftScreenCenter"),
|
||||||
|
config.LeftScreenCenter[:], rl.ShaderUniformVec2)
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "rightScreenCenter"),
|
||||||
|
config.RightScreenCenter[:], rl.ShaderUniformVec2)
|
||||||
|
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "scale"),
|
||||||
|
config.Scale[:], rl.ShaderUniformVec2)
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "scaleIn"),
|
||||||
|
config.ScaleIn[:], rl.ShaderUniformVec2)
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "deviceWarpParam"),
|
||||||
|
device.LensDistortionValues[:], rl.ShaderUniformVec4)
|
||||||
|
rl.SetShaderValue(distortion, rl.GetShaderLocation(distortion, "chromaAbParam"),
|
||||||
|
device.ChromaAbCorrection[:], rl.ShaderUniformVec4)
|
||||||
|
|
||||||
|
// Initialize frame buffer for stereo rendering
|
||||||
|
// NOTE: Screen size should match HMD aspect ratio
|
||||||
|
target := rl.LoadRenderTexture(device.HResolution, device.VResolution)
|
||||||
|
|
||||||
|
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||||
|
sourceRec := rl.Rectangle{Width: float32(target.Texture.Width), Height: float32(-target.Texture.Height)}
|
||||||
|
destRec := rl.Rectangle{Width: float32(rl.GetScreenWidth()), Height: float32(rl.GetScreenHeight())}
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
|
||||||
|
camera := rl.Camera{
|
||||||
|
Position: rl.Vector3{X: 5, Y: 2, Z: 5},
|
||||||
|
Target: rl.Vector3{Y: 2},
|
||||||
|
Up: rl.Vector3{Y: 1},
|
||||||
|
Fovy: 60.0,
|
||||||
|
Projection: rl.CameraPerspective,
|
||||||
|
}
|
||||||
|
|
||||||
|
cubePosition := rl.Vector3{}
|
||||||
|
|
||||||
|
rl.DisableCursor() // Limit cursor to relative movement inside the window
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Update
|
||||||
|
rl.UpdateCamera(&camera, rl.CameraFirstPerson)
|
||||||
|
|
||||||
|
// Draw texture
|
||||||
|
rl.BeginTextureMode(target)
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.BeginVrStereoMode(config)
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
rl.DrawCube(cubePosition, 2.0, 2.0, 2.0, rl.Red)
|
||||||
|
rl.DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, rl.Maroon)
|
||||||
|
rl.DrawGrid(40, 1.0)
|
||||||
|
|
||||||
|
rl.EndMode3D()
|
||||||
|
rl.EndVrStereoMode()
|
||||||
|
rl.EndTextureMode()
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.BeginShaderMode(distortion)
|
||||||
|
rl.DrawTexturePro(target.Texture, sourceRec, destRec, rl.Vector2{}, 0.0, rl.White)
|
||||||
|
rl.EndShaderMode()
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.UnloadVrStereoConfig(config) // Unload stereo config
|
||||||
|
|
||||||
|
rl.UnloadRenderTexture(target) // Unload stereo render fbo
|
||||||
|
rl.UnloadShader(distortion) // Unload distortion shader
|
||||||
|
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
260
examples/core/window_flags/main.go
Normal file
260
examples/core/window_flags/main.go
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - window flags
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 3.5, last time updated with raylib 3.5
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
// Possible window flags
|
||||||
|
/*
|
||||||
|
FLAG_VSYNC_HINT
|
||||||
|
FLAG_FULLSCREEN_MODE -> not working properly -> wrong scaling!
|
||||||
|
FLAG_WINDOW_RESIZABLE
|
||||||
|
FLAG_WINDOW_UNDECORATED
|
||||||
|
FLAG_WINDOW_TRANSPARENT
|
||||||
|
FLAG_WINDOW_HIDDEN
|
||||||
|
FLAG_WINDOW_MINIMIZED -> Not supported on window creation
|
||||||
|
FLAG_WINDOW_MAXIMIZED -> Not supported on window creation
|
||||||
|
FLAG_WINDOW_UNFOCUSED
|
||||||
|
FLAG_WINDOW_TOPMOST
|
||||||
|
FLAG_WINDOW_HIGHDPI -> errors after minimize-resize, fb size is recalculated
|
||||||
|
FLAG_WINDOW_ALWAYS_RUN
|
||||||
|
FLAG_MSAA_4X_HINT
|
||||||
|
*/
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Set configuration flags for window creation
|
||||||
|
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Window Flags")
|
||||||
|
|
||||||
|
ballPosition := rl.Vector2{X: float32(rl.GetScreenWidth()) / 2.0, Y: float32(rl.GetScreenHeight()) / 2.0}
|
||||||
|
ballSpeed := rl.Vector2{X: 5.0, Y: 4.0}
|
||||||
|
ballRadius := float32(20.0)
|
||||||
|
framesCounter := 0
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
if rl.IsKeyPressed(rl.KeyF) {
|
||||||
|
rl.ToggleFullscreen() // modifies window size when scaling!
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyR) {
|
||||||
|
if rl.IsWindowState(rl.FlagWindowResizable) {
|
||||||
|
rl.ClearWindowState(rl.FlagWindowResizable)
|
||||||
|
} else {
|
||||||
|
rl.SetWindowState(rl.FlagWindowResizable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyD) {
|
||||||
|
if rl.IsWindowState(rl.FlagWindowUndecorated) {
|
||||||
|
rl.ClearWindowState(rl.FlagWindowUndecorated)
|
||||||
|
} else {
|
||||||
|
rl.SetWindowState(rl.FlagWindowUndecorated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyH) {
|
||||||
|
if !rl.IsWindowState(rl.FlagWindowHidden) {
|
||||||
|
rl.SetWindowState(rl.FlagWindowHidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
framesCounter = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsWindowState(rl.FlagWindowHidden) {
|
||||||
|
framesCounter++
|
||||||
|
if framesCounter >= 240 {
|
||||||
|
rl.ClearWindowState(rl.FlagWindowHidden) // Show window after 3 seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyN) {
|
||||||
|
if !rl.IsWindowState(rl.FlagWindowMinimized) {
|
||||||
|
rl.MinimizeWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
framesCounter = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsWindowState(rl.FlagWindowMinimized) {
|
||||||
|
framesCounter++
|
||||||
|
if framesCounter >= 240 {
|
||||||
|
rl.RestoreWindow() // Restore window after 3 seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyM) {
|
||||||
|
// NOTE: Requires FLAG_WINDOW_RESIZABLE enabled!
|
||||||
|
if rl.IsWindowState(rl.FlagWindowMaximized) {
|
||||||
|
rl.RestoreWindow()
|
||||||
|
} else {
|
||||||
|
rl.MaximizeWindow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyU) {
|
||||||
|
if rl.IsWindowState(rl.FlagWindowUnfocused) {
|
||||||
|
rl.ClearWindowState(rl.FlagWindowUnfocused)
|
||||||
|
} else {
|
||||||
|
rl.SetWindowState(rl.FlagWindowUnfocused)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyT) {
|
||||||
|
if rl.IsWindowState(rl.FlagWindowTopmost) {
|
||||||
|
rl.ClearWindowState(rl.FlagWindowTopmost)
|
||||||
|
} else {
|
||||||
|
rl.SetWindowState(rl.FlagWindowTopmost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyA) {
|
||||||
|
if rl.IsWindowState(rl.FlagWindowAlwaysRun) {
|
||||||
|
rl.ClearWindowState(rl.FlagWindowAlwaysRun)
|
||||||
|
} else {
|
||||||
|
rl.SetWindowState(rl.FlagWindowAlwaysRun)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeyV) {
|
||||||
|
if rl.IsWindowState(rl.FlagVsyncHint) {
|
||||||
|
rl.ClearWindowState(rl.FlagVsyncHint)
|
||||||
|
} else {
|
||||||
|
rl.SetWindowState(rl.FlagVsyncHint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bouncing ball logic
|
||||||
|
ballPosition.X += ballSpeed.X
|
||||||
|
ballPosition.Y += ballSpeed.Y
|
||||||
|
if (ballPosition.X >= (float32(rl.GetScreenWidth()) - ballRadius)) || (ballPosition.X <= ballRadius) {
|
||||||
|
ballSpeed.X *= -1.0
|
||||||
|
}
|
||||||
|
if (ballPosition.Y >= (float32(rl.GetScreenHeight()) - ballRadius)) || (ballPosition.Y <= ballRadius) {
|
||||||
|
ballSpeed.Y *= -1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
if rl.IsWindowState(rl.FlagWindowTransparent) {
|
||||||
|
rl.ClearBackground(rl.Blank)
|
||||||
|
} else {
|
||||||
|
rl.ClearBackground(rl.White)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawCircleV(ballPosition, ballRadius, rl.Maroon)
|
||||||
|
rl.DrawRectangleLinesEx(
|
||||||
|
rl.Rectangle{
|
||||||
|
Width: float32(rl.GetScreenWidth()),
|
||||||
|
Height: float32(rl.GetScreenHeight()),
|
||||||
|
},
|
||||||
|
4, rl.White,
|
||||||
|
)
|
||||||
|
|
||||||
|
rl.DrawCircleV(rl.GetMousePosition(), 10, rl.DarkBlue)
|
||||||
|
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
|
|
||||||
|
rl.DrawText(
|
||||||
|
fmt.Sprintf("Screen Size: [%d, %d]", rl.GetScreenWidth(), rl.GetScreenHeight()),
|
||||||
|
10,
|
||||||
|
40,
|
||||||
|
10,
|
||||||
|
rl.Green,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Draw window state info
|
||||||
|
rl.DrawText("Following flags can be set after window creation:", 10, 60, 10, rl.Gray)
|
||||||
|
if rl.IsWindowState(rl.FlagFullscreenMode) {
|
||||||
|
rl.DrawText("[F] FLAG_FULLSCREEN_MODE: on", 10, 80, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[F] FLAG_FULLSCREEN_MODE: off", 10, 80, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowResizable) {
|
||||||
|
rl.DrawText("[R] FLAG_WINDOW_RESIZABLE: on", 10, 100, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[R] FLAG_WINDOW_RESIZABLE: off", 10, 100, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowUndecorated) {
|
||||||
|
rl.DrawText("[D] FLAG_WINDOW_UNDECORATED: on", 10, 120, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[D] FLAG_WINDOW_UNDECORATED: off", 10, 120, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowHidden) {
|
||||||
|
rl.DrawText("[H] FLAG_WINDOW_HIDDEN: on", 10, 140, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[H] FLAG_WINDOW_HIDDEN: off", 10, 140, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowMinimized) {
|
||||||
|
rl.DrawText("[N] FLAG_WINDOW_MINIMIZED: on", 10, 160, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[N] FLAG_WINDOW_MINIMIZED: off", 10, 160, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowMaximized) {
|
||||||
|
rl.DrawText("[M] FLAG_WINDOW_MAXIMIZED: on", 10, 180, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[M] FLAG_WINDOW_MAXIMIZED: off", 10, 180, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowUnfocused) {
|
||||||
|
rl.DrawText("[G] FLAG_WINDOW_UNFOCUSED: on", 10, 200, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[U] FLAG_WINDOW_UNFOCUSED: off", 10, 200, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowTopmost) {
|
||||||
|
rl.DrawText("[T] FLAG_WINDOW_TOPMOST: on", 10, 220, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[T] FLAG_WINDOW_TOPMOST: off", 10, 220, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowAlwaysRun) {
|
||||||
|
rl.DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: on", 10, 240, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: off", 10, 240, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagVsyncHint) {
|
||||||
|
rl.DrawText("[V] FLAG_VSYNC_HINT: on", 10, 260, 10,
|
||||||
|
rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("[V] FLAG_VSYNC_HINT: off", 10, 260, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawText("Following flags can only be set before window creation:", 10, 300, 10, rl.Gray)
|
||||||
|
if rl.IsWindowState(rl.FlagWindowHighdpi) {
|
||||||
|
rl.DrawText("FLAG_WINDOW_HIGHDPI: on", 10, 320, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("FLAG_WINDOW_HIGHDPI: off", 10, 320, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagWindowTransparent) {
|
||||||
|
rl.DrawText("FLAG_WINDOW_TRANSPARENT: on", 10, 340, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("FLAG_WINDOW_TRANSPARENT: off", 10, 340, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
if rl.IsWindowState(rl.FlagMsaa4xHint) {
|
||||||
|
rl.DrawText("FLAG_MSAA_4X_HINT: on", 10, 360, 10, rl.Lime)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("FLAG_MSAA_4X_HINT: off", 10, 360, 10, rl.Maroon)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
115
examples/core/window_letterbox/main.go
Normal file
115
examples/core/window_letterbox/main.go
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Enable config flags for resizable window and vertical synchro
|
||||||
|
rl.SetConfigFlags(rl.FlagWindowResizable | rl.FlagVsyncHint)
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - Window Scale Letterbox")
|
||||||
|
rl.SetWindowMinSize(320, 240)
|
||||||
|
|
||||||
|
gameScreenWidth, gameScreenHeight := int32(640), int32(480)
|
||||||
|
|
||||||
|
// Render texture initialization, used to hold the rendering result so we can easily resize it
|
||||||
|
target := rl.LoadRenderTexture(gameScreenWidth, gameScreenHeight)
|
||||||
|
rl.SetTextureFilter(target.Texture, rl.FilterBilinear) // Texture scale filter to use
|
||||||
|
|
||||||
|
colors := getRandomColors()
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Compute required frame buffer scaling
|
||||||
|
scale := min(float32(rl.GetScreenWidth())/float32(gameScreenWidth),
|
||||||
|
float32(rl.GetScreenHeight())/float32(gameScreenHeight))
|
||||||
|
|
||||||
|
if rl.IsKeyPressed(rl.KeySpace) {
|
||||||
|
// Recalculate random colors for the bars
|
||||||
|
colors = getRandomColors()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update virtual mouse (clamped mouse value behind game screen)
|
||||||
|
mouse := rl.GetMousePosition()
|
||||||
|
virtualMouse := rl.Vector2{
|
||||||
|
X: (mouse.X - (float32(rl.GetScreenWidth())-(float32(gameScreenWidth)*scale))*0.5) / scale,
|
||||||
|
Y: (mouse.Y - (float32(rl.GetScreenHeight())-(float32(gameScreenHeight)*scale))*0.5) / scale,
|
||||||
|
}
|
||||||
|
virtualMouse = rl.Vector2Clamp(
|
||||||
|
virtualMouse,
|
||||||
|
rl.Vector2{},
|
||||||
|
rl.Vector2{X: float32(gameScreenWidth), Y: float32(gameScreenHeight)},
|
||||||
|
)
|
||||||
|
|
||||||
|
// Apply the same transformation as the virtual mouse to the real mouse (i.e. to work with raygui)
|
||||||
|
//rl.SetMouseOffset(
|
||||||
|
// int(-(float32(rl.GetScreenWidth())-(float32(gameScreenWidth)*scale))*0.5),
|
||||||
|
// int(-(float32(rl.GetScreenHeight())-(float32(gameScreenHeight)*scale))*0.5),
|
||||||
|
//)
|
||||||
|
//rl.SetMouseScale(1/scale, 1/scale)
|
||||||
|
|
||||||
|
// Draw everything in the render texture, note this will not be rendered on screen, yet
|
||||||
|
rl.BeginTextureMode(target)
|
||||||
|
|
||||||
|
rl.ClearBackground(rl.White)
|
||||||
|
for i := int32(0); i < 10; i++ {
|
||||||
|
rl.DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
text := "If executed inside a window,\nyou can resize the window,\nand see the screen scaling!"
|
||||||
|
rl.DrawText(text, 10, 25, 20, rl.White)
|
||||||
|
text = fmt.Sprintf("Default Mouse: [%.0f , %.0f]", mouse.X, mouse.Y)
|
||||||
|
rl.DrawText(text, 350, 25, 20, rl.Green)
|
||||||
|
text = fmt.Sprintf("Virtual Mouse: [%.0f , %.0f]", virtualMouse.X, virtualMouse.Y)
|
||||||
|
rl.DrawText(text, 350, 55, 20, rl.Yellow)
|
||||||
|
|
||||||
|
rl.EndTextureMode()
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.Black)
|
||||||
|
// Draw render texture to screen, properly scaled
|
||||||
|
rl.DrawTexturePro(
|
||||||
|
target.Texture,
|
||||||
|
rl.Rectangle{Width: float32(target.Texture.Width), Height: float32(-target.Texture.Height)},
|
||||||
|
rl.Rectangle{
|
||||||
|
X: (float32(rl.GetScreenWidth()) - float32(gameScreenWidth)*scale) * 0.5,
|
||||||
|
Y: (float32(rl.GetScreenHeight()) - float32(gameScreenHeight)*scale) * 0.5,
|
||||||
|
Width: float32(gameScreenWidth) * scale,
|
||||||
|
Height: float32(gameScreenHeight) * scale,
|
||||||
|
},
|
||||||
|
rl.Vector2{X: 0, Y: 0}, 0, rl.White,
|
||||||
|
)
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
rl.UnloadRenderTexture(target)
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRandomColors() []color.RGBA {
|
||||||
|
var colors []color.RGBA
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
randomColor := color.RGBA{
|
||||||
|
R: rndUint8(100, 250),
|
||||||
|
G: rndUint8(50, 150),
|
||||||
|
B: rndUint8(10, 100),
|
||||||
|
A: 255,
|
||||||
|
}
|
||||||
|
colors = append(colors, randomColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return colors
|
||||||
|
}
|
||||||
|
|
||||||
|
func rndUint8(min, max int32) uint8 {
|
||||||
|
return uint8(rl.GetRandomValue(min, max))
|
||||||
|
}
|
47
examples/core/window_should_close/main.go
Normal file
47
examples/core/window_should_close/main.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 850
|
||||||
|
screenHeight = 480
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [core] example - window should close")
|
||||||
|
|
||||||
|
rl.SetExitKey(rl.KeyNull) // Disable KEY_ESCAPE to close window, X-button still works
|
||||||
|
|
||||||
|
exitWindowRequested := false // Flag to request window to exit
|
||||||
|
exitWindow := false // Flag to set window to exit
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
for !exitWindow {
|
||||||
|
if rl.WindowShouldClose() || rl.IsMouseButtonPressed(rl.KeyEscape) {
|
||||||
|
exitWindowRequested = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if exitWindowRequested {
|
||||||
|
if rl.IsKeyPressed(rl.KeyY) {
|
||||||
|
exitWindow = true
|
||||||
|
} else if rl.IsKeyPressed(rl.KeyN) {
|
||||||
|
exitWindowRequested = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
|
if exitWindowRequested {
|
||||||
|
rl.DrawRectangle(0, 100, screenWidth, 200, rl.Black)
|
||||||
|
rl.DrawText("Are you sure you want to exit the program? [Y/N]", 40, 180, 30, rl.White)
|
||||||
|
} else {
|
||||||
|
rl.DrawText("Try to close the window to get confirmation message!", 120, 200, 20, rl.LightGray)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -3,9 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gen2brain/raylib-go/easings"
|
"git.terah.dev/UnrealXR/raylib-go/easings"
|
||||||
"github.com/gen2brain/raylib-go/raygui"
|
"git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -18,7 +18,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
174
examples/games/pong/main.go
Normal file
174
examples/games/pong/main.go
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Game settings
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 600
|
||||||
|
)
|
||||||
|
|
||||||
|
// Paddle struct
|
||||||
|
type Paddle struct {
|
||||||
|
Pos rl.Vector2
|
||||||
|
Width float32
|
||||||
|
Height float32
|
||||||
|
Speed float32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ball struct
|
||||||
|
type Ball struct {
|
||||||
|
Pos rl.Vector2
|
||||||
|
Speed rl.Vector2
|
||||||
|
Radius float32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game struct
|
||||||
|
type Game struct {
|
||||||
|
paddle1 Paddle
|
||||||
|
paddle2 Paddle
|
||||||
|
ball Ball
|
||||||
|
player1Score int
|
||||||
|
player2Score int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for collision between ball and paddle, and determine side
|
||||||
|
func CheckCollisionSide(ball Ball, paddle Paddle) string {
|
||||||
|
closestX := rl.Clamp(ball.Pos.X, paddle.Pos.X, paddle.Pos.X+paddle.Width)
|
||||||
|
closestY := rl.Clamp(ball.Pos.Y, paddle.Pos.Y, paddle.Pos.Y+paddle.Height)
|
||||||
|
|
||||||
|
dx := ball.Pos.X - closestX
|
||||||
|
dy := ball.Pos.Y - closestY
|
||||||
|
|
||||||
|
distanceSq := dx*dx + dy*dy
|
||||||
|
radiusSq := ball.Radius * ball.Radius
|
||||||
|
|
||||||
|
if distanceSq <= radiusSq {
|
||||||
|
// Determine where it hit
|
||||||
|
if closestX == paddle.Pos.X || closestX == paddle.Pos.X+paddle.Width {
|
||||||
|
return "side"
|
||||||
|
}
|
||||||
|
if closestY == paddle.Pos.Y || closestY == paddle.Pos.Y+paddle.Height {
|
||||||
|
return "topbottom"
|
||||||
|
}
|
||||||
|
return "side" // fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
return "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the game state
|
||||||
|
func (g *Game) Init() {
|
||||||
|
g.paddle1 = Paddle{
|
||||||
|
Pos: rl.NewVector2(30, float32(screenHeight/2-50)),
|
||||||
|
Width: 10,
|
||||||
|
Height: 100,
|
||||||
|
Speed: 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
g.paddle2 = Paddle{
|
||||||
|
Pos: rl.NewVector2(float32(screenWidth-40), float32(screenHeight/2-50)),
|
||||||
|
Width: 10,
|
||||||
|
Height: 100,
|
||||||
|
Speed: 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
g.ball = Ball{
|
||||||
|
Pos: rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2)),
|
||||||
|
Speed: rl.NewVector2(5, 4),
|
||||||
|
Radius: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
g.player1Score = 0
|
||||||
|
g.player2Score = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game update logic
|
||||||
|
func (g *Game) Update() {
|
||||||
|
// Player 1 - W/S
|
||||||
|
if rl.IsKeyDown(rl.KeyW) && g.paddle1.Pos.Y > 0 {
|
||||||
|
g.paddle1.Pos.Y -= g.paddle1.Speed
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(rl.KeyS) && g.paddle1.Pos.Y < screenHeight-g.paddle1.Height {
|
||||||
|
g.paddle1.Pos.Y += g.paddle1.Speed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Player 2 - Up/Down
|
||||||
|
if rl.IsKeyDown(rl.KeyUp) && g.paddle2.Pos.Y > 0 {
|
||||||
|
g.paddle2.Pos.Y -= g.paddle2.Speed
|
||||||
|
}
|
||||||
|
if rl.IsKeyDown(rl.KeyDown) && g.paddle2.Pos.Y < screenHeight-g.paddle2.Height {
|
||||||
|
g.paddle2.Pos.Y += g.paddle2.Speed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ball movement
|
||||||
|
g.ball.Pos.X += g.ball.Speed.X
|
||||||
|
g.ball.Pos.Y += g.ball.Speed.Y
|
||||||
|
|
||||||
|
// Ball bounce off top/bottom walls
|
||||||
|
if g.ball.Pos.Y <= g.ball.Radius || g.ball.Pos.Y >= float32(screenHeight)-g.ball.Radius {
|
||||||
|
g.ball.Speed.Y *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ball collisions with paddle sides only
|
||||||
|
if CheckCollisionSide(g.ball, g.paddle1) == "side" {
|
||||||
|
g.ball.Speed.X *= -1
|
||||||
|
// Reposition ball outside paddle1
|
||||||
|
g.ball.Pos.X = g.paddle1.Pos.X + g.paddle1.Width + g.ball.Radius
|
||||||
|
}
|
||||||
|
|
||||||
|
if CheckCollisionSide(g.ball, g.paddle2) == "side" {
|
||||||
|
g.ball.Speed.X *= -1
|
||||||
|
// Reposition ball outside paddle2
|
||||||
|
g.ball.Pos.X = g.paddle2.Pos.X - g.ball.Radius
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scoring
|
||||||
|
if g.ball.Pos.X < 0 {
|
||||||
|
g.player2Score++
|
||||||
|
g.ball.Pos = rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2))
|
||||||
|
g.ball.Speed.X *= -1
|
||||||
|
}
|
||||||
|
if g.ball.Pos.X > float32(screenWidth) {
|
||||||
|
g.player1Score++
|
||||||
|
g.ball.Pos = rl.NewVector2(float32(screenWidth/2), float32(screenHeight/2))
|
||||||
|
g.ball.Speed.X *= -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw game elements
|
||||||
|
func (g *Game) Draw() {
|
||||||
|
// Draw paddles
|
||||||
|
rl.DrawRectangleV(g.paddle1.Pos, rl.NewVector2(g.paddle1.Width, g.paddle1.Height), rl.Black)
|
||||||
|
rl.DrawRectangleV(g.paddle2.Pos, rl.NewVector2(g.paddle2.Width, g.paddle2.Height), rl.Black)
|
||||||
|
|
||||||
|
// Draw ball
|
||||||
|
rl.DrawCircleV(g.ball.Pos, g.ball.Radius, rl.Black)
|
||||||
|
|
||||||
|
// Draw scores
|
||||||
|
rl.DrawText(fmt.Sprintf("Player 1 : %d", g.player1Score), 20, 20, 20, rl.DarkGray)
|
||||||
|
rl.DrawText(fmt.Sprintf("Player 2 : %d", g.player2Score), screenWidth-140, 20, 20, rl.DarkGray)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "Pong in Go!")
|
||||||
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
|
var game Game
|
||||||
|
game.Init()
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
game.Update()
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
game.Draw()
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
snakeLength = 256
|
snakeLength = 256
|
||||||
squareSize = 31
|
squareSize = 31
|
||||||
|
|
|
@ -2,24 +2,25 @@ module examples
|
||||||
|
|
||||||
go 1.21
|
go 1.21
|
||||||
|
|
||||||
replace github.com/gen2brain/raylib-go/raylib => ../raylib
|
replace git.terah.dev/UnrealXR/raylib-go/raylib => ../raylib
|
||||||
|
|
||||||
replace github.com/gen2brain/raylib-go/raygui => ../raygui
|
replace git.terah.dev/UnrealXR/raylib-go/raygui => ../raygui
|
||||||
|
|
||||||
replace github.com/gen2brain/raylib-go/easings => ../easings
|
replace git.terah.dev/UnrealXR/raylib-go/easings => ../easings
|
||||||
|
|
||||||
replace github.com/gen2brain/raylib-go/physics => ../physics
|
replace git.terah.dev/UnrealXR/raylib-go/physics => ../physics
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gen2brain/raylib-go/easings v0.0.0-00010101000000-000000000000
|
git.terah.dev/UnrealXR/raylib-go/easings v0.0.0-00010101000000-000000000000
|
||||||
github.com/gen2brain/raylib-go/physics v0.0.0-00010101000000-000000000000
|
git.terah.dev/UnrealXR/raylib-go/physics v0.0.0-00010101000000-000000000000
|
||||||
github.com/gen2brain/raylib-go/raygui v0.0.0-00010101000000-000000000000
|
git.terah.dev/UnrealXR/raylib-go/raygui v0.0.0-00010101000000-000000000000
|
||||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20231118125650-a1c890e8cbfc
|
git.terah.dev/UnrealXR/raylib-go/raylib v0.0.0-20241202103652-5d50abe7c65b
|
||||||
github.com/jakecoffman/cp v1.2.1
|
github.com/jakecoffman/cp v1.2.1
|
||||||
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b
|
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ebitengine/purego v0.5.0 // indirect
|
github.com/ebitengine/purego v0.8.1 // indirect
|
||||||
golang.org/x/sys v0.14.0 // indirect
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
|
||||||
|
golang.org/x/sys v0.27.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
github.com/ebitengine/purego v0.5.0 h1:JrMGKfRIAM4/QVKaesIIT7m/UVjTj5GYhRSQYwfVdpo=
|
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
|
||||||
github.com/ebitengine/purego v0.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||||
github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI=
|
github.com/jakecoffman/cp v1.2.1 h1:zkhc2Gpo9l4NLUZfeG3j33+3bQD7MkqPa+n5PdX+5mI=
|
||||||
github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
|
github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
|
||||||
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI=
|
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b h1:+67TGbwfgeB5o03Rx+ZBW44zAQ+wUujcwdRA0p9CbJI=
|
||||||
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b/go.mod h1:kvKwD9codtns5mvpA53V3vLnqFb/Ahcu8zgkGM0SIbI=
|
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b/go.mod h1:kvKwD9codtns5mvpA53V3vLnqFb/Ahcu8zgkGM0SIbI=
|
||||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
|
||||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
|
||||||
|
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||||
|
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
|
|
@ -3,8 +3,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
gui "github.com/gen2brain/raylib-go/raygui"
|
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
gui "github.com/gen2brain/raylib-go/raygui"
|
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
|
|
3
examples/gui/icons/README.md
Normal file
3
examples/gui/icons/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
This example loads a custom .rgi-file and draws the 255th icon. You can use the [rGuiIcons](https://raylibtech.itch.io/rguiicons) tool to view or create icon files.
|
||||||
|
|
||||||
|

|
BIN
examples/gui/icons/default_icons_with_255.rgi
Normal file
BIN
examples/gui/icons/default_icons_with_255.rgi
Normal file
Binary file not shown.
20
examples/gui/icons/main.go
Normal file
20
examples/gui/icons/main.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(800, 600, "raylib-go - icons example")
|
||||||
|
defer rl.CloseWindow()
|
||||||
|
|
||||||
|
raygui.LoadIcons("default_icons_with_255.rgi", false)
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
raygui.DrawIcon(raygui.ICON_255, 100, 100, 8, rl.Gray)
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
}
|
BIN
examples/gui/icons/screenshot.png
Normal file
BIN
examples/gui/icons/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8 KiB |
|
@ -3,8 +3,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
gui "github.com/gen2brain/raylib-go/raygui"
|
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
|
|
|
@ -3,8 +3,8 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
gui "github.com/gen2brain/raylib-go/raygui"
|
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
|
|
|
@ -1,20 +1,42 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - Load 3d model with animations and play them
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 2.5, last time updated with raylib 3.5
|
||||||
|
*
|
||||||
|
* Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2024 Culacant (@culacant) and Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************
|
||||||
|
*
|
||||||
|
* NOTE: To export a model from blender, make sure it is not posed, the vertices need to be
|
||||||
|
* in the same position as they would be in edit mode and the scale of your models is
|
||||||
|
* set to 0. Scaling can be done from the export menu.
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(1280)
|
|
||||||
screenHeight := int32(800)
|
|
||||||
|
|
||||||
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation")
|
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation")
|
||||||
|
|
||||||
camera := rl.Camera{}
|
camera := rl.Camera{}
|
||||||
camera.Position = rl.NewVector3(10.0, 15.0, 10.0)
|
camera.Position = rl.NewVector3(10.0, 10.0, 10.0)
|
||||||
camera.Target = rl.NewVector3(0.0, 0.0, 0.0)
|
camera.Target = rl.NewVector3(0.0, 0.0, 0.0)
|
||||||
camera.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
camera.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
||||||
camera.Fovy = 75.0
|
camera.Fovy = 45.0
|
||||||
camera.Projection = rl.CameraPerspective
|
camera.Projection = rl.CameraPerspective
|
||||||
|
|
||||||
model := rl.LoadModel("guy.iqm")
|
model := rl.LoadModel("guy.iqm")
|
||||||
|
@ -32,7 +54,7 @@ func main() {
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
|
|
||||||
rl.UpdateCamera(&camera, rl.CameraOrbital)
|
rl.UpdateCamera(&camera, rl.CameraFirstPerson)
|
||||||
|
|
||||||
if rl.IsKeyDown(rl.KeySpace) {
|
if rl.IsKeyDown(rl.KeySpace) {
|
||||||
animFrameCount++
|
animFrameCount++
|
||||||
|
@ -43,17 +65,18 @@ func main() {
|
||||||
if animFrameCount >= int(animFrameNum) {
|
if animFrameCount >= int(animFrameNum) {
|
||||||
animFrameCount = 0
|
animFrameCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
rl.BeginMode3D(camera)
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
rl.DrawModelEx(model, position, rl.NewVector3(1, 0, 0), -90, rl.NewVector3(1, 1, 1), rl.White)
|
rl.DrawModelEx(model, position, rl.NewVector3(1, 0, 0), -90, rl.NewVector3(1, 1, 1), rl.White)
|
||||||
|
// Draw translation cubes
|
||||||
|
for i := int32(0); i < model.BoneCount; i++ {
|
||||||
|
pose := anims[0].GetFramePose(animFrameCount, int(i))
|
||||||
|
rl.DrawCube(pose.Translation, 0.2, 0.2, 0.2, rl.Red)
|
||||||
|
}
|
||||||
rl.DrawGrid(10, 1)
|
rl.DrawGrid(10, 1)
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
@ -65,6 +88,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.UnloadModel(model)
|
rl.UnloadModel(model)
|
||||||
|
rl.UnloadModelAnimations(anims)
|
||||||
rl.UnloadTexture(texture)
|
rl.UnloadTexture(texture)
|
||||||
|
|
||||||
rl.CloseWindow()
|
rl.CloseWindow()
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
package main
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - Drawing billboards
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 1.3, last time updated with raylib 3.5
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(800)
|
|
||||||
screenHeight := int32(450)
|
|
||||||
|
|
||||||
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards")
|
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards")
|
||||||
|
|
||||||
camera := rl.Camera{}
|
camera := rl.Camera{}
|
||||||
|
@ -18,25 +31,60 @@ func main() {
|
||||||
camera.Projection = rl.CameraPerspective
|
camera.Projection = rl.CameraPerspective
|
||||||
|
|
||||||
bill := rl.LoadTexture("billboard.png") // Our texture billboard
|
bill := rl.LoadTexture("billboard.png") // Our texture billboard
|
||||||
billPosition := rl.NewVector3(0.0, 2.0, 0.0) // Position where draw billboard
|
billPositionStatic := rl.NewVector3(0.0, 2.0, 0.0) // Position of static billboard
|
||||||
|
billPositionRotating := rl.NewVector3(1.0, 2.0, 1.0) // Position of rotating billboard
|
||||||
|
|
||||||
|
// Entire billboard texture, source is used to take a segment from a larger texture.
|
||||||
|
source := rl.Rectangle{
|
||||||
|
Width: float32(bill.Width),
|
||||||
|
Height: float32(bill.Height),
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Billboard locked on axis-Y
|
||||||
|
billUp := rl.Vector3{Y: 1.0}
|
||||||
|
|
||||||
|
// Set the height of the rotating billboard to 1.0 with the aspect ratio fixed
|
||||||
|
size := rl.Vector2{
|
||||||
|
X: source.Width / source.Height,
|
||||||
|
Y: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate around origin
|
||||||
|
// Here we choose to rotate around the image center
|
||||||
|
origin := rl.Vector2Scale(size, 0.5)
|
||||||
|
|
||||||
|
// Distance is needed for the correct billboard draw order
|
||||||
|
// Larger distance (further away from the camera) should be drawn prior to smaller distance.
|
||||||
|
var distanceStatic, distanceRotating, rotation float32
|
||||||
|
|
||||||
rl.SetTargetFPS(60)
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
|
// Update
|
||||||
rl.UpdateCamera(&camera, rl.CameraOrbital) // Update camera with orbital camera mode
|
rl.UpdateCamera(&camera, rl.CameraOrbital) // Update camera with orbital camera mode
|
||||||
|
|
||||||
|
rotation += 0.4
|
||||||
|
distanceStatic = rl.Vector3Distance(camera.Position, billPositionStatic)
|
||||||
|
distanceRotating = rl.Vector3Distance(camera.Position, billPositionRotating)
|
||||||
|
|
||||||
|
// Draw
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
rl.BeginMode3D(camera)
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
rl.DrawGrid(10, 1.0) // Draw a grid
|
rl.DrawGrid(10, 1.0) // Draw a grid
|
||||||
|
|
||||||
rl.DrawBillboard(camera, bill, billPosition, 2.0, rl.White)
|
// Draw order matters!
|
||||||
|
if distanceStatic > distanceRotating {
|
||||||
|
rl.DrawBillboard(camera, bill, billPositionStatic, 2.0, rl.White)
|
||||||
|
rl.DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, size, origin, rotation, rl.White)
|
||||||
|
} else {
|
||||||
|
rl.DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, size, origin, rotation, rl.White)
|
||||||
|
rl.DrawBillboard(camera, bill, billPositionStatic, 2.0, rl.White)
|
||||||
|
}
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
BIN
examples/models/draw_cube_texture/cubicmap_atlas.png
Normal file
BIN
examples/models/draw_cube_texture/cubicmap_atlas.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
256
examples/models/draw_cube_texture/main.go
Normal file
256
examples/models/draw_cube_texture/main.go
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - Draw textured cube
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - draw cube texture")
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
camera := rl.Camera{
|
||||||
|
Position: rl.Vector3{
|
||||||
|
Y: 10.0,
|
||||||
|
Z: 10.0,
|
||||||
|
},
|
||||||
|
Target: rl.Vector3{},
|
||||||
|
Up: rl.Vector3{Y: 1.0},
|
||||||
|
Fovy: 45.0,
|
||||||
|
Projection: rl.CameraPerspective,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load texture to be applied to the cubes sides
|
||||||
|
texture := rl.LoadTexture("cubicmap_atlas.png")
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Update
|
||||||
|
// TODO: Update your variables here
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
// Draw cube with an applied texture
|
||||||
|
vec := rl.Vector3{
|
||||||
|
X: -2.0,
|
||||||
|
Y: 2.0,
|
||||||
|
}
|
||||||
|
DrawCubeTexture(texture, vec, 2.0, 4.0, 2.0, rl.White)
|
||||||
|
|
||||||
|
// Draw cube with an applied texture, but only a defined rectangle piece of the texture
|
||||||
|
rec := rl.Rectangle{
|
||||||
|
Y: float32(texture.Height) / 2.0,
|
||||||
|
Width: float32(texture.Width) / 2.0,
|
||||||
|
Height: float32(texture.Height) / 2.0,
|
||||||
|
}
|
||||||
|
vec = rl.Vector3{
|
||||||
|
X: 2.0,
|
||||||
|
Y: 1.0,
|
||||||
|
}
|
||||||
|
DrawCubeTextureRec(texture, rec, vec, 2.0, 2.0, 2.0, rl.White)
|
||||||
|
|
||||||
|
rl.DrawGrid(10, 1.0) // Draw a grid
|
||||||
|
rl.EndMode3D()
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.UnloadTexture(texture) // Unload texture
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawCubeTexture draws a textured cube
|
||||||
|
// NOTE: Cube position is the center position
|
||||||
|
func DrawCubeTexture(texture rl.Texture2D, position rl.Vector3, width, height, length float32, color rl.Color) {
|
||||||
|
x := position.X
|
||||||
|
y := position.Y
|
||||||
|
z := position.Z
|
||||||
|
|
||||||
|
// Set desired texture to be enabled while drawing following vertex data
|
||||||
|
rl.SetTexture(texture.ID)
|
||||||
|
|
||||||
|
// Vertex data transformation can be defined with the commented lines,
|
||||||
|
// but in this example we calculate the transformed vertex data directly when calling rlVertex3f()
|
||||||
|
// rl.PushMatrix()
|
||||||
|
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
|
||||||
|
//rl.Translatef(2.0, 0.0, 0.0)
|
||||||
|
//rl.Rotatef(45, 0, 1, )
|
||||||
|
//rl.Scalef(2.0, 2.0, 2.0)
|
||||||
|
|
||||||
|
rl.Begin(rl.Quads)
|
||||||
|
rl.Color4ub(color.R, color.G, color.B, color.A)
|
||||||
|
// Front Face
|
||||||
|
rl.Normal3f(0.0, 0.0, 1.0) // Normal Pointing Towards Viewer
|
||||||
|
rl.TexCoord2f(0.0, 0.0)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z+length/2) // Bottom Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 0.0)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z+length/2) // Bottom Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 1.0)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z+length/2) // Top Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 1.0)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z+length/2) // Top Left Of The Texture and Quad
|
||||||
|
// Back Face
|
||||||
|
rl.Normal3f(0.0, 0.0, -1.0) // Normal Pointing Away From Viewer
|
||||||
|
rl.TexCoord2f(1.0, 0.0)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z-length/2) // Bottom Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 1.0)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z-length/2) // Top Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 1.0)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z-length/2) // Top Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 0.0)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z-length/2) // Bottom Left Of The Texture and Quad
|
||||||
|
// Top Face
|
||||||
|
rl.Normal3f(0.0, 1.0, 0.0) // Normal Pointing Up
|
||||||
|
rl.TexCoord2f(0.0, 1.0)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z-length/2) // Top Left Of The Texture and Quad.
|
||||||
|
rl.TexCoord2f(0.0, 0.0)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z+length/2) // Bottom Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 0.0)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z+length/2) // Bottom Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 1.0)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z-length/2) // Top Right Of The Texture and Quad Bottom Face
|
||||||
|
rl.Normal3f(0.0, -1.0, 0.0) // Normal Pointing Down
|
||||||
|
rl.TexCoord2f(1.0, 1.0)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z-length/2) // Top Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 1.0)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z-length/2) // Top Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 0.0)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z+length/2) // Bottom Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 0.0)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z+length/2) // Bottom Right Of The Texture and Quad
|
||||||
|
// Right face
|
||||||
|
rl.Normal3f(1.0, 0.0, 0.0) // Normal Pointing Right
|
||||||
|
rl.TexCoord2f(1.0, 0.0)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z-length/2) // Bottom Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 1.0)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z-length/2) // Top Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 1.0)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z+length/2) // Top Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 0.0)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z+length/2) // Bottom Left Of The Texture and Quad
|
||||||
|
// Left Face
|
||||||
|
rl.Normal3f(-1.0, 0.0, 0.0) // Normal Pointing Left
|
||||||
|
rl.TexCoord2f(0.0, 0.0)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z-length/2) // Bottom Left Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 0.0)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z+length/2) // Bottom Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(1.0, 1.0)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z+length/2) // Top Right Of The Texture and Quad
|
||||||
|
rl.TexCoord2f(0.0, 1.0)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z-length/2) // Top Left Of The Texture and Quad
|
||||||
|
|
||||||
|
rl.End()
|
||||||
|
//rl.PopMatrix()
|
||||||
|
|
||||||
|
rl.SetTexture(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawCubeTextureRec draws a cube with texture piece applied to all faces
|
||||||
|
func DrawCubeTextureRec(texture rl.Texture2D, source rl.Rectangle, position rl.Vector3, width, height,
|
||||||
|
length float32, color rl.Color) {
|
||||||
|
|
||||||
|
x := position.X
|
||||||
|
y := position.Y
|
||||||
|
z := position.Z
|
||||||
|
|
||||||
|
texWidth := float32(texture.Width)
|
||||||
|
texHeight := float32(texture.Height)
|
||||||
|
|
||||||
|
// Set desired texture to be enabled while drawing following vertex data
|
||||||
|
rl.SetTexture(texture.ID)
|
||||||
|
|
||||||
|
// We calculate the normalized texture coordinates for the desired texture-source-rectangle
|
||||||
|
// It means converting from (tex.width, tex.height) coordinates to [0.0f, 1.0f] equivalent
|
||||||
|
rl.Begin(rl.Quads)
|
||||||
|
rl.Color4ub(color.R, color.G, color.B, color.A)
|
||||||
|
|
||||||
|
// Front face
|
||||||
|
rl.Normal3f(0.0, 0.0, 1.0)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z+length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z+length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z+length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z+length/2)
|
||||||
|
|
||||||
|
// Back face
|
||||||
|
rl.Normal3f(0.0, 0.0, -1.0)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z-length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z-length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z-length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z-length/2)
|
||||||
|
|
||||||
|
// Top face
|
||||||
|
rl.Normal3f(0.0, 1.0, 0.0)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z-length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z+length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z+length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z-length/2)
|
||||||
|
|
||||||
|
// Bottom face
|
||||||
|
rl.Normal3f(0.0, -1.0, 0.0)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z-length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z-length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z+length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z+length/2)
|
||||||
|
|
||||||
|
// Right face
|
||||||
|
rl.Normal3f(1.0, 0.0, 0.0)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z-length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z-length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y+height/2, z+length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x+width/2, y-height/2, z+length/2)
|
||||||
|
|
||||||
|
// Left face
|
||||||
|
rl.Normal3f(-1.0, 0.0, 0.0)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z-length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, (source.Y+source.Height)/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y-height/2, z+length/2)
|
||||||
|
rl.TexCoord2f((source.X+source.Width)/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z+length/2)
|
||||||
|
rl.TexCoord2f(source.X/texWidth, source.Y/texHeight)
|
||||||
|
rl.Vertex3f(x-width/2, y+height/2, z-length/2)
|
||||||
|
|
||||||
|
rl.End()
|
||||||
|
|
||||||
|
rl.SetTexture(0)
|
||||||
|
}
|
|
@ -2,8 +2,8 @@
|
||||||
*
|
*
|
||||||
* raylib [models] example - first person maze
|
* raylib [models] example - first person maze
|
||||||
*
|
*
|
||||||
* This example has been created using raylib-go v0.0.0-20220104071325-2f072dc2d259 (https://github.com/gen2brain/raylib-go)
|
* This example has been created using raylib-go v0.0.0-20220104071325-2f072dc2d259 (https://git.terah.dev/UnrealXR/raylib-go)
|
||||||
* raylib-go is licensed under an unmodified zlib/libpng license (https://github.com/gen2brain/raylib-go/blob/master/LICENSE)
|
* raylib-go is licensed under an unmodified zlib/libpng license (https://git.terah.dev/UnrealXR/raylib-go/blob/master/LICENSE)
|
||||||
*
|
*
|
||||||
* Original C version for Raylib 2.5 Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
* Original C version for Raylib 2.5 Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
||||||
* Converted to Go by Michael Redman January 4, 2022
|
* Converted to Go by Michael Redman January 4, 2022
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(800)
|
screenWidth := int32(800)
|
||||||
screenHeight := int32(450)
|
screenHeight := int32(450)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -62,7 +62,7 @@ func main() {
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
|
||||||
rl.DrawText("current animation number: "+fmt.Sprint(animIndex), 10, 10, 10, rl.Black)
|
rl.DrawText(fmt.Sprintf("current animation: %s [%d]", animPlaying.GetName(), animIndex), 10, 10, 10, rl.Black)
|
||||||
rl.DrawText("UP/DOWN ARROW KEYS CHANGE ANIMATION", 10, 30, 10, rl.Black)
|
rl.DrawText("UP/DOWN ARROW KEYS CHANGE ANIMATION", 10, 30, 10, rl.Black)
|
||||||
|
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
//"fmt"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
BIN
examples/models/m3d_loading/cesium_man.m3d
Normal file
BIN
examples/models/m3d_loading/cesium_man.m3d
Normal file
Binary file not shown.
155
examples/models/m3d_loading/main.go
Normal file
155
examples/models/m3d_loading/main.go
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - Load models M3D
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||||
|
*
|
||||||
|
* Example contributed by bzt (@bztsrc) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* NOTES:
|
||||||
|
* - Model3D (M3D) fileformat specs: https://gitlab.com/bztsrc/model3d
|
||||||
|
* - Bender M3D exported: https://gitlab.com/bztsrc/model3d/-/tree/master/blender
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022-2024 bzt (@bztsrc)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialization
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - M3D model loading")
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
camera := rl.Camera{
|
||||||
|
Position: rl.NewVector3(1.5, 1.5, 1.5),
|
||||||
|
Target: rl.NewVector3(0.0, 0.4, 0.0),
|
||||||
|
Up: rl.NewVector3(0.0, 1.0, 0.0),
|
||||||
|
Fovy: 45.0,
|
||||||
|
Projection: rl.CameraPerspective,
|
||||||
|
}
|
||||||
|
|
||||||
|
position := rl.NewVector3(0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
modelFileName := "cesium_man.m3d"
|
||||||
|
drawMesh := true
|
||||||
|
drawSkeleton := true
|
||||||
|
animPlaying := false // Store anim state, what to draw
|
||||||
|
|
||||||
|
// Load model
|
||||||
|
model := rl.LoadModel(modelFileName)
|
||||||
|
|
||||||
|
// Load animations
|
||||||
|
|
||||||
|
animFrameCounter := 0
|
||||||
|
animID := 0
|
||||||
|
anims := rl.LoadModelAnimations(modelFileName)
|
||||||
|
animsCount := int32(len(anims))
|
||||||
|
|
||||||
|
rl.DisableCursor()
|
||||||
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
// Update
|
||||||
|
rl.UpdateCamera(&camera, rl.CameraFirstPerson)
|
||||||
|
|
||||||
|
if animsCount > 0 {
|
||||||
|
// Play animation when space bar is held down (or step one frame with N)
|
||||||
|
if rl.IsKeyDown(rl.KeySpace) || rl.IsKeyPressed(rl.KeyN) {
|
||||||
|
animFrameCounter++
|
||||||
|
if animFrameCounter >= int(anims[animID].FrameCount) {
|
||||||
|
animFrameCounter = 0
|
||||||
|
}
|
||||||
|
rl.UpdateModelAnimation(model, anims[animID], int32(animFrameCounter))
|
||||||
|
animPlaying = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select animation by pressing C
|
||||||
|
if rl.IsKeyPressed(rl.KeyC) {
|
||||||
|
animFrameCounter = 0
|
||||||
|
animID++
|
||||||
|
if animID >= int(animsCount) {
|
||||||
|
animID = 0
|
||||||
|
}
|
||||||
|
rl.UpdateModelAnimation(model, anims[animID], 0)
|
||||||
|
animPlaying = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle skeleton drawing
|
||||||
|
if rl.IsKeyPressed(rl.KeyB) {
|
||||||
|
drawSkeleton = !drawSkeleton
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle mesh drawing
|
||||||
|
if rl.IsKeyPressed(rl.KeyM) {
|
||||||
|
drawMesh = !drawMesh
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
// Draw 3d model with texture
|
||||||
|
if drawMesh {
|
||||||
|
rl.DrawModel(model, position, 1.0, rl.White)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the animated skeleton
|
||||||
|
if drawSkeleton {
|
||||||
|
modelBones := model.GetBones()
|
||||||
|
modelPoses := model.GetBindPose()
|
||||||
|
anim := anims[animID]
|
||||||
|
animBones := anim.GetBones()
|
||||||
|
for bone := 0; bone < int(model.BoneCount)-1; bone++ {
|
||||||
|
if !animPlaying || animsCount == 0 {
|
||||||
|
// Display the bind-pose skeleton
|
||||||
|
rl.DrawCube(modelPoses[bone].Translation, 0.04, 0.04, 0.04, rl.Red)
|
||||||
|
if modelBones[bone].Parent >= 0 {
|
||||||
|
rl.DrawLine3D(modelPoses[bone].Translation, modelPoses[modelBones[bone].Parent].Translation, rl.Red)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// // Display the frame-pose skeleton
|
||||||
|
pos := anim.GetFramePose(animFrameCounter, bone).Translation
|
||||||
|
rl.DrawCube(pos, 0.05, 0.05, 0.05, rl.Red)
|
||||||
|
if animBones[bone].Parent >= 0 {
|
||||||
|
endPos := anim.GetFramePose(animFrameCounter, int(animBones[bone].Parent)).Translation
|
||||||
|
rl.DrawLine3D(pos, endPos, rl.Red)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawGrid(10, 1.0)
|
||||||
|
|
||||||
|
rl.EndMode3D()
|
||||||
|
|
||||||
|
rl.DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, screenHeight-80, 10, rl.Maroon)
|
||||||
|
rl.DrawText("PRESS N to STEP ONE ANIMATION FRAME", 10, screenHeight-60, 10, rl.DarkGray)
|
||||||
|
rl.DrawText("PRESS C to CYCLE THROUGH ANIMATIONS", 10, screenHeight-40, 10, rl.DarkGray)
|
||||||
|
rl.DrawText("PRESS M to toggle MESH, B to toggle SKELETON DRAWING", 10, screenHeight-20, 10, rl.DarkGray)
|
||||||
|
rl.DrawText("(c) CesiumMan model by KhronosGroup", screenWidth-210, screenHeight-20, 10, rl.Gray)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.UnloadModelAnimations(anims)
|
||||||
|
rl.UnloadModel(model)
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
|
@ -1,14 +1,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
"unsafe"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(1280)
|
screenWidth := int32(1280)
|
||||||
screenHeight := int32(720)
|
screenHeight := int32(720)
|
||||||
|
|
||||||
numModels := 8
|
numModels := 9
|
||||||
|
|
||||||
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh generation")
|
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh generation")
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ func main() {
|
||||||
models[5] = rl.LoadModelFromMesh(rl.GenMeshTorus(0.25, 4, 16, 32))
|
models[5] = rl.LoadModelFromMesh(rl.GenMeshTorus(0.25, 4, 16, 32))
|
||||||
models[6] = rl.LoadModelFromMesh(rl.GenMeshKnot(1, 2, 16, 128))
|
models[6] = rl.LoadModelFromMesh(rl.GenMeshKnot(1, 2, 16, 128))
|
||||||
models[7] = rl.LoadModelFromMesh(rl.GenMeshPoly(5, 2))
|
models[7] = rl.LoadModelFromMesh(rl.GenMeshPoly(5, 2))
|
||||||
|
models[8] = rl.LoadModelFromMesh(GenMeshCustom())
|
||||||
|
|
||||||
for i := 0; i < numModels; i++ {
|
for i := 0; i < numModels; i++ {
|
||||||
rl.SetMaterialTexture(models[i].Materials, rl.MapDiffuse, texture)
|
rl.SetMaterialTexture(models[i].Materials, rl.MapDiffuse, texture)
|
||||||
|
@ -49,12 +52,17 @@ func main() {
|
||||||
rl.UpdateCamera(&camera, rl.CameraOrbital)
|
rl.UpdateCamera(&camera, rl.CameraOrbital)
|
||||||
|
|
||||||
if rl.IsKeyPressed(rl.KeyUp) {
|
if rl.IsKeyPressed(rl.KeyUp) {
|
||||||
currentModel++
|
currentModel = (currentModel + 1) % numModels // Cycle between the textures
|
||||||
if currentModel >= numModels {
|
|
||||||
currentModel = 0
|
|
||||||
}
|
}
|
||||||
|
if rl.IsKeyPressed(rl.KeyDown) {
|
||||||
|
// Adding numModels here is necessary to avoid a crash
|
||||||
|
// where the golang % (modulus) operator, doesn't work as
|
||||||
|
// one might expect for negative numbers.
|
||||||
|
currentModel = (currentModel + numModels - 1) % numModels // Cycle between the textures
|
||||||
|
}
|
||||||
|
if rl.IsMouseButtonPressed(rl.MouseButtonLeft) {
|
||||||
|
currentModel = (currentModel + 1) % numModels // Cycle between the textures
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
@ -66,9 +74,10 @@ func main() {
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
|
||||||
rl.DrawRectangle(10, 10, 310, 30, rl.Fade(rl.SkyBlue, 0.5))
|
rl.DrawRectangle(10, 10, 310, 50, rl.Fade(rl.SkyBlue, 0.5))
|
||||||
rl.DrawRectangleLines(10, 10, 310, 30, rl.Fade(rl.DarkBlue, 0.5))
|
rl.DrawRectangleLines(10, 10, 310, 50, rl.Fade(rl.DarkBlue, 0.5))
|
||||||
rl.DrawText("UP ARROW KEY TO CHANGE MODELS", 20, 20, 10, rl.Blue)
|
rl.DrawText("UP/DOWN ARROW KEY OR LEFT MOUSE", 20, 20, 10, rl.Blue)
|
||||||
|
rl.DrawText("BUTTON TO CHANGE MODELS", 20, 40, 10, rl.Blue)
|
||||||
|
|
||||||
txt := "PLANE"
|
txt := "PLANE"
|
||||||
switch currentModel {
|
switch currentModel {
|
||||||
|
@ -86,6 +95,8 @@ func main() {
|
||||||
txt = "KNOT"
|
txt = "KNOT"
|
||||||
case 7:
|
case 7:
|
||||||
txt = "POLY"
|
txt = "POLY"
|
||||||
|
case 8:
|
||||||
|
txt = "Custom (triangle)"
|
||||||
}
|
}
|
||||||
txtlen := rl.MeasureText(txt, 20)
|
txtlen := rl.MeasureText(txt, 20)
|
||||||
rl.DrawText(txt, screenWidth/2-txtlen/2, 10, 20, rl.DarkBlue)
|
rl.DrawText(txt, screenWidth/2-txtlen/2, 10, 20, rl.DarkBlue)
|
||||||
|
@ -94,9 +105,63 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.UnloadTexture(texture)
|
rl.UnloadTexture(texture)
|
||||||
|
// Custom models meshes needs to be
|
||||||
|
// cleared manually
|
||||||
|
clearCustomMesh(models[8])
|
||||||
for i := 0; i < numModels; i++ {
|
for i := 0; i < numModels; i++ {
|
||||||
rl.UnloadModel(models[i])
|
rl.UnloadModel(models[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.CloseWindow()
|
rl.CloseWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearCustomMesh(model rl.Model) {
|
||||||
|
// Vertices, Normals and Texcoords of your CUSTOM mesh are Go slices.
|
||||||
|
// UnloadModel calls UnloadMesh for every mesh and UnloadMesh tries
|
||||||
|
// to free your Go slices. This will panic because it cannot free
|
||||||
|
// Go slices. Free() is a C function and it expects to free C memory
|
||||||
|
// and not a Go slice. So clear the slices manually like this.
|
||||||
|
model.Meshes.Vertices = nil
|
||||||
|
model.Meshes.Normals = nil
|
||||||
|
model.Meshes.Texcoords = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenMeshCustom generates a simple triangle mesh from code
|
||||||
|
func GenMeshCustom() rl.Mesh {
|
||||||
|
mesh := rl.Mesh{
|
||||||
|
TriangleCount: 1,
|
||||||
|
VertexCount: 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
var vertices, normals, texcoords []float32
|
||||||
|
|
||||||
|
// 3 vertices
|
||||||
|
vertices = addCoord(vertices, 0, 0, 0)
|
||||||
|
vertices = addCoord(vertices, 1, 0, 2)
|
||||||
|
vertices = addCoord(vertices, 2, 0, 0)
|
||||||
|
mesh.Vertices = unsafe.SliceData(vertices)
|
||||||
|
|
||||||
|
// 3 normals
|
||||||
|
normals = addCoord(normals, 0, 1, 0)
|
||||||
|
normals = addCoord(normals, 0, 1, 0)
|
||||||
|
normals = addCoord(normals, 0, 1, 0)
|
||||||
|
mesh.Normals = unsafe.SliceData(normals)
|
||||||
|
|
||||||
|
// 3 texcoords
|
||||||
|
texcoords = addCoord(texcoords, 0, 0)
|
||||||
|
texcoords = addCoord(texcoords, 0.5, 1)
|
||||||
|
texcoords = addCoord(texcoords, 1, 0)
|
||||||
|
mesh.Texcoords = unsafe.SliceData(texcoords)
|
||||||
|
|
||||||
|
// Upload mesh data from CPU (RAM) to GPU (VRAM) memory
|
||||||
|
rl.UploadMesh(&mesh, false)
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
}
|
||||||
|
|
||||||
|
func addCoord(slice []float32, values ...float32) []float32 {
|
||||||
|
for _, value := range values {
|
||||||
|
slice = append(slice, value)
|
||||||
|
}
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
261
examples/models/mesh_picking/main.go
Normal file
261
examples/models/mesh_picking/main.go
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - Mesh picking in 3d mode, ground plane, triangle, mesh
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 1.7, last time updated with raylib 4.0
|
||||||
|
*
|
||||||
|
* Example contributed by Joel Davis (@joeld42) 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) 2017-2024 Joel Davis (@joeld42) and Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
// Program main entry point
|
||||||
|
func main() {
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - mesh picking")
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
camera := rl.Camera{
|
||||||
|
Position: rl.Vector3{
|
||||||
|
X: 20.0,
|
||||||
|
Y: 20.0,
|
||||||
|
Z: 20.0,
|
||||||
|
}, // Camera position
|
||||||
|
Target: rl.Vector3{Y: 8.0}, // Camera looking at point
|
||||||
|
Up: rl.Vector3{Y: 1.6}, // Camera up vector (rotation towards target)
|
||||||
|
Fovy: 45.0, // Camera field-of-view Y
|
||||||
|
Projection: rl.CameraPerspective, // Camera projection type
|
||||||
|
}
|
||||||
|
var ray rl.Ray // Picking ray
|
||||||
|
|
||||||
|
tower := rl.LoadModel("turret.obj") // Load OBJ model
|
||||||
|
texture := rl.LoadTexture("turret_diffuse.png") // Load model texture
|
||||||
|
materials := unsafe.Slice(tower.Materials, tower.MaterialCount)
|
||||||
|
materials[0].GetMap(rl.MapDiffuse).Texture = texture // Set model diffuse texture
|
||||||
|
|
||||||
|
towerPos := rl.Vector3{} // Set model position
|
||||||
|
meshes := unsafe.Slice(tower.Meshes, tower.MeshCount)
|
||||||
|
towerBBox := rl.GetMeshBoundingBox(meshes[0]) // Get mesh bounding box
|
||||||
|
|
||||||
|
// Ground quad
|
||||||
|
g0 := rl.Vector3{
|
||||||
|
X: -50.0,
|
||||||
|
Z: -50.0,
|
||||||
|
}
|
||||||
|
g1 := rl.Vector3{
|
||||||
|
X: -50.0,
|
||||||
|
Z: 50.0,
|
||||||
|
}
|
||||||
|
g2 := rl.Vector3{
|
||||||
|
X: 50.0,
|
||||||
|
Z: 50.0,
|
||||||
|
}
|
||||||
|
g3 := rl.Vector3{
|
||||||
|
X: 50.0,
|
||||||
|
Z: -50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test triangle
|
||||||
|
ta := rl.Vector3{
|
||||||
|
X: -25.0,
|
||||||
|
Y: 0.5,
|
||||||
|
}
|
||||||
|
tb := rl.Vector3{
|
||||||
|
X: -4.0,
|
||||||
|
Y: 2.5,
|
||||||
|
Z: 1.0,
|
||||||
|
}
|
||||||
|
tc := rl.Vector3{
|
||||||
|
X: -8.0,
|
||||||
|
Y: 6.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
bary := rl.Vector3{}
|
||||||
|
|
||||||
|
// Test sphere
|
||||||
|
sp := rl.Vector3{
|
||||||
|
X: -30.0,
|
||||||
|
Y: 5.0,
|
||||||
|
Z: 5.0,
|
||||||
|
}
|
||||||
|
sr := float32(4.0)
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Update
|
||||||
|
if rl.IsCursorHidden() {
|
||||||
|
rl.UpdateCamera(&camera, rl.CameraFirstPerson) // Update camera
|
||||||
|
}
|
||||||
|
// Toggle camera controls
|
||||||
|
if rl.IsMouseButtonPressed(rl.MouseButtonRight) {
|
||||||
|
if rl.IsCursorHidden() {
|
||||||
|
rl.EnableCursor()
|
||||||
|
} else {
|
||||||
|
rl.DisableCursor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display information about the closest hit
|
||||||
|
collision := rl.RayCollision{
|
||||||
|
Distance: math.MaxFloat32,
|
||||||
|
Hit: false,
|
||||||
|
}
|
||||||
|
hitObjectName := "None"
|
||||||
|
cursorColor := rl.White
|
||||||
|
|
||||||
|
// Get ray and test against objects
|
||||||
|
// See issue : https://git.terah.dev/UnrealXR/raylib-go/issues/457
|
||||||
|
//ray = rl.GetScreenToWorldRay(rl.GetMousePosition(), camera)
|
||||||
|
ray = rl.GetMouseRay(rl.GetMousePosition(), camera)
|
||||||
|
|
||||||
|
// Check ray collision against ground quad
|
||||||
|
groundHitInfo := rl.GetRayCollisionQuad(ray, g0, g1, g2, g3)
|
||||||
|
|
||||||
|
if (groundHitInfo.Hit) && (groundHitInfo.Distance < collision.Distance) {
|
||||||
|
collision = groundHitInfo
|
||||||
|
cursorColor = rl.Green
|
||||||
|
hitObjectName = "Ground"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ray collision against test triangle
|
||||||
|
triHitInfo := rl.GetRayCollisionTriangle(ray, ta, tb, tc)
|
||||||
|
|
||||||
|
if (triHitInfo.Hit) && (triHitInfo.Distance < collision.Distance) {
|
||||||
|
collision = triHitInfo
|
||||||
|
cursorColor = rl.Purple
|
||||||
|
hitObjectName = "Triangle"
|
||||||
|
|
||||||
|
bary = rl.Vector3Barycenter(collision.Point, ta, tb, tc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ray collision against test sphere
|
||||||
|
sphereHitInfo := rl.GetRayCollisionSphere(ray, sp, sr)
|
||||||
|
|
||||||
|
if (sphereHitInfo.Hit) && (sphereHitInfo.Distance < collision.Distance) {
|
||||||
|
collision = sphereHitInfo
|
||||||
|
cursorColor = rl.Orange
|
||||||
|
hitObjectName = "Sphere"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ray collision against bounding box first, before trying the full ray-mesh test
|
||||||
|
boxHitInfo := rl.GetRayCollisionBox(ray, towerBBox)
|
||||||
|
|
||||||
|
if (boxHitInfo.Hit) && (boxHitInfo.Distance < collision.Distance) {
|
||||||
|
collision = boxHitInfo
|
||||||
|
cursorColor = rl.Orange
|
||||||
|
hitObjectName = "Box"
|
||||||
|
|
||||||
|
// Check ray collision against model meshes
|
||||||
|
meshHitInfo := rl.RayCollision{}
|
||||||
|
for m := int32(0); m < tower.MeshCount; m++ {
|
||||||
|
// NOTE: We consider the model.transform for the collision check, but
|
||||||
|
// it can be checked against any transform Matrix, used when checking against same
|
||||||
|
// model drawn multiple times with multiple transforms
|
||||||
|
meshHitInfo = rl.GetRayCollisionMesh(ray, meshes[m], tower.Transform)
|
||||||
|
if meshHitInfo.Hit {
|
||||||
|
// Save the closest hit mesh
|
||||||
|
if (!collision.Hit) || (collision.Distance > meshHitInfo.Distance) {
|
||||||
|
collision = meshHitInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
break // Stop once one mesh collision is detected, the colliding mesh is m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if meshHitInfo.Hit {
|
||||||
|
collision = meshHitInfo
|
||||||
|
cursorColor = rl.Orange
|
||||||
|
hitObjectName = "Mesh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
// Draw the tower
|
||||||
|
// WARNING: If scale is different from 1.0f,
|
||||||
|
// not considered by GetRayCollisionModel()
|
||||||
|
rl.DrawModel(tower, towerPos, 1.0, rl.White)
|
||||||
|
|
||||||
|
// Draw the test triangle
|
||||||
|
rl.DrawLine3D(ta, tb, rl.Purple)
|
||||||
|
rl.DrawLine3D(tb, tc, rl.Purple)
|
||||||
|
rl.DrawLine3D(tc, ta, rl.Purple)
|
||||||
|
|
||||||
|
// Draw the test sphere
|
||||||
|
rl.DrawSphereWires(sp, sr, 8, 8, rl.Purple)
|
||||||
|
|
||||||
|
// Draw the mesh bbox if we hit it
|
||||||
|
if boxHitInfo.Hit {
|
||||||
|
rl.DrawBoundingBox(towerBBox, rl.Lime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we hit something, draw the cursor at the hit point
|
||||||
|
if collision.Hit {
|
||||||
|
rl.DrawCube(collision.Point, 0.3, 0.3, 0.3, cursorColor)
|
||||||
|
rl.DrawCubeWires(collision.Point, 0.3, 0.3, 0.3, rl.Red)
|
||||||
|
|
||||||
|
normalEnd := rl.Vector3{}
|
||||||
|
normalEnd.X = collision.Point.X + collision.Normal.X
|
||||||
|
normalEnd.Y = collision.Point.Y + collision.Normal.Y
|
||||||
|
normalEnd.Z = collision.Point.Z + collision.Normal.Z
|
||||||
|
|
||||||
|
rl.DrawLine3D(collision.Point, normalEnd, rl.Red)
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawRay(ray, rl.Maroon)
|
||||||
|
rl.DrawGrid(10, 10.0)
|
||||||
|
|
||||||
|
rl.EndMode3D()
|
||||||
|
|
||||||
|
// Draw some debug GUI text
|
||||||
|
rl.DrawText(fmt.Sprintf("Hit Object: %s", hitObjectName), 10, 50, 10, rl.Black)
|
||||||
|
|
||||||
|
if collision.Hit {
|
||||||
|
ypos := int32(70)
|
||||||
|
rl.DrawText(fmt.Sprintf("Distance: %3.2f", collision.Distance), 10, ypos, 10, rl.Black)
|
||||||
|
rl.DrawText(Vec2Str("Hit Pos : %3.2f %3.2f %3.2f", collision.Point), 10, ypos+15, 10, rl.Black)
|
||||||
|
rl.DrawText(Vec2Str("Hit Norm: %3.2f %3.2f %3.2f", collision.Normal), 10, ypos+30, 10, rl.Black)
|
||||||
|
if triHitInfo.Hit && hitObjectName == "Triangle" {
|
||||||
|
rl.DrawText(Vec2Str("Barycenter: %3.2f %3.2f %3.2f", bary), 10, ypos+45, 10, rl.Black)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawText("Right click mouse to toggle camera controls", 10, 430, 10, rl.Gray)
|
||||||
|
rl.DrawText("(c) Turret 3D model by Alberto Cano", screenWidth-200, screenHeight-20, 10, rl.Gray)
|
||||||
|
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.UnloadModel(tower) // Unload model
|
||||||
|
rl.UnloadTexture(texture) // Unload texture
|
||||||
|
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
func Vec2Str(format string, vec rl.Vector3) string {
|
||||||
|
return fmt.Sprintf(format, vec.X, vec.Y, vec.Z)
|
||||||
|
}
|
1888
examples/models/mesh_picking/turret.obj
Normal file
1888
examples/models/mesh_picking/turret.obj
Normal file
File diff suppressed because it is too large
Load diff
BIN
examples/models/mesh_picking/turret_diffuse.png
Normal file
BIN
examples/models/mesh_picking/turret_diffuse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 371 KiB |
|
@ -1,9 +1,22 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var supportedFileTypes = []string{
|
||||||
|
".obj",
|
||||||
|
".gltf",
|
||||||
|
".glb",
|
||||||
|
".vox",
|
||||||
|
".iqm",
|
||||||
|
".m3d",
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
screenWidth := int32(800)
|
screenWidth := int32(800)
|
||||||
screenHeight := int32(450)
|
screenHeight := int32(450)
|
||||||
|
@ -24,26 +37,75 @@ func main() {
|
||||||
|
|
||||||
position := rl.NewVector3(0.0, 0.0, 0.0) // Set model position
|
position := rl.NewVector3(0.0, 0.0, 0.0) // Set model position
|
||||||
|
|
||||||
|
meshes := unsafe.Slice(obj.Meshes, obj.MeshCount)
|
||||||
|
bounds := rl.GetMeshBoundingBox(meshes[0]) // Set model bounds
|
||||||
|
|
||||||
|
selected := false
|
||||||
|
|
||||||
|
rl.DisableCursor()
|
||||||
rl.SetTargetFPS(60)
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
for !rl.WindowShouldClose() {
|
for !rl.WindowShouldClose() {
|
||||||
|
// Update
|
||||||
|
rl.UpdateCamera(&camera, rl.CameraFirstPerson)
|
||||||
|
|
||||||
|
// Load new models/textures on drag&drop
|
||||||
|
if rl.IsFileDropped() {
|
||||||
|
droppedFiles := rl.LoadDroppedFiles()
|
||||||
|
|
||||||
|
if len(droppedFiles) == 1 { // Only support one file dropped
|
||||||
|
if slices.Contains(supportedFileTypes, filepath.Ext(droppedFiles[0])) { // Model file formats supported
|
||||||
|
rl.UnloadModel(obj) // Unload previous model
|
||||||
|
obj = rl.LoadModel(droppedFiles[0]) // Load new model
|
||||||
|
rl.SetMaterialTexture(obj.Materials, rl.MapDiffuse, texture) // Set current map diffuse texture
|
||||||
|
|
||||||
|
meshes = unsafe.Slice(obj.Meshes, obj.MeshCount)
|
||||||
|
bounds = rl.GetMeshBoundingBox(meshes[0])
|
||||||
|
|
||||||
|
// TODO: Move camera position from target enough distance to visualize model properly
|
||||||
|
} else if filepath.Ext(droppedFiles[0]) == ".png" { // Texture file formats supported
|
||||||
|
// Unload current model texture and load new one
|
||||||
|
rl.UnloadTexture(texture)
|
||||||
|
texture = rl.LoadTexture(droppedFiles[0])
|
||||||
|
rl.SetMaterialTexture(obj.Materials, rl.MapDiffuse, texture) // Set current map diffuse texture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.UnloadDroppedFiles() // Unload file paths from memory
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select model on mouse click
|
||||||
|
if rl.IsMouseButtonPressed(rl.MouseButtonLeft) {
|
||||||
|
// Check collision between ray and box
|
||||||
|
if rl.GetRayCollisionBox(rl.GetMouseRay(rl.GetMousePosition(), camera), bounds).Hit {
|
||||||
|
selected = !selected
|
||||||
|
} else {
|
||||||
|
selected = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rl.BeginDrawing()
|
rl.BeginDrawing()
|
||||||
|
|
||||||
rl.ClearBackground(rl.RayWhite)
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
rl.BeginMode3D(camera)
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
rl.DrawModel(obj, position, 1.0, rl.White) // Draw 3d model with texture
|
rl.DrawModel(obj, position, 1.0, rl.White) // Draw 3d model with texture
|
||||||
|
|
||||||
rl.DrawGrid(20, 10.0) // Draw a grid
|
rl.DrawGrid(20, 10.0) // Draw a grid
|
||||||
|
|
||||||
|
if selected {
|
||||||
|
rl.DrawBoundingBox(bounds, rl.Green) // Draw selection box
|
||||||
|
}
|
||||||
|
|
||||||
rl.EndMode3D()
|
rl.EndMode3D()
|
||||||
|
|
||||||
|
rl.DrawText("Drag & drop model to load mesh/texture", 10, screenHeight-20, 10, rl.Gray)
|
||||||
|
if selected {
|
||||||
|
rl.DrawText("Model selected!", screenWidth-110, 10, 10, rl.Green)
|
||||||
|
}
|
||||||
rl.DrawText("(c) Castle 3D model by Alberto Cano", screenWidth-200, screenHeight-20, 10, rl.Gray)
|
rl.DrawText("(c) Castle 3D model by Alberto Cano", screenWidth-200, screenHeight-20, 10, rl.Gray)
|
||||||
|
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
rl.EndDrawing()
|
rl.EndDrawing()
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.UnloadTexture(texture) // Unload texture
|
rl.UnloadTexture(texture) // Unload texture
|
||||||
rl.UnloadModel(obj) // Unload model
|
rl.UnloadModel(obj) // Unload model
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
155
examples/models/rlgl_solar_system/main.go
Normal file
155
examples/models/rlgl_solar_system/main.go
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - rlgl module usage with push/pop matrix transformations
|
||||||
|
*
|
||||||
|
* NOTE: This example uses [rlgl] module functionality (pseudo-OpenGL 1.1 style coding)
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018-2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
|
||||||
|
sunRadius = 4.0
|
||||||
|
earthRadius = 0.6
|
||||||
|
moonRadius = 0.16
|
||||||
|
|
||||||
|
earthOrbitRadius = 8.0
|
||||||
|
moonOrbitRadius = 1.5
|
||||||
|
|
||||||
|
rings, slices = 16, 16
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialization
|
||||||
|
title := "raylib [models] example - rlgl module usage with push/pop matrix transformations"
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, title)
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
camera := rl.Camera{
|
||||||
|
Position: rl.Vector3{
|
||||||
|
X: 16.0,
|
||||||
|
Y: 16.0,
|
||||||
|
Z: 16.0,
|
||||||
|
}, // Camera position
|
||||||
|
Target: rl.Vector3{}, // Camera looking at point
|
||||||
|
Up: rl.Vector3{Y: 1.0}, // Camera up vector (rotation towards target)
|
||||||
|
Fovy: 45.0, // Camera field-of-view Y
|
||||||
|
Projection: rl.CameraPerspective, // Camera projection type
|
||||||
|
}
|
||||||
|
|
||||||
|
var rotationSpeed float32 = 0.2 // General system rotation speed
|
||||||
|
var earthRotation float32 // Rotation of earth around itself (days) in degrees
|
||||||
|
var earthOrbitRotation float32 // Rotation of earth around the Sun (years) in degrees
|
||||||
|
var moonRotation float32 // Rotation of moon around itself
|
||||||
|
var moonOrbitRotation float32 // Rotation of moon around earth in degrees
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Update
|
||||||
|
rl.UpdateCamera(&camera, rl.CameraOrbital)
|
||||||
|
|
||||||
|
earthRotation += 5.0 * rotationSpeed
|
||||||
|
earthOrbitRotation += 365 / 360.0 * (5.0 * rotationSpeed) * rotationSpeed
|
||||||
|
moonRotation += 2.0 * rotationSpeed
|
||||||
|
moonOrbitRotation += 8.0 * rotationSpeed
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
rl.PushMatrix()
|
||||||
|
rl.Scalef(sunRadius, sunRadius, sunRadius) // Scale Sun
|
||||||
|
DrawSphereBasic(rl.Gold) // Draw the Sun
|
||||||
|
rl.PopMatrix()
|
||||||
|
|
||||||
|
rl.PushMatrix()
|
||||||
|
rl.Rotatef(earthOrbitRotation, 0.0, 1.0, 0.0) // Rotation for Earth orbit around Sun
|
||||||
|
rl.Translatef(earthOrbitRadius, 0.0, 0.0) // Translation for Earth orbit
|
||||||
|
|
||||||
|
rl.PushMatrix()
|
||||||
|
rl.Rotatef(earthRotation, 0.25, 1.0, 0.0) // Rotation for Earth itself
|
||||||
|
rl.Scalef(earthRadius, earthRadius, earthRadius) // Scale Earth
|
||||||
|
|
||||||
|
DrawSphereBasic(rl.Blue) // Draw the Earth
|
||||||
|
rl.PopMatrix()
|
||||||
|
|
||||||
|
rl.Rotatef(moonOrbitRotation, 0.0, 1.0, 0.0) // Rotation for Moon orbit around Earth
|
||||||
|
rl.Translatef(moonOrbitRadius, 0.0, 0.0) // Translation for Moon orbit
|
||||||
|
rl.Rotatef(moonRotation, 0.0, 1.0, 0.0) // Rotation for Moon itself
|
||||||
|
rl.Scalef(moonRadius, moonRadius, moonRadius) // Scale Moon
|
||||||
|
|
||||||
|
DrawSphereBasic(rl.LightGray) // Draw the Moon
|
||||||
|
rl.PopMatrix()
|
||||||
|
|
||||||
|
// Some reference elements (not affected by previous matrix transformations)
|
||||||
|
rl.DrawCircle3D(rl.Vector3{}, earthOrbitRadius, rl.NewVector3(1, 0, 0), 90.0, rl.Fade(rl.Red, 0.5))
|
||||||
|
rl.DrawGrid(20, 1.0)
|
||||||
|
|
||||||
|
rl.EndMode3D()
|
||||||
|
|
||||||
|
rl.DrawText("EARTH ORBITING AROUND THE SUN!", 400, 10, 20, rl.Maroon)
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawSphereBasic draws a sphere without any matrix transformation
|
||||||
|
// NOTE: Sphere is drawn in world position ( 0, 0, 0 ) with radius 1.0f
|
||||||
|
func DrawSphereBasic(color rl.Color) {
|
||||||
|
// Make sure there is enough space in the internal render batch
|
||||||
|
// buffer to store all required vertex, batch is reset if required
|
||||||
|
rl.CheckRenderBatchLimit((rings + 2) * slices * 6)
|
||||||
|
|
||||||
|
rl.Begin(rl.Triangles)
|
||||||
|
rl.Color4ub(color.R, color.G, color.B, color.A)
|
||||||
|
|
||||||
|
for ring := int32(0); ring < (rings + 2); ring++ {
|
||||||
|
for slice := int32(0); slice < slices; slice++ {
|
||||||
|
rl.Vertex3f(getCoords(ring, slice))
|
||||||
|
rl.Vertex3f(getCoords(ring+1, slice+1))
|
||||||
|
rl.Vertex3f(getCoords(ring+1, slice))
|
||||||
|
rl.Vertex3f(getCoords(ring, slice))
|
||||||
|
rl.Vertex3f(getCoords(ring, slice+1))
|
||||||
|
rl.Vertex3f(getCoords(ring+1, slice+1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rl.End()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCoords(ring, slice int32) (x, y, z float32) {
|
||||||
|
ringF := float64(ring)
|
||||||
|
sliceF := float64(slice)
|
||||||
|
|
||||||
|
// Calculate angels
|
||||||
|
alpha := rl.Deg2rad * (270 + (180/(float64(rings)+1))*ringF)
|
||||||
|
beta := rl.Deg2rad * (sliceF * 360 / float64(slices))
|
||||||
|
|
||||||
|
// Calculate coords
|
||||||
|
x = float32(math.Cos(alpha) * math.Sin(beta))
|
||||||
|
y = float32(math.Sin(alpha))
|
||||||
|
z = float32(math.Cos(alpha) * math.Cos(beta))
|
||||||
|
|
||||||
|
return x, y, z
|
||||||
|
}
|
125
examples/models/skybox/main.go
Normal file
125
examples/models/skybox/main.go
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
skyboxFilename := "skybox.png"
|
||||||
|
|
||||||
|
rl.InitWindow(800, 450, "raylib [models] example - skybox loading and drawing")
|
||||||
|
|
||||||
|
camera := rl.NewCamera3D(
|
||||||
|
rl.NewVector3(1.0, 1.0, 1.0),
|
||||||
|
rl.NewVector3(4.0, 1.0, 4.0),
|
||||||
|
rl.NewVector3(0.0, 1.0, 0.0),
|
||||||
|
45.0,
|
||||||
|
rl.CameraPerspective,
|
||||||
|
)
|
||||||
|
|
||||||
|
// load skybox shader and set required locations
|
||||||
|
skyboxShader := rl.LoadShader("skybox.vs", "skybox.fs")
|
||||||
|
|
||||||
|
setShaderIntValue(skyboxShader, "environmentMap", rl.MapCubemap)
|
||||||
|
|
||||||
|
// load skybox model
|
||||||
|
cube := rl.GenMeshCube(1.0, 1.0, 1.0)
|
||||||
|
skybox := rl.LoadModelFromMesh(cube)
|
||||||
|
|
||||||
|
skybox.Materials.Shader = skyboxShader
|
||||||
|
|
||||||
|
// load cubemap texture
|
||||||
|
skyboxImg := rl.LoadImage(skyboxFilename)
|
||||||
|
|
||||||
|
skyboxTexture := rl.LoadTextureCubemap(skyboxImg, rl.CubemapLayoutAutoDetect)
|
||||||
|
|
||||||
|
rl.UnloadImage(skyboxImg)
|
||||||
|
|
||||||
|
rl.SetMaterialTexture(skybox.Materials, rl.MapCubemap, skyboxTexture)
|
||||||
|
|
||||||
|
// limit cursor to relative movement inside the window
|
||||||
|
rl.DisableCursor()
|
||||||
|
|
||||||
|
// set our game to run at 60 frames-per-second
|
||||||
|
rl.SetTargetFPS(60)
|
||||||
|
|
||||||
|
for !rl.WindowShouldClose() {
|
||||||
|
rl.UpdateCamera(&camera, rl.CameraFirstPerson)
|
||||||
|
|
||||||
|
// load new cubemap texture on drag&drop
|
||||||
|
if rl.IsFileDropped() {
|
||||||
|
droppedFiles := rl.LoadDroppedFiles()
|
||||||
|
|
||||||
|
// only support one file dropped
|
||||||
|
if len(droppedFiles) == 1 {
|
||||||
|
switch filepath.Ext(droppedFiles[0]) {
|
||||||
|
case ".png", ".jpg", ".bmp", ".tga":
|
||||||
|
skyboxFilename = droppedFiles[0]
|
||||||
|
|
||||||
|
rl.UnloadTexture(skyboxTexture)
|
||||||
|
|
||||||
|
img := rl.LoadImage(skyboxFilename)
|
||||||
|
|
||||||
|
skyboxTexture = rl.LoadTextureCubemap(img, rl.CubemapLayoutAutoDetect)
|
||||||
|
|
||||||
|
rl.UnloadImage(img)
|
||||||
|
|
||||||
|
rl.SetMaterialTexture(skybox.Materials, rl.MapCubemap, skyboxTexture)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.UnloadDroppedFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.BeginDrawing()
|
||||||
|
|
||||||
|
rl.ClearBackground(rl.White)
|
||||||
|
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
// we are inside the cube, we need to disable backface culling
|
||||||
|
rl.DisableBackfaceCulling()
|
||||||
|
rl.DisableDepthMask()
|
||||||
|
|
||||||
|
rl.DrawModel(skybox, rl.NewVector3(0, 0, 0), 1.0, rl.White)
|
||||||
|
|
||||||
|
// restore depth and backface culling
|
||||||
|
rl.EnableBackfaceCulling()
|
||||||
|
rl.EnableDepthMask()
|
||||||
|
|
||||||
|
rl.DrawGrid(10, 1.0)
|
||||||
|
|
||||||
|
rl.EndMode3D()
|
||||||
|
|
||||||
|
rl.DrawText(
|
||||||
|
fmt.Sprintf("File: %s", skyboxFilename),
|
||||||
|
10,
|
||||||
|
int32(rl.GetScreenHeight()-20),
|
||||||
|
10,
|
||||||
|
rl.Black,
|
||||||
|
)
|
||||||
|
|
||||||
|
rl.DrawFPS(10, 10)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.UnloadModel(skybox)
|
||||||
|
rl.UnloadTexture(skyboxTexture)
|
||||||
|
rl.UnloadShader(skyboxShader)
|
||||||
|
|
||||||
|
rl.CloseWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setShaderIntValue(shader rl.Shader, name string, value int32) {
|
||||||
|
rl.SetShaderValue(
|
||||||
|
shader,
|
||||||
|
rl.GetShaderLocation(shader, name),
|
||||||
|
unsafe.Slice((*float32)(unsafe.Pointer(&value)), 4),
|
||||||
|
rl.ShaderUniformInt,
|
||||||
|
)
|
||||||
|
}
|
19
examples/models/skybox/skybox.fs
Normal file
19
examples/models/skybox/skybox.fs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// input vertex attributes (from vertex shader)
|
||||||
|
in vec3 fragPosition;
|
||||||
|
|
||||||
|
// input uniform values
|
||||||
|
uniform samplerCube environmentMap;
|
||||||
|
|
||||||
|
// output fragment color
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// fetch color from texture map
|
||||||
|
vec3 color = texture(environmentMap, fragPosition).rgb;
|
||||||
|
|
||||||
|
// calculate final fragment color
|
||||||
|
finalColor = vec4(color, 1.0);
|
||||||
|
}
|
BIN
examples/models/skybox/skybox.png
Normal file
BIN
examples/models/skybox/skybox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
24
examples/models/skybox/skybox.vs
Normal file
24
examples/models/skybox/skybox.vs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// input vertex attributes
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
|
||||||
|
// input uniform values
|
||||||
|
uniform mat4 matProjection;
|
||||||
|
uniform mat4 matView;
|
||||||
|
|
||||||
|
// output vertex attributes (to fragment shader)
|
||||||
|
out vec3 fragPosition;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// calculate fragment position based on model transformations
|
||||||
|
fragPosition = vertexPosition;
|
||||||
|
|
||||||
|
// remove translation from the view matrix
|
||||||
|
mat4 rotView = mat4(mat3(matView));
|
||||||
|
vec4 clipPos = matProjection*rotView*vec4(vertexPosition, 1.0);
|
||||||
|
|
||||||
|
// calculate final vertex position
|
||||||
|
gl_Position = clipPos;
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
rl "github.com/gen2brain/raylib-go/raylib"
|
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
113
examples/models/yaw_pitch_roll/main.go
Normal file
113
examples/models/yaw_pitch_roll/main.go
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - Plane rotations (yaw, pitch, roll)
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 1.8, last time updated with raylib 4.0
|
||||||
|
*
|
||||||
|
* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2024 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 450
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI)
|
||||||
|
title := "raylib [models] example - plane rotations (yaw, pitch, roll)"
|
||||||
|
rl.InitWindow(screenWidth, screenHeight, title)
|
||||||
|
|
||||||
|
camera := rl.Camera{
|
||||||
|
Position: rl.Vector3{
|
||||||
|
Y: 50.0,
|
||||||
|
Z: -120.0,
|
||||||
|
}, // Camera position perspective
|
||||||
|
Target: rl.Vector3{}, // Camera looking at point
|
||||||
|
Up: rl.Vector3{Y: 1.0}, // Camera up vector (rotation towards target)
|
||||||
|
Fovy: 30.0, // Camera field-of-view Y
|
||||||
|
Projection: rl.CameraPerspective, // Camera type
|
||||||
|
}
|
||||||
|
model := rl.LoadModel("plane.obj") // Load model
|
||||||
|
texture := rl.LoadTexture("plane_diffuse.png") // Load model texture
|
||||||
|
rl.SetMaterialTexture(model.Materials, rl.MapDiffuse, texture) // Set map diffuse texture
|
||||||
|
|
||||||
|
var pitch, roll, yaw float32
|
||||||
|
|
||||||
|
rl.SetTargetFPS(60) // Set our game to run at 60 frames-per-second
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
for !rl.WindowShouldClose() { // Detect window close button or ESC key
|
||||||
|
// Update
|
||||||
|
|
||||||
|
// Plane pitch (x-axis) controls
|
||||||
|
pitch = controlPlane(pitch, 0.6, rl.KeyDown, rl.KeyUp)
|
||||||
|
// Plane yaw (y-axis) controls
|
||||||
|
roll = controlPlane(roll, 1.0, rl.KeyLeft, rl.KeyRight)
|
||||||
|
// Plane roll (z-axis) controls
|
||||||
|
yaw = controlPlane(yaw, 1.0, rl.KeyA, rl.KeyS)
|
||||||
|
|
||||||
|
// Transformation matrix for rotations
|
||||||
|
rotationV := rl.Vector3{
|
||||||
|
X: rl.Deg2rad * pitch,
|
||||||
|
Y: rl.Deg2rad * yaw,
|
||||||
|
Z: rl.Deg2rad * roll,
|
||||||
|
}
|
||||||
|
model.Transform = rl.MatrixRotateXYZ(rotationV)
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
rl.BeginDrawing()
|
||||||
|
|
||||||
|
rl.ClearBackground(rl.RayWhite)
|
||||||
|
|
||||||
|
// Draw 3D model (recommended to draw 3D always before 2D)
|
||||||
|
rl.BeginMode3D(camera)
|
||||||
|
|
||||||
|
// Draw 3d model with texture
|
||||||
|
rl.DrawModel(model, rl.Vector3{Y: -8.0}, 1.0, rl.White)
|
||||||
|
rl.DrawGrid(10, 10.0)
|
||||||
|
|
||||||
|
rl.EndMode3D()
|
||||||
|
|
||||||
|
// Draw controls info
|
||||||
|
rl.DrawRectangle(30, 370, 260, 70, rl.Fade(rl.Green, 0.5))
|
||||||
|
rl.DrawRectangleLines(30, 370, 260, 70, rl.Fade(rl.DarkGreen, 0.5))
|
||||||
|
rl.DrawText("Pitch controlled with: KEY_UP / KEY_DOWN", 40, 380, 10, rl.DarkGray)
|
||||||
|
rl.DrawText("Roll controlled with: KEY_LEFT / KEY_RIGHT", 40, 400, 10, rl.DarkGray)
|
||||||
|
rl.DrawText("Yaw controlled with: KEY_A / KEY_S", 40, 420, 10, rl.DarkGray)
|
||||||
|
|
||||||
|
rl.DrawText("(c) WWI Plane Model created by GiaHanLam", screenWidth-240, screenHeight-20, 10, rl.DarkGray)
|
||||||
|
|
||||||
|
rl.EndDrawing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
rl.UnloadModel(model) // Unload model data
|
||||||
|
rl.UnloadTexture(texture) // Unload texture data
|
||||||
|
|
||||||
|
rl.CloseWindow() // Close window and OpenGL context
|
||||||
|
}
|
||||||
|
|
||||||
|
func controlPlane(ctrl, value float32, key1, key2 int32) float32 {
|
||||||
|
if rl.IsKeyDown(key1) {
|
||||||
|
ctrl -= value
|
||||||
|
} else if rl.IsKeyDown(key2) {
|
||||||
|
ctrl += value
|
||||||
|
} else {
|
||||||
|
if ctrl > 0.0 {
|
||||||
|
ctrl -= value / 2
|
||||||
|
} else if ctrl < 0.0 {
|
||||||
|
ctrl += value / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctrl
|
||||||
|
}
|
10858
examples/models/yaw_pitch_roll/plane.obj
Normal file
10858
examples/models/yaw_pitch_roll/plane.obj
Normal file
File diff suppressed because it is too large
Load diff
BIN
examples/models/yaw_pitch_roll/plane_diffuse.png
Normal file
BIN
examples/models/yaw_pitch_roll/plane_diffuse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 804 KiB |
|
@ -3,7 +3,7 @@
|
||||||
To compile example to shared library you will need [Android NDK](https://developer.android.com/ndk/downloads/index.html).
|
To compile example to shared library you will need [Android NDK](https://developer.android.com/ndk/downloads/index.html).
|
||||||
To build Android apk you will need [Android SDK](http://developer.android.com/sdk/index.html#Other).
|
To build Android apk you will need [Android SDK](http://developer.android.com/sdk/index.html#Other).
|
||||||
|
|
||||||
Export path to Android NDK, point to location where you have unpacked archive:
|
Export path to Android NDK, point to location where you have unpacked archive (WARNING: NDK 27 is not supported . See https://github.com/raysan5/raylib/issues/4166):
|
||||||
|
|
||||||
export ANDROID_NDK_HOME=/opt/android-ndk
|
export ANDROID_NDK_HOME=/opt/android-ndk
|
||||||
|
|
||||||
|
@ -33,16 +33,17 @@ To build apk export path to Android SDK, point to location where you unpacked ar
|
||||||
|
|
||||||
export ANDROID_HOME=/opt/android-sdk
|
export ANDROID_HOME=/opt/android-sdk
|
||||||
|
|
||||||
And build apk with ant:
|
And build apk:
|
||||||
|
|
||||||
cd android
|
|
||||||
ant clean debug
|
|
||||||
|
|
||||||
Or with gradle:
|
|
||||||
|
|
||||||
./gradlew assembleDebug
|
./gradlew assembleDebug
|
||||||
|
|
||||||
If everything is successfully built apk can be found in bin/ directory or in the android/build/outputs in case `gradle` is used.
|
If everything is successfully built apk can be found in the android/build/outputs.
|
||||||
|
|
||||||
|
|
||||||
For aarch64/arm64 replace `arm-linux-androideabi` with `aarch64-linux-android`, set GOARCH to arm64 and use minimum `ANDROID_API=21`.
|
For aarch64/arm64 replace `arm-linux-androideabi` with `aarch64-linux-android`, set GOARCH to arm64 and use minimum `ANDROID_API=21`.
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
To build shared libraries on Windows you can inspect the file `androidcompile.bat` by opening it on a text editor, it can then be configured to generate the libraries when running the .bat file
|
||||||
|
|
||||||
|
See also [instructions](https://developer.android.com/build/building-cmdline#build_bundle) to build a android app bundle for appstore distribution
|
|
@ -1,10 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.github.gen2brain.raylib.go"
|
|
||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="1.0">
|
android:versionName="1.0">
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="27" />
|
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="34" />
|
||||||
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||||
|
|
||||||
<!-- We do not have Java code. Therefore android:hasCode is set to false. -->
|
<!-- We do not have Java code. Therefore android:hasCode is set to false. -->
|
||||||
|
@ -15,6 +14,7 @@
|
||||||
|
|
||||||
<!-- Our activity is the built-in NativeActivity framework class. -->
|
<!-- Our activity is the built-in NativeActivity framework class. -->
|
||||||
<activity android:name="android.app.NativeActivity"
|
<activity android:name="android.app.NativeActivity"
|
||||||
|
android:exported="true"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
android:screenOrientation="landscape"
|
android:screenOrientation="landscape"
|
||||||
android:clearTaskOnLaunch="true">
|
android:clearTaskOnLaunch="true">
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
namespace = "com.example.android"
|
||||||
buildToolsVersion '27.0.3'
|
compileSdkVersion 34
|
||||||
|
buildToolsVersion '34.0.0'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.example.android"
|
applicationId "com.example.android"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 27
|
targetSdkVersion 34
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName '1.0'
|
versionName '1.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project name="example" default="help">
|
|
||||||
|
|
||||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
|
||||||
It contains the path to the SDK. It should *NOT* be checked into
|
|
||||||
Version Control Systems. -->
|
|
||||||
<property file="local.properties" />
|
|
||||||
|
|
||||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
|
||||||
'android' tool to add properties to it.
|
|
||||||
This is the place to change some Ant specific build properties.
|
|
||||||
Here are some properties you may want to change/update:
|
|
||||||
|
|
||||||
source.dir
|
|
||||||
The name of the source directory. Default is 'src'.
|
|
||||||
out.dir
|
|
||||||
The name of the output directory. Default is 'bin'.
|
|
||||||
|
|
||||||
For other overridable properties, look at the beginning of the rules
|
|
||||||
files in the SDK, at tools/ant/build.xml
|
|
||||||
|
|
||||||
Properties related to the SDK location or the project target should
|
|
||||||
be updated using the 'android' tool with the 'update' action.
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property file="ant.properties" />
|
|
||||||
|
|
||||||
<!-- if sdk.dir was not set from one of the property file, then
|
|
||||||
get it from the ANDROID_HOME env var.
|
|
||||||
This must be done before we load project.properties since
|
|
||||||
the proguard config can use sdk.dir -->
|
|
||||||
<property environment="env" />
|
|
||||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
|
||||||
<isset property="env.ANDROID_HOME" />
|
|
||||||
</condition>
|
|
||||||
|
|
||||||
<!-- The project.properties file is created and updated by the 'android'
|
|
||||||
tool, as well as ADT.
|
|
||||||
|
|
||||||
This contains project specific properties such as project target, and library
|
|
||||||
dependencies. Lower level build properties are stored in ant.properties
|
|
||||||
(or in .classpath for Eclipse projects).
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems. -->
|
|
||||||
<loadproperties srcFile="project.properties" />
|
|
||||||
|
|
||||||
<!-- quick check on sdk.dir -->
|
|
||||||
<fail
|
|
||||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
|
||||||
unless="sdk.dir"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Import per project custom build rules if present at the root of the project.
|
|
||||||
This is the place to put custom intermediary targets such as:
|
|
||||||
-pre-build
|
|
||||||
-pre-compile
|
|
||||||
-post-compile (This is typically used for code obfuscation.
|
|
||||||
Compiled code location: ${out.classes.absolute.dir}
|
|
||||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
|
||||||
-post-package
|
|
||||||
-post-build
|
|
||||||
-pre-clean
|
|
||||||
-->
|
|
||||||
<import file="custom_rules.xml" optional="true" />
|
|
||||||
|
|
||||||
<!-- Import the actual build file.
|
|
||||||
|
|
||||||
To customize existing targets, there are two options:
|
|
||||||
- Customize only one target:
|
|
||||||
- copy/paste the target into this file, *before* the
|
|
||||||
<import> task.
|
|
||||||
- customize it to your needs.
|
|
||||||
- Customize the whole content of build.xml
|
|
||||||
- copy/paste the content of the rules files (minus the top node)
|
|
||||||
into this file, replacing the <import> task.
|
|
||||||
- customize to your needs.
|
|
||||||
|
|
||||||
***********************
|
|
||||||
****** IMPORTANT ******
|
|
||||||
***********************
|
|
||||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
|
||||||
in order to avoid having your file be overridden by tools such as "android update project"
|
|
||||||
-->
|
|
||||||
<!-- version-tag: 1 -->
|
|
||||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Project target.
|
|
||||||
target=android-27
|
|
68
examples/others/android/example/androidcompile.bat
Normal file
68
examples/others/android/example/androidcompile.bat
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
@REM Set your desired api. Max is 31
|
||||||
|
@set ANDROID_API=31
|
||||||
|
@REM Your library name. If you change it here you should also change it in your android manifest...
|
||||||
|
@set LIBRARY_NAME=example
|
||||||
|
@REM Set your android sdk folder here
|
||||||
|
@set ANDROID_HOME=F:/AndroidSDK
|
||||||
|
@REM Set your android NDK folder here. WARNING: NDK 27 is not supported yet. See https://github.com/raysan5/raylib/issues/4166
|
||||||
|
@set ANDROID_NDK_HOME=F:/AndroidSDK/ndk/23.2.8568313
|
||||||
|
@REM The target architecture for android. See https://developer.android.com/ndk/guides/abis.
|
||||||
|
@REM Valid options are: armeabi-v7a,arm64-v8a,x86,x86_64 or "all" if you want to build for all architectures.
|
||||||
|
@set TARGET_ARCH="all"
|
||||||
|
@REM Automatic setup. Should work by default. Do not change anything below here
|
||||||
|
@set PATH=%ANDROID_NDK_HOME%/toolchains/llvm/prebuilt/windows-x86_64/bin;%PATH%
|
||||||
|
@set ANDROID_SYSROOT=%ANDROID_NDK_HOME%/toolchains/llvm/prebuilt/windows-x86_64/sysroot
|
||||||
|
@set ANDROID_TOOLCHAIN=%ANDROID_NDK_HOME%/toolchains/llvm/prebuilt/windows-x86_64
|
||||||
|
@IF %TARGET_ARCH% == "all" (
|
||||||
|
@GOTO:BUILDALL
|
||||||
|
) else (
|
||||||
|
@GOTO:MAIN
|
||||||
|
)
|
||||||
|
|
||||||
|
:COMPILE
|
||||||
|
@echo compiling for platform %FL% and architecture %GOARCH%
|
||||||
|
@set CGO_CFLAGS="-I%ANDROID_SYSROOT%/usr/include -I%ANDROID_SYSROOT%/usr/include/%TRIPLE% --sysroot=%ANDROID_SYSROOT% -D__ANDROID_API__=%ANDROID_API%"
|
||||||
|
@set CGO_LDFLAGS="-L%ANDROID_SYSROOT%/usr/lib/%TRIPLE%/%ANDROID_API% -L%ANDROID_TOOLCHAIN%/%TRIPLE%/lib --sysroot=%ANDROID_SYSROOT%"
|
||||||
|
@set CGO_ENABLED=1
|
||||||
|
@set GOOS=android
|
||||||
|
@set GOARCH=%GOARCH%
|
||||||
|
@go build -buildmode=c-shared -ldflags="-s -w -extldflags=-Wl,-soname,lib%LIBRARY_NAME%.so" -o=android/libs/%FL%/lib%LIBRARY_NAME%.so
|
||||||
|
@EXIT /B
|
||||||
|
|
||||||
|
:BUILDALL
|
||||||
|
@set TARGET_ARCH="armeabi-v7a"
|
||||||
|
@CALL:MAIN
|
||||||
|
@set TARGET_ARCH="arm64-v8a"
|
||||||
|
@CALL:MAIN
|
||||||
|
@set TARGET_ARCH="x86"
|
||||||
|
@CALL:MAIN
|
||||||
|
@set TARGET_ARCH="x86_64"
|
||||||
|
@CALL:MAIN
|
||||||
|
@EXIT /B
|
||||||
|
|
||||||
|
:MAIN
|
||||||
|
@IF %TARGET_ARCH% == "armeabi-v7a" (
|
||||||
|
@set CC="armv7a-linux-androideabi%ANDROID_API%-clang"
|
||||||
|
@set TRIPLE=arm-linux-androideabi
|
||||||
|
@set FL=armeabi-v7a
|
||||||
|
@set GOARCH=arm
|
||||||
|
@CALL:COMPILE )
|
||||||
|
@IF %TARGET_ARCH% == "arm64-v8a" (
|
||||||
|
@set CC="aarch64-linux-android%ANDROID_API%-clang"
|
||||||
|
@set TRIPLE=aarch64-linux-android
|
||||||
|
@set FL=arm64-v8a
|
||||||
|
@set GOARCH=arm64
|
||||||
|
@CALL:COMPILE )
|
||||||
|
@IF %TARGET_ARCH% == "x86" (
|
||||||
|
@set CC="i686-linux-android%ANDROID_API%-clang"
|
||||||
|
@set TRIPLE=i686-linux-android
|
||||||
|
@set FL=x86
|
||||||
|
@set GOARCH=386
|
||||||
|
@CALL:COMPILE )
|
||||||
|
@IF %TARGET_ARCH% == "x86_64" (
|
||||||
|
@set CC="x86_64-linux-android%ANDROID_API%-clang"
|
||||||
|
@set TRIPLE=x86_64-linux-android
|
||||||
|
@set FL=x86_64
|
||||||
|
@set GOARCH=amd64
|
||||||
|
@CALL:COMPILE )
|
||||||
|
@EXIT /B
|
|
@ -4,7 +4,7 @@ buildscript {
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
classpath 'com.android.tools.build:gradle:8.2.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/gen2brain/raylib-go/raylib"
|
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Game states
|
// Game states
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue