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
|
||||
[](https://github.com/gen2brain/raylib-go/actions)
|
||||
[](https://godoc.org/github.com/gen2brain/raylib-go/raylib)
|
||||
[](https://goreportcard.com/report/github.com/gen2brain/raylib-go/raylib)
|
||||
[](https://github.com/gen2brain/raylib-go/tree/master/examples)
|
||||
[](https://git.terah.dev/UnrealXR/raylib-go/actions)
|
||||
[](https://godoc.org/git.terah.dev/UnrealXR/raylib-go/raylib)
|
||||
[](https://goreportcard.com/report/git.terah.dev/UnrealXR/raylib-go/raylib)
|
||||
[](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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
###### X11
|
||||
|
||||
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
|
||||
apt-get install libgl1-mesa-dev libxi-dev libxcursor-dev libxrandr-dev libxinerama-dev libwayland-dev libxkbcommon-dev
|
||||
|
||||
##### Fedora
|
||||
|
||||
###### X11
|
||||
|
||||
dnf install mesa-libGL-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel
|
||||
|
||||
###### Wayland
|
||||
|
||||
dnf install mesa-libGL-devel wayland-devel libxkbcommon-devel
|
||||
dnf install mesa-libGL-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel wayland-devel libxkbcommon-devel
|
||||
|
||||
##### 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
|
||||
|
||||
|
@ -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`.
|
||||
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 build the dll yourself. You can find more infos at [raylib's wiki](https://github.com/raysan5/raylib/wiki/Working-on-Windows).
|
||||
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).
|
||||
|
||||
##### 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
|
||||
|
||||
go get -v -u github.com/gen2brain/raylib-go/raylib
|
||||
go get -v -u git.terah.dev/UnrealXR/raylib-go/raylib
|
||||
|
||||
### Build tags
|
||||
|
||||
* `drm` - build for Linux native DRM mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM)
|
||||
* `sdl` - build for SDL backend instead of internal GLFW (PLATFORM_DESKTOP_SDL)
|
||||
* `wayland` - build against Wayland libraries (internal GLFW)
|
||||
* `drm` - build for Linux native [DRM](https://en.wikipedia.org/wiki/Direct_Rendering_Manager) mode, including Raspberry Pi 4 and other devices (PLATFORM_DRM)
|
||||
* `drm_disable_input` - disables keyboard input capabilities for the DRM backend. Requires the `drm` build tag as a prerequisite
|
||||
* `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
|
||||
* `opengl43` - uses OpenGL 4.3 backend
|
||||
* `opengl21` - uses OpenGL 2.1 backend (default is 3.3 on desktop)
|
||||
* `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))
|
||||
* `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 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
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import rl "github.com/gen2brain/raylib-go/raylib"
|
||||
import rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
|
||||
func main() {
|
||||
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)
|
||||
|
||||
|
@ -133,4 +131,4 @@ basic_window: Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|
|
|||
|
||||
### 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.
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module github.com/gen2brain/raylib-go/easings
|
||||
module git.terah.dev/UnrealXR/raylib-go/easings
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const maxCircles = 64
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(800, 450, "raylib [audio] example - music playing (streaming)")
|
||||
rl.InitAudioDevice()
|
||||
|
|
|
@ -1,71 +1,69 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
maxSamples = 22050
|
||||
maxSamplesPerUpdate = 4096
|
||||
nSamples = 44000 * 10
|
||||
sampleRate = 6000
|
||||
bufferSize = nSamples
|
||||
frequency = 440
|
||||
targetFPS = 240
|
||||
)
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(800, 450, "raylib [audio] example - raw audio streaming")
|
||||
position := rl.NewVector2(0, 0)
|
||||
|
||||
rl.SetAudioStreamBufferSizeDefault(bufferSize)
|
||||
|
||||
rl.InitAudioDevice()
|
||||
|
||||
// Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono)
|
||||
stream := rl.LoadAudioStream(22050, 32, 1)
|
||||
// Init raw audio stream (sample rate: <nSamples>, sample size: 32bit-float, channels: 1-mono)
|
||||
stream := rl.LoadAudioStream(nSamples, 32, 1)
|
||||
|
||||
//// Fill audio stream with some samples (sine wave)
|
||||
data := make([]float32, maxSamples)
|
||||
//// Create sine wave to play
|
||||
data := make([]float32, nSamples)
|
||||
|
||||
for i := 0; i < maxSamples; i++ {
|
||||
data[i] = float32(math.Sin(float64((2*rl.Pi*float32(i))/2) * rl.Deg2rad))
|
||||
for i := 0; i < nSamples; i++ {
|
||||
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
|
||||
// for that reason, there is a clip everytime audio stream is looped
|
||||
// NOTE: The buffer can only be updated when it has been processed. Time between buffer processing and next load and causes clipping
|
||||
rl.PlayAudioStream(stream)
|
||||
|
||||
totalSamples := int32(maxSamples)
|
||||
samplesLeft := int32(totalSamples)
|
||||
|
||||
position := rl.NewVector2(0, 0)
|
||||
|
||||
rl.SetTargetFPS(30)
|
||||
startTime := time.Now()
|
||||
rl.SetTargetFPS(targetFPS)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
// Refill audio stream if required
|
||||
// Refill audio stream if buffer is processed
|
||||
if rl.IsAudioStreamProcessed(stream) {
|
||||
numSamples := int32(0)
|
||||
if samplesLeft >= maxSamplesPerUpdate {
|
||||
numSamples = maxSamplesPerUpdate
|
||||
elapsedTime := time.Since(startTime).Seconds()
|
||||
currentSampleIndex := int(math.Mod(elapsedTime*float64(sampleRate), float64(nSamples)))
|
||||
nextSampleIndex := currentSampleIndex + bufferSize
|
||||
|
||||
if nextSampleIndex > nSamples {
|
||||
nextSampleIndex = bufferSize - (nSamples - currentSampleIndex)
|
||||
rl.UpdateAudioStream(stream, append(data[currentSampleIndex:], data[:nextSampleIndex]...))
|
||||
} else {
|
||||
numSamples = samplesLeft
|
||||
}
|
||||
|
||||
rl.UpdateAudioStream(stream, data[totalSamples-samplesLeft:])
|
||||
|
||||
samplesLeft -= numSamples
|
||||
|
||||
// Reset samples feeding (loop audio)
|
||||
if samplesLeft <= 0 {
|
||||
samplesLeft = totalSamples
|
||||
rl.UpdateAudioStream(stream, data[currentSampleIndex:nextSampleIndex])
|
||||
}
|
||||
}
|
||||
|
||||
rl.BeginDrawing()
|
||||
|
||||
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)
|
||||
for i := 0; i < int(rl.GetScreenWidth()); 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)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* 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 (
|
||||
"fmt"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"os"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const colorCount = 23
|
||||
|
|
|
@ -1,22 +1,43 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
"fmt"
|
||||
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
maxColumns = 20
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
False = 0
|
||||
True = 1
|
||||
)
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(800, 450, "raylib [core] example - 3d camera first person")
|
||||
var camModes = map[rl.CameraMode]string{
|
||||
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.Position = rl.NewVector3(4.0, 2.0, 4.0)
|
||||
camera.Target = rl.NewVector3(0.0, 1.8, 0.0)
|
||||
camera.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
||||
camera.Fovy = 60.0
|
||||
camera.Projection = rl.CameraPerspective
|
||||
camera.Position = rl.NewVector3(0.0, 2.0, 4.0) // Camera position
|
||||
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 vector (rotation towards target)
|
||||
camera.Fovy = 60.0 // Camera field-of-view Y
|
||||
camera.Projection = rl.CameraPerspective // Camera projection type
|
||||
|
||||
cameraMode := rl.CameraFirstPerson
|
||||
|
||||
// Generates some random columns
|
||||
heights := make([]float32, maxColumns)
|
||||
|
@ -24,15 +45,81 @@ func main() {
|
|||
colors := make([]rl.Color, maxColumns)
|
||||
|
||||
for i := 0; i < maxColumns; i++ {
|
||||
heights[i] = float32(rl.GetRandomValue(1, 12))
|
||||
positions[i] = rl.NewVector3(float32(rl.GetRandomValue(-15, 15)), heights[i]/2, float32(rl.GetRandomValue(-15, 15)))
|
||||
colors[i] = rl.NewColor(uint8(rl.GetRandomValue(20, 255)), uint8(rl.GetRandomValue(10, 55)), 30, 255)
|
||||
heights[i] = rndF(1, 12)
|
||||
positions[i] = rl.NewVector3(rndF(-15, 15), heights[i]/2, rndF(-15, 15))
|
||||
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() {
|
||||
rl.UpdateCamera(&camera, rl.CameraFirstPerson) // Update camera with first person mode
|
||||
// Main game loop
|
||||
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()
|
||||
|
||||
|
@ -51,17 +138,57 @@ func main() {
|
|||
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.DrawRectangle(10, 10, 220, 70, rl.Fade(rl.SkyBlue, 0.5))
|
||||
rl.DrawRectangleLines(10, 10, 220, 70, rl.Blue)
|
||||
// Draw info boxes
|
||||
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("- Move with keys: W, A, S, D", 40, 40, 10, rl.DarkGray)
|
||||
rl.DrawText("- Mouse move to look around", 40, 60, 10, rl.DarkGray)
|
||||
rl.DrawText("Camera controls:", 15, 15, 10, rl.Black)
|
||||
rl.DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, rl.Black)
|
||||
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.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
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -44,8 +44,6 @@ func main() {
|
|||
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 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.EndDrawing()
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
var (
|
||||
screenW = int32(800)
|
||||
screenH = int32(450)
|
||||
playerSize = float32(40)
|
||||
cam1, cam2 rl.Camera3D
|
||||
)
|
||||
|
||||
|
@ -15,67 +14,63 @@ func main() {
|
|||
|
||||
rl.InitWindow(screenW, screenH, "raylib [core] example - 3d camera split screen")
|
||||
|
||||
// Setup player 1 camera and screen
|
||||
cam1.Fovy = 45
|
||||
cam1.Up.Y = 1
|
||||
cam1.Target.Y = 1
|
||||
cam1.Position.Z = -3
|
||||
cam1.Position.Y = 0.5
|
||||
cam1.Position.Y = 1
|
||||
|
||||
cam2 = cam1
|
||||
cam1.Position.Z = 3
|
||||
// Setup player two camera and screen
|
||||
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)
|
||||
screenCam2 := rl.LoadRenderTexture(screenW/2, screenH)
|
||||
|
||||
splitScreenRec := rl.NewRectangle(0, 0, float32(screenCam1.Texture.Width), -float32(screenCam1.Texture.Height))
|
||||
|
||||
count := 5
|
||||
count := float32(5)
|
||||
spacing := float32(4)
|
||||
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
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()
|
||||
|
||||
// Move Player1 forward and backwards (no turning)
|
||||
if rl.IsKeyDown(rl.KeyW) {
|
||||
cam1.Position.Z -= frameOffset
|
||||
cam1.Target.Z -= frameOffset
|
||||
} else if rl.IsKeyDown(rl.KeyS) {
|
||||
cam1.Position.Z += frameOffset
|
||||
cam1.Target.Z += frameOffset
|
||||
}
|
||||
if rl.IsKeyDown(rl.KeyD) {
|
||||
cam1.Position.X += frameOffset
|
||||
cam1.Target.X += frameOffset
|
||||
} else if rl.IsKeyDown(rl.KeyA) {
|
||||
cam1.Position.X -= frameOffset
|
||||
cam1.Target.X -= frameOffset
|
||||
} else if rl.IsKeyDown(rl.KeyS) {
|
||||
cam1.Position.Z -= frameOffset
|
||||
cam1.Target.Z -= frameOffset
|
||||
}
|
||||
|
||||
// Move Player2 forward and backwards (no turning)
|
||||
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.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.ClearBackground(rl.SkyBlue)
|
||||
rl.BeginMode3D(cam1)
|
||||
|
||||
rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige)
|
||||
|
||||
for x := -float32(count) * spacing; x <= float32(count)*spacing; x += spacing {
|
||||
for z := -float32(count) * spacing; z <= float32(count)*spacing; z += spacing {
|
||||
for x := -count * spacing; x <= count*spacing; x += 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, 0.5, z), 0.25, 1, 0.25, rl.Brown)
|
||||
}
|
||||
|
@ -87,17 +82,18 @@ func main() {
|
|||
rl.EndMode3D()
|
||||
|
||||
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()
|
||||
|
||||
// Draw Player2 view to the render texture
|
||||
rl.BeginTextureMode(screenCam2)
|
||||
rl.ClearBackground(rl.SkyBlue)
|
||||
rl.BeginMode3D(cam2)
|
||||
|
||||
rl.DrawPlane(rl.Vector3Zero(), rl.NewVector2(50, 50), rl.Beige)
|
||||
|
||||
for x := -float32(count) * spacing; x <= float32(count)*spacing; x += spacing {
|
||||
for z := -float32(count) * spacing; z <= float32(count)*spacing; z += spacing {
|
||||
for x := -count * spacing; x <= count*spacing; x += 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, 0.5, z), 0.25, 1, 0.25, rl.Brown)
|
||||
}
|
||||
|
@ -109,9 +105,10 @@ func main() {
|
|||
rl.EndMode3D()
|
||||
|
||||
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()
|
||||
|
||||
// Draw both views render textures to the screen side by side
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.Black)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package main
|
||||
|
||||
import "github.com/gen2brain/raylib-go/raylib"
|
||||
import "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
|
||||
func main() {
|
||||
rl.SetConfigFlags(rl.FlagVsyncHint)
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const screenW = int32(1280)
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(800, 450, "raylib [core] example - color selection (collision detection)")
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
screenWidth := int32(800)
|
||||
screenHeight := int32(450)
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
var (
|
||||
maxGestureStrings int = 20
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
screenWidth := int32(800)
|
||||
screenHeight := int32(450)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -3,9 +3,9 @@ package main
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gen2brain/raylib-go/easings"
|
||||
"github.com/gen2brain/raylib-go/raygui"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/easings"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -18,7 +18,7 @@ package main
|
|||
import (
|
||||
"math"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"math/rand"
|
||||
"time"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
snakeLength = 256
|
||||
squareSize = 31
|
||||
|
|
|
@ -2,24 +2,25 @@ module examples
|
|||
|
||||
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 (
|
||||
github.com/gen2brain/raylib-go/easings v0.0.0-00010101000000-000000000000
|
||||
github.com/gen2brain/raylib-go/physics v0.0.0-00010101000000-000000000000
|
||||
github.com/gen2brain/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/easings v0.0.0-00010101000000-000000000000
|
||||
git.terah.dev/UnrealXR/raylib-go/physics v0.0.0-00010101000000-000000000000
|
||||
git.terah.dev/UnrealXR/raylib-go/raygui v0.0.0-00010101000000-000000000000
|
||||
git.terah.dev/UnrealXR/raylib-go/raylib v0.0.0-20241202103652-5d50abe7c65b
|
||||
github.com/jakecoffman/cp v1.2.1
|
||||
github.com/neguse/go-box2d-lite v0.0.0-20170921151050-5d8ed9b7272b
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.5.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.1 // 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.5.0/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
|
||||
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/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/go.mod h1:kvKwD9codtns5mvpA53V3vLnqFb/Ahcu8zgkGM0SIbI=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
|
||||
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 (
|
||||
"fmt"
|
||||
|
||||
gui "github.com/gen2brain/raylib-go/raygui"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -3,8 +3,8 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
gui "github.com/gen2brain/raylib-go/raygui"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||
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 (
|
||||
"fmt"
|
||||
|
||||
gui "github.com/gen2brain/raylib-go/raygui"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
/*******************************************************************************************
|
||||
|
|
|
@ -3,8 +3,8 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
gui "github.com/gen2brain/raylib-go/raygui"
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
gui "git.terah.dev/UnrealXR/raylib-go/raygui"
|
||||
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
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
)
|
||||
|
||||
func main() {
|
||||
screenWidth := int32(1280)
|
||||
screenHeight := int32(800)
|
||||
|
||||
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation")
|
||||
|
||||
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.Up = rl.NewVector3(0.0, 1.0, 0.0)
|
||||
camera.Fovy = 75.0
|
||||
camera.Fovy = 45.0
|
||||
camera.Projection = rl.CameraPerspective
|
||||
|
||||
model := rl.LoadModel("guy.iqm")
|
||||
|
@ -32,7 +54,7 @@ func main() {
|
|||
|
||||
for !rl.WindowShouldClose() {
|
||||
|
||||
rl.UpdateCamera(&camera, rl.CameraOrbital)
|
||||
rl.UpdateCamera(&camera, rl.CameraFirstPerson)
|
||||
|
||||
if rl.IsKeyDown(rl.KeySpace) {
|
||||
animFrameCount++
|
||||
|
@ -43,17 +65,18 @@ func main() {
|
|||
if animFrameCount >= int(animFrameNum) {
|
||||
animFrameCount = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rl.BeginDrawing()
|
||||
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
|
||||
rl.BeginMode3D(camera)
|
||||
|
||||
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.EndMode3D()
|
||||
|
@ -65,6 +88,7 @@ func main() {
|
|||
}
|
||||
|
||||
rl.UnloadModel(model)
|
||||
rl.UnloadModelAnimations(anims)
|
||||
rl.UnloadTexture(texture)
|
||||
|
||||
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 (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
const (
|
||||
screenWidth = 800
|
||||
screenHeight = 450
|
||||
)
|
||||
|
||||
func main() {
|
||||
screenWidth := int32(800)
|
||||
screenHeight := int32(450)
|
||||
|
||||
rl.InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards")
|
||||
|
||||
camera := rl.Camera{}
|
||||
|
@ -18,25 +31,60 @@ func main() {
|
|||
camera.Projection = rl.CameraPerspective
|
||||
|
||||
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)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
// Update
|
||||
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.ClearBackground(rl.RayWhite)
|
||||
|
||||
rl.BeginMode3D(camera)
|
||||
|
||||
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.DrawFPS(10, 10)
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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
|
||||
*
|
||||
* This example has been created using raylib-go v0.0.0-20220104071325-2f072dc2d259 (https://github.com/gen2brain/raylib-go)
|
||||
* raylib-go is licensed under an unmodified zlib/libpng license (https://github.com/gen2brain/raylib-go/blob/master/LICENSE)
|
||||
* 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://git.terah.dev/UnrealXR/raylib-go/blob/master/LICENSE)
|
||||
*
|
||||
* Original C version for Raylib 2.5 Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
||||
* Converted to Go by Michael Redman January 4, 2022
|
||||
|
@ -13,7 +13,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
screenWidth := int32(800)
|
||||
screenHeight := int32(450)
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -62,7 +62,7 @@ func main() {
|
|||
|
||||
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.EndDrawing()
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
//"fmt"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
"unsafe"
|
||||
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
screenWidth := int32(1280)
|
||||
screenHeight := int32(720)
|
||||
|
||||
numModels := 8
|
||||
numModels := 9
|
||||
|
||||
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[6] = rl.LoadModelFromMesh(rl.GenMeshKnot(1, 2, 16, 128))
|
||||
models[7] = rl.LoadModelFromMesh(rl.GenMeshPoly(5, 2))
|
||||
models[8] = rl.LoadModelFromMesh(GenMeshCustom())
|
||||
|
||||
for i := 0; i < numModels; i++ {
|
||||
rl.SetMaterialTexture(models[i].Materials, rl.MapDiffuse, texture)
|
||||
|
@ -49,12 +52,17 @@ func main() {
|
|||
rl.UpdateCamera(&camera, rl.CameraOrbital)
|
||||
|
||||
if rl.IsKeyPressed(rl.KeyUp) {
|
||||
currentModel++
|
||||
if currentModel >= numModels {
|
||||
currentModel = 0
|
||||
currentModel = (currentModel + 1) % numModels // Cycle between the textures
|
||||
}
|
||||
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.ClearBackground(rl.RayWhite)
|
||||
|
@ -66,9 +74,10 @@ func main() {
|
|||
|
||||
rl.EndMode3D()
|
||||
|
||||
rl.DrawRectangle(10, 10, 310, 30, rl.Fade(rl.SkyBlue, 0.5))
|
||||
rl.DrawRectangleLines(10, 10, 310, 30, rl.Fade(rl.DarkBlue, 0.5))
|
||||
rl.DrawText("UP ARROW KEY TO CHANGE MODELS", 20, 20, 10, rl.Blue)
|
||||
rl.DrawRectangle(10, 10, 310, 50, rl.Fade(rl.SkyBlue, 0.5))
|
||||
rl.DrawRectangleLines(10, 10, 310, 50, rl.Fade(rl.DarkBlue, 0.5))
|
||||
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"
|
||||
switch currentModel {
|
||||
|
@ -86,6 +95,8 @@ func main() {
|
|||
txt = "KNOT"
|
||||
case 7:
|
||||
txt = "POLY"
|
||||
case 8:
|
||||
txt = "Custom (triangle)"
|
||||
}
|
||||
txtlen := rl.MeasureText(txt, 20)
|
||||
rl.DrawText(txt, screenWidth/2-txtlen/2, 10, 20, rl.DarkBlue)
|
||||
|
@ -94,9 +105,63 @@ func main() {
|
|||
}
|
||||
|
||||
rl.UnloadTexture(texture)
|
||||
// Custom models meshes needs to be
|
||||
// cleared manually
|
||||
clearCustomMesh(models[8])
|
||||
for i := 0; i < numModels; i++ {
|
||||
rl.UnloadModel(models[i])
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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() {
|
||||
screenWidth := int32(800)
|
||||
screenHeight := int32(450)
|
||||
|
@ -24,26 +37,75 @@ func main() {
|
|||
|
||||
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)
|
||||
|
||||
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.ClearBackground(rl.RayWhite)
|
||||
|
||||
rl.BeginMode3D(camera)
|
||||
|
||||
rl.DrawModel(obj, position, 1.0, rl.White) // Draw 3d model with texture
|
||||
|
||||
rl.DrawGrid(20, 10.0) // Draw a grid
|
||||
|
||||
if selected {
|
||||
rl.DrawBoundingBox(bounds, rl.Green) // Draw selection box
|
||||
}
|
||||
|
||||
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.DrawFPS(10, 10)
|
||||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
rl.UnloadTexture(texture) // Unload texture
|
||||
rl.UnloadModel(obj) // Unload model
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"math"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
rl "git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
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 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
|
||||
|
||||
|
@ -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
|
||||
|
||||
And build apk with ant:
|
||||
|
||||
cd android
|
||||
ant clean debug
|
||||
|
||||
Or with gradle:
|
||||
And build apk:
|
||||
|
||||
./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`.
|
||||
|
||||
### 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"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.gen2brain.raylib.go"
|
||||
android:versionCode="1"
|
||||
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" />
|
||||
|
||||
<!-- 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. -->
|
||||
<activity android:name="android.app.NativeActivity"
|
||||
android:exported="true"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:screenOrientation="landscape"
|
||||
android:clearTaskOnLaunch="true">
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '27.0.3'
|
||||
namespace = "com.example.android"
|
||||
compileSdkVersion 34
|
||||
buildToolsVersion '34.0.0'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.android"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 27
|
||||
targetSdkVersion 34
|
||||
versionCode 1
|
||||
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()
|
||||
}
|
||||
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
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
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"
|
||||
"runtime"
|
||||
|
||||
"github.com/gen2brain/raylib-go/raylib"
|
||||
"git.terah.dev/UnrealXR/raylib-go/raylib"
|
||||
)
|
||||
|
||||
// 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