84 Commits
Author SHA1 Message Date
klemek 2a7d1f6df4 docs: update README
Clang Lint CI / lint-no-video (push) Successful in 50s
Clang Build CI / run-no-video (push) Successful in 58s
Clang Build CI / run-video (push) Successful in 59s
Clang Build CI / build-release (push) Successful in 1m29s
Clang Lint CI / lint-video (push) Successful in 1m5s
2026-08-29 12:00:56 +02:00
klemek 80add2ec67 feat(state): auto-save 2026-08-29 12:00:50 +02:00
klemek 9d300a69c1 feat(state): save more data in files
Clang Lint CI / lint-no-video (push) Successful in 1m24s
Clang Build CI / run-no-video (push) Successful in 1m29s
Clang Build CI / run-video (push) Successful in 1m41s
Clang Build CI / build-release (push) Successful in 2m48s
Clang Lint CI / lint-video (push) Successful in 1m48s
2026-08-29 11:29:11 +02:00
klemek 1f7291fce9 refactor(default): add demo logo on main screen 2026-08-28 20:15:38 +02:00
klemek 674dc50ff7 refactor(default): glsl cleaning (2/2) 2026-08-28 20:10:09 +02:00
klemek 749206746d refactor(default): glsl cleaning (1/2) 2026-08-28 19:46:46 +02:00
klemek 69f98e536f fix: switch auto random with demo mode
Clang Lint CI / lint-no-video (push) Successful in 1m36s
Clang Build CI / run-no-video (push) Successful in 1m37s
Clang Build CI / run-video (push) Successful in 1m43s
Clang Build CI / build-release (push) Successful in 2m11s
Clang Lint CI / lint-video (push) Successful in 50s
2026-08-28 18:01:27 +02:00
klemek 0a43f3f582 fix: add opengl metadata
Clang Lint CI / lint-no-video (push) Successful in 46s
Clang Build CI / run-no-video (push) Successful in 1m4s
Clang Build CI / run-video (push) Successful in 1m4s
Clang Build CI / build-release (push) Successful in 1m43s
Clang Lint CI / lint-video (push) Successful in 1m4s
2026-08-27 18:45:48 +02:00
klemek 6110e1df7f fix: add ext to gl.h 2026-08-27 17:43:32 +02:00
klemek 3a228122cf fix: compatibility
Clang Build CI / run-no-video (push) Successful in 49s
Clang Build CI / run-video (push) Successful in 51s
Clang Lint CI / lint-no-video (push) Successful in 56s
Clang Build CI / build-release (push) Successful in 1m14s
Clang Lint CI / lint-video (push) Successful in 46s
2026-08-27 17:21:30 +02:00
klemek a440535953 forge (steel) v1.2.4
Clang Build CI / build-release (push) Successful in 1m16s
Clang Build CI / run-no-video (push) Successful in 58s
Clang Build CI / run-video (push) Successful in 1m1s
Clang Lint CI / lint-no-video (push) Successful in 53s
Clang Lint CI / lint-video (push) Successful in 53s
2026-08-27 16:38:49 +02:00
klemek cec3d54685 fix(shaders): remove unused warning
Clang Lint CI / lint-no-video (push) Successful in 46s
Clang Build CI / run-video (push) Successful in 51s
Clang Build CI / run-no-video (push) Successful in 1m2s
Clang Build CI / build-release (push) Successful in 1m15s
Clang Lint CI / lint-video (push) Successful in 53s
2026-08-27 16:34:51 +02:00
klemek 7355d0937c fix(window): sometimes no GLFW_PLATFORM
Clang Lint CI / lint-no-video (push) Successful in 50s
Clang Build CI / run-no-video (push) Successful in 55s
Clang Build CI / run-video (push) Successful in 1m3s
Clang Build CI / build-release (push) Successful in 1m26s
Clang Lint CI / lint-video (push) Successful in 53s
2026-08-27 16:33:00 +02:00
klemek 1c44239a8d feat(window): can specify opengl version from args
Clang Build CI / run-no-video (push) Failing after 48s
Clang Lint CI / lint-no-video (push) Failing after 48s
Clang Build CI / run-video (push) Failing after 50s
Clang Build CI / build-release (push) Failing after 1m12s
Clang Lint CI / lint-video (push) Failing after 51s
2026-08-27 16:29:06 +02:00
klemek 73dd4b75d3 forge (steel) v1.2.3
Clang Build CI / build-release (push) Failing after 1m36s
Clang Build CI / run-no-video (push) Failing after 56s
Clang Build CI / run-video (push) Failing after 57s
Clang Lint CI / lint-no-video (push) Failing after 57s
Clang Lint CI / lint-video (push) Failing after 1m7s
2026-08-22 10:26:23 +02:00
klemek 50f5d6f6cb fix(default): projection mapping ARI 2026-08-22 10:26:01 +02:00
klemek 9b7fbfbeeb forge (steel) v1.2.2
Clang Build CI / run-no-video (push) Failing after 48s
Clang Build CI / build-release (push) Failing after 1m12s
Clang Build CI / run-video (push) Failing after 2m1s
Clang Lint CI / lint-video (push) Failing after 1m48s
Clang Lint CI / lint-no-video (push) Failing after 1m45s
2026-08-21 23:18:08 +02:00
klemek 192cf571b1 feat(glfw): allow to switch backend 2026-08-21 23:17:21 +02:00
klemek 519a9b88f4 fix(window): bug with swap interval 2026-08-21 23:17:05 +02:00
klemek f124cfacfb forge (steel) v1.2.1
Clang Build CI / run-no-video (push) Successful in 2m44s
Clang Build CI / build-release (push) Failing after 52s
Clang Build CI / run-video (push) Successful in 2m41s
Clang Lint CI / lint-no-video (push) Successful in 2m38s
Clang Lint CI / lint-video (push) Successful in 1m22s
2026-05-24 23:32:25 +02:00
klemek 4e14404726 docs: add projection mapping docs 2026-05-24 23:31:55 +02:00
klemek db77846f1b feat: default project up to 4 masks 2026-05-24 23:29:41 +02:00
klemek 57fa627bed forge (steel) v1.2.0
Clang Build CI / run-no-video (push) Successful in 1m8s
Clang Lint CI / lint-no-video (push) Successful in 1m7s
Clang Build CI / build-release (push) Successful in 1m48s
Clang Build CI / run-video (push) Successful in 1m13s
Clang Lint CI / lint-video (push) Successful in 1m55s
2026-05-21 00:43:02 +02:00
klemek 9dbfd34566 docs: update DEVELOPMENT.md 2026-05-21 00:42:42 +02:00
klemek 3dc2a77529 fix: same key multiple uses
Clang Lint CI / lint-no-video (push) Successful in 1m4s
Clang Build CI / run-video (push) Successful in 1m4s
Clang Build CI / run-no-video (push) Successful in 1m4s
Clang Build CI / build-release (push) Has been cancelled
Clang Lint CI / lint-video (push) Successful in 1m27s
2026-05-21 00:41:44 +02:00
klemek 7dbce62182 feat: ignore some values in auto random 2026-05-21 00:32:03 +02:00
klemek bb84350591 feat: default projection mapping with shift + M 2026-05-20 23:20:55 +02:00
klemek 7db7f4b89e Update README.md 2026-05-17 01:01:53 +02:00
klemek e5b2d2306f forge (steel) v1.1.3
Clang Build CI / run-no-video (push) Successful in 1m10s
Clang Lint CI / lint-no-video (push) Successful in 1m18s
Clang Build CI / build-release (push) Successful in 1m53s
Clang Build CI / run-video (push) Successful in 1m20s
Clang Lint CI / lint-video (push) Successful in 2m48s
2026-05-17 00:58:34 +02:00
klemek 54b166d33f fix: clock_gettime instead of clock
Clang Build CI / build-release (push) Has been cancelled
Clang Build CI / run-no-video (push) Has been cancelled
Clang Build CI / run-video (push) Has been cancelled
Clang Lint CI / lint-no-video (push) Successful in 1m14s
Clang Lint CI / lint-video (push) Successful in 1m16s
2026-05-17 00:57:59 +02:00
klemek 344029f195 fix: default video buffers to 1 2026-05-17 00:41:59 +02:00
klemek 4837ab2786 fix: on video disconnect reset all context resolution 2026-05-17 00:41:13 +02:00
klemek e38f57af46 feat: select fourcc and handle hw decoded
Clang Build CI / build-release (push) Failing after 54s
Clang Build CI / run-video (push) Successful in 1m12s
Clang Lint CI / lint-no-video (push) Successful in 1m12s
Clang Build CI / run-no-video (push) Successful in 1m17s
Clang Lint CI / lint-video (push) Successful in 4m33s
2026-05-17 00:40:22 +02:00
klemek e667c6b869 fix: default project src inputs 2026-05-16 21:42:01 +02:00
klemek 0b344eb52a fix: video input on both output and monitoring 2026-05-16 21:41:14 +02:00
klemek fddb11dbe3 forge (steel) v1.1.2
Clang Build CI / run-video (push) Successful in 1m31s
Clang Build CI / run-no-video (push) Successful in 1m31s
Clang Build CI / build-release (push) Successful in 1m42s
Clang Lint CI / lint-no-video (push) Successful in 2m29s
Clang Lint CI / lint-video (push) Successful in 2m29s
2026-05-16 19:04:47 +02:00
klemek 591bfbe0aa fix: remove not backward compatible snd_lib_log_set_handler
Clang Lint CI / lint-no-video (push) Successful in 55s
Clang Build CI / run-no-video (push) Successful in 1m36s
Clang Build CI / run-video (push) Successful in 1m37s
Clang Build CI / build-release (push) Successful in 1m57s
Clang Lint CI / lint-video (push) Successful in 2m5s
2026-05-16 18:56:45 +02:00
klemek b01314778d docs: add comment for project_free
Clang Lint CI / lint-no-video (push) Failing after 3m4s
Clang Build CI / run-no-video (push) Failing after 3m49s
Clang Build CI / run-video (push) Failing after 3m48s
Clang Build CI / build-release (push) Failing after 4m3s
Clang Lint CI / lint-video (push) Failing after 1m26s
2026-05-16 18:49:44 +02:00
klemek cbdf4c768d fix: const vertex_shader_text
Clang Build CI / build-release (push) Has been cancelled
Clang Build CI / run-no-video (push) Has been cancelled
Clang Build CI / run-video (push) Has been cancelled
Clang Lint CI / lint-video (push) Has been cancelled
Clang Lint CI / lint-no-video (push) Has been cancelled
2026-05-16 18:48:26 +02:00
klemek 9787f468e8 fix: dont shadow stdlib rand 2026-05-16 18:47:51 +02:00
klemek 2a8bd612b3 fix: unnecessary structs 2026-05-16 18:47:16 +02:00
klemek ba44237661 fix: MidiBackgroundListenArgs bad typedef 2026-05-16 18:46:34 +02:00
klemek efb13bb9ea fix: auto random debug string bad practice 2026-05-16 18:45:18 +02:00
klemek d89de9d6dd fix: check_eglerror_ro dead code 2026-05-16 18:42:17 +02:00
klemek 6ff0246f42 fix: GLint uniform location instead of GLuint 2026-05-16 18:40:52 +02:00
klemek c45b5ef405 fix: glGetShaderInfoLog with invalid parameters 2026-05-16 18:38:05 +02:00
klemek 12942267d2 fix: dont allow empty values in string args 2026-05-16 18:35:32 +02:00
klemek 15fb29b673 fix: boundary check in parse_uint 2026-05-16 18:32:44 +02:00
klemek 39e1fcc709 fix: set gl context before freeing shaders 2026-05-16 18:32:08 +02:00
klemek 3ae3b23c2a fix: add default value for tex_resolution width 2026-05-16 18:30:28 +02:00
klemek 61c88aae2a fix: check pthread_create return code 2026-05-16 18:29:38 +02:00
klemek fcb2baf84a fix: check return_code of snd_rawmidi_open 2026-05-16 18:26:37 +02:00
klemek 8e7be2258f fix: handle division by 0 in window_use 2026-05-16 18:24:36 +02:00
klemek dcb334ff81 fix: handle VIDIOC_QBUF error while reading video 2026-05-16 18:22:48 +02:00
klemek aab770ba3d fix: free video capture on early init error 2026-05-16 18:19:17 +02:00
klemek 6a7c9b3aab fix: bound timer counter to uint max on fail 2026-05-16 18:10:31 +02:00
klemek 3b6d4d642d fix: use clock instead of timeofday 2026-05-16 18:09:06 +02:00
klemek 988cf799b4 fix: config_file_read handle file error before hashmap_new 2026-05-16 17:54:05 +02:00
klemek a92cca33ad fix: state_parse_config clamp lengths to ARRAY_SIZE 2026-05-16 17:51:40 +02:00
klemek fd9f94d48a fix: save_to_file array size bound check 2026-05-16 17:51:36 +02:00
klemek 859dfc4307 fix: log tempo error 2026-05-16 17:37:49 +02:00
klemek a85a75f93d fix: sync midi read/write 2026-05-16 17:36:50 +02:00
klemek 7e1328aab0 fix: check for snd_rawmidi_info_malloc 2026-05-16 17:35:21 +02:00
klemek 7cce5babc2 fix: don't log errors while reconnecting 2026-05-16 17:12:40 +02:00
klemek 9969230cd9 fix: free process args in pthread 2026-05-16 16:44:34 +02:00
klemek fb77d8e893 fix: revert project files free (already freed in init) 2026-05-16 16:22:39 +02:00
klemek 0fd78bf4cc fix: unsigned comparison 2026-05-16 16:02:53 +02:00
klemek 20e3d39963 fix: init_single_program check linking status 2026-05-16 16:00:39 +02:00
klemek aa8d6c85c0 fix: shaders_free glDeleteShader 2026-05-16 15:55:18 +02:00
klemek b9fd36debd fix: project files free 2026-05-16 15:52:39 +02:00
klemek 7e8eb187d8 fix: parse_fragment_shader_file free content before overwrite 2026-05-16 15:49:22 +02:00
klemek bd61cb0a2d fix: config_file_read dont initialize hashmap on file error 2026-05-16 15:40:03 +02:00
klemek fe1fc9864c fix: string_replace_at check args validity 2026-05-16 15:39:17 +02:00
klemek 233b75e854 fix: string_replace_at check malloc 2026-05-16 15:38:19 +02:00
klemek 910c122c8d fix: unsigned overflow in string_trim 2026-05-16 15:36:09 +02:00
klemek fbd73ebf4c fix: handle partial reads 2026-05-16 15:34:09 +02:00
klemek 43ce38f2f4 fix: file free dangling pointer 2026-05-16 15:31:30 +02:00
klemek ca3e523f93 fix: ftell failure handling 2026-05-16 13:26:40 +02:00
klemek c68bebfd7c fix: unsigned underflow on empty array 2026-05-16 13:25:02 +02:00
klemek 2843e5e863 fix: better full-clean 2026-05-16 00:36:28 +02:00
klemek 433cf61a91 forge (steel) v1.1.1
Clang Build CI / run-no-video (push) Successful in 1m18s
Clang Build CI / build-release (push) Successful in 1m30s
Clang Build CI / run-video (push) Successful in 1m26s
Clang Lint CI / lint-no-video (push) Successful in 1m22s
Clang Lint CI / lint-video (push) Successful in 1m17s
2026-05-16 00:33:24 +02:00
klemek fe3316f730 feat: better src 4 2026-05-16 00:32:41 +02:00
klemek 96f97d81df fix: update default project with internal buffer swap 2026-05-15 16:36:57 +02:00
klemek 365fee352e tools: better clean 2026-05-15 00:24:16 +02:00
54 changed files with 1716 additions and 1207 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ build build project into build/forge
run run project with test args run run project with test args
demo run project with demo mode demo run project with demo mode
valgrind valgrind analysis valgrind valgrind analysis
clean-release remove autoconf/automake files full-clean remove build files and untracked files
test-release try to build release test-release try to build release
release-% make full release of version % release-% make full release of version %
release-arch make arch-linux release package release-arch make arch-linux release package
@@ -124,7 +124,7 @@ make -f Makefile.dev release-arch
- [x] (clean) static functions at top of files - [x] (clean) static functions at top of files
- [x] Configurable key codes - [x] Configurable key codes
- [x] Monitor improvements - [x] Monitor improvements
- [ ] Ignore some values in auto random - [x] Ignore some values in auto random
- [x] build without video in - [x] build without video in
- [ ] Update README monitor/keymap - [ ] Update README monitor/keymap
- [x] Auto reconnect midi input - [x] Auto reconnect midi input
+14 -10
View File
@@ -7,7 +7,7 @@ SHELL := /bin/bash
clean: clean:
@rm -rf build @rm -rf build
build: build/$(TARGET):
@mkdir -p build @mkdir -p build
gcc \ gcc \
src/*.h src/*.c \ src/*.h src/*.c \
@@ -25,6 +25,9 @@ build:
-o build/$(TARGET) \ -o build/$(TARGET) \
-g -Og -g -Og
.PHONY: build
build: build/$(TARGET)
.PHONY: build-no-video .PHONY: build-no-video
build-no-video: build-no-video:
@mkdir -p build @mkdir -p build
@@ -36,7 +39,6 @@ build-no-video:
-lm -lGL -lglfw -lasound \ -lm -lGL -lglfw -lasound \
-Wall -Wextra \ -Wall -Wextra \
-Wno-format-truncation \ -Wno-format-truncation \
-Wno-unused-parameter \
-DGLFW_INCLUDE_NONE \ -DGLFW_INCLUDE_NONE \
-DGLFW_NATIVE_INCLUDE_NONE \ -DGLFW_NATIVE_INCLUDE_NONE \
-DLOG_USE_COLOR \ -DLOG_USE_COLOR \
@@ -48,26 +50,28 @@ format:
clang-format -i src/* clang-format -i src/*
.PHONY: run .PHONY: run
run: build run: build/$(TARGET)
./build/$(TARGET) $(RUN_ARGS) ./build/$(TARGET) $(RUN_ARGS)
.PHONY: sample .PHONY: sample
sample: build sample: build/$(TARGET)
./build/$(TARGET) --project=sample ./build/$(TARGET) --project=sample $(RUN_ARGS)
.PHONY: valgrind .PHONY: valgrind
valgrind: build valgrind: build/$(TARGET)
valgrind \ valgrind \
--show-realloc-size-zero=no \ --show-realloc-size-zero=no \
--undef-value-errors=no \ --undef-value-errors=no \
./build/$(TARGET) $(RUN_ARGS) ./build/$(TARGET) $(RUN_ARGS)
.PHONY: clean-release .PHONY: full-clean
clean-release: full-clean:
git clean -f -x git clean -f -x
rm -rf */*/.deps
rm -rf */.deps
.PHONY: test-release .PHONY: test-release
test-release: clean clean-release test-release: clean full-clean
aclocal aclocal
autoconf autoconf
automake --add-missing automake --add-missing
@@ -77,7 +81,7 @@ test-release: clean clean-release
cp $(TARGET)-steel-*.tar.gz build/ cp $(TARGET)-steel-*.tar.gz build/
.PHONY: release-% .PHONY: release-%
release-%: clean clean-release release-%: clean full-clean
git pull origin main git pull origin main
sed -i -E "s/[0-9]+\\.[0-9]+\\.[0-9]+/$*/g" configure.ac sed -i -E "s/[0-9]+\\.[0-9]+\\.[0-9]+/$*/g" configure.ac
aclocal aclocal
+2 -2
View File
@@ -1,12 +1,12 @@
pkgname=forge-steel pkgname=forge-steel
pkgver=1.1.0 pkgver=1.2.4
pkgrel=1 pkgrel=1
pkgdesc="Fusion Of Real Time Generative Effects" pkgdesc="Fusion Of Real Time Generative Effects"
arch=('i686' 'pentium4' 'x86_64' 'arm' 'armv7h' 'armv6h' 'aarch64' 'riscv64') arch=('i686' 'pentium4' 'x86_64' 'arm' 'armv7h' 'armv6h' 'aarch64' 'riscv64')
depends=('glfw>=1:3', 'v4l-utils>=1.32', 'alsa-lib>=1.2', 'libglvnd>=1.7') depends=('glfw>=1:3', 'v4l-utils>=1.32', 'alsa-lib>=1.2', 'libglvnd>=1.7')
url="https://git.klemek.fr/klemek/forge-steel" url="https://git.klemek.fr/klemek/forge-steel"
source=("${pkgname}-steel-${pkgver}.tar.gz::https://git.klemek.fr/klemek/forge-steel/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz") source=("${pkgname}-steel-${pkgver}.tar.gz::https://git.klemek.fr/klemek/forge-steel/releases/download/v${pkgver}/${pkgname}-${pkgver}.tar.gz")
sha256sums=('794fb0f170cff19872acfba8a556e2a08c55a78e497ac0b330eca6db65343529') sha256sums=('a34c7f8101d8d947e26bee1fa5ab8d87f4292014e5ef17d03eb34fefb387db9e')
srcdir=build srcdir=build
backup=("usr/share/${pkgname}") backup=("usr/share/${pkgname}")
+37 -14
View File
@@ -1,4 +1,4 @@
[![](https://git.klemek.fr/klemek/forge-steel/actions/workflows/lint.yml/badge.svg?branch=main&style=flat-square)](https://git.klemek.fr/klemek/forge-steel/actions?workflow=lint.yml) [![](https://git.klemek.fr/klemek/forge-steel/actions/workflows/build.yml/badge.svg?branch=main&style=flat-square)](https://git.klemek.fr/klemek/forge-steel/actions?workflow=build.yml) ![LOC](https://img.shields.io/badge/cloc-3.4k-blue?style=flat-square) [![](https://git.klemek.fr/klemek/forge-steel/actions/workflows/lint.yml/badge.svg?branch=main&style=flat-square)](https://git.klemek.fr/klemek/forge-steel/actions?workflow=lint.yml) [![](https://git.klemek.fr/klemek/forge-steel/actions/workflows/build.yml/badge.svg?branch=main&style=flat-square)](https://git.klemek.fr/klemek/forge-steel/actions?workflow=build.yml) ![LOC](https://img.shields.io/badge/cloc-3.6k-blue?style=flat-square)
<!-- omit from toc --> <!-- omit from toc -->
# F.O.R.G.E. (Steel) # F.O.R.G.E. (Steel)
@@ -133,7 +133,7 @@ make install
```shell ```shell
git clone --recursive https://git.klemek.fr/klemek/forge-steel git clone --recursive https://git.klemek.fr/klemek/forge-steel
cd forge cd forge-steel
makepkg -si makepkg -si
``` ```
@@ -142,11 +142,11 @@ makepkg -si
```shell ```shell
git clone --recursive https://git.klemek.fr/klemek/forge-steel git clone --recursive https://git.klemek.fr/klemek/forge-steel
cd forge cd forge-steel
aclocal aclocal
autoconf autoconf
automake --add-missing automake --add-missing
./configure ./configure --prefix=$HOME/.local
make make
make install make install
``` ```
@@ -174,9 +174,7 @@ These are configurable in the [`forge_project.cfg`](#forge_projectcfg).
### CLI arguments ### CLI arguments
```txt ```txt
forge steel-VERSION usage: forge [-h] [-v] [-p=PROJECT_PATH] [-c=CFG_FILE] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-w] [-t=TEMPO] [-d] [-ar / -nar] [-arc=CYCLES] [-is=SIZE] [-ls / -nls] [-ss / -nss] [-mr / -nmr] [-tm] [-tf] [--x11] [--wayland] [--cocoa] [--win32] [-as / -nas] [-oma=MAJOR] [-omi=MINOR]
usage: forge [-h] [-v] [-p=PROJECT_PATH] [-c=CFG_FILE] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-w] [-t=TEMPO] [-d] [-ar / -nar] [-arc=CYCLES] [-vi=FILE] [-vs=SIZE] [-vb=COUNT] [-vr / -nvr] [-is=SIZE] [-ls / -nls] [-ss / -nss] [-mr / -nmr] [-tm] [-tf]
Fusion Of Real-time Generative Effects. Fusion Of Real-time Generative Effects.
@@ -195,20 +193,23 @@ options:
-ar, --auto-random randomize state every cycle (4 beats) -ar, --auto-random randomize state every cycle (4 beats)
-nar, --no-auto-random do not randomize state (default) -nar, --no-auto-random do not randomize state (default)
-arc, --auto-random-cycle auto random cycle length (default: 4) -arc, --auto-random-cycle auto random cycle length (default: 4)
-vi, --video-in path to video capture device (multiple allowed)
-vb, --video-buffers number of video buffers to use (default: 2)
-vs, --video-size video capture desired height (default: internal texture height)
-vr, --video-reconnect auto-reconnect video (default)
-nvr, --no-video-reconnect do not auto-reconnect video
-is, --internal-size internal texture height (default: 720) -is, --internal-size internal texture height (default: 720)
-ls, --load-state load saved state (default) -ls, --load-state load saved state (default)
-nls, --no-load-state do not load saved state -nls, --no-load-state do not load saved state
-ss, --save-state save state (default) -ss, --save-state save state (default)
-nss, --no-save-state do not save state -nss, --no-save-state do not save state
-as, --auto-save continuously save state (every ~10ms)
-nas, --no-auto-save do not continuously save state (default)
-mr, --midi-reconnect auto-reconnect midi (default) -mr, --midi-reconnect auto-reconnect midi (default)
-nmr, --no-midi-reconnect do not auto-reconnect midi -nmr, --no-midi-reconnect do not auto-reconnect midi
-tm, --trace-midi print midi code and values -tm, --trace-midi print midi code and values
-tf, --trace-fps print fps status of subsystems -tf, --trace-fps print fps status of subsystems
--x11 force X11 GLFW backend
--wayland force Wayland GLFW backend
--cocoa force Cocoa GLFW backend
--win32 force Win32 GLFW backend
-oma, --opengl-major-version OpenGL major version (default: 4)
-omi, --opengl-minor-version OpenGL minor version (default: 6)
``` ```
## Default Project ## Default Project
@@ -247,7 +248,7 @@ Working with pages and items, you can use the following predefined sources and e
| **1** | **0** | Feedback + Thru | _Hue_ | _Saturation_ | _Light_ | Thru | _Hue_ | _Saturation_ | _Light_ | | **1** | **0** | Feedback + Thru | _Hue_ | _Saturation_ | _Light_ | Thru | _Hue_ | _Saturation_ | _Light_ |
| | **1** | Lines | _Thick. / Dezoom_ | _Rotation_ | _Distortion_ | Feedback + Shift | _Zoom / Dezoom_ | _X Shift_ | _Y Shift_ | | | **1** | Lines | _Thick. / Dezoom_ | _Rotation_ | _Distortion_ | Feedback + Shift | _Zoom / Dezoom_ | _X Shift_ | _Y Shift_ |
| | **2** | Dots | _Zoom_ | _Rotation_ | _Lens_ | Shift | _Zoom / Dezoom_ | _X Shift_ | _Y Shift_ | | | **2** | Dots | _Zoom_ | _Rotation_ | _Lens_ | Shift | _Zoom / Dezoom_ | _X Shift_ | _Y Shift_ |
| | **3** | Circuit | _Zoom_ | _H. connect_ | _V. connect_ | Colorize | _Black Color_ | _White Color_ | _Shift_ | | | **3** | Bacteria | _Zoom_ | _Details_ | _Delta details_ | Colorize | _Black Color_ | _White Color_ | _Shift_ |
| | **4** | Noise | _Zoom_ | _Voronoi dist._ | _Details_ | Quantize | _Pixel Size_ | _Bit Depth_ | _Blur_ | | | **4** | Noise | _Zoom_ | _Voronoi dist._ | _Details_ | Quantize | _Pixel Size_ | _Bit Depth_ | _Blur_ |
| **2** | **5** | Video In 1 + Thru | _Hue_ | _Saturation_ | _Light_ | Dithering | _Pixel Size_ | _Bit Depth_ | _Blur_ | | **2** | **5** | Video In 1 + Thru | _Hue_ | _Saturation_ | _Light_ | Dithering | _Pixel Size_ | _Bit Depth_ | _Blur_ |
| | **6** | CP437 | _Zoom_ | _Charset_ | _Char. Delta_ | TV | _Lens_ | _Horz. Noise_ | _Dezoom_ | | | **6** | CP437 | _Zoom_ | _Charset_ | _Char. Delta_ | TV | _Lens_ | _Horz. Noise_ | _Dezoom_ |
@@ -262,6 +263,28 @@ Working with pages and items, you can use the following predefined sources and e
See the [printable version](./docs/forge_default_mapping.pdf). See the [printable version](./docs/forge_default_mapping.pdf).
### Available hotkeys
| Hotkey | Function |
| ------ | -------- |
| <kbd>Shift</kbd> + <kbd>F</kbd> | Switch between shader-decoded or hardware decoded YUYV |
| <kbd>M</kbd> | Projection mapping 1 |
| <kbd>Shift</kbd> + <kbd>M</kbd> | Projection mapping 2 |
| <kbd>Ctrl</kbd> + <kbd>M</kbd> | Projection mapping 3 |
| <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>M</kbd> | Projection mapping 4 |
### Projection Mappings
In any of the projection mapping mode, use the nanoKONTROL2 last 4 columns to control 4 on-screen points:
| Midi Control | Function |
| ------ | -------- |
| Fader N | point N - X position |
| Knob N | point N - Y position |
| Last column top button | activate projection mapping |
| Last column middle button | invert projection mapping |
| Last column bottom button | show projection borders |
## Making your own FORGE project ## Making your own FORGE project
You want to embrace the "user" in "user-defined"? It's time to make your own project. You want to embrace the "user" in "user-defined"? It's time to make your own project.
@@ -499,7 +522,7 @@ You can check your device real FPS on [V4L2 UCP](https://github.com/HedgeHawk/v4
### My video feed got strange lines ### My video feed got strange lines
You need to decode the [V4L2 YUYV format](https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-yuyv.html). You may need to decode the [V4L2 YUYV format](https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-yuyv.html).
The code is available in the default project [default/inc_yuyv.glsl](./default/inc_yuyv.glsl) The code is available in the default project [default/inc_yuyv.glsl](./default/inc_yuyv.glsl)
+1 -2
View File
@@ -1,4 +1,4 @@
AC_INIT([forge], [steel-1.1.0], [klemek.dev@proton.me]) AC_INIT([forge], [steel-1.2.4], [klemek.dev@proton.me])
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_PROG_CC AC_PROG_CC
@@ -11,7 +11,6 @@ AC_CHECK_HEADERS([stdlib.h])
AC_CHECK_HEADERS([sys/ioctl.h]) AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([sys/mman.h]) AC_CHECK_HEADERS([sys/mman.h])
AC_CHECK_HEADERS([sys/stat.h]) AC_CHECK_HEADERS([sys/stat.h])
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_HEADERS([sys/types.h]) AC_CHECK_HEADERS([sys/types.h])
AC_CHECK_HEADERS([sys/wait.h]) AC_CHECK_HEADERS([sys/wait.h])
+78 -9
View File
@@ -115,13 +115,13 @@ FRAG_FILE_PREFIX=frag
FRAG_COUNT=10 FRAG_COUNT=10
# To which texture will the shader fragX.glsl will render to # To which texture will the shader fragX.glsl will render to
FRAG_1_OUT=5 FRAG_1_OUT=3
FRAG_2_OUT=6 FRAG_2_OUT=4
FRAG_3_OUT=7 FRAG_3_OUT=5
FRAG_4_OUT=8 FRAG_4_OUT=6
FRAG_5_OUT=9 FRAG_5_OUT=7
FRAG_6_OUT=10 FRAG_6_OUT=8
FRAG_7_OUT=11 FRAG_7_OUT=9
FRAG_8_OUT=0 FRAG_8_OUT=0
# Which fragment shader renders to output window # Which fragment shader renders to output window
FRAG_OUTPUT=9 FRAG_OUTPUT=9
@@ -235,10 +235,14 @@ GROUP_1_6_Y=19
GROUP_1_6_Z= GROUP_1_6_Z=
# Same for group 2 # Same for group 2
GROUP_2_ACTIVE_COUNT=3 GROUP_2_ACTIVE_COUNT=7
GROUP_2_ACTIVE_1=36 GROUP_2_ACTIVE_1=36
GROUP_2_ACTIVE_2=68 GROUP_2_ACTIVE_2=68
GROUP_2_ACTIVE_3=52 GROUP_2_ACTIVE_3=52
GROUP_2_ACTIVE_4=1077
GROUP_2_ACTIVE_5=11077
GROUP_2_ACTIVE_6=101077
GROUP_2_ACTIVE_7=111077
GROUP_2_COUNT=7 GROUP_2_COUNT=7
GROUP_2_1_X=37 GROUP_2_1_X=37
GROUP_2_1_Y=53 GROUP_2_1_Y=53
@@ -269,7 +273,72 @@ GROUP_3_1_Y=58
GROUP_3_1_Z= GROUP_3_1_Z=
GROUP_3_2_X=0 GROUP_3_2_X=0
GROUP_3_2_Y=16 GROUP_3_2_Y=16
GROUP_3_2_Z= GROUP_3_2_Z=11089
# Auto-Random Ignore (ARI) prefixes
ARI_COUNT=62
ARI_1=GROUP_3_1_Y
ARI_2=GROUP_3_2_Z
ARI_3=GROUP_2_5_X_4
ARI_4=GROUP_2_5_Y_4
ARI_5=GROUP_2_5_Z_4
ARI_6=GROUP_2_2_X_4
ARI_7=GROUP_2_2_Y_4
ARI_8=GROUP_2_2_Z_4
ARI_9=GROUP_2_4_X_4
ARI_10=GROUP_2_4_Y_4
ARI_11=GROUP_2_4_Z_4
ARI_12=GROUP_2_6_X_4
ARI_13=GROUP_2_6_Y_4
ARI_14=GROUP_2_6_Z_4
ARI_15=GROUP_2_7_X_4
ARI_16=GROUP_2_7_Y_4
ARI_17=GROUP_2_7_Z_4
ARI_18=GROUP_2_5_X_5
ARI_19=GROUP_2_5_Y_5
ARI_20=GROUP_2_5_Z_5
ARI_21=GROUP_2_2_X_5
ARI_22=GROUP_2_2_Y_5
ARI_23=GROUP_2_2_Z_5
ARI_24=GROUP_2_4_X_5
ARI_25=GROUP_2_4_Y_5
ARI_26=GROUP_2_4_Z_5
ARI_27=GROUP_2_6_X_5
ARI_28=GROUP_2_6_Y_5
ARI_29=GROUP_2_6_Z_5
ARI_30=GROUP_2_7_X_5
ARI_31=GROUP_2_7_Y_5
ARI_32=GROUP_2_7_Z_5
ARI_33=GROUP_2_5_X_6
ARI_34=GROUP_2_5_Y_6
ARI_35=GROUP_2_5_Z_6
ARI_36=GROUP_2_2_X_6
ARI_37=GROUP_2_2_Y_6
ARI_38=GROUP_2_2_Z_6
ARI_39=GROUP_2_4_X_6
ARI_40=GROUP_2_4_Y_6
ARI_41=GROUP_2_4_Z_6
ARI_42=GROUP_2_6_X_6
ARI_43=GROUP_2_6_Y_6
ARI_44=GROUP_2_6_Z_6
ARI_45=GROUP_2_7_X_6
ARI_46=GROUP_2_7_Y_6
ARI_47=GROUP_2_7_Z_6
ARI_48=GROUP_2_5_X_7
ARI_49=GROUP_2_5_Y_7
ARI_50=GROUP_2_5_Z_7
ARI_51=GROUP_2_2_X_7
ARI_52=GROUP_2_2_Y_7
ARI_53=GROUP_2_2_Z_7
ARI_54=GROUP_2_4_X_7
ARI_55=GROUP_2_4_Y_7
ARI_56=GROUP_2_4_Z_7
ARI_57=GROUP_2_6_X_7
ARI_58=GROUP_2_6_Y_7
ARI_59=GROUP_2_6_Z_7
ARI_60=GROUP_2_7_X_7
ARI_61=GROUP_2_7_Y_7
ARI_62=GROUP_2_7_Z_7
# ===== # =====
# OTHER # OTHER
+8 -10
View File
@@ -1,9 +1,9 @@
#version 460 #version 140
// VIDEO 1 // VIDEO 1
// ----------- // -----------
// IN: 1+3 (RAW IN A) // IN: 1 (RAW IN A)
// OUT: 5 (IN A) // OUT: 3 (IN A)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
@@ -14,16 +14,14 @@ uniform sampler2D iTex0;
uniform sampler2D iTex1; uniform sampler2D iTex1;
uniform sampler2D iTex3; uniform sampler2D iTex3;
uniform int iInputFormat1; uniform int iInputFormat1;
uniform int iInputSwap1;
uniform vec2 iInputResolution1; uniform vec2 iInputResolution1;
uniform vec3 iGroup3_1[2];
void main() { void main() {
if (iInputFormat1 == YUYV_FOURCC) { if (iGroup3_1[1].z > 0) {
if (iInputSwap1 > 0) { fragColor = texture(iTex1, vUV * vec2(1, -1));
fragColor = yuyvTex(iTex3, vUV, int(iInputResolution1.x)); } else if (iInputFormat1 == YUYV_FOURCC) {
} else { fragColor = yuyvTex(iTex1, vUV, int(iInputResolution1.x));
fragColor = yuyvTex(iTex1, vUV, int(iInputResolution1.x));
}
} else { } else {
fragColor = texture(iTex0, vUV); fragColor = texture(iTex0, vUV);
} }
+37 -39
View File
@@ -1,4 +1,4 @@
#version 460 #version 140
// MONITOR // MONITOR
// --- // ---
@@ -9,13 +9,13 @@ out vec4 fragColor;
#include inc_debug.glsl #include inc_debug.glsl
uniform sampler2D iTex0; uniform sampler2D iTex0;
uniform sampler2D iTex3;
uniform sampler2D iTex4;
uniform sampler2D iTex5; uniform sampler2D iTex5;
uniform sampler2D iTex6; uniform sampler2D iTex6;
uniform sampler2D iTex7; uniform sampler2D iTex7;
uniform sampler2D iTex8; uniform sampler2D iTex8;
uniform sampler2D iTex9; uniform sampler2D iTex9;
uniform sampler2D iTex10;
uniform sampler2D iTex11;
uniform int iFPS; uniform int iFPS;
uniform int iInputFPS1; uniform int iInputFPS1;
uniform int iInputFPS2; uniform int iInputFPS2;
@@ -25,20 +25,18 @@ float s(vec2 uv, float x0, float y0) {
step(-y0 - 1, -uv.y); step(-y0 - 1, -uv.y);
} }
const int texts[12][5] = { const int textINA[] = int[5](0x49, 0x4E, 0x20, 0x41, 0x00);
{0x49, 0x4E, 0x20, 0x41, 0x00}, // IN A const int textINB[] = int[5](0x49, 0x4E, 0x20, 0x42, 0x00);
{0x49, 0x4E, 0x20, 0x42, 0x00}, // IN B const int textSRCA[] = int[5](0x49, 0x4E, 0x20, 0x41, 0x00);
{0x53, 0x52, 0x43, 0x20, 0x41}, // SRC A const int textSRCB[] = int[5](0x49, 0x4E, 0x20, 0x42, 0x00);
{0x53, 0x52, 0x43, 0x20, 0x42}, // SRC B const int textFXA[] = int[5](0x46, 0x58, 0x20, 0x41, 0x00);
{0x46, 0x58, 0x20, 0x41, 0x00}, // FX A const int textFXB[] = int[5](0x46, 0x58, 0x20, 0x42, 0x00);
{0x46, 0x58, 0x20, 0x42, 0x00}, // FX B const int textAB[] = int[5](0x41, 0x2B, 0x42, 0x00, 0x00);
{0x41, 0x2B, 0x42, 0x00, 0x00}, // A+B const int textMFX[] = int[5](0x4D, 0x46, 0x58, 0x00, 0x00);
{0x4D, 0x46, 0x58, 0x00, 0x00}, // MFX const int textFPS[] = int[5](0x46, 0x50, 0x53, 0x00, 0x00);
{0x46, 0x50, 0x53, 0x00, 0x00}, // FPS const int textOFF[] = int[5](0x4F, 0x46, 0x46, 0x00, 0x00);
{0x4F, 0x46, 0x46, 0x00, 0x00}, // OFF const int textDEMO[] = int[5](0x44, 0x45, 0x4D, 0x4F, 0x00);
{0x44, 0x45, 0x4D, 0x4F, 0x00}, // DEMO const int textLIVE[] = int[5](0x4C, 0x49, 0x56, 0x45, 0x00);
{0x4C, 0x49, 0x56, 0x45, 0x00}, // LIVE
};
void main() { void main() {
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
@@ -50,14 +48,14 @@ void main() {
vec4 c = vec4(0); vec4 c = vec4(0);
c += s(uv2, 1, 2) * texture(iTex7, uv2); c += s(uv2, 1, 2) * texture(iTex5, uv2);
c += s(uv2, 2, 2) * texture(iTex9, uv2); c += s(uv2, 2, 2) * texture(iTex7, uv2);
c += s(uv2, 1, 0) * texture(iTex8, uv2); c += s(uv2, 1, 0) * texture(iTex6, uv2);
c += s(uv2, 2, 0) * texture(iTex10, uv2); c += s(uv2, 2, 0) * texture(iTex8, uv2);
c += s(uv2, 0, 1) * debug(mod(uv2, 1)); c += s(uv2, 0, 1) * debug(mod(uv2, 1));
c += s(uv2, 1, 1) * texture(iTex11, uv2); c += s(uv2, 1, 1) * texture(iTex9, uv2);
c += s(uv2, 2, 1) * texture(iTex0, uv2); c += s(uv2, 2, 1) * texture(iTex0, uv2);
float sel = 0; float sel = 0;
@@ -74,65 +72,65 @@ void main() {
float t = 0; float t = 0;
f += rect(uv3, vec2(-35, 28.5), vec2(2.1, 0.7)); f += rect(uv3, vec2(-35, 28.5), vec2(2.1, 0.7));
t += write_5(uv3, vec2(-37, 28), texts[0]); t += write_5(uv3, vec2(-37, 28), textINA);
if (iInputFormat1 == YUYV_FOURCC) { if (iInputFormat1 == YUYV_FOURCC) {
c += s(uv2, 0, 2) * texture(iTex5, uv2); c += s(uv2, 0, 2) * texture(iTex3, uv2);
f += rect(uv3, vec2(-35, 26.75), vec2(2.8, 0.7)); f += rect(uv3, vec2(-35, 26.75), vec2(2.8, 0.7));
t += write_int(uv3, vec2(-37.6, 26.1), iInputFPS1, 2); t += write_int(uv3, vec2(-37.6, 26.1), iInputFPS1, 2);
t += write_5(uv3, vec2(-35.1, 26.1), texts[8]); t += write_5(uv3, vec2(-35.1, 26.1), textFPS);
} else { } else {
f += rect(uv3, vec2(-35, 26.75), vec2(1.6, 0.7)); f += rect(uv3, vec2(-35, 26.75), vec2(1.6, 0.7));
t += write_5(uv3, vec2(-36.5, 26.1), texts[9]); t += write_5(uv3, vec2(-36.5, 26.1), textOFF);
} }
f += rect(uv3, vec2(-35, -11.5), vec2(2.1, 0.7)); f += rect(uv3, vec2(-35, -11.5), vec2(2.1, 0.7));
t += write_5(uv3, vec2(-37, -12), texts[1]); t += write_5(uv3, vec2(-37, -12), textINB);
if (iInputFormat2 == YUYV_FOURCC) { if (iInputFormat2 == YUYV_FOURCC) {
c += s(uv2, 0, 0) * texture(iTex6, uv2); c += s(uv2, 0, 0) * texture(iTex4, uv2);
f += rect(uv3, vec2(-35, -13.25), vec2(2.8, 0.7)); f += rect(uv3, vec2(-35, -13.25), vec2(2.8, 0.7));
t += write_int(uv3, vec2(-37.6, -13.9), iInputFPS2, 2); t += write_int(uv3, vec2(-37.6, -13.9), iInputFPS2, 2);
t += write_5(uv3, vec2(-35.1, -13.9), texts[8]); t += write_5(uv3, vec2(-35.1, -13.9), textFPS);
} else { } else {
f += rect(uv3, vec2(-35, -13.25), vec2(1.6, 0.7)); f += rect(uv3, vec2(-35, -13.25), vec2(1.6, 0.7));
t += write_5(uv3, vec2(-36.5, -13.9), texts[9]); t += write_5(uv3, vec2(-36.5, -13.9), textOFF);
} }
f += rect(uv3, vec2(-35, 8.5), vec2(2.1, 0.7)); f += rect(uv3, vec2(-35, 8.5), vec2(2.1, 0.7));
if (iDemo > 0) { if (iDemo > 0) {
t += write_5(uv3, vec2(-37, 8), texts[10]); t += write_5(uv3, vec2(-37, 8), textDEMO);
} else { } else {
t += write_5(uv3, vec2(-37, 8), texts[11]); t += write_5(uv3, vec2(-37, 8), textLIVE);
} }
f += rect(uv3, vec2(0, 28.5), vec2(2.6, 0.7)); f += rect(uv3, vec2(0, 28.5), vec2(2.6, 0.7));
f += iActive1 == 1 ? h_rect(uv3, vec2(0, 28.5), vec2(3, 1), 0.2) : 0; f += iActive1 == 1 ? h_rect(uv3, vec2(0, 28.5), vec2(3, 1), 0.2) : 0;
t += write_5(uv3, vec2(-2.5, 28), texts[2]); t += write_5(uv3, vec2(-2.5, 28), textSRCA);
f += rect(uv3, vec2(0, -11.5), vec2(2.6, 0.7)); f += rect(uv3, vec2(0, -11.5), vec2(2.6, 0.7));
f += iActive1 == 2 ? h_rect(uv3, vec2(0, -11.5), vec2(3, 1), 0.2) : 0; f += iActive1 == 2 ? h_rect(uv3, vec2(0, -11.5), vec2(3, 1), 0.2) : 0;
t += write_5(uv3, vec2(-2.5, -12), texts[3]); t += write_5(uv3, vec2(-2.5, -12), textSRCB);
f += rect(uv3, vec2(35, 28.5), vec2(2.1, 0.7)); f += rect(uv3, vec2(35, 28.5), vec2(2.1, 0.7));
f += iActive2 == 1 ? h_rect(uv3, vec2(35, 28.5), vec2(2.5, 1), 0.2) : 0; f += iActive2 == 1 ? h_rect(uv3, vec2(35, 28.5), vec2(2.5, 1), 0.2) : 0;
t += write_5(uv3, vec2(33, 28), texts[4]); t += write_5(uv3, vec2(33, 28), textFXA);
f += rect(uv3, vec2(35, -11.5), vec2(2.1, 0.7)); f += rect(uv3, vec2(35, -11.5), vec2(2.1, 0.7));
f += iActive2 == 2 ? h_rect(uv3, vec2(35, -11.5), vec2(2.5, 1), 0.2) : 0; f += iActive2 == 2 ? h_rect(uv3, vec2(35, -11.5), vec2(2.5, 1), 0.2) : 0;
t += write_5(uv3, vec2(33, -12), texts[5]); t += write_5(uv3, vec2(33, -12), textFXB);
f += rect(uv3, vec2(0, 8.5), vec2(1.6, 0.7)); f += rect(uv3, vec2(0, 8.5), vec2(1.6, 0.7));
t += write_5(uv3, vec2(-1.5, 8), texts[6]); t += write_5(uv3, vec2(-1.5, 8), textAB);
f += rect(uv3, vec2(35, 8.5), vec2(1.6, 0.7)); f += rect(uv3, vec2(35, 8.5), vec2(1.6, 0.7));
f += iActive2 == 3 ? h_rect(uv3, vec2(35, 8.5), vec2(2, 1), 0.2) : 0; f += iActive2 == 3 ? h_rect(uv3, vec2(35, 8.5), vec2(2, 1), 0.2) : 0;
t += write_5(uv3, vec2(33.5, 8), texts[7]); t += write_5(uv3, vec2(33.5, 8), textMFX);
f += rect(uv3, vec2(35, 6.75), vec2(2.8, 0.7)); f += rect(uv3, vec2(35, 6.75), vec2(2.8, 0.7));
t += write_int(uv3, vec2(32.4, 6.1), iFPS, 2); t += write_int(uv3, vec2(32.4, 6.1), iFPS, 2);
t += write_5(uv3, vec2(34.9, 6.1), texts[8]); t += write_5(uv3, vec2(34.9, 6.1), textFPS);
fragColor = mix(c, vec4(min(1, f) - t), min(1, f)); fragColor = mix(c, vec4(min(1, f) - t), min(1, f));
} }
+8 -10
View File
@@ -1,9 +1,9 @@
#version 460 #version 140
// VIDEO 2 // VIDEO 2
// ----------- // -----------
// IN: 2+4 (RAW IN B) // IN: 2 (RAW IN B)
// OUT: 6 (IN B) // OUT: 4 (IN B)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
@@ -14,16 +14,14 @@ uniform sampler2D iTex0;
uniform sampler2D iTex2; uniform sampler2D iTex2;
uniform sampler2D iTex4; uniform sampler2D iTex4;
uniform int iInputFormat2; uniform int iInputFormat2;
uniform int iInputSwap2;
uniform vec2 iInputResolution2; uniform vec2 iInputResolution2;
uniform vec3 iGroup3_1[2];
void main() { void main() {
if (iInputFormat2 == YUYV_FOURCC) { if (iGroup3_1[1].z > 0) {
if (iInputSwap2 > 0) { fragColor = texture(iTex2, vUV * vec2(1, -1));
fragColor = yuyvTex(iTex4, vUV, int(iInputResolution2.x)); } else if (iInputFormat2 == YUYV_FOURCC) {
} else { fragColor = yuyvTex(iTex2, vUV, int(iInputResolution2.x));
fragColor = yuyvTex(iTex2, vUV, int(iInputResolution2.x));
}
} else { } else {
fragColor = texture(iTex0, vUV); fragColor = texture(iTex0, vUV);
} }
+1 -3
View File
@@ -3,15 +3,13 @@
// SRC A // SRC A
// ----------- // -----------
// OUT: 7 (FX A) // OUT: 5 (FX A)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
#include inc_src.glsl #include inc_src.glsl
subroutine uniform src_stage_sub src_stage;
uniform int iSeed3; uniform int iSeed3;
uniform vec3 iGroup1_1[6]; uniform vec3 iGroup1_1[6];
+1 -3
View File
@@ -2,15 +2,13 @@
// SRC B // SRC B
// ----------- // -----------
// OUT: 8 (FX B) // OUT: 6 (FX B)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
#include inc_src.glsl #include inc_src.glsl
subroutine uniform src_stage_sub src_stage;
uniform int iSeed4; uniform int iSeed4;
uniform vec3 iGroup1_2[6]; uniform vec3 iGroup1_2[6];
+5 -5
View File
@@ -2,20 +2,20 @@
// FX A // FX A
// ------------- // -------------
// IN: 7 (SRC A) // IN: 5 (SRC A)
// IN: 9 (FX A) // IN: 7 (FX A)
// OUT: 9 (A+B) // OUT: 7 (A+B)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
#include inc_fx.glsl #include inc_fx.glsl
uniform sampler2D iTex5;
uniform sampler2D iTex7; uniform sampler2D iTex7;
uniform sampler2D iTex9;
uniform int iSeed5; uniform int iSeed5;
uniform vec3 iGroup2_1[7]; uniform vec3 iGroup2_1[7];
void main() { void main() {
fragColor = fx_stage(vUV, iTex7, iTex9, iSeed5, iGroup2_1[0], iGroup2_1[1].xy, iGroup2_1[2], iGroup2_1[3].xy, iGroup2_1[4], iGroup2_1[5].xy, iGroup2_1[6]); fragColor = fx_stage(vUV, iTex5, iTex7, iSeed5, iGroup2_1[0], iGroup2_1[1].xy, iGroup2_1[2], iGroup2_1[3].xy, iGroup2_1[4], iGroup2_1[5].xy, iGroup2_1[6]);
} }
+5 -5
View File
@@ -2,20 +2,20 @@
// FX B // FX B
// ------------- // -------------
// IN: 8 (SRC B) // IN: 6 (SRC B)
// IN: 10 (FX B) // IN: 8 (FX B)
// OUT: 10 (A+B) // OUT: 8 (A+B)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
#include inc_fx.glsl #include inc_fx.glsl
uniform sampler2D iTex6;
uniform sampler2D iTex8; uniform sampler2D iTex8;
uniform sampler2D iTex10;
uniform int iSeed6; uniform int iSeed6;
uniform vec3 iGroup2_2[7]; uniform vec3 iGroup2_2[7];
void main() { void main() {
fragColor = fx_stage(vUV, iTex8, iTex10, iSeed6, iGroup2_2[0], iGroup2_2[1].xy, iGroup2_2[2], iGroup2_2[3].xy, iGroup2_2[4], iGroup2_2[5].xy, iGroup2_2[6]); fragColor = fx_stage(vUV, iTex6, iTex8, iSeed6, iGroup2_2[0], iGroup2_2[1].xy, iGroup2_2[2], iGroup2_2[3].xy, iGroup2_2[4], iGroup2_2[5].xy, iGroup2_2[6]);
} }
+8 -8
View File
@@ -1,10 +1,10 @@
#version 460 #version 140
// A+B // A+B
// ------------ // ------------
// IN: 9 (FX A) // IN: 7 (FX A)
// IN: 10 (FX B) // IN: 8 (FX B)
// OUT: 11 (MFX) // OUT: 9 (MFX)
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
@@ -13,8 +13,8 @@ out vec4 fragColor;
#include inc_functions.glsl #include inc_functions.glsl
uniform int iDemo; uniform int iDemo;
uniform sampler2D iTex9; uniform sampler2D iTex7;
uniform sampler2D iTex10; uniform sampler2D iTex8;
uniform int iSeed7; uniform int iSeed7;
uniform vec3 iGroup3_1[2]; uniform vec3 iGroup3_1[2];
@@ -22,8 +22,8 @@ void main() {
float mix_value = magic(iGroup3_1[1].xy, vec3(1, 0, 0), iSeed7); float mix_value = magic(iGroup3_1[1].xy, vec3(1, 0, 0), iSeed7);
bool mix_type = magic_trigger(vec3(iGroup3_1[0].x, 0, 0), iSeed7 + 10); bool mix_type = magic_trigger(vec3(iGroup3_1[0].x, 0, 0), iSeed7 + 10);
vec4 color_a = texture(iTex9, vUV); vec4 color_a = texture(iTex7, vUV);
vec4 color_b = texture(iTex10, vUV); vec4 color_b = texture(iTex8, vUV);
float k = mean(color_a); float k = mean(color_a);
+4 -8
View File
@@ -2,7 +2,7 @@
// MFX // MFX
// ------------ // ------------
// IN: 11 (A+B) // IN: 9 (A+B)
// IN: 0 (OUT) // IN: 0 (OUT)
// OUT: 0 (OUT) // OUT: 0 (OUT)
@@ -11,20 +11,16 @@ out vec4 fragColor;
#include inc_fx.glsl #include inc_fx.glsl
uniform sampler2D iTex11; uniform sampler2D iTex9;
uniform sampler2D iTex0; uniform sampler2D iTex0;
uniform int iSeed8; uniform int iSeed8;
uniform vec3 iGroup2_3[7]; uniform vec3 iGroup2_3[7];
uniform vec3 iGroup3_1[2]; uniform vec3 iGroup3_1[2];
uniform int iDemo;
uniform int iAutoRand;
void main() { void main() {
vec4 color = fx_stage(vUV, iTex11, iTex0, iSeed8, iGroup2_3[0], iGroup2_3[1].xy, iGroup2_3[2], iGroup2_3[3].xy, iGroup2_3[4], iGroup2_3[5].xy, iGroup2_3[6]); vec4 color = fx_stage(vUV, iTex9, iTex0, iSeed8, iGroup2_3[0], iGroup2_3[1].xy, iGroup2_3[2], iGroup2_3[3].xy, iGroup2_3[4], iGroup2_3[5].xy, iGroup2_3[6]);
if (iDemo < 1 && iAutoRand < 1) { color = mix(color, vec4(0), iGroup3_1[0].y);
color = mix(color, vec4(0), iGroup3_1[0].y);
}
fragColor = color; fragColor = color;
} }
+111 -2
View File
@@ -1,4 +1,4 @@
#version 460 #version 140
// OUT // OUT
// --- // ---
@@ -6,8 +6,117 @@
in vec2 vUV; in vec2 vUV;
out vec4 fragColor; out vec4 fragColor;
#include inc_map.glsl
#include inc_cp437.glsl
uniform sampler2D iTex0; uniform sampler2D iTex0;
uniform vec3 iGroup2_4[7];
uniform vec3 iGroup2_5[7];
uniform vec3 iGroup2_6[7];
uniform vec3 iGroup2_7[7];
uniform int iFPS;
uniform int iDemo;
const int[] textDEMO = int[5](0x44, 0x45, 0x4D, 0x4F, 0x00);
void main() { void main() {
fragColor = texture(iTex0, vUV); bool visible = (iGroup2_4[4].x + iGroup2_5[4].x + iGroup2_6[4].x + iGroup2_7[4].x) > 0;
bool invert = (iGroup2_4[4].y + iGroup2_5[4].y + iGroup2_6[4].y + iGroup2_7[4].y) > 0;
float rect = clamp(iGroup2_4[4].z + iGroup2_5[4].z + iGroup2_6[4].z + iGroup2_7[4].z, 0, 1);
bool modified = false;
vec2 uv = mix(vec2(0), vUV, base_mask(vUV));
if (iGroup2_4[4].x > 0) {
vec2 p11 = vec2(iGroup2_4[6].xy);
vec2 p12 = vec2(iGroup2_4[1].xy);
vec2 p13 = vec2(iGroup2_4[3].xy);
vec2 p14 = vec2(iGroup2_4[5].xy);
p12.x = 1 - p12.x;
p13.y = 1 - p13.y;
p14.x = 1 - p14.x;
p14.y = 1 - p14.y;
vec2 uv1 = project_4p(vUV, p11, p12, p13, p14);
uv1 = mix(vec2(0), uv1, base_mask(uv1));
uv = uv1;
modified = true;
}
if (iGroup2_5[4].x > 0) {
vec2 p21 = vec2(iGroup2_5[6].xy);
vec2 p22 = vec2(iGroup2_5[1].xy);
vec2 p23 = vec2(iGroup2_5[3].xy);
vec2 p24 = vec2(iGroup2_5[5].xy);
p22.x = 1 - p22.x;
p23.y = 1 - p23.y;
p24.x = 1 - p24.x;
p24.y = 1 - p24.y;
vec2 uv2 = project_4p(vUV, p21, p22, p23, p24);
uv2 = mix(vec2(0), uv2, base_mask(uv2));
if (modified) {
uv = mix(uv, uv2, step(0.0001, length(uv2)));
} else {
uv = uv2;
}
modified = true;
}
if (iGroup2_6[4].x > 0) {
vec2 p31 = vec2(iGroup2_6[6].xy);
vec2 p32 = vec2(iGroup2_6[1].xy);
vec2 p33 = vec2(iGroup2_6[3].xy);
vec2 p34 = vec2(iGroup2_6[5].xy);
p32.x = 1 - p32.x;
p33.y = 1 - p33.y;
p34.x = 1 - p34.x;
p34.y = 1 - p34.y;
vec2 uv3 = project_4p(vUV, p31, p32, p33, p34);
uv3 = mix(vec2(0), uv3, base_mask(uv3));
if (modified) {
uv = mix(uv, uv3, step(0.0001, length(uv3)));
} else {
uv = uv3;
}
modified = true;
}
if (iGroup2_7[4].x > 0) {
vec2 p41 = vec2(iGroup2_7[6].xy);
vec2 p42 = vec2(iGroup2_7[1].xy);
vec2 p43 = vec2(iGroup2_7[3].xy);
vec2 p44 = vec2(iGroup2_7[5].xy);
p42.x = 1 - p42.x;
p43.y = 1 - p43.y;
p44.x = 1 - p44.x;
p44.y = 1 - p44.y;
vec2 uv4 = project_4p(vUV, p41, p42, p43, p44);
uv4 = mix(vec2(0), uv4, base_mask(uv4));
if (modified) {
uv = mix(uv, uv4, step(0.0001, length(uv4)));
} else {
uv = uv4;
}
modified = true;
}
vec4 color = texture(iTex0, invert ? vUV : uv);
color = mix(color, 1. - color, iDemo * write_int(uv * 20., vec2(1.), iFPS, 2));
color = mix(color, 1. - color, iDemo * write_5(uv * 20., vec2(1., 18.), textDEMO));
if (visible) {
float mask = step(0.0001, length(uv));
color *= mix(mask, 1 - mask, invert ? 1 : 0);
color = mix(color, color + mask * vec4(1), rect * (step(uv.x, 0.01) + step(uv.y, 0.01) + step(1 - uv.y, 0.01) + step(1 - uv.x, 0.01)));
}
fragColor = color;
} }
+42 -80
View File
@@ -1,7 +1,9 @@
#include inc_sentences.glsl
#ifndef INC_CP437 #ifndef INC_CP437
#define INC_CP437 #define INC_CP437
const int cp437[] = { const int cp437[] = int[1024](
0x0000, 0x0000, 0x0000, 0x0000, // 0x00, NUL 0x0000, 0x0000, 0x0000, 0x0000, // 0x00, NUL
0x151E, 0x8A87, 0xE19D, 0x789B, // 0x01, SOH, SMILEY BLACK 0x151E, 0x8A87, 0xE19D, 0x789B, // 0x01, SOH, SMILEY BLACK
0xFBFE, 0xFDF7, 0xEF73, 0x7FEC, // 0x02, STX, SMILEY LIGHT 0xFBFE, 0xFDF7, 0xEF73, 0x7FEC, // 0x02, STX, SMILEY LIGHT
@@ -257,10 +259,10 @@ const int cp437[] = {
0x666E, 0x3331, 0x0006, 0x0003, // 0xFC, ⁿ 0x666E, 0x3331, 0x0006, 0x0003, // 0xFC, ⁿ
0x6C8E, 0x0010, 0x000E, 0x0001, // 0xFD, ² 0x6C8E, 0x0010, 0x000E, 0x0001, // 0xFD, ²
0xCC00, 0x3300, 0x00CC, 0x0033, // 0xFE, ■ 0xCC00, 0x3300, 0x00CC, 0x0033, // 0xFE, ■
0x0000, 0x0000, 0x0000, 0x0000, // 0xFF, NBSP 0x0000, 0x0000, 0x0000, 0x0000 // 0xFF, NBSP
}; );
const int charsets[] = { const int charsets[] = int[18](
0x30, 10, // NUMBERS 0x30, 10, // NUMBERS
0x41, 26, // UPPERCASE LETTERS 0x41, 26, // UPPERCASE LETTERS
0x61, 26, // LOWERCASE LETTERS 0x61, 26, // LOWERCASE LETTERS
@@ -269,12 +271,12 @@ const int charsets[] = {
0xB3, 40, // BARS 0xB3, 40, // BARS
0xE0, 16, // GREEK 0xE0, 16, // GREEK
0x80, 28, // ACCENTS 0x80, 28, // ACCENTS
0xB0, 3, // SHADES 0xB0, 3 // SHADES
}; );
#define CHARSETS 8 #define CHARSETS 8
const int hex_chars[] = { const int hex_chars[] = int[16](
0x30, 0x30,
0x31, 0x31,
0x32, 0x32,
@@ -290,29 +292,29 @@ const int hex_chars[] = {
0x43, 0x43,
0x44, 0x44,
0x45, 0x45,
0x46, 0x46
}; );
bool char(vec2 pos, int code) bool char(vec2 pos, int code)
{ {
if (pos.x < 0.0 || pos.y < 0.0 || pos.x >= 1.0 || pos.y >= 1.0) { if (pos.x < .0 || pos.y < .0 || pos.x >= 1. || pos.y >= 1.) {
return false; return false;
} }
ivec2 pos2 = ivec2(pos.x * 8.0, (1 - pos.y) * 8.0); ivec2 pos2 = ivec2(pos.x * 8., (1 - pos.y) * 8.);
ivec2 subpos = pos2 % 4; ivec2 subpos = pos2 % 4;
int v = int(pow(2, subpos.y * 4 + subpos.x)); int v = int(pow(2., subpos.y * 4. + subpos.x));
int d = int(pos2.y * 0.25) * 2 + int(pos2.x * 0.25); int d = int(pos2.y * .25) * 2 + int(pos2.x * .25);
return (cp437[code * 4 + d] & v) > 0; return (cp437[code * 4 + d] & v) > 0;
} }
float char_at(vec2 uv, vec2 pos, int code) float char_at(vec2 uv, vec2 pos, int code)
{ {
return char(uv - pos, code) ? 1 : 0; return char(uv - pos, code) ? 1. : 0.;
} }
float write_5(vec2 uv, vec2 pos, int str[5]) float write_5(vec2 uv, vec2 pos, int str[5])
{ {
float d = 0; float d = 0.;
int i; int i;
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
@@ -320,7 +322,7 @@ float write_5(vec2 uv, vec2 pos, int str[5])
return d; return d;
} }
d += char_at(uv, pos + vec2(i, 0), str[i]); d += char_at(uv, pos + vec2(i, 0.), str[i]);
} }
return d; return d;
@@ -328,7 +330,7 @@ float write_5(vec2 uv, vec2 pos, int str[5])
float write_10(vec2 uv, vec2 pos, int str[10]) float write_10(vec2 uv, vec2 pos, int str[10])
{ {
float d = 0; float d = 0.;
int i; int i;
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
@@ -336,7 +338,7 @@ float write_10(vec2 uv, vec2 pos, int str[10])
return d; return d;
} }
d += char_at(uv, pos + vec2(i, 0), str[i]); d += char_at(uv, pos + vec2(i, 0.), str[i]);
} }
return d; return d;
@@ -344,7 +346,7 @@ float write_10(vec2 uv, vec2 pos, int str[10])
float write_20(vec2 uv, vec2 pos, int str[20]) float write_20(vec2 uv, vec2 pos, int str[20])
{ {
float d = 0; float d = 0.;
int i; int i;
for (i = 0; i < 20; i++) { for (i = 0; i < 20; i++) {
@@ -352,96 +354,56 @@ float write_20(vec2 uv, vec2 pos, int str[20])
return d; return d;
} }
d += char_at(uv, pos + vec2(i, 0), str[i]); d += char_at(uv, pos + vec2(i, 0.), str[i]);
} }
return d; return d;
} }
float write_int(vec2 uv, vec2 pos, uint value, uint magnitude) float write_int(vec2 uv, vec2 pos, int value, int magnitude)
{ {
value = max(0, value);
int i; int i;
uint m = 1; int m = 1;
float d = 0; float d = 0.;
for (i = 0; i < magnitude; i++) { for (i = 0; i < magnitude; i++) {
if (i == 0 || value >= m) { if (i == 0 || value >= m) {
d += char_at(uv, pos + vec2(magnitude - i - 1, 0), int(0x30 + (value % (m * 10u)) / m)); d += char_at(uv, pos + vec2(magnitude - i - 1, 0.), int(0x30 + (value % (m * 10)) / m));
m *= 10u; m *= 10;
} }
} }
return d; return d;
} }
float write_int_left(vec2 uv, vec2 pos, uint value, uint magnitude) float write_int_left(vec2 uv, vec2 pos, int value, int magnitude)
{ {
value = max(0, value);
int i; int i;
uint m = 1; int m = 1;
float d = 0; float d = 0.;
for (i = 0; i < magnitude; i++) { for (i = 0; i < magnitude; i++) {
if (i == 0 || value >= m) { if (i == 0 || value >= m) {
pos.x += 1; pos.x += 1.;
m *= 10u; m *= 10;
} }
} }
return write_int(uv, pos, value, magnitude); return write_int(uv, pos, value, magnitude);
} }
int read(sampler2D tex, vec2 uv, float k, int d, float t) float write_sentence(vec2 uv, vec2 pos, int n)
{ {
float inv_k = 1 / k; float d = 0.;
vec2 tex_uv = floor(uv * k) * inv_k;
tex_uv += vec2(d % 2, floor(d * 0.5)) * 0.5 * inv_k;
return
((mean(reframe(tex, tex_uv + vec2(0, 3) * inv_k * 0.125)) > t) ? 1 : 0) +
((mean(reframe(tex, tex_uv + vec2(0, 2) * inv_k * 0.125)) > t) ? 2 : 0) +
((mean(reframe(tex, tex_uv + vec2(0, 1) * inv_k * 0.125)) > t) ? 4 : 0) +
((mean(reframe(tex, tex_uv + vec2(0, 0) * inv_k * 0.125)) > t) ? 8 : 0) +
((mean(reframe(tex, tex_uv + vec2(1, 3) * inv_k * 0.125)) > t) ? 16 : 0) +
((mean(reframe(tex, tex_uv + vec2(1, 2) * inv_k * 0.125)) > t) ? 32 : 0) +
((mean(reframe(tex, tex_uv + vec2(1, 1) * inv_k * 0.125)) > t) ? 64 : 0) +
((mean(reframe(tex, tex_uv + vec2(1, 0) * inv_k * 0.125)) > t) ? 128 : 0) +
((mean(reframe(tex, tex_uv + vec2(2, 3) * inv_k * 0.125)) > t) ? 256 : 0) +
((mean(reframe(tex, tex_uv + vec2(2, 2) * inv_k * 0.125)) > t) ? 512 : 0) +
((mean(reframe(tex, tex_uv + vec2(2, 1) * inv_k * 0.125)) > t) ? 1024 : 0) +
((mean(reframe(tex, tex_uv + vec2(2, 0) * inv_k * 0.125)) > t) ? 2048 : 0) +
((mean(reframe(tex, tex_uv + vec2(3, 3) * inv_k * 0.125)) > t) ? 4096 : 0) +
((mean(reframe(tex, tex_uv + vec2(3, 2) * inv_k * 0.125)) > t) ? 8192 : 0) +
((mean(reframe(tex, tex_uv + vec2(3, 1) * inv_k * 0.125)) > t) ? 16384 : 0) +
((mean(reframe(tex, tex_uv + vec2(3, 0) * inv_k * 0.125)) > t) ? 32768 : 0);
}
// https://web.archive.org/web/20151229003112/http://blogs.msdn.com/b/jeuge/archive/2005/06/08/hakmem-bit-count.aspx
int bit_count(int u)
{
int c;
c = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
return ((c + (c >> 3)) & 030707070707) % 63;
}
int guess_char(sampler2D tex, vec2 uv, float k, float t)
{
int b0 = read(tex, uv, k, 0, t);
int b1 = read(tex, uv, k, 1, t);
int b2 = read(tex, uv, k, 2, t);
int b3 = read(tex, uv, k, 3, t);
int mc = 0;
int mb = 100;
int i; int i;
int b;
for (i = 0x01; i <= 0xFF; i++) { for (i = 0; i < SENTENCE_MAX_LENGTH; i++) {
if (i == 0x20 || i == 0xff || i == 0xDB) { if (sentences[n * SENTENCE_MAX_LENGTH + i] == 0) {
continue; return d;
}
b = bit_count(cp437[i * 4] ^ b0) + bit_count(cp437[i * 4 + 1] ^ b1) + bit_count(cp437[i * 4 + 2] ^ b2) + + bit_count(cp437[i * 4 + 3] ^ b3);
if (b < mb) {
mb = b;
mc = i;
} }
d += char_at(uv, pos + vec2(i, 0.), sentences[n * SENTENCE_MAX_LENGTH + i]);
} }
return mc; return d;
} }
#endif #endif
+98 -163
View File
@@ -46,27 +46,27 @@ vec4 debug(vec2 vUV)
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// inputs // inputs
int selected_srca = iState3 - 1; int selected_srca = iState3 - 1;
bool random_srca = iState3 == 15; bool random_srca = iState3 == 15;
if (random_srca) { if (random_srca) {
selected_srca = int(randTime(iSeed3 + 100) * 14); selected_srca = int(randTime(iSeed3 + 100.) * 14.);
} }
if (selected_srca == 5 && iDemo > 0) { if (selected_srca == 5 && iDemo > 0.) {
selected_srca = 1; selected_srca = 1;
random_srca = true; random_srca = true;
} }
if (selected_srca == 10 && iDemo > 0) { if (selected_srca == 10 && iDemo > 0.) {
selected_srca = 2; selected_srca = 2;
random_srca = true; random_srca = true;
} }
int selected_srcb = iState4 - 1; int selected_srcb = iState4 - 1;
bool random_srcb = iState4 == 15; bool random_srcb = iState4 == 15;
if (random_srcb) { if (random_srcb) {
selected_srcb = int(randTime(iSeed4 + 100) * 14); selected_srcb = int(randTime(iSeed4 + 100.) * 14.);
} }
if (selected_srcb == 5 && iDemo > 0) { if (selected_srcb == 5 && iDemo > 0) {
selected_srcb = 1; selected_srcb = 1;
@@ -79,181 +79,116 @@ vec4 debug(vec2 vUV)
int selected_fxa = iState5 - 1; int selected_fxa = iState5 - 1;
bool random_fxa = iState5 == 15; bool random_fxa = iState5 == 15;
if (random_fxa) { if (random_fxa) {
selected_fxa = int(randTime(iSeed5 + 100) * 14); selected_fxa = int(randTime(iSeed5 + 100.) * 14.);
} }
int selected_fxb = iState6 - 1; int selected_fxb = iState6 - 1;
bool random_fxb = iState6 == 15; bool random_fxb = iState6 == 15;
if (random_fxb) { if (random_fxb) {
selected_fxb = int(randTime(iSeed6 + 100) * 14); selected_fxb = int(randTime(iSeed6 + 100.) * 14.);
} }
int selected_mfx = iState8 - 1; int selected_mfx = iState8 - 1;
bool random_mfx = iState8 == 15; bool random_mfx = iState8 == 15;
if (random_mfx) { if (random_mfx) {
selected_mfx = int(randTime(iSeed8 + 100) * 14); selected_mfx = int(randTime(iSeed8 + 100.) * 14.);
} }
float fxa_value = magic(iGroup2_1[6].xy, vec3(1, 0, 0), iSeed5); float fxa_value = magic(iGroup2_1[6].xy, vec3(1., 0., 0.), iSeed5);
bool fxa_invert = magic_trigger(vec3(iGroup2_1[6].z, 0, 0), iSeed5); bool fxa_invert = magic_trigger(vec3(iGroup2_1[6].z, 0., 0.), iSeed5);
float fxb_value = magic(iGroup2_2[6].xy, vec3(1, 0, 0), iSeed6); float fxb_value = magic(iGroup2_2[6].xy, vec3(1., 0., 0.), iSeed6);
bool fxb_invert = magic_trigger(vec3(iGroup2_2[6].z, 0, 0), iSeed6); bool fxb_invert = magic_trigger(vec3(iGroup2_2[6].z, 0., 0.), iSeed6);
float mfx_value = magic(iGroup2_3[6].xy, vec3(1, 0, 0), iSeed8); float mfx_value = magic(iGroup2_3[6].xy, vec3(1., 0., 0.), iSeed8);
bool mfx_invert = magic_trigger(vec3(iGroup2_3[6].z, 0, 0), iSeed8); bool mfx_invert = magic_trigger(vec3(iGroup2_3[6].z, 0., 0.), iSeed8);
float mix_value = magic(iGroup3_1[1].xy, vec3(1, 0, 0), iSeed7); float mix_value = magic(iGroup3_1[1].xy, vec3(1., 0., 0.), iSeed7);
mix_value = mix(mix_value, mix_value * 0.9 + 0.05, iDemo); mix_value = mix(mix_value, mix_value * .9 + .05, iDemo);
bool mix_type = magic_trigger(vec3(iGroup3_1[0].x, 0, 0), iSeed7 + 10); bool mix_type = magic_trigger(vec3(iGroup3_1[0].x, 0., 0.), iSeed7 + 10.);
// logic // logic
const int texts[10][5] = { const int textTEMPO[] = int[5](0x54, 0x45, 0x4D, 0x50, 0x4F);
{ const int textTIME[] = int[5](0x54, 0x49, 0x4D, 0x45, 0x00);
0x46, const int textRAND[] = int[5](0x52, 0x41, 0x4E, 0x44, 0x00);
0x50, const int textSRC[] = int[5](0x53, 0x52, 0x43, 0x00, 0x00);
0x53, const int textFX[] = int[5](0x46, 0x58, 0x00, 0x00, 0x00);
0x00, const int textIN[] = int[5](0x49, 0x4E, 0x00, 0x00, 0x00);
0x00 const int textMFX[] = int[5](0x4D, 0x46, 0x58, 0x00, 0x00);
}, // FPS
{
0x54,
0x45,
0x4D,
0x50,
0x4F
}, // TEMPO
{
0x54,
0x49,
0x4D,
0x45,
0x00
}, // TIME
{
0x44,
0x45,
0x4D,
0x4F,
0x00
}, // DEMO
{
0x4C,
0x49,
0x56,
0x45,
0x00
}, // LIVE
{
0x52,
0x41,
0x4E,
0x44,
0x00
}, // RAND
{
0x53,
0x52,
0x43,
0x00,
0x00
}, // SRC
{
0x46,
0x58,
0x00,
0x00,
0x00
}, // FX
{
0x49,
0x4E,
0x00,
0x00,
0x00
}, // IN
{
0x4D,
0x46,
0x58,
0x00,
0x00
}, // MFX
};
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= 10; uv2 *= 10.;
uv2.x -= 0.5; uv2.x -= .5;
uv2.y += 0.5; uv2.y += .5;
vec2 uv3 = uv1 * 30; vec2 uv3 = uv1 * 30.;
// base frame // base frame
float f = float f =
h_rect(uv2, vec2(-5, -2), vec2(1), 0.1) + h_rect(uv2, vec2(-5., -2.), vec2(1.), .1) +
h_rect(uv2, vec2(-2, -2), vec2(1), 0.1) + h_rect(uv2, vec2(-2., -2.), vec2(1.), .1) +
rect(uv2, vec2(-3.5, -2), vec2(0.5, 0.1)) + rect(uv2, vec2(-3.5, -2.), vec2(.5, .1)) +
h_rect(uv2, vec2(-5, 2), vec2(1), 0.1) + h_rect(uv2, vec2(-5, 2.), vec2(1.), .1) +
h_rect(uv2, vec2(-2, 2), vec2(1), 0.1) + h_rect(uv2, vec2(-2, 2.), vec2(1.), .1) +
rect(uv2, vec2(-3.5, 2), vec2(0.5, 0.1)) + rect(uv2, vec2(-3.5, 2.), vec2(.5, .1)) +
h_rect(uv2, vec2(2, 0), vec2(1), 0.1) + h_rect(uv2, vec2(2., 0.), vec2(1.), .1) +
h_rect(uv2, vec2(5, 0), vec2(1), 0.1) + h_rect(uv2, vec2(5., 0.), vec2(1.), .1) +
rect(uv2, vec2(3.5, 0), vec2(0.5, 0.1)) + rect(uv2, vec2(3.5, 0.), vec2(.5, .1)) +
rect(uv2, vec2(0.55, -2), vec2(1.5, 0.1)) + rect(uv2, vec2(.55, -2.), vec2(1.5, .1)) +
rect(uv2, vec2(2, -1.55), vec2(0.1, 0.55)) + rect(uv2, vec2(2., -1.55), vec2(.1, .55)) +
rect(uv2, vec2(0.55, 2), vec2(1.5, 0.1)) + rect(uv2, vec2(.55, 2.), vec2(1.5, .1)) +
rect(uv2, vec2(2, 1.55), vec2(0.1, 0.55)) + rect(uv2, vec2(2., 1.55), vec2(.1, .55)) +
rect(uv2, vec2(6.8, 0), vec2(0.75, 0.1)) + rect(uv2, vec2(6.8, 0.), vec2(.75, .1)) +
h_circle(uv2, vec2(7.8, 0), 0.3, 0.1); h_circle(uv2, vec2(7.8, 0.), .3, .1);
if (iDemo < 1 && iInputFormat1 == YUYV_FOURCC) { if (iDemo < 1 && iInputFormat1 == YUYV_FOURCC) {
f += circle(uv2, vec2(-9, 2), 0.3); f += circle(uv2, vec2(-9., 2.), .3);
} }
if (iDemo < 1 && iInputFormat2 == YUYV_FOURCC) { if (iDemo < 1 && iInputFormat2 == YUYV_FOURCC) {
f += circle(uv2, vec2(-9, -2), 0.3); f += circle(uv2, vec2(-9., -2.), .3);
} }
// show selected src/fx // show selected src/fx
f += char_at(uv2, vec2(-5.4, 1.45), hex_chars[selected_srca]); f += char_at(uv2, vec2(-5.4, 1.45), hex_chars[selected_srca]);
f += random_srca ? circle(uv2, vec2(-4.25, 2.7), 0.1) : 0; f += random_srca ? circle(uv2, vec2(-4.25, 2.7), .1) : 0.;
f += char_at(uv2, vec2(-5.4, -2.55), hex_chars[selected_srcb]); f += char_at(uv2, vec2(-5.4, -2.55), hex_chars[selected_srcb]);
f += random_srcb ? circle(uv2, vec2(-4.25, -1.3), 0.1) : 0; f += random_srcb ? circle(uv2, vec2(-4.25, -1.3), .1) : 0.;
f += char_at(uv2, vec2(-2.4, 1.45), hex_chars[selected_fxa]); f += char_at(uv2, vec2(-2.4, 1.45), hex_chars[selected_fxa]);
f += fxa_invert ? rect(uv2, vec2(-2, 2.7), vec2(0.5, 0.05)) : 0; f += fxa_invert ? rect(uv2, vec2(-2., 2.7), vec2(.5, .05)) : 0.;
f += random_fxa ? circle(uv2, vec2(-1.25, 2.7), 0.1) : 0; f += random_fxa ? circle(uv2, vec2(-1.25, 2.7), .1) : 0.;
f += char_at(uv2, vec2(-2.4, -2.55), hex_chars[selected_fxb]); f += char_at(uv2, vec2(-2.4, -2.55), hex_chars[selected_fxb]);
f += fxb_invert ? rect(uv2, vec2(-2, -1.3), vec2(0.5, 0.05)) : 0; f += fxb_invert ? rect(uv2, vec2(-2., -1.3), vec2(.5, .05)) : 0.;
f += random_fxb ? circle(uv2, vec2(-1.25, -1.3), 0.1) : 0; f += random_fxb ? circle(uv2, vec2(-1.25, -1.3), .1) : 0.;
f += char_at(uv2, vec2(4.6, -0.55), hex_chars[selected_mfx]); f += char_at(uv2, vec2(4.6, -.55), hex_chars[selected_mfx]);
f += mfx_invert ? rect(uv2, vec2(5, 0.7), vec2(0.5, 0.05)) : 0; f += mfx_invert ? rect(uv2, vec2(5., .7), vec2(.5, .05)) : 0.;
f += random_mfx ? circle(uv2, vec2(5.75, 0.7), 0.1) : 0; f += random_mfx ? circle(uv2, vec2(5.75, .7), .1) : 0.;
// show current selected // show current selected
f += iSelected == 3 ? h_rect(uv2, vec2(-5, 2), vec2(1.2), 0.1) : 0; f += iSelected == 3 ? h_rect(uv2, vec2(-5., 2.), vec2(1.2), .1) : 0.;
f += iSelected == 4 ? h_rect(uv2, vec2(-5, -2), vec2(1.2), 0.1) : 0; f += iSelected == 4 ? h_rect(uv2, vec2(-5., -2.), vec2(1.2), .1) : 0.;
f += iSelected == 5 ? h_rect(uv2, vec2(-2, 2), vec2(1.2), 0.1) : 0; f += iSelected == 5 ? h_rect(uv2, vec2(-2., 2.), vec2(1.2), .1) : 0.;
f += iSelected == 6 ? h_rect(uv2, vec2(-2, -2), vec2(1.2), 0.1) : 0; f += iSelected == 6 ? h_rect(uv2, vec2(-2., -2.), vec2(1.2), .1) : 0.;
f += iSelected == 8 ? h_rect(uv2, vec2(5, 0), vec2(1.2), 0.1) : 0; f += iSelected == 8 ? h_rect(uv2, vec2(5., 0.), vec2(1.2), .1) : 0.;
// show selected src/fx // show selected src/fx
f += iActive1 == 1 ? h_rect(uv2, vec2(-5, 0.8), vec2(1, 0), 0.1) : 0; f += iActive1 == 1 ? h_rect(uv2, vec2(-5., .8), vec2(1., 0.), .1) : 0.;
f += iActive1 == 2 ? h_rect(uv2, vec2(-5, -3.2), vec2(1, 0), 0.1) : 0; f += iActive1 == 2 ? h_rect(uv2, vec2(-5., -3.2), vec2(1., 0.), .1) : 0.;
f += iActive2 == 1 ? h_rect(uv2, vec2(-2, 0.8), vec2(1.2, 0), 0.1) : 0; f += iActive2 == 1 ? h_rect(uv2, vec2(-2., .8), vec2(1.2, 0.), .1) : 0.;
f += iActive2 == 2 ? h_rect(uv2, vec2(-2, -3.2), vec2(1, 0), 0.1) : 0; f += iActive2 == 2 ? h_rect(uv2, vec2(-2., -3.2), vec2(1., 0.), .1) : 0.;
f += iActive2 == 3 ? h_rect(uv2, vec2(5, -1.2), vec2(1, 0), 0.1) : 0; f += iActive2 == 3 ? h_rect(uv2, vec2(5., -1.2), vec2(1., 0.), .1) : 0.;
// show src/fx // show src/fx
f += write_5(uv3 * 0.75, vec2(-11.6, -1.8), texts[6]); f += write_5(uv3 * .75, vec2(-11.6, -1.8), textSRC);
f += write_5(uv3 * 0.75, vec2(-4.2, -1.8), texts[7]); f += write_5(uv3 * .75, vec2(-4.2, -1.8), textFX);
f += char_at(uv3 * 0.5, vec2(-11.5, 3.5), 0x41); f += char_at(uv3 * .5, vec2(-11.5, 3.5), 0x41);
f += char_at(uv3 * 0.5, vec2(-11.5, -6), 0x42); f += char_at(uv3 * .5, vec2(-11.5, -6.), 0x42);
if (iDemo < 1 && (iInputFormat1 == YUYV_FOURCC || iInputFormat2 == YUYV_FOURCC)) { if (iDemo < 1 && (iInputFormat1 == YUYV_FOURCC || iInputFormat2 == YUYV_FOURCC)) {
f += write_5(uv3 * 0.75, vec2(-19.7, -1.8), texts[8]); f += write_5(uv3 * .75, vec2(-19.7, -1.8), textIN);
} }
f += write_5(uv3 * 0.75, vec2(10.9, 2), texts[9]); f += write_5(uv3 * .75, vec2(10.9, 2.), textMFX);
// show inputs / feedback // show inputs / feedback
float line_a_a = rect(uv2, vec2(-7.5, 2), vec2(1.5, 0.1)); float line_a_a = rect(uv2, vec2(-7.5, 2.), vec2(1.5, .1));
float line_a_b = rect(uv2, vec2(-6.5, 2), vec2(0.5, 0.1)) + rect(uv2, vec2(-8.5, -2), vec2(0.5, 0.1)) + line(uv2, vec2(-7, 2.1), vec2(-8, -2.1), 0.2); float line_a_b = rect(uv2, vec2(-6.5, 2.), vec2(.5, .1)) + rect(uv2, vec2(-8.5, -2), vec2(.5, .1)) + line(uv2, vec2(-7., 2.1), vec2(-8., -2.1), .2);
float line_a_f = rect(uv2, vec2(-6.5, 2), vec2(0.5, 0.1)) + rect(uv2, vec2(0, 3.6), vec2(7, 0.1)) + rect(uv2, vec2(-7, 2.8), vec2(0.1, 0.9)) + rect(uv2, vec2(7, 1.8), vec2(0.1, 1.9)); float line_a_f = rect(uv2, vec2(-6.5, 2.), vec2(.5, .1)) + rect(uv2, vec2(0., 3.6), vec2(7., .1)) + rect(uv2, vec2(-7., 2.8), vec2(.1, .9)) + rect(uv2, vec2(7., 1.8), vec2(.1, 1.9));
if (selected_srca == 5 && iInputFormat1 == YUYV_FOURCC) { if (selected_srca == 5 && iInputFormat1 == YUYV_FOURCC) {
f += line_a_a; f += line_a_a;
} else if (selected_srca == 10 && iInputFormat2 == YUYV_FOURCC) { } else if (selected_srca == 10 && iInputFormat2 == YUYV_FOURCC) {
@@ -262,9 +197,9 @@ vec4 debug(vec2 vUV)
f += line_a_f; f += line_a_f;
} }
float line_b_a = rect(uv2, vec2(-6.5, -2), vec2(0.5, 0.1)) + rect(uv2, vec2(-8.5, 2), vec2(0.5, 0.1)) + line(uv2, vec2(-7, -2.1), vec2(-8, 2.1), 0.2); float line_b_a = rect(uv2, vec2(-6.5, -2.), vec2(.5, .1)) + rect(uv2, vec2(-8.5, 2.), vec2(.5, .1)) + line(uv2, vec2(-7., -2.1), vec2(-8., 2.1), .2);
float line_b_b = rect(uv2, vec2(-7.5, -2), vec2(1.5, 0.1)); float line_b_b = rect(uv2, vec2(-7.5, -2.), vec2(1.5, .1));
float line_b_f = rect(uv2, vec2(-6.5, -2), vec2(0.5, 0.1)) + rect(uv2, vec2(0, -3.6), vec2(7, 0.1)) + rect(uv2, vec2(-7, -2.8), vec2(0.1, 0.9)) + rect(uv2, vec2(7, -1.8), vec2(0.1, 1.9)); float line_b_f = rect(uv2, vec2(-6.5, -2.), vec2(.5, .1)) + rect(uv2, vec2(0., -3.6), vec2(7., .1)) + rect(uv2, vec2(-7., -2.8), vec2(.1, .9)) + rect(uv2, vec2(7., -1.8), vec2(.1, 1.9));
if (selected_srcb == 5 && iInputFormat1 == YUYV_FOURCC) { if (selected_srcb == 5 && iInputFormat1 == YUYV_FOURCC) {
f += line_b_a; f += line_b_a;
} else if (selected_srcb == 10 && iInputFormat2 == YUYV_FOURCC) { } else if (selected_srcb == 10 && iInputFormat2 == YUYV_FOURCC) {
@@ -274,44 +209,44 @@ vec4 debug(vec2 vUV)
} }
// show page // show page
f += iPage == 0 ? circle(uv2, vec2(-0.75, -4.1), 0.3) : h_circle(uv2, vec2(-0.75, -4.1), 0.25, 0.1); f += iPage == 0 ? circle(uv2, vec2(-.75, -4.1), .3) : h_circle(uv2, vec2(-.75, -4.1), .25, .1);
f += iPage == 1 ? circle(uv2, vec2(0, -4.1), 0.3) : h_circle(uv2, vec2(0, -4.1), 0.20, 0.1); f += iPage == 1 ? circle(uv2, vec2(0., -4.1), .3) : h_circle(uv2, vec2(0., -4.1), .20, .1);
f += iPage == 2 ? circle(uv2, vec2(0.75, -4.1), 0.3) : h_circle(uv2, vec2(0.75, -4.1), 0.20, 0.1); f += iPage == 2 ? circle(uv2, vec2(.75, -4.1), .3) : h_circle(uv2, vec2(.75, -4.1), .20, .1);
// show fx values // show fx values
float fx_rect = 0; float fx_rect = 0;
f = mix(f, 1 - f, rect(uv2, vec2(-2, 1.1 + 0.9 * fxa_value), vec2(0.9, 0.9 * fxa_value))); f = mix(f, 1 - f, rect(uv2, vec2(-2., 1.1 + .9 * fxa_value), vec2(.9, .9 * fxa_value)));
f = mix(f, 1 - f, rect(uv2, vec2(-2, -2.9 + 0.9 * fxb_value), vec2(0.9, 0.9 * fxb_value))); f = mix(f, 1 - f, rect(uv2, vec2(-2., -2.9 + .9 * fxb_value), vec2(.9, .9 * fxb_value)));
f = mix(f, 1 - f, rect(uv2, vec2(5, -0.9 + 0.9 * mfx_value), vec2(0.9, 0.9 * mfx_value))); f = mix(f, 1 - f, rect(uv2, vec2(5., -.9 + .9 * mfx_value), vec2(.9, .9 * mfx_value)));
// show mix // show mix
f += char_at(uv2, vec2(1.55, -0.6), mix_type ? 0x4B : 0x4D); f += char_at(uv2, vec2(1.55, -.6), mix_type ? 0x4B : 0x4D);
f = mix(f, 1 - f, rect(uv2, vec2(2, -0.9 + 0.9 * mix_value), vec2(0.9, 0.9 * mix_value))); f = mix(f, 1 - f, rect(uv2, vec2(.2, -.9 + .9 * mix_value), vec2(.9, .9 * mix_value)));
// show debug info // show debug info
float v = 0; float v = 0.;
float x = 0; float x = 0.;
x = -15; x = -15.;
f += write_5(uv3, vec2(x - 4.5, 13), texts[1]); f += write_5(uv3, vec2(x - 4.5, 13.), textTEMPO);
f += write_int(uv3, vec2(x + 1.5, 13), int(iTempo), 3); f += write_int(uv3, vec2(x + 1.5, 13.), int(iTempo), 3);
v = fract(iBeats); v = fract(iBeats);
f += h_rect(uv3, vec2(x, 12), vec2(4, 0.5), 0.2); f += h_rect(uv3, vec2(x, 12.), vec2(4., .5), .2);
f += rect(uv3, vec2(x + 4 * v - 4, 12), vec2(4 * v, 0.4)); f += rect(uv3, vec2(x + 4. * v - 4., 12.), vec2(4. * v, .4));
x = 15; x = 15.;
if (iAutoRand > 0) { if (iAutoRand > 0) {
f += write_5(uv3, vec2(x - 4.5, 13), texts[5]); f += write_5(uv3, vec2(x - 4.5, 13.), textRAND);
f += write_int(uv3, vec2(x - 0.5, 13), int(iAutoRandCycle), 5); f += write_int(uv3, vec2(x - .5, 13.), int(iAutoRandCycle), 5);
v = fract(iBeats / iAutoRandCycle); v = fract(iBeats / iAutoRandCycle);
} else { } else {
f += write_int(uv3, vec2(x - 0.5, 13), int(iTime), 5); f += write_int(uv3, vec2(x - .5, 13.), int(iTime), 5);
v = fract(iTime); v = fract(iTime);
f += write_5(uv3, vec2(x - 4.5, 13), texts[2]); f += write_5(uv3, vec2(x - 4.5, 13.), textTIME);
} }
f += h_rect(uv3, vec2(x, 12), vec2(4, 0.5), 0.2); f += h_rect(uv3, vec2(x, 12.), vec2(4., .5), .2);
f += rect(uv3, vec2(x + 4 * v - 4, 12), vec2(4 * v, 0.4)); f += rect(uv3, vec2(x + 4. * v - 4., 12), vec2(4. * v, .4));
return vec4(f); return vec4(f);
} }
+129 -128
View File
@@ -12,68 +12,68 @@
// BASICS // BASICS
float istep(float x, float y) { float istep(float x, float y) {
return 1 - step(x, y); return 1. - step(x, y);
} }
float estep(float x, float y) { float estep(float x, float y) {
return smoothstep(x - 0.0001, x + 0.0001, y); return smoothstep(x - .0001, x + .0001, y);
} }
float iestep(float x, float y) { float iestep(float x, float y) {
return 1 - estep(x, y); return 1. - estep(x, y);
} }
float ease(float x) { float ease(float x) {
return 0.5 - cos(max(min(x, 1.0), 0.0)*PI) * 0.5; return .5 - cos(max(min(x, 1.), 0.) * PI) * .5;
} }
vec2 ease(vec2 x) { vec2 ease(vec2 x) {
return 0.5 - cos(max(min(x, 1.0), 0.0)*PI) * 0.5; return .5 - cos(max(min(x, 1.), 0.) * PI) * .5;
} }
vec3 ease(vec3 x) { vec3 ease(vec3 x) {
return 0.5 - cos(max(min(x, 1.0), 0.0)*PI) * 0.5; return .5 - cos(max(min(x, 1.), 0.) * PI) * .5;
} }
float saw(float x){ float saw(float x) {
return abs(mod(x+1,2)-1); return abs(mod(x + 1., 2.) - 1.);
} }
vec2 saw(vec2 x){ vec2 saw(vec2 x) {
return abs(mod(x+1,2)-1); return abs(mod(x + 1., 2.) - 1.);
} }
vec3 saw(vec3 x){ vec3 saw(vec3 x) {
return abs(mod(x+1,2)-1); return abs(mod(x + 1., 2.) - 1.);
} }
float cmod(float x, float k){ float cmod(float x, float k) {
return mod(x + k * 0.5, k) - k * 0.5; return mod(x + k * .5, k) - k * .5;
} }
vec2 cmod(vec2 x, float k){ vec2 cmod(vec2 x, float k) {
return mod(x + k * 0.5, k) - k * 0.5; return mod(x + k * .5, k) - k * .5;
} }
vec3 cmod(vec3 x, float k){ vec3 cmod(vec3 x, float k) {
return mod(x + k * 0.5, k) - k * 0.5; return mod(x + k * .5, k) - k * .5;
} }
// COLORS // COLORS
vec3 col(float x){ vec3 col(float x) {
return vec3( return vec3(
.5*(sin(x*2.*PI)+1.), .5 * (sin(x * 2. * PI) + 1.),
.5*(sin(x*2.*PI+2.*PI/3.)+1.), .5 * (sin(x * 2. * PI + PI * .6666667) + 1.),
.5*(sin(x*2.*PI-2.*PI/3.)+1.) .5 * (sin(x * 2. * PI - PI * .6666667) + 1.)
); );
} }
vec3 shift(vec3 c, float f) { vec3 shift(vec3 c, float f) {
return vec3( return vec3(
c.x * (1 - f) + c.y * f, c.x * (1. - f) + c.y * f,
c.y * (1 - f) + c.z * f, c.y * (1. - f) + c.z * f,
c.z * (1 - f) + c.x * f c.z * (1. - f) + c.x * f
); );
} }
@@ -82,115 +82,112 @@ vec3 shift3(vec3 c, float f) {
} }
vec3 mix3(vec3 c1, vec3 c2, vec3 c3, float x) { vec3 mix3(vec3 c1, vec3 c2, vec3 c3, float x) {
return istep(0.5, x) * mix(c1, c2, x * 2) return istep(.5, x) * mix(c1, c2, x * 2.)
+ step(0.5, x) * mix(c2, c3, x * 2 - 1) + step(.5, x) * mix(c2, c3, x * 2. - 1.);
;
} }
vec3 mix4(vec3 c1, vec3 c2, vec3 c3, vec3 c4, float x) { vec3 mix4(vec3 c1, vec3 c2, vec3 c3, vec3 c4, float x) {
return istep(0.333, x) * mix(c1, c2, x * 3) return istep(.333, x) * mix(c1, c2, x * 3.)
+ step(0.333, x) * istep(0.667, x) * mix(c2, c3, x * 3 - 1) + step(.333, x) * istep(.667, x) * mix(c2, c3, x * 3. - 1.)
+ step(0.667, x) * mix(c3, c4, x * 3 - 2); + step(.667, x) * mix(c3, c4, x * 3. - 2.);
; ;
} }
vec3 mix5(vec3 c1, vec3 c2, vec3 c3, vec3 c4, vec3 c5, float x) { vec3 mix5(vec3 c1, vec3 c2, vec3 c3, vec3 c4, vec3 c5, float x) {
return istep(0.25, x) * mix(c1, c2, x * 4) return istep(.25, x) * mix(c1, c2, x * 4.)
+ step(0.25, x) * istep(0.5, x) * mix(c2, c3, x * 4 - 1) + step(.25, x) * istep(.5, x) * mix(c2, c3, x * 4. - 1.)
+ step(0.5, x) * istep(0.75, x) * mix(c3, c4, x * 4 - 2) + step(.5, x) * istep(.75, x) * mix(c3, c4, x * 4. - 2.)
+ step(0.75, x) * mix(c4, c5, x * 4 - 3) + step(.75, x) * mix(c4, c5, x * 4. - 3.);
;
} }
vec3 mix6(vec3 c1, vec3 c2, vec3 c3, vec3 c4, vec3 c5, vec3 c6, float x) { vec3 mix6(vec3 c1, vec3 c2, vec3 c3, vec3 c4, vec3 c5, vec3 c6, float x) {
return istep(0.2, x) * mix(c1, c2, x * 5) return istep(.2, x) * mix(c1, c2, x * 5.)
+ step(0.2, x) * istep(0.4, x) * mix(c2, c3, x * 5 - 1) + step(.2, x) * istep(.4, x) * mix(c2, c3, x * 5. - 1.)
+ step(0.4, x) * istep(0.6, x) * mix(c3, c4, x * 5 - 2) + step(.4, x) * istep(.6, x) * mix(c3, c4, x * 5. - 2.)
+ step(0.6, x) * istep(0.8, x) * mix(c4, c5, x * 5 - 3) + step(.6, x) * istep(.8, x) * mix(c4, c5, x * 5. - 3.)
+ step(0.8, x) * mix(c5, c6, x * 5 - 4) + step(.8, x) * mix(c5, c6, x * 5. - 4.);
;
} }
float mean(vec3 v) float mean(vec3 v)
{ {
return v.x * 0.3333 + v.y * 0.3333 + v.z * 0.3333; return v.x * .3333 + v.y * .3333 + v.z * .3333;
} }
float mean(vec4 v) float mean(vec4 v)
{ {
return v.x * 0.3333 + v.y * 0.3333 + v.z * 0.3333; return v.x * .3333 + v.y * .3333 + v.z * .3333;
} }
// OTHER // OTHER
mat2 rot(float angle){ mat2 rot(float angle) {
return mat2( return mat2(
cos(angle*2.*PI),-sin(angle*2.*PI), cos(angle * 2. * PI), -sin(angle * 2. * PI),
sin(angle*2.*PI),cos(angle*2.*PI) sin(angle * 2. * PI), cos(angle * 2. * PI)
); );
} }
// EFFECTS // EFFECTS
vec2 lens(vec2 uv, float limit, float power) { vec2 lens(vec2 uv, float limit, float power) {
return uv * (1 + limit + length(uv * power)); return uv * (1. + limit + length(uv * power));
} }
vec2 kal(vec2 uv, float n) { vec2 kal(vec2 uv, float n) {
float t = atan(uv.y, uv.x) + PI * 0.5; float t = atan(uv.y, uv.x) + PI * .5;
float q = 3.0 / (2.0 * PI); float q = .4774648; // 3. / (2. * PI);
t = abs(mod(t + PI / (n), 2 * PI / n) - PI / (n)); t = abs(mod(t + PI / n, 2. * PI / n) - PI / n);
return length(uv) * vec2( return length(uv) * vec2(
cos(t), cos(t),
sin(t) sin(t)
); );
} }
vec2 kal2(vec2 uv, float n) { vec2 kal2(vec2 uv, float n) {
float t = atan(uv.y, uv.x) + PI * 0.5; float t = atan(uv.y, uv.x) + PI * .5;
float t2 = abs(mod(t + PI / n, 2 * PI / n) - PI / n); float t2 = abs(mod(t + PI / n, 2. * PI / n) - PI / n);
return length(uv) * vec2( return length(uv) * vec2(
cos(t2), cos(t2),
sin(t2) sin(t2)
); );
} }
// NOISE // NOISE
float noise(vec2 n) float noise(vec2 n)
{ {
const vec2 d = vec2(0, 1); const vec2 d = vec2(0., 1.);
vec2 b = floor(n); vec2 b = floor(n);
vec2 f = fract(n); vec2 f = fract(n);
f *= f * (3 - 2 * f); f *= f * (3. - 2. * f);
return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y); return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
} }
float noise_f(vec2 n, int f) float noise_f(vec2 n, int f)
{ {
float o = noise(n) / 2; float o = noise(n) * .5;
o += mix(o, noise(n * 2), f > 1 ? 1 : 0) / 4; o += mix(o, noise(n * 2.), f > 1. ? 1. : 0.) * .25;
o += mix(o, noise(n * 4), f > 2 ? 1 : 0) / 8; o += mix(o, noise(n * 4.), f > 2. ? 1. : 0.) * .125;
o += mix(o, noise(n * 8), f > 3 ? 1 : 0) / 16; o += mix(o, noise(n * 8.), f > 3. ? 1. : 0.) * .0625;
o += mix(o, noise(n * 16), f > 4 ? 1 : 0) / 32; o += mix(o, noise(n * 16.), f > 4. ? 1. : 0.) * .03125;
return o; return o;
} }
// VORONOI // VORONOI
float v_index(vec2 uv) { float v_index(vec2 uv) {
return floor(uv.x) + floor(uv.y) * 45; return floor(uv.x) + floor(uv.y) * 45.;
} }
vec2 v_pos(float i) { vec2 v_pos(float i, int seed, float time) {
int iTimeId = int(iBeats); int iTimeId = int(time);
float iTimeV = iBeats - iTimeId; float iTimeV = time - iTimeId;
float x0 = rand(i + 823 + iTimeId); float x0 = rand(i + seed + iTimeId);
float y0 = rand(i + 328 + iTimeId); float y0 = rand(i + seed + 10. + iTimeId);
float x1 = rand(i + 823 + iTimeId + 1); float x1 = rand(i + seed + iTimeId + 1.);
float y1 = rand(i + 328 + iTimeId + 1); float y1 = rand(i + seed + 10. + iTimeId + 1.);
return vec2( return vec2(
mix(x0, x1, ease(ease(iTimeV))), mix(x0, x1, ease(ease(iTimeV))),
@@ -198,16 +195,17 @@ vec2 v_pos(float i) {
); );
} }
vec4 voronoi(vec2 uv, float dist) { vec4 voronoi(vec2 uv, float dist, int seed, float time) {
vec4 o = vec4(0, 0, 2, 0); vec4 o = vec4(0., 0., 2., 0.);
vec4 t = vec4(0, 0, 2, 0); vec4 t = vec4(0., 0., 2., 0.);
float d, i; float d, i;
vec2 uv2, p; vec2 uv2, p;
for (int dx = -1; dx <= 1; dx++) { int dx, dy;
for (int dy = -1; dy <= 1; dy++) { for (dx = -1; dx <= 1; dx++) {
for (dy = -1; dy <= 1; dy++) {
uv2 = vec2(floor(uv.x) + dx, floor(uv.y) + dy); uv2 = vec2(floor(uv.x) + dx, floor(uv.y) + dy);
i = v_index(uv2); i = v_index(uv2);
p = uv2 + v_pos(i) * dist; p = uv2 + v_pos(i, seed, time) * dist;
d = length(p - uv); d = length(p - uv);
if (d < o.z) { if (d < o.z) {
t = o; t = o;
@@ -227,21 +225,21 @@ float circle(vec2 uv, vec2 c, float size) {
} }
float h_circle(vec2 uv, vec2 c, float size, float k) { float h_circle(vec2 uv, vec2 c, float size, float k) {
return circle(uv, c, size + k * 0.5) - circle(uv, c, size - k * 0.5); return circle(uv, c, size + k * .5) - circle(uv, c, size - k * .5);
} }
float stripe(float x, float k1, float k2) float stripe(float x, float k1, float k2)
{ {
return k2 > k1 ? (1 - step(x, k1)) * (step(x, k2)) : ((1 - step(x, k2)) * (step(x, k1))); return k2 > k1 ? (1. - step(x, k1)) * (step(x, k2)) : ((1. - step(x, k2)) * (step(x, k1)));
} }
float capsule(vec2 uv, float r, float d, float a) float capsule(vec2 uv, float r, float d, float a)
{ {
uv *= rot(a); uv *= rot(a);
float f1 = step(uv.x, r) * step(-uv.x, r) * step(uv.y, d - r) * step(-uv.y, d - r); float f1 = step(uv.x, r) * step(-uv.x, r) * step(uv.y, d - r) * step(-uv.y, d - r);
float f2 = step(length(uv - vec2(0, d - r)), r); float f2 = step(length(uv - vec2(0., d - r)), r);
float f3 = step(length(uv + vec2(0, d - r)), r); float f3 = step(length(uv + vec2(0., d - r)), r);
return min(1, f1 + f2 + f3); return min(1., f1 + f2 + f3);
} }
float rect(vec2 uv, vec2 c, vec2 size) { float rect(vec2 uv, vec2 c, vec2 size) {
@@ -250,7 +248,7 @@ float rect(vec2 uv, vec2 c, vec2 size) {
} }
float h_rect(vec2 uv, vec2 c, vec2 size, float k) { float h_rect(vec2 uv, vec2 c, vec2 size, float k) {
return rect(uv, c, size + k * 0.5) - rect(uv, c, size - k * 0.5); return rect(uv, c, size + k * .5) - rect(uv, c, size - k * .5);
} }
float line(vec2 uv, vec2 p1, vec2 p2, float thick) { float line(vec2 uv, vec2 p1, vec2 p2, float thick) {
@@ -260,28 +258,31 @@ float line(vec2 uv, vec2 p1, vec2 p2, float thick) {
if (abs(p.y) > abs(p.x)) { if (abs(p.y) > abs(p.x)) {
k = vec2( k = vec2(
uv.x - p.x * uv.y / p.y, uv.x - p.x * uv.y / p.y,
uv.y / p.y uv.y / p.y
); );
return step(k.x, thick * 0.5) return step(k.x, thick * .5)
* step(-k.x, thick * 0.5) * step(-k.x, thick * .5)
* step(k.y, 1) * step(k.y, 1.)
* (1 - step(k.y, 0)); * (1. - step(k.y, 0.));
} else { } else {
k = vec2( k = vec2(
uv.x / p.x, uv.x / p.x,
uv.y - p.y * uv.x / p.x uv.y - p.y * uv.x / p.x
); );
return step(k.y, thick * 0.5) return step(k.y, thick * .5)
* step(-k.y, thick * 0.5) * step(-k.y, thick * .5)
* step(k.x, 1) * step(k.x, 1.)
* (1 - step(k.x, 0)); * (1. - step(k.x, 0.));
} }
} }
const mat2x2 ISOMETRIC_MATRIX = {{0.5, 1}, {0.5, -1}}; const mat2x2 ISOMETRIC_MATRIX = mat2x2(
.5, 1.,
.5, -1.
);
vec2 iso(vec2 p) { vec2 iso(vec2 p) {
return p * ISOMETRIC_MATRIX; return p * ISOMETRIC_MATRIX;
@@ -302,14 +303,14 @@ vec2 iso(vec3 uv) {
vec4 reframe(sampler2D tex, vec2 uv) vec4 reframe(sampler2D tex, vec2 uv)
{ {
uv = uv * vec2(iResolution.y / iResolution.x, 1) + .5; uv = uv * vec2(iResolution.y / iResolution.x, 1.) + .5;
uv = saw(uv); uv = saw(uv);
return texture(tex, uv); return texture(tex, uv);
} }
vec4 reframe_b(sampler2D tex, vec2 uv) vec4 reframe_b(sampler2D tex, vec2 uv)
{ {
uv = uv * vec2(iResolution.y / iResolution.x, 1) + .5; uv = uv * vec2(iResolution.y / iResolution.x, 1.) + .5;
return texture(tex, uv); return texture(tex, uv);
} }
@@ -317,11 +318,11 @@ vec4 kernel(sampler2D tex, vec2 uv, mat3x3 k, float spm)
{ {
int x, y; int x, y;
vec2 offset; vec2 offset;
vec4 sum = vec4(0); vec4 sum = vec4(0.);
for (y = -1; y <= 1; ++y) { for (y = -1; y <= 1; ++y) {
for (x = -1; x <= 1; ++x) { for (x = -1; x <= 1; ++x) {
offset = vec2(x, y) * spm; offset = vec2(x, y) * spm;
if (abs(k[x + 1][y + 1]) > 0) { if (abs(k[x + 1][y + 1]) > 0.) {
sum += k[x + 1][y + 1] * texture(tex, uv + offset); sum += k[x + 1][y + 1] * texture(tex, uv + offset);
} }
} }
@@ -333,7 +334,7 @@ vec4 kernel(sampler2D tex, vec2 uv, mat3x3 k, float spm)
float gaussian_weight(float x, float sigma) float gaussian_weight(float x, float sigma)
{ {
return exp(-(x * x) / (2.0 * sigma * sigma)); return exp(-(x * x) / (2. * sigma * sigma));
} }
vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm, float sigma, float bloom) vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm, float sigma, float bloom)
@@ -341,8 +342,8 @@ vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm, float sigma
int x, y; int x, y;
vec2 offset; vec2 offset;
float w; float w;
vec4 sum = vec4(0); vec4 sum = vec4(0.);
float weight_sum = 0; float weight_sum = 0.;
for (y = -kernel_size; y <= kernel_size; ++y) { for (y = -kernel_size; y <= kernel_size; ++y) {
for (x = -kernel_size; x <= kernel_size; ++x) { for (x = -kernel_size; x <= kernel_size; ++x) {
offset = vec2(x, y) * spm; offset = vec2(x, y) * spm;
@@ -356,17 +357,17 @@ vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm, float sigma
vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm, float sigma) vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm, float sigma)
{ {
return gauss(tex, uv, kernel_size, spm, sigma, 1.0); return gauss(tex, uv, kernel_size, spm, sigma, 1.);
} }
vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm) vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size, float spm)
{ {
return gauss(tex, uv, kernel_size, spm, 2.0); return gauss(tex, uv, kernel_size, spm, 2.);
} }
vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size) vec4 gauss(sampler2D tex, vec2 uv, const int kernel_size)
{ {
return gauss(tex, uv, kernel_size, 1 / max(iResolution.x, iResolution.y)); return gauss(tex, uv, kernel_size, 1. / max(iResolution.x, iResolution.y));
} }
vec4 gauss(sampler2D tex, vec2 uv) vec4 gauss(sampler2D tex, vec2 uv)
@@ -377,23 +378,23 @@ vec4 gauss(sampler2D tex, vec2 uv)
float dither(vec2 uv, float x) float dither(vec2 uv, float x)
{ {
bool o = false; bool o = false;
o = o || x * 16 >= 1 && floor(mod(uv.x, 4)) == 0 && floor(mod(uv.y, 4)) == 0; o = o || x * 16. >= 1. && floor(mod(uv.x, 4.)) == 0. && floor(mod(uv.y, 4.)) == 0.;
o = o || x * 16 >= 2 && floor(mod(uv.x, 4)) == 2 && floor(mod(uv.y, 4)) == 2; o = o || x * 16. >= 2. && floor(mod(uv.x, 4.)) == 2. && floor(mod(uv.y, 4.)) == 2.;
o = o || x * 16 >= 3 && floor(mod(uv.x, 4)) == 0 && floor(mod(uv.y, 4)) == 2; o = o || x * 16. >= 3. && floor(mod(uv.x, 4.)) == 0. && floor(mod(uv.y, 4.)) == 2.;
o = o || x * 16 >= 4 && floor(mod(uv.x, 4)) == 2 && floor(mod(uv.y, 4)) == 0; o = o || x * 16. >= 4. && floor(mod(uv.x, 4.)) == 2. && floor(mod(uv.y, 4.)) == 0.;
o = o || x * 16 >= 5 && floor(mod(uv.x, 4)) == 1 && floor(mod(uv.y, 4)) == 1; o = o || x * 16. >= 5. && floor(mod(uv.x, 4.)) == 1. && floor(mod(uv.y, 4.)) == 1.;
o = o || x * 16 >= 6 && floor(mod(uv.x, 4)) == 3 && floor(mod(uv.y, 4)) == 3; o = o || x * 16. >= 6. && floor(mod(uv.x, 4.)) == 3. && floor(mod(uv.y, 4.)) == 3.;
o = o || x * 16 >= 7 && floor(mod(uv.x, 4)) == 1 && floor(mod(uv.y, 4)) == 3; o = o || x * 16. >= 7. && floor(mod(uv.x, 4.)) == 1. && floor(mod(uv.y, 4.)) == 3.;
o = o || x * 16 >= 8 && floor(mod(uv.x, 4)) == 3 && floor(mod(uv.y, 4)) == 1; o = o || x * 16. >= 8. && floor(mod(uv.x, 4.)) == 3. && floor(mod(uv.y, 4.)) == 1.;
o = o || x * 16 >= 9 && floor(mod(uv.x, 4)) == 1 && floor(mod(uv.y, 4)) == 0; o = o || x * 16. >= 9. && floor(mod(uv.x, 4.)) == 1. && floor(mod(uv.y, 4.)) == 0.;
o = o || x * 16 >= 10 && floor(mod(uv.x, 4)) == 3 && floor(mod(uv.y, 4)) == 2; o = o || x * 16. >= 10. && floor(mod(uv.x, 4.)) == 3. && floor(mod(uv.y, 4.)) == 2.;
o = o || x * 16 >= 11 && floor(mod(uv.x, 4)) == 1 && floor(mod(uv.y, 4)) == 2; o = o || x * 16. >= 11. && floor(mod(uv.x, 4.)) == 1. && floor(mod(uv.y, 4.)) == 2.;
o = o || x * 16 >= 12 && floor(mod(uv.x, 4)) == 3 && floor(mod(uv.y, 4)) == 0; o = o || x * 16. >= 12. && floor(mod(uv.x, 4.)) == 3. && floor(mod(uv.y, 4.)) == 0.;
o = o || x * 16 >= 13 && floor(mod(uv.x, 4)) == 0 && floor(mod(uv.y, 4)) == 1; o = o || x * 16. >= 13. && floor(mod(uv.x, 4.)) == 0. && floor(mod(uv.y, 4.)) == 1.;
o = o || x * 16 >= 14 && floor(mod(uv.x, 4)) == 2 && floor(mod(uv.y, 4)) == 3; o = o || x * 16. >= 14. && floor(mod(uv.x, 4.)) == 2. && floor(mod(uv.y, 4.)) == 3.;
o = o || x * 16 >= 15 && floor(mod(uv.x, 4)) == 0 && floor(mod(uv.y, 4)) == 3; o = o || x * 16. >= 15. && floor(mod(uv.x, 4.)) == 0. && floor(mod(uv.y, 4.)) == 3.;
o = o || x * 16 >= 16 && floor(mod(uv.x, 4)) == 2 && floor(mod(uv.y, 4)) == 1; o = o || x * 16. >= 16. && floor(mod(uv.x, 4.)) == 2. && floor(mod(uv.y, 4.)) == 1.;
return o ? 1 : 0; return o ? 1. : 0.;
} }
#endif #endif
+122 -123
View File
@@ -1,19 +1,20 @@
#include inc_res.glsl #include inc_res.glsl
#include inc_magic.glsl #include inc_magic.glsl
#include inc_functions.glsl #include inc_functions.glsl
#include inc_cp437.glsl
#ifndef INC_FX #ifndef INC_FX
#define INC_FX #define INC_FX
vec4 fx_master(vec3 c0, vec3 c, int seed, vec3 m0) { vec4 fx_master(vec3 c0, vec3 c, int seed, vec3 m0) {
float fx = magic(m0.xy, vec3(1,0,0), seed); float fx = magic(m0.xy, vec3(1., 0., 0.), seed);
bool invert = magic_trigger(vec3(m0.z, 0, 0), seed); bool invert = magic_trigger(vec3(m0.z, 0., 0.), seed);
vec3 c_out = mix(c0, c, fx); vec3 c_out = mix(c0, c, fx);
c_out = mix(c_out, 1 - c_out, invert ? 1 : 0); c_out = mix(c_out, 1. - c_out, invert ? 1. : 0.);
return vec4(c_out, 1.0); return vec4(c_out, 1.);
} }
subroutine vec4 fx_stage_sub(vec2 vUV, sampler2D previous, sampler2D feedback, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0); subroutine vec4 fx_stage_sub(vec2 vUV, sampler2D previous, sampler2D feedback, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0);
@@ -29,29 +30,29 @@ subroutine(fx_stage_sub) vec4 fx_1(vec2 vUV, sampler2D previous, sampler2D feedb
// controls // controls
float hue = magic(f1, b1, seed + 10); float hue = magic(f1, b1, seed + 10.);
float saturation = magic(f2, b2, seed + 20); float saturation = magic(f2, b2, seed + 20.);
float light = magic(f3, b3, seed + 30); float light = magic(f3, b3, seed + 30.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec3 c = c0; vec3 c = c0;
c = shift3(c, hue); c = shift3(c, hue);
c *= 1 + saturation; c *= 1. + saturation;
c = mix(c + light * 2.0, c - (1 - light) * 2.0, step(0.5, light)); c = mix(c + light * 2., c - (1. - light) * 2., step(.5, light));
return fx_master(c0, c, seed, m0); return fx_master(c0, c, seed, m0);
} }
// FX 2 : feedback + shift // FX 2 : feedback + shift
vec4 fx_shift(vec2 vUV, sampler2D src0, sampler2D src1, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0) subroutine(fx_stage_sub) vec4 fx_shift(vec2 vUV, sampler2D src0, sampler2D src1, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
@@ -64,7 +65,7 @@ vec4 fx_shift(vec2 vUV, sampler2D src0, sampler2D src1, int seed, vec3 b1, vec2
vec3 c0 = texture(src0, uv0).xyz; vec3 c0 = texture(src0, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 = mix(uv2 * (1 + zoom * 2), uv2 * (zoom), step(0.5, zoom)); uv2 = mix(uv2 * (1 + zoom * 2), uv2 * (zoom), step(.5, zoom));
uv2 += vec2(x_shift * ratio, y_shift) * 2; uv2 += vec2(x_shift * ratio, y_shift) * 2;
vec3 c = reframe(src1, uv2).xyz; vec3 c = reframe(src1, uv2).xyz;
@@ -115,28 +116,28 @@ subroutine(fx_stage_sub) vec4 fx_5(vec2 vUV, sampler2D previous, sampler2D feedb
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float pixel_size = magic(f1, b1, seed + 10); float pixel_size = magic(f1, b1, seed + 10.);
float quantize = magic(f2, b2, seed + 20); float quantize = magic(f2, b2, seed + 20.);
bool quantize_trigger = magic_trigger(b2, seed + 20); bool quantize_trigger = magic_trigger(b2, seed + 20.);
float blur = magic(f3, b3, seed + 30); float blur = magic(f3, b3, seed + 30.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
float pixel = (1 - pixel_size) * 250 + 25; float pixel = (1., - pixel_size) * 250. + 25.;
uv2 = round(uv2 * pixel) / pixel; uv2 = round(uv2 * pixel) / pixel;
vec3 c = gauss(previous, uv2 * vec2(1 / ratio, 1) + .5, 3, 0.005 * blur).xyz; vec3 c = gauss(previous, uv2 * vec2(1. / ratio, 1.) + .5, 3, .005 * blur).xyz;
float colors = (1 - quantize) * 10 + 1; float colors = (1. - quantize) * 10. + 1.;
if (quantize_trigger) { if (quantize_trigger) {
c = round(c * colors) / colors; c = round(c * colors) / colors;
} }
// c = mix(c, 1 - c, step(noise_f(uv0 * 10 + vec2(iTime * 0.1, 0), 5), 0.5)); // c = mix(c, 1 - c, step(noise_f(uv0 * 10 + vec2(iTime * .1, 0), 5), .5));
return fx_master(c0, c, seed, m0); return fx_master(c0, c, seed, m0);
} }
@@ -148,7 +149,7 @@ subroutine(fx_stage_sub) vec4 fx_6(vec2 vUV, sampler2D previous, sampler2D feedb
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
@@ -168,7 +169,7 @@ subroutine(fx_stage_sub) vec4 fx_6(vec2 vUV, sampler2D previous, sampler2D feedb
if (pixel_size_trigger) { if (pixel_size_trigger) {
uv2 = floor(uv2 * k1) / k1; uv2 = floor(uv2 * k1) / k1;
} }
vec3 c = gauss(previous, uv2 * vec2(1 / ratio, 1) + .5, 3, 0.005 * blur).xyz; vec3 c = gauss(previous, uv2 * vec2(1 / ratio, 1) + .5, 3, .005 * blur).xyz;
float k3 = pow(2, 5 - floor(quantize * 5)); float k3 = pow(2, 5 - floor(quantize * 5));
if (quantize_trigger) { if (quantize_trigger) {
c *= k3; c *= k3;
@@ -190,26 +191,26 @@ subroutine(fx_stage_sub) vec4 fx_7(vec2 vUV, sampler2D previous, sampler2D feedb
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float lens_v = magic(f1, b1, seed + 10); float lens_v = magic(f1, b1, seed + 10.);
float horizontal_noise = magic(f2, b2, seed + 20); float horizontal_noise = magic(f2, b2, seed + 20.);
float zoom = magic(f3, b3, seed + 30); float zoom = magic(f3, b3, seed + 30.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
float k1 = lens_v * 0.5; float k1 = lens_v * .5;
uv2 *= 1 + zoom * 2; uv2 *= 1. + zoom * 2.;
uv2 = lens(uv2, -k1, k1); uv2 = lens(uv2, -k1, k1);
float k = horizontal_noise; float k = horizontal_noise;
vec3 c = vec3( vec3 c = vec3(
reframe_b(previous, uv2 + vec2((rand(uv0.y * 1000 + iTime) - 0.5) * k * 0.1)).x, reframe_b(previous, uv2 + vec2((rand(uv0.y * 1000. + iTime) - .5) * k * .1)).x,
reframe_b(previous, uv2 + vec2((rand(uv0.y * 1100 + iTime) - 0.5) * k * 0.1)).y, reframe_b(previous, uv2 + vec2((rand(uv0.y * 1100. + iTime) - .5) * k * .1)).y,
reframe_b(previous, uv2).z reframe_b(previous, uv2).z
); );
@@ -223,30 +224,28 @@ subroutine(fx_stage_sub) vec4 fx_8(vec2 vUV, sampler2D previous, sampler2D feedb
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float axes = magic(f1, b1, seed + 10); float axes = magic(f1, b1, seed + 10.);
float axes_trigger = magic_b(b1, seed + 10).x; float axes_trigger = magic_b(b1, seed + 10.).x;
float rotation = magic(f2, b2, seed + 20); float rotation = magic(f2, b2, seed + 20.);
float h_scroll = magic(f3, b3, seed + 30); float h_scroll = magic(f3, b3, seed + 30.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 = mix(uv2, kal2(uv2 * rot(0.25), floor(axes * 9 + 1)) * vec2(1, -2) + vec2(0, -0.5), axes_trigger); uv2 = mix(uv2, kal2(uv2 * rot(.25), floor(axes * 9. + 1.)) * vec2(1., -2.) + vec2(0., -.5), axes_trigger);
uv2 *= rot(rotation); uv2 *= rot(rotation);
uv2.x = (saw(uv2.x / ratio + 0.5 + h_scroll * 2) - 0.5) * ratio; uv2.x = (saw(uv2.x / ratio + .5 + h_scroll * 2.) - .5) * ratio;
vec3 c = reframe(previous, uv2).xyz; vec3 c = reframe(previous, uv2).xyz;
return fx_master(c0, c, seed, m0); return fx_master(c0, c, seed, m0);
} }
#include inc_cp437.glsl
// FX 9 : cp437 // FX 9 : cp437
subroutine(fx_stage_sub) vec4 fx_9(vec2 vUV, sampler2D previous, sampler2D feedback, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0) subroutine(fx_stage_sub) vec4 fx_9(vec2 vUV, sampler2D previous, sampler2D feedback, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0)
{ {
@@ -254,35 +253,35 @@ subroutine(fx_stage_sub) vec4 fx_9(vec2 vUV, sampler2D previous, sampler2D feedb
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = magic(f1, b1, seed + 10); float zoom = magic(f1, b1, seed + 10.);
vec2 charset = magic_f(f2, b2, seed + 20); vec2 charset = magic_f(f2, b2, seed + 20.);
vec3 charset_ctrl = magic_b(b2, seed + 20); vec3 charset_ctrl = magic_b(b2, seed + 20.);
float char_delta = magic(f3, b3, seed + 30); float char_delta = magic(f3, b3, seed + 30.);
float t = magic(seed + 40); float t = magic(seed + 40.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
float k1 = 100 * (1 - zoom) + 10; float k1 = 100. * (1. - zoom) + 10.;
float inv_k = 1 / k1; float inv_k = 1. / k1;
uv2 = floor(uv2 * k1) * inv_k; uv2 = floor(uv2 * k1) * inv_k;
int start_char = charset_ctrl.x > 0 ? charsets[int(charset.x * CHARSETS) * 2] : 0x01; int start_char = charset_ctrl.x > 0. ? charsets[int(charset.x * CHARSETS) * 2] : 0x01;
int char_span = int((charset_ctrl.x > 0 ? charsets[int(charset.x * CHARSETS) * 2 + 1] : 255)); int char_span = int((charset_ctrl.x > 0. ? charsets[int(charset.x * CHARSETS) * 2 + 1] : 255));
char_span = int(char_span * max(1 - charset.y, 1 / (char_span * 0.75))); char_span = int(char_span * max(1. - charset.y, 1. / (char_span * .75)));
ivec2 uv2i = ivec2(uv2 * k1); ivec2 uv2i = ivec2(uv2 * k1);
int code = ((charset_ctrl.y < 1 || (uv2i.x % 2 ^ uv2i.y % 2) > 0) ? 1 : 0) * (start_char + int((rand(uv2i) + char_delta) * char_span) % char_span); int code = ((charset_ctrl.y < 1. || (uv2i.x % 2 ^ uv2i.y % 2) > 0) ? 1 : 0) * (start_char + int((rand(uv2i) + char_delta) * char_span) % char_span);
vec3 c = reframe(previous, uv2 + vec2(0, 0) * inv_k * 0.125).xyz * 0.2 vec3 c = reframe(previous, uv2 + vec2(0., 0.) * inv_k * .125).xyz * .2
+ reframe(previous, uv2 + vec2(1, 0) * inv_k * 0.125).xyz * 0.2 + reframe(previous, uv2 + vec2(1., 0.) * inv_k * .125).xyz * .2
+ reframe(previous, uv2 + vec2(1, 1) * inv_k * 0.125).xyz * 0.2 + reframe(previous, uv2 + vec2(1., 1.) * inv_k * .125).xyz * .2
+ reframe(previous, uv2 + vec2(0, 1) * inv_k * 0.125).xyz * 0.2 + reframe(previous, uv2 + vec2(0., 1.) * inv_k * .125).xyz * .2
+ reframe(previous, uv2 + vec2(0.5, 0.5) * inv_k * 0.125).xyz * 0.2; + reframe(previous, uv2 + vec2(.5, .5) * inv_k * .125).xyz * .2;
c = char(mod(uv1 * k1, 1), code) ? c : vec3(0); c = char(mod(uv1 * k1, 1.), code) ? c : vec3(0.);
return fx_master(c0, c, seed, m0); return fx_master(c0, c, seed, m0);
} }
@@ -294,22 +293,22 @@ subroutine(fx_stage_sub) vec4 fx_10(vec2 vUV, sampler2D previous, sampler2D feed
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float lens_v1 = magic(f1, b1, seed + 10); float lens_v1 = magic(f1, b1, seed + 10.);
float lens_v2 = magic(f2, b2, seed + 20); float lens_v2 = magic(f2, b2, seed + 20.);
float zoom = magic(f3, b3, seed + 30); float zoom = magic(f3, b3, seed + 30.);
float k = magic(seed + 40); float k = magic(seed + 40.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= 1 + zoom * 2; uv2 *= 1. + zoom * 2.;
uv2 = lens(uv2, -lens_v2 * 10, lens_v1 * 10); uv2 = lens(uv2, -lens_v2 * 10., lens_v1 * 10.);
vec3 c = reframe(previous, uv2).xyz; vec3 c = reframe(previous, uv2).xyz;
return fx_master(c0, c, seed, m0); return fx_master(c0, c, seed, m0);
@@ -322,13 +321,13 @@ subroutine(fx_stage_sub) vec4 fx_11(vec2 vUV, sampler2D previous, sampler2D feed
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float wall1 = magic(f1, b1, seed + 10); float wall1 = magic(f1, b1, seed + 10.);
float wall2 = magic(f2, b2, seed + 20); float wall2 = magic(f2, b2, seed + 20.);
float angle = magic(f3, b3, seed + 30); float angle = magic(f3, b3, seed + 30.);
// logic // logic
@@ -336,8 +335,8 @@ subroutine(fx_stage_sub) vec4 fx_11(vec2 vUV, sampler2D previous, sampler2D feed
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= rot(angle); uv2 *= rot(angle);
uv2.y = min(uv2.y, 1 - wall1); uv2.y = min(uv2.y, 1. - wall1);
uv2.y = -min(-uv2.y, 1 - wall2); uv2.y = -min(-uv2.y, 1. - wall2);
uv2 *= rot(-angle); uv2 *= rot(-angle);
vec3 c = reframe(previous, uv2).xyz; vec3 c = reframe(previous, uv2).xyz;
@@ -351,33 +350,33 @@ subroutine(fx_stage_sub) vec4 fx_12(vec2 vUV, sampler2D previous, sampler2D feed
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - 0.5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float pixel_size = magic(f1, b1, seed + 10); float pixel_size = magic(f1, b1, seed + 10.);
bool pixel_size_trigger = magic_trigger(b1, seed + 10); bool pixel_size_trigger = magic_trigger(b1, seed + 10.);
f2 = magic_f(f2, b2, seed + 20); f2 = magic_f(f2, b2, seed + 20.);
int rule = int(f2.x * 12); int rule = int(f2.x * 12.);
float threshold = f2.y * 0.9 + 0.05; float threshold = f2.y * .9 + .05;
float fb = magic(f3, b3, seed + 30); float fb = magic(f3, b3, seed + 30.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
vec2 uv2 = uv1; vec2 uv2 = uv1;
float k1 = pow(2, 9 - floor(pixel_size * 5)); float k1 = pow(2., 9. - floor(pixel_size * 5.));
float p = 1 / k1; float p = 1. / k1;
uv2 = round(uv2 * k1) / k1; uv2 = round(uv2 * k1) / k1;
vec3 c1 = mix( vec3 c1 = mix(
reframe(previous, uv2 + vec2(0.5, 0.5) * p).xyz, reframe(previous, uv2 + vec2(.5, .5) * p).xyz,
reframe(feedback, uv2 + vec2(0.5, 0.5) * p).xyz, reframe(feedback, uv2 + vec2(.5, .5) * p).xyz,
fb fb
); );
vec3 c2 = mix( vec3 c2 = mix(
reframe(previous, uv2 + vec2(1.5, 0.5) * p).xyz, reframe(previous, uv2 + vec2(1.5, .5) * p).xyz,
reframe(feedback, uv2 + vec2(1.5, 0.5) * p).xyz, reframe(feedback, uv2 + vec2(1.5, .5) * p).xyz,
fb fb
); );
vec3 c3 = mix( vec3 c3 = mix(
@@ -386,33 +385,33 @@ subroutine(fx_stage_sub) vec4 fx_12(vec2 vUV, sampler2D previous, sampler2D feed
fb fb
); );
vec3 c4 = mix( vec3 c4 = mix(
reframe(previous, uv2 + vec2(0.5, 1.5) * p).xyz, reframe(previous, uv2 + vec2(.5, 1.5) * p).xyz,
reframe(feedback, uv2 + vec2(0.5, 1.5) * p).xyz, reframe(feedback, uv2 + vec2(.5, 1.5) * p).xyz,
fb fb
); );
vec3 c5 = mix( vec3 c5 = mix(
reframe(previous, uv2 + vec2(-0.5, 1.5) * p).xyz, reframe(previous, uv2 + vec2(-.5, 1.5) * p).xyz,
reframe(feedback, uv2 + vec2(-0.5, 1.5) * p).xyz, reframe(feedback, uv2 + vec2(-.5, 1.5) * p).xyz,
fb fb
); );
vec3 c6 = mix( vec3 c6 = mix(
reframe(previous, uv2 + vec2(-0.5, 0.5) * p).xyz, reframe(previous, uv2 + vec2(-.5, .5) * p).xyz,
reframe(feedback, uv2 + vec2(-0.5, 0.5) * p).xyz, reframe(feedback, uv2 + vec2(-.5, .5) * p).xyz,
fb fb
); );
vec3 c7 = mix( vec3 c7 = mix(
reframe(previous, uv2 + vec2(-0.5, -0.5) * p).xyz, reframe(previous, uv2 + vec2(-.5, -.5) * p).xyz,
reframe(feedback, uv2 + vec2(-0.5, -0.5) * p).xyz, reframe(feedback, uv2 + vec2(-.5, -.5) * p).xyz,
fb fb
); );
vec3 c8 = mix( vec3 c8 = mix(
reframe(previous, uv2 + vec2(0.5, -0.5) * p).xyz, reframe(previous, uv2 + vec2(.5, -.5) * p).xyz,
reframe(feedback, uv2 + vec2(0.5, -0.5) * p).xyz, reframe(feedback, uv2 + vec2(.5, -.5) * p).xyz,
fb fb
); );
vec3 c9 = mix( vec3 c9 = mix(
reframe(previous, uv2 + vec2(-0.5, -0.5) * p).xyz, reframe(previous, uv2 + vec2(-.5, -.5) * p).xyz,
reframe(feedback, uv2 + vec2(-0.5, -0.5) * p).xyz, reframe(feedback, uv2 + vec2(-.5, -.5) * p).xyz,
fb fb
); );
bool alive = mean(c1) >= threshold; bool alive = mean(c1) >= threshold;
@@ -453,7 +452,7 @@ subroutine(fx_stage_sub) vec4 fx_12(vec2 vUV, sampler2D previous, sampler2D feed
alive = n >= 6 || !alive && n == 4 || alive && (n == 3 || n == 5); alive = n >= 6 || !alive && n == 4 || alive && (n == 3 || n == 5);
} }
vec3 cout = vec3(alive ? 1 : 0); vec3 cout = vec3(alive ? 1. : 0.);
return fx_master(c0, cout, seed, m0); return fx_master(c0, cout, seed, m0);
} }
@@ -465,20 +464,20 @@ subroutine(fx_stage_sub) vec4 fx_13(vec2 vUV, sampler2D previous, sampler2D feed
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float sx = magic(f1, b1, seed + 10) * 2; float sx = magic(f1, b1, seed + 10.) * 2.;
float sy = magic(f2, b2, seed + 20) * 2; float sy = magic(f2, b2, seed + 20.) * 2.;
float disp = 0.005 * magic(f3, b3, seed + 30); float disp = .005 * magic(f3, b3, seed + 30.);
// logic // logic
vec3 c0 = texture(previous, uv0).xyz; vec3 c0 = texture(previous, uv0).xyz;
const mat3x3 sobelx = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; const mat3x3 sobelx = mat3x3(-1., -2., -1., 0., 0., 0., 1., 2., 1.);
const mat3x3 sobely = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; const mat3x3 sobely = mat3x3(-1., 0., 1., -2., 0., 2., -1., 0., 1.);
mat3x3 sobel = sobelx * sx + sobely * sy; mat3x3 sobel = sobelx * sx + sobely * sy;
@@ -494,13 +493,13 @@ subroutine(fx_stage_sub) vec4 fx_14(vec2 vUV, sampler2D previous, sampler2D feed
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = 1 + magic(f1, b1, seed + 10) * 9; float zoom = 1 + magic(f1, b1, seed + 10.) * 9.;
float h_scroll = magic(f2, b2, seed + 20); float h_scroll = magic(f2, b2, seed + 20.);
float angle = magic(f3, b3, seed + 30); float angle = magic(f3, b3, seed + 30.);
// logic // logic
@@ -512,11 +511,11 @@ subroutine(fx_stage_sub) vec4 fx_14(vec2 vUV, sampler2D previous, sampler2D feed
uv3 *= rot(angle); uv3 *= rot(angle);
uv3 += vec2(h_scroll, 0); uv3 += vec2(h_scroll, 0.);
uv3 *= round(zoom); uv3 *= round(zoom);
vec2 umax = vec2(round(zoom), 300); vec2 umax = vec2(round(zoom), 300.);
vec3 c = reframe(previous, mod(uv3, umax)).xyz; vec3 c = reframe(previous, mod(uv3, umax)).xyz;
@@ -526,33 +525,33 @@ subroutine(fx_stage_sub) vec4 fx_14(vec2 vUV, sampler2D previous, sampler2D feed
// FX 15 : Random // FX 15 : Random
subroutine(fx_stage_sub) vec4 fx_15(vec2 vUV, sampler2D previous, sampler2D feedback, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0) subroutine(fx_stage_sub) vec4 fx_15(vec2 vUV, sampler2D previous, sampler2D feedback, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3, vec3 m0)
{ {
int fx = int(randTime(seed + 100) * 14); int fx = int(randTime(seed + 100.) * 14.) + 1;
if (fx == 0) { if (fx == 1) {
return fx_1(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_1(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 1) {
return fx_2(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 2) { } else if (fx == 2) {
return fx_3(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_2(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 3) { } else if (fx == 3) {
return fx_4(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_3(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 4) { } else if (fx == 4) {
return fx_5(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_4(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 5) { } else if (fx == 5) {
return fx_6(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_5(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 6) { } else if (fx == 6) {
return fx_7(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_6(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 7) { } else if (fx == 7) {
return fx_8(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_7(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 8) { } else if (fx == 8) {
return fx_9(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_8(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 9) { } else if (fx == 9) {
return fx_10(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_9(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 10) { } else if (fx == 10) {
return fx_11(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_10(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 11) { } else if (fx == 11) {
return fx_12(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_11(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 12) { } else if (fx == 12) {
return fx_12(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else if (fx == 13) {
return fx_13(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_13(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
} else { } else {
return fx_14(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0); return fx_14(vUV, previous, feedback, seed, b1, f1, b2, f2, b3, f3, m0);
+26 -26
View File
@@ -3,75 +3,75 @@
#ifndef INC_MAGIC #ifndef INC_MAGIC
#define INC_MAGIC #define INC_MAGIC
vec2 magic_f(vec2 F, vec3 B, float i) vec2 magic_f(vec2 f, vec3 b, float i)
{ {
return vec2( return vec2(
mix(F.x, randTime(i + 1), min(1, B.z)), mix(f.x, randTime(i + 1.), min(1., b.z)),
mix(F.y, randTime(i + 2), min(1, B.z)) mix(f.y, randTime(i + 2.), min(1., b.z))
); );
} }
vec2 magic_f(float i) vec2 magic_f(float i)
{ {
return magic_f(vec2(0), vec3(0, 0, 1), i); return magic_f(vec2(0.), vec3(0., 0., 1.), i);
} }
vec3 magic_b(vec3 B, float i) vec3 magic_b(vec3 b, float i)
{ {
return vec3( return vec3(
mix(B.x, step(0.2, randTime(i + 3)), min(1, B.z)), mix(b.x, step(.2, randTime(i + 3.)), min(1., b.z)),
mix(B.y, step(0.5, randTime(i + 4)), min(1, B.z)), mix(b.y, step(.5, randTime(i + 4.)), min(1., b.z)),
min(1, B.z) min(1., b.z)
); );
} }
vec3 magic_b(float i) vec3 magic_b(float i)
{ {
return magic_b(vec3(0, 0, 1), i); return magic_b(vec3(0., 0., 1.), i);
} }
bool magic_trigger(vec3 B, float i) bool magic_trigger(vec3 b, float i)
{ {
return magic_b(B, i).x > 0; return magic_b(b, i).x > 0.;
} }
bool magic_trigger(float i) bool magic_trigger(float i)
{ {
return magic_b(i).x > 0; return magic_b(i).x > 0.;
} }
float magic(vec2 F, vec3 B, float i) float magic(vec2 f, vec3 b, float i)
{ {
vec2 f = magic_f(F, B, i); vec2 mf = magic_f(f, b, i);
vec3 b = magic_b(B, i); vec3 mb = magic_b(b, i);
return mix(0, f.x * mix(1 - modTime(f.y), cosTime(f.y) * 0.5 + 0.5, b.y), b.x); return mix(0., mf.x * mix(1. - modTime(mf.y), cosTime(mf.y) * .5 + .5, mb.y), mb.x);
} }
float fmagic(vec2 F, vec3 B, float i) float fmagic(vec2 f, vec3 b, float i)
{ {
vec2 f = magic_f(F, B, i); vec2 mf = magic_f(f, b, i);
vec3 b = magic_b(B, i); vec3 mb = magic_b(b, i);
return f.x * mix(1 - modTime(f.y), cosTime(f.y) * 0.5 + 0.5, b.y); return mf.x * mix(1. - modTime(mf.y), cosTime(mf.y) * .5 + .5, mb.y);
} }
float magic(float i) float magic(float i)
{ {
return magic(vec2(0), vec3(0, 0, 1), i); return magic(vec2(0.), vec3(0., 0., 1.), i);
} }
float magic_reverse(vec2 F, vec3 B, float i) float magic_reverse(vec2 f, vec3 b, float i)
{ {
vec2 f = magic_f(F, B, i); vec2 mf = magic_f(f, b, i);
vec3 b = magic_b(B, i); vec3 mb = magic_b(b, i);
return mix(0, f.x * mix(1 - modTime(f.y), modTime(f.y), b.y), b.x); return mix(0., mf.x * mix(1. - modTime(mf.y), modTime(mf.y), mb.y), mb.x);
} }
float magic_reverse(float i) float magic_reverse(float i)
{ {
return magic_reverse(vec2(0), vec3(0, 0, 1), i); return magic_reverse(vec2(0.), vec3(0., 0., 1.), i);
} }
#endif #endif
+30
View File
@@ -0,0 +1,30 @@
#ifndef INC_MAP
#define INC_MAP
vec2 project_4p(vec2 uv, vec2 p1, vec2 p2, vec2 p3, vec2 p4) {
float k1 = (p4.y - p3.y) / (p2.y - p3.y);
float k2 = (p3.y - p1.y) / (p2.y - p3.y);
float a = (p4.x - p3.x + k1 * p3.x - k1 * p2.x) / (p1.x - p3.x - k2 * p3.x + k2 * p2.x);
float b = k1 + a * k2;
float c = 1. - a - b;
// https://math.stackexchange.com/questions/296794/finding-the-transform-matrix-from-4-projected-points-with-javascript/339033#339033
mat3 projection_a = mat3(
a * p1.x, a * p1.y, a,
b * p2.x, b * p2.y, b,
c * p3.x, c * p3.y, c
);
mat3 projection_a_prime = inverse(projection_a);
mat3 projection_b = mat3(
0., 0., -1.,
1., 0., 1.,
0., 1., 1.
);
vec3 tmp = projection_b * projection_a_prime * vec3(uv, 1.);
return tmp.xy / tmp.z;
}
float base_mask(vec2 uv) {
return step(0., uv.x) * step(-1., -uv.x) * step(0., uv.y) * step(-1., -uv.y);
}
#endif
+3 -3
View File
@@ -2,13 +2,13 @@
#define INC_RAND #define INC_RAND
float rand(float seed){ float rand(float seed){
float v=pow(abs(seed),6./7.); float v = pow(abs(seed), .8571429); // 6. / 7.
v*=sin(v)+1.; v *= sin(v) + 1.;
return fract(v); return fract(v);
} }
float rand(vec2 n){ float rand(vec2 n){
return rand(n.x * 1234 + n.y * 9876); return rand(n.x * 1234. + n.y * 9876.);
} }
#endif #endif
+22 -21
View File
@@ -2,28 +2,29 @@
#define INC_SENTENCES #define INC_SENTENCES
#define SENTENCE_COUNT 17 #define SENTENCE_COUNT 17
#define SENTENCE_MAX_LENGTH 20
const int sentences[SENTENCE_COUNT][20] = { const int sentences[] = int[SENTENCE_COUNT * SENTENCE_MAX_LENGTH](
{0x66, 0x6F, 0x72, 0x67, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x66, 0x6F, 0x72, 0x67, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x46, 0x4F, 0x52, 0x47, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x46, 0x4F, 0x52, 0x47, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x46, 0x2E, 0x4F, 0x2E, 0x52, 0x2E, 0x47, 0x2E, 0x45, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x46, 0x2E, 0x4F, 0x2E, 0x52, 0x2E, 0x47, 0x2E, 0x45, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x46, 0x75, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x46, 0x75, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x4F, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x4F, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x52, 0x65, 0x61, 0x6C, 0x2D, 0x74, 0x69, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x52, 0x65, 0x61, 0x6C, 0x2D, 0x74, 0x69, 0x6D, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x45, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x73, 0x65, 0x65, 0x00, 0x00}, 0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x73, 0x65, 0x65, 0x00, 0x00,
{0x50, 0x69, 0x78, 0x65, 0x6C, 0x20, 0x62, 0x79, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x50, 0x69, 0x78, 0x65, 0x6C, 0x20, 0x62, 0x79, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x4C, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x4C, 0x69, 0x76, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x43, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x6C, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x43, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x6C, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x4B, 0x6C, 0x65, 0xE3, 0x65, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x4B, 0x6C, 0x65, 0xE3, 0x65, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x43, 0x6F, 0x64, 0x65, 0x20, 0x61, 0x73, 0x20, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x43, 0x6F, 0x64, 0x65, 0x20, 0x61, 0x73, 0x20, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
{0x41, 0x72, 0x74, 0x20, 0x61, 0x73, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x41, 0x72, 0x74, 0x20, 0x61, 0x73, 0x20, 0x63, 0x6F, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; );
const int lengths[SENTENCE_COUNT] = { const int lengths[] = int[SENTENCE_COUNT](
5, 5, 10, 6, 2, 9, 10, 7, 18, 14, 4, 9, 10, 1, 6, 11, 11 5, 5, 10, 6, 2, 9, 10, 7, 18, 14, 4, 9, 10, 1, 6, 11, 11
}; );
#endif #endif
+169 -273
View File
@@ -1,6 +1,7 @@
#include inc_res.glsl #include inc_res.glsl
#include inc_magic.glsl #include inc_magic.glsl
#include inc_functions.glsl #include inc_functions.glsl
#include inc_cp437.glsl
#ifndef INC_SRC #ifndef INC_SRC
#define INC_SRC #define INC_SRC
@@ -8,11 +9,13 @@
uniform int iDemo; uniform int iDemo;
uniform sampler2D iTex0; uniform sampler2D iTex0;
uniform sampler2D iTex5; uniform sampler2D iTex3;
uniform sampler2D iTex6; uniform sampler2D iTex4;
subroutine vec4 src_stage_sub(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3); subroutine vec4 src_stage_sub(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3);
subroutine uniform src_stage_sub src_stage;
vec4 src_thru(vec2 vUV, sampler2D tex, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) vec4 src_thru(vec2 vUV, sampler2D tex, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
@@ -21,9 +24,9 @@ vec4 src_thru(vec2 vUV, sampler2D tex, int seed, vec3 b1, vec2 f1, vec3 b2, vec2
// controls // controls
float hue = magic(f1, b1, seed + 10); float hue = magic(f1, b1, seed + 10.);
float saturation = magic(f2, b2, seed + 20); float saturation = magic(f2, b2, seed + 20.);
float light = magic(f3, b3, seed + 30); float light = magic(f3, b3, seed + 30.);
// logic // logic
@@ -31,8 +34,8 @@ vec4 src_thru(vec2 vUV, sampler2D tex, int seed, vec3 b1, vec2 f1, vec3 b2, vec2
c = shift3(c, hue); c = shift3(c, hue);
c *= 1 + saturation; c *= 1. + saturation;
c = mix(c + light * 2.0, c - (1 - light) * 2.0, step(0.5, light)); c = mix(c + light * 2., c - (1. - light) * 2., step(.5, light));
// output // output
@@ -40,356 +43,249 @@ vec4 src_thru(vec2 vUV, sampler2D tex, int seed, vec3 b1, vec2 f1, vec3 b2, vec2
} }
// SRC 1: feedback + thru // SRC 1: feedback + thru
subroutine ( src_stage_sub ) vec4 src_1(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_1(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
return src_thru(vUV, iTex0, seed, b1, f1, b2, f2, b3, f3); return src_thru(vUV, iTex0, seed, b1, f1, b2, f2, b3, f3);
} }
// SRC 2 : lines // SRC 2 : lines
subroutine ( src_stage_sub ) vec4 src_2(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_2(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float thickness = magic(f1, b1, seed + 10); float thickness = magic(f1, b1, seed + 10.);
float rotation = magic(f2, b2, seed + 20); float rotation = magic(f2, b2, seed + 20.);
float distort = magic(f3, b3, seed + 30); float distort = magic(f3, b3, seed + 30.);
// logic // logic
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2.y *= cos(uv2.x * 5 * distort); uv2.y *= cos(uv2.x * 5. * distort);
uv2 *= rot(rotation + iBeats / 16); uv2 *= rot(rotation + iBeats * .0625);
float k = thickness * 2; float k = thickness * 2.;
uv2.y = cmod(uv2.y, k * 2 + 0.1); uv2.y = cmod(uv2.y, k * 2. + .1);
float f = istep(k * 0.125 + 0.05, uv2.y) * istep(k * 0.125 + 0.01, -uv2.y); float f = istep(k * .125 + .05, uv2.y) * istep(k * .125 + .01, -uv2.y);
return vec4(f); return vec4(f);
} }
// SRC 3 : dots // SRC 3 : dots
subroutine ( src_stage_sub ) vec4 src_3(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_3(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = magic(f1, b1, seed + 10); float zoom = magic(f1, b1, seed + 10.);
float rotation = magic(f2, b2, seed + 20); float rotation = magic(f2, b2, seed + 20.);
float lens_v = magic(f3, b3, seed + 30); float lens_v = magic(f3, b3, seed + 30.);
// logic // logic
vec2 uv2 = uv1; vec2 uv2 = uv1;
float k1 = lens_v * 5; float k1 = lens_v * 5.;
uv2 = lens(uv2, -k1, k1); uv2 = lens(uv2, -k1, k1);
uv2 = kal(uv2, 5); uv2 = kal(uv2, 5.);
uv2 *= rot(rotation + iBeats / 16); uv2 *= rot(rotation + iBeats * .0625);
float k = zoom * 0.1 + 0.05; float k = zoom * .1 + .05;
uv2 = cmod(uv2, k * 2); uv2 = cmod(uv2, k * 2.);
float f = istep(k / (1 + length(uv1) * 2), length(uv2)); float f = istep(k / (1. + length(uv1) * 2.), length(uv2));
return vec4(f); return vec4(f);
} }
// SRC 4 : circuit
subroutine ( src_stage_sub ) vec4 src_4(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) // SRC 4 : bacteria
subroutine(src_stage_sub) vec4 src_4(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float z = 10 + magic(f1, b1, 123) * 20; float zoom = 2. + magic(f1, b1, seed + 10.) * 20.;
float h = magic(f2, b2, seed + 20) * 0.8 + 0.1; float details = 5. * magic(f2, b2, seed + 20.);
float v = magic_reverse(f3, b3, seed + 30) * 0.8 + 0.1; float delta = magic(f3, b3, seed + 30.);
// logic // logic
uv1 *= z; uv1 *= zoom;
uv1 += iBeats;
float s0 = rand(floor(mod(uv1, 1000))) * 1000; vec4 data = voronoi(uv1, 1., seed + 40, iBeats * .25);
float s1 = rand(floor(mod(uv1 + vec2(0, 1), 1000))) * 1000;
float s2 = rand(floor(mod(uv1 - vec2(1, 0), 1000))) * 1000;
bool up = rand(s1 + 1) < h; float f = ease(data.x) + ease(data.y);
bool left = rand(s2 + 2) < v;
bool down = rand(s0 + 1) < h;
bool right = rand(s0 + 2) < v;
bool up_down = up && down;
bool left_right = left && right;
uv1 = mod(uv1, 1.0) - 0.5; f = saw(f * (1. + data.x * details) - delta * 2.);
const float t = 0.1;
float f = 0;
int c = 0;
if (up) {
f += stripe(uv1.x, -t * 0.5, t * 0.5) * step(-t * 0.5, uv1.y);
c += 1;
}
if (down) {
f += stripe(uv1.x, -t * 0.5, t * 0.5) * istep(t * 0.5, uv1.y);
c += 1;
}
if (left) {
f += stripe(uv1.y, -t * 0.5, t * 0.5) * istep(t * 0.5, uv1.x);
c += 1;
}
if (right) {
f += stripe(uv1.y, -t * 0.5, t * 0.5) * step(-t * 0.5, uv1.x);
c += 1;
}
if (c == 1) {
f += istep(t, length(uv1));
}
f = min(f, 1);
if ((up_down ^^ left_right) && c == 2) {
if (up_down) {
uv1.xy = uv1.yx;
}
if (rand(s0 + 3) < 0.5) {
uv1.x = -uv1.x;
}
float k = rand(s0 + 4) * 60;
f -= rect(uv1, vec2(0), vec2(t * 3, t));
f = max(0, f);
if (k < 10) { // resistor
f += line(uv1, vec2(-t * 3.25, -t * 0.5), vec2(-t * 2.5, t * 2), t * 0.75);
f += line(uv1, vec2(-t * 2.5, t * 2), vec2(-t * 1.5, -t * 2), t * 0.75);
f += line(uv1, vec2(-t * 1.5, -t * 2), vec2(-t * 0.5, t * 2), t * 0.75);
f += line(uv1, vec2(-t * 0.5, t * 2), vec2(t * 0.5, -t * 2), t * 0.75);
f += line(uv1, vec2(t * 0.5, -t * 2), vec2(t * 1.5, t * 2), t * 0.75);
f += line(uv1, vec2(t * 1.5, t * 2), vec2(t * 2.5, -t * 2), t * 0.75);
f += line(uv1, vec2(t * 2.5, -t * 2), vec2(t * 3.25, t * 0.5), t * 0.75);
} else if (k < 20) { // capacitor
f += rect(uv1, vec2(-t * 2, 0), vec2(t, t * 0.5));
f += rect(uv1, vec2(t * 2, 0), vec2(t, t * 0.5));
f += rect(uv1, vec2(t, 0), vec2(t * 0.5, t * 3.5));
f += rect(uv1, vec2(-t, 0), vec2(t * 0.5, t * 3.5));
} else if (k < 30) { // diode
f += line(uv1, vec2(-t * 2, t * 2.5), vec2(t * 2, 0), t);
f += line(uv1, vec2(-t * 2, -t * 2.5), vec2(t * 2, 0), t);
f += rect(uv1, vec2(t * 2.5, 0), vec2(t * 0.5, t * 3));
f += rect(uv1, vec2(-t * 2.5, 0), vec2(t * 0.5, t * 3));
} else if (k < 40) { // lamp
f += istep(t * 3.5, length(uv1));
f -= istep(t * 2.5, length(uv1));
f += line(uv1, vec2(-t * 2), vec2(t * 2), t);
f += line(uv1, vec2(-t * 2, t * 2), vec2(t * 2, -t * 2), t);
} else if (k < 50) { // inductor
f += istep(t * 2, length(uv1 - vec2(t * 2.5, 0)));
f += istep(t * 2, length(uv1 - vec2(0, 0)));
f += istep(t * 2, length(uv1 - vec2(-t * 2.5, 0)));
f -= 2 * istep(t, length(uv1 - vec2(t * 2.5, 0)));
f -= 2 * istep(t, length(uv1 - vec2(0, 0)));
f -= 2 * istep(t, length(uv1 - vec2(-t * 2.5, 0)));
f *= step(-t * 0.5, uv1.y);
} else if (k < 60) { // switch
f += istep(t, length(uv1 - vec2(t * 2.5, 0)));
f += istep(t, length(uv1 + vec2(t * 2.5, 0)));
f += line(uv1, vec2(t * 2, 0), vec2(-t * 2.5, t * (k < 55 ? 3 : 1)), t);
}
} else if (c == 3) {
if (left_right) {
uv1.xy = uv1.yx;
if (up) {
uv1.x = -uv1.x;
}
} else if (right) {
uv1.x = -uv1.x;
}
float k = rand(s0 + 4) * 20;
if (k < 10) {
f -= rect(uv1, vec2(0), vec2(t * 3));
f = max(0, f);
f += rect(uv1, vec2(-t * 3, 0), vec2(t * 0.5, t * 3));
f += line(uv1, vec2(t * 0.25, t * 3.25), vec2(-t * 3, t), t);
f += line(uv1, vec2(t * 0.25, -t * 3.25), vec2(-t * 3, -t), t);
}
}
return vec4(f); return vec4(f);
} }
// SRC 5 : noise // SRC 5 : noise
subroutine ( src_stage_sub ) vec4 src_5(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_5(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = magic(f1, b1, seed + 10); float zoom = magic(f1, b1, seed + 10.);
float voronoi_distort = magic(f2, b2, seed + 20); float voronoi_distort = magic(f2, b2, seed + 20.);
float details = magic(f3, b3, seed + 30); float details = magic(f3, b3, seed + 30.);
float noise_factor = magic(seed + 40); float noise_factor = magic(seed + 40.);
// logic // logic
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= zoom * 20 + 3; uv2 *= zoom * 20. + 3.;
uv2.x += iBeats; uv2.x += iBeats;
vec4 data = voronoi(uv2, voronoi_distort); vec4 data = voronoi(uv2, voronoi_distort, seed + 50, iBeats);
float f = data.x / (data.x + data.y); float f = data.x / (data.x + data.y);
f = sin(f * PI * (details * 20)) * 0.5 + 1; f = sin(f * PI * (details * 20.)) * .5 + 1.;
int nf = int(noise_factor * 6); int nf = int(noise_factor * 6.);
f *= mix(1, noise_f(uv2, nf - 1), step(0.0, float(nf))); f *= mix(1., noise_f(uv2, nf - 1), step(.0, float(nf)));
return vec4(f); return vec4(f);
} }
// SRC 6 : video in 1 + thru // SRC 6 : video in 1 + thru
subroutine ( src_stage_sub ) vec4 src_6(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_6(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
if (iDemo > 0) { if (iDemo > 0) {
return src_2(vUV, seed, b1, f1, b2, f2, b3, f3); return src_2(vUV, seed, b1, f1, b2, f2, b3, f3);
} }
return src_thru(vUV, iTex5, seed, b1, f1, b2, f2, b3, f3); return src_thru(vUV, iTex3, seed, b1, f1, b2, f2, b3, f3);
} }
#include inc_cp437.glsl
// SRC 7 : cp437 // SRC 7 : cp437
subroutine ( src_stage_sub ) vec4 src_7(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_7(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = magic(f1, b1, seed + 10); float zoom = magic(f1, b1, seed + 10.);
vec2 charset = magic_f(f2, b2, seed + 20); vec2 charset = magic_f(f2, b2, seed + 20.);
vec3 charset_ctrl = magic_b(b2, seed + 20); vec3 charset_ctrl = magic_b(b2, seed + 20.);
float char_delta = magic(f3, b3, seed + 30); float char_delta = magic(f3, b3, seed + 30.);
// logic // logic
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= zoom * 20 + 3; uv2 *= zoom * 20. + 3.;
uv2 += iBeats; uv2 += iBeats;
uv2 = mod(uv2, 100) + 100; uv2 = mod(uv2, 100.) + 100.;
int start_char = charset_ctrl.x > 0 ? charsets[int(charset.x * CHARSETS) * 2] : 0x01; int start_char = charset_ctrl.x > 0. ? charsets[int(charset.x * CHARSETS) * 2] : 0x01;
int char_span = int((charset_ctrl.x > 0 ? charsets[int(charset.x * CHARSETS) * 2 + 1] : 255)); int char_span = int((charset_ctrl.x > 0. ? charsets[int(charset.x * CHARSETS) * 2 + 1] : 255));
char_span = int(char_span * max(1 - charset.y, 1 / (char_span * 0.75))); char_span = int(char_span * max(1. - charset.y, 1. / (char_span * .75)));
ivec2 uv2i = ivec2(uv2); ivec2 uv2i = ivec2(uv2);
int code = ((charset_ctrl.y < 1 || (uv2i.x % 2 ^ uv2i.y % 2) > 0) ? 1 : 0) * (start_char + int((rand(uv2i) + char_delta) * char_span) % char_span); int code = ((charset_ctrl.y < 1. || (uv2i.x % 2 ^ uv2i.y % 2) > 0) ? 1 : 0) * (start_char + int((rand(uv2i) + char_delta) * char_span) % char_span);
uv2 = mod(uv2, 1); uv2 = mod(uv2, 1.);
float f = char(uv2, code) ? 1 : 0; float f = char(uv2, code) ? 1. : 0.;
return vec4(f); return vec4(f);
} }
// SRC 8 : sentences // SRC 8 : sentences
#include inc_sentences.glsl subroutine(src_stage_sub) vec4 src_8(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
subroutine ( src_stage_sub ) vec4 src_8(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = magic(f1, b1, seed + 10); float zoom = magic(f1, b1, seed + 10.);
float sentence = magic_reverse(f2, b2, seed + 20); float sentence = magic_reverse(f2, b2, seed + 20.);
float h_delta = magic(f3, b3, seed + 30); float h_delta = magic(f3, b3, seed + 30.);
vec3 h_delta_b = magic_b(b3, seed + 30); vec3 h_delta_b = magic_b(b3, seed + 30.);
// logic // logic
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= (1 + zoom) * 12; uv2 *= (1. + zoom) * 12.;
uv2.y += 0.5; uv2.y += .5;
int s = int(sentence * (SENTENCE_COUNT - 1)); int s = int(sentence * (SENTENCE_COUNT - 1));
uv2.x += floor(uv2.y) * (h_delta - 0.5) * 2; uv2.x += floor(uv2.y) * (h_delta - .5) * 2.;
uv2.y = mix(uv2.y, mod(uv2.y, 1), h_delta_b.x); uv2.y = mix(uv2.y, mod(uv2.y, 1.), h_delta_b.x);
float f = write_20(uv2, vec2(-float(lengths[s]) * 0.5, 0), sentences[s]); float f = write_sentence(uv2, vec2(-float(lengths[s]) * .5, 0.), s);
return vec4(f); return vec4(f);
} }
// SRC 9 : sentences repeat // SRC 9 : sentences repeat
subroutine ( src_stage_sub ) vec4 src_9(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_9(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float h_shift = magic(f1, b1, seed + 10); float h_shift = magic(f1, b1, seed + 10.);
float sentence = magic_reverse(f2, b2, seed + 20); float sentence = magic_reverse(f2, b2, seed + 20.);
float h_delta = magic(f3, b3, seed + 30); float h_delta = magic(f3, b3, seed + 30.);
vec3 h_delta_b = magic_b(b3, seed + 30); vec3 h_delta_b = magic_b(b3, seed + 30.);
// logic // logic
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2.x += h_shift; uv2.x += h_shift;
uv2 *= 15; uv2 *= 15.;
uv2.y += 0.5; uv2.y += .5;
int s = int(sentence * (SENTENCE_COUNT - 1)); int s = int(sentence * (SENTENCE_COUNT - 1));
float slen = float(lengths[s]); float slen = float(lengths[s]);
uv2.x += floor(uv2.y) * (h_delta - 0.5) * 2; uv2.x += floor(uv2.y) * (h_delta - .5) * 2.;
uv2.x = cmod(uv2.x, slen + 1); uv2.x = cmod(uv2.x, slen + 1.);
vec2 uv3 = uv2; vec2 uv3 = uv2;
uv3.y = mix(uv3.y, mod(uv3.y, 1), h_delta_b.x); uv3.y = mix(uv3.y, mod(uv3.y, 1.), h_delta_b.x);
float f = write_20(uv3, vec2(-slen * 0.5, 0), sentences[s]); float f = write_sentence(uv3, vec2(-slen * .5, 0.), s);
f *= (1 - abs(floor(uv2.y) * 0.125)) * (1 - abs(floor(uv2.y) * 0.125)); f *= (1. - abs(floor(uv2.y) * .125)) * (1. - abs(floor(uv2.y) * .125));
return vec4(f); return vec4(f);
} }
// SRC 10 : isometric grid // SRC 10 : isometric grid
subroutine ( src_stage_sub ) vec4 src_10(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_10(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = 5 + magic(f1, b1, seed + 10) * 15; float zoom = 5. + magic(f1, b1, seed + 10.) * 15.;
float h_scroll = magic(f2, b2, seed + 20); float h_scroll = magic(f2, b2, seed + 20.);
float max_elevation = magic(f3, b3, seed + 30) * 0.5; float max_elevation = magic(f3, b3, seed + 30.) * .5;
float thick = 0.1; float thick = .1;
// logic // logic
@@ -397,103 +293,103 @@ subroutine ( src_stage_sub ) vec4 src_10(vec2 vUV, int seed, vec3 b1, vec2 f1, v
vec2 uv3 = iso(uv2); vec2 uv3 = iso(uv2);
uv3 += vec2(h_scroll, 0); uv3 += vec2(h_scroll, 0.);
uv3 *= round(zoom); uv3 *= round(zoom);
vec2 umax = vec2(round(zoom), 300); vec2 umax = vec2(round(zoom), 300.);
vec2 u0 = mod(floor(uv3), umax); vec2 u0 = mod(floor(uv3), umax);
vec2 u1 = mod(floor(uv3 + vec2(1, 0)), umax); vec2 u1 = mod(floor(uv3 + vec2(1., 0.)), umax);
vec2 u2 = mod(floor(uv3 + vec2(0, 1)), umax); vec2 u2 = mod(floor(uv3 + vec2(0., 1.)), umax);
vec2 u3 = mod(floor(uv3 + vec2(-1, 0)), umax); vec2 u3 = mod(floor(uv3 + vec2(-1., 0.)), umax);
vec2 u4 = mod(floor(uv3 + vec2(0, -1)), umax); vec2 u4 = mod(floor(uv3 + vec2(0., -1.)), umax);
float e0 = (rand(floor(u0)) * 2 - 1) * max_elevation; float e0 = (rand(floor(u0)) * 2. - 1.) * max_elevation;
float e1 = (rand(floor(u1)) * 2 - 1) * max_elevation; float e1 = (rand(floor(u1)) * 2. - 1.) * max_elevation;
float e2 = (rand(floor(u2)) * 2 - 1) * max_elevation; float e2 = (rand(floor(u2)) * 2. - 1.) * max_elevation;
float e3 = (rand(floor(u3)) * 2 - 1) * max_elevation; float e3 = (rand(floor(u3)) * 2. - 1.) * max_elevation;
float e4 = (rand(floor(u4)) * 2 - 1) * max_elevation; float e4 = (rand(floor(u4)) * 2. - 1.) * max_elevation;
uv3 = mod(uv3, 1.0) - 0.5; uv3 = mod(uv3, 1.) - .5;
float f = 0; float f = 0.;
f = line(uv3, vec2(0, 0) - iso_z(e0), vec2(1, 0) - iso_z(e1), thick) f = line(uv3, vec2(0., 0.) - iso_z(e0), vec2(1., 0.) - iso_z(e1), thick)
+ line(uv3, vec2(0, 0) - iso_z(e0), vec2(0, 1) - iso_z(e2), thick) + line(uv3, vec2(0., 0.) - iso_z(e0), vec2(0., 1.) - iso_z(e2), thick)
+ line(uv3, vec2(0, 0) - iso_z(e0), vec2(-1, 0) - iso_z(e3), thick) + line(uv3, vec2(0., 0.) - iso_z(e0), vec2(-1., 0.) - iso_z(e3), thick)
+ line(uv3, vec2(0, 0) - iso_z(e0), vec2(0, -1) - iso_z(e4), thick); + line(uv3, vec2(0., 0.) - iso_z(e0), vec2(0., -1.) - iso_z(e4), thick);
return vec4(f); return vec4(f);
} }
// SRC 11 : video in 2 + thru // SRC 11 : video in 2 + thru
subroutine ( src_stage_sub ) vec4 src_11(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_11(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
if (iDemo > 0) { if (iDemo > 0) {
return src_3(vUV, seed, b1, f1, b2, f2, b3, f3); return src_3(vUV, seed, b1, f1, b2, f2, b3, f3);
} }
return src_thru(vUV, iTex6, seed, b1, f1, b2, f2, b3, f3); return src_thru(vUV, iTex4, seed, b1, f1, b2, f2, b3, f3);
} }
// SRC 12 : Scales // SRC 12 : Scales
subroutine ( src_stage_sub ) vec4 src_12(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_12(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = 5 + magic(f1, b1, seed + 10) * 15; float zoom = 5. + magic(f1, b1, seed + 10.) * 15.;
float shape = magic(f2, b2, seed + 20); float shape = magic(f2, b2, seed + 20.);
float repeat = 1 + magic(f3, b3, seed + 30) * 10; float repeat = 1. + magic(f3, b3, seed + 30.) * 10.;
// logic // logic
float f = 0; float f = 0.;
vec2 uv2 = uv1; vec2 uv2 = uv1;
uv2 *= zoom; uv2 *= zoom;
uv2 = mod(uv2, 4); uv2 = mod(uv2, 4.);
vec2 uv3 = uv2; vec2 uv3 = uv2;
uv3.y = mix(uv3.y, -uv3.y, step(2, uv2.x) * step(2, uv2.y)); uv3.y = mix(uv3.y, -uv3.y, step(2., uv2.x) * step(2., uv2.y));
uv3.y = mix(uv3.y, -uv3.y, istep(2, uv2.x) * istep(2, uv2.y)); uv3.y = mix(uv3.y, -uv3.y, istep(2., uv2.x) * istep(2., uv2.y));
uv3.y = -uv3.y; uv3.y = -uv3.y;
uv3.x = mix(-uv3.x, uv3.x, istep(3, uv2.x) * step(1, uv2.x)); uv3.x = mix(-uv3.x, uv3.x, istep(3., uv2.x) * step(1., uv2.x));
uv3.x = mix(-uv3.x, uv3.x, istep(3, uv2.y) * step(1, uv2.y)); uv3.x = mix(-uv3.x, uv3.x, istep(3., uv2.y) * step(1., uv2.y));
f = istep(0.5, saw((length(mod(uv3, 1)) + shape + 0.5) * repeat)); f = istep(.5, saw((length(mod(uv3, 1.)) + shape + .5) * repeat));
f = mix(1 - f, f, istep(1, abs(uv2.y - 2)) * istep(2, uv2.x)); f = mix(1. - f, f, istep(1., abs(uv2.y - 2.)) * istep(2., uv2.x));
f = mix(1 - f, f, step(1, abs(uv2.y - 2)) * step(2, uv2.x)); f = mix(1. - f, f, step(1., abs(uv2.y - 2.)) * step(2., uv2.x));
return vec4(f); return vec4(f);
} }
// SRC 13 : Credenza // SRC 13 : Credenza
subroutine ( src_stage_sub ) vec4 src_13(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_13(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float zoom = 5 + magic(f1, b1, seed + 10) * 15; float zoom = 5. + magic(f1, b1, seed + 10.) * 15.;
float shape = 0.1 + magic(f2, b2, seed + 20) * 0.9; float shape = .1 + magic(f2, b2, seed + 20.) * .9;
float repeat = 1 + magic(f3, b3, seed + 30) * 10; float repeat = 1. + magic(f3, b3, seed + 30.) * 10.;
// logic // logic
@@ -501,33 +397,33 @@ subroutine ( src_stage_sub ) vec4 src_13(vec2 vUV, int seed, vec3 b1, vec2 f1, v
uv2 *= zoom; uv2 *= zoom;
uv2 = mod(uv2, 2); uv2 = mod(uv2, 2.);
uv2 = abs(uv2 - 1); uv2 = abs(uv2 - 1.);
float f = istep(1, length(uv2)) * istep(1, length(1 - uv2)); float f = istep(1., length(uv2)) * istep(1., length(1. - uv2));
f *= istep(0.5, saw((length(uv2) + shape + 0.5) * repeat)) * istep(0.5, saw((length(1 - uv2) + shape + 0.5) * repeat)); f *= istep(.5, saw((length(uv2) + shape + .5) * repeat)) * istep(.5, saw((length(1. - uv2) + shape + .5) * repeat));
return vec4(f); return vec4(f);
} }
// SRC 14 : Cursor // SRC 14 : Cursor
subroutine ( src_stage_sub ) vec4 src_14(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_14(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
// start // start
vec2 uv0 = vUV.st; vec2 uv0 = vUV.st;
float ratio = iResolution.x / iResolution.y; float ratio = iResolution.x / iResolution.y;
vec2 uv1 = (uv0 - .5) * vec2(ratio, 1); vec2 uv1 = (uv0 - .5) * vec2(ratio, 1.);
// controls // controls
float size = magic(f1, b1, seed + 10) * 2 + 0.1; float size = magic(f1, b1, seed + 10.) * 2. + .1;
float dx = (fmagic(f2, b2, seed + 20) * (1 - size * 0.06) - 0.5) * ratio; float dx = (fmagic(f2, b2, seed + 20.) * (1. - size * .06) - .5) * ratio;
bool flip_x = magic_trigger(b2, seed + 20); bool flip_x = magic_trigger(b2, seed + 20.);
float dy = fmagic(f3, b3, seed + 30) * (1 - size * 0.17) - 0.5; float dy = fmagic(f3, b3, seed + 30.) * (1. - size * .17) - .5;
bool flip_y = magic_trigger(b3, seed + 30); bool flip_y = magic_trigger(b3, seed + 30.);
// logic // logic
@@ -545,49 +441,49 @@ subroutine ( src_stage_sub ) vec4 src_14(vec2 vUV, int seed, vec3 b1, vec2 f1, v
uv2 /= size; uv2 /= size;
uv2 *= -rot(-PI / 2); uv2 *= -rot(-PI * 0.5);
float f = istep(0, (uv2.x * 2 + uv2.y) * (uv2.x * 2 - uv2.y)) * istep(0, uv2.y); float f = istep(0., (uv2.x * 2. + uv2.y) * (uv2.x * 2. - uv2.y)) * istep(0., uv2.y);
uv2.y += 0.1; uv2.y += .1;
f -= istep(0, (uv2.x + uv2.y * 3) * (uv2.x - uv2.y * 3)) * istep(0, uv2.y); f -= istep(0., (uv2.x + uv2.y * 3.) * (uv2.x - uv2.y * 3.)) * istep(0., uv2.y);
f += rect(uv2, vec2(0, -0.04), vec2(0.01, 0.04)); f += rect(uv2, vec2(0., -.04), vec2(.01, .04));
return vec4(f); return vec4(f);
} }
// SRC 15 : Random // SRC 15 : Random
subroutine ( src_stage_sub ) vec4 src_15(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3) subroutine(src_stage_sub) vec4 src_15(vec2 vUV, int seed, vec3 b1, vec2 f1, vec3 b2, vec2 f2, vec3 b3, vec2 f3)
{ {
int src = int(randTime(seed + 100) * 14); int src = int(randTime(seed + 100.) * 14.) + 1;
if (src == 0) { if (src == 1) {
return src_1(vUV, seed, b1, f1, b2, f2, b3, f3); return src_1(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 1) {
return src_2(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 2) { } else if (src == 2) {
return src_3(vUV, seed, b1, f1, b2, f2, b3, f3); return src_2(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 3) { } else if (src == 3) {
return src_4(vUV, seed, b1, f1, b2, f2, b3, f3); return src_3(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 4) { } else if (src == 4) {
return src_5(vUV, seed, b1, f1, b2, f2, b3, f3); return src_4(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 5) { } else if (src == 5) {
return src_6(vUV, seed, b1, f1, b2, f2, b3, f3); return src_5(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 6) { } else if (src == 6) {
return src_7(vUV, seed, b1, f1, b2, f2, b3, f3); return src_6(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 7) { } else if (src == 7) {
return src_8(vUV, seed, b1, f1, b2, f2, b3, f3); return src_7(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 8) { } else if (src == 8) {
return src_9(vUV, seed, b1, f1, b2, f2, b3, f3); return src_8(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 9) { } else if (src == 9) {
return src_10(vUV, seed, b1, f1, b2, f2, b3, f3); return src_9(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 10) { } else if (src == 10) {
return src_11(vUV, seed, b1, f1, b2, f2, b3, f3); return src_10(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 11) { } else if (src == 11) {
return src_12(vUV, seed, b1, f1, b2, f2, b3, f3); return src_11(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 12) { } else if (src == 12) {
return src_12(vUV, seed, b1, f1, b2, f2, b3, f3);
} else if (src == 13) {
return src_13(vUV, seed, b1, f1, b2, f2, b3, f3); return src_13(vUV, seed, b1, f1, b2, f2, b3, f3);
} else { } else {
return src_14(vUV, seed, b1, f1, b2, f2, b3, f3); return src_14(vUV, seed, b1, f1, b2, f2, b3, f3);
+11 -11
View File
@@ -21,33 +21,33 @@ float randTime(float seed){
float divider(float x) float divider(float x)
{ {
if (x < 0.1) return 0; if (x < .1) return 0.;
if (x < 0.2) return 0.125; if (x < .2) return .125;
if (x < 0.3) return 0.25; if (x < .3) return .25;
if (x < 0.4) return 0.5; if (x < .4) return .5;
if (x < 0.6) return 1; if (x < .6) return 1.;
if (x < 0.8) return 2; if (x < .8) return 2.;
return 4; return 4.;
} }
float modTime(float k, float k2) float modTime(float k, float k2)
{ {
return mod(divider(k) * iBeats * k2 / 4, 1); return mod(divider(k) * iBeats * k2 * .25, 1.);
} }
float modTime(float k) float modTime(float k)
{ {
return modTime(k, 1.0); return modTime(k, 1.);
} }
float sinTime(float k) float sinTime(float k)
{ {
return sin(modTime(k, 0.5) * 2 * PI); return sin(modTime(k, .5) * 2. * PI);
} }
float cosTime(float k) float cosTime(float k)
{ {
return cos(modTime(k, 0.5) * 2 * PI); return cos(modTime(k, .5) * 2. * PI);
} }
#endif #endif
+10 -10
View File
@@ -3,26 +3,26 @@
const int YUYV_FOURCC = 1448695129; const int YUYV_FOURCC = 1448695129;
const mat3x3 yuyv_to_rgb = {{1,1,1},{0,-0.39465,2.03211},{1.13983,-0.5806,0}}; // https://en.wikipedia.org/wiki/Y%E2%80%B2UV
const mat3x3 yuyv_to_rgb_bt709 = mat3x3(1., 1., 1., 0., -.21482, 2.12798, 1.28033, -.38059, 0.);
vec4 yuyvTex(sampler2D tex, vec2 vUV, int base_width) { vec4 yuyvTex(sampler2D tex, vec2 vUV, int base_width) {
float w = base_width - 1; float w = base_width - 1.;
int x = int(vUV.x * w); int x = int(vUV.x * w);
int xU = x - x % 2; int xU = x - x % 2;
int xV = x - x % 2 + 1; int xV = x - x % 2 + 1;
vec4 tU = texture(tex, vec2(xU / w, 1 - vUV.y)); vec4 tU = texture(tex, vec2(xU / w, 1. - vUV.y));
vec4 tV = texture(tex, vec2(xV / w, 1 - vUV.y)); vec4 tV = texture(tex, vec2(xV / w, 1. - vUV.y));
vec3 yuv = vec3( vec3 yuv = vec3(
x % 2 == 0 ? tU.x : tV.x, x % 2 == 0. ? tU.x : tV.x,
tU.y - 0.5, tU.y - .5,
tV.y - 0.5 tV.y - .5
); );
return vec4(yuyv_to_rgb * yuv, 1.0); return vec4(yuyv_to_rgb_bt709 * yuv, 1.);
} }
#endif #endif
Binary file not shown.
+9 -4
View File
@@ -1,11 +1,11 @@
/** /**
* Loader generated by glad 2.0.8 on Wed May 13 21:57:23 2026 * Loader generated by glad 2.0.8 on Thu Aug 27 15:42:48 2026
* *
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
* *
* Generator: C/C++ * Generator: C/C++
* Specification: gl * Specification: gl
* Extensions: 4 * Extensions: 5
* *
* APIs: * APIs:
* - gl:compatibility=4.6 * - gl:compatibility=4.6
@@ -19,10 +19,10 @@
* - ON_DEMAND = False * - ON_DEMAND = False
* *
* Commandline: * Commandline:
* --api='gl:compatibility=4.6' --extensions='GL_ARB_direct_state_access,GL_EXT_EGL_image_storage,GL_EXT_direct_state_access,GL_KHR_debug' c --header-only --loader * --api='gl:compatibility=4.6' --extensions='GL_ARB_arrays_of_arrays,GL_ARB_direct_state_access,GL_EXT_EGL_image_storage,GL_EXT_direct_state_access,GL_KHR_debug' c --header-only --loader
* *
* Online: * Online:
* http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=GL_ARB_direct_state_access%2CGL_EXT_EGL_image_storage%2CGL_EXT_direct_state_access%2CGL_KHR_debug&generator=c&options=HEADER_ONLY%2CLOADER * http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=GL_ARB_arrays_of_arrays%2CGL_ARB_direct_state_access%2CGL_EXT_EGL_image_storage%2CGL_EXT_direct_state_access%2CGL_KHR_debug&generator=c&options=HEADER_ONLY%2CLOADER
* *
*/ */
@@ -2403,6 +2403,8 @@ GLAD_API_CALL int GLAD_GL_VERSION_4_4;
GLAD_API_CALL int GLAD_GL_VERSION_4_5; GLAD_API_CALL int GLAD_GL_VERSION_4_5;
#define GL_VERSION_4_6 1 #define GL_VERSION_4_6 1
GLAD_API_CALL int GLAD_GL_VERSION_4_6; GLAD_API_CALL int GLAD_GL_VERSION_4_6;
#define GL_ARB_arrays_of_arrays 1
GLAD_API_CALL int GLAD_GL_ARB_arrays_of_arrays;
#define GL_ARB_direct_state_access 1 #define GL_ARB_direct_state_access 1
GLAD_API_CALL int GLAD_GL_ARB_direct_state_access; GLAD_API_CALL int GLAD_GL_ARB_direct_state_access;
#define GL_EXT_EGL_image_storage 1 #define GL_EXT_EGL_image_storage 1
@@ -6395,6 +6397,7 @@ int GLAD_GL_VERSION_4_3 = 0;
int GLAD_GL_VERSION_4_4 = 0; int GLAD_GL_VERSION_4_4 = 0;
int GLAD_GL_VERSION_4_5 = 0; int GLAD_GL_VERSION_4_5 = 0;
int GLAD_GL_VERSION_4_6 = 0; int GLAD_GL_VERSION_4_6 = 0;
int GLAD_GL_ARB_arrays_of_arrays = 0;
int GLAD_GL_ARB_direct_state_access = 0; int GLAD_GL_ARB_direct_state_access = 0;
int GLAD_GL_EXT_EGL_image_storage = 0; int GLAD_GL_EXT_EGL_image_storage = 0;
int GLAD_GL_EXT_direct_state_access = 0; int GLAD_GL_EXT_direct_state_access = 0;
@@ -9290,6 +9293,7 @@ static int glad_gl_find_extensions_gl(void) {
char **exts_i = NULL; char **exts_i = NULL;
if (!glad_gl_get_extensions(&exts, &exts_i)) return 0; if (!glad_gl_get_extensions(&exts, &exts_i)) return 0;
GLAD_GL_ARB_arrays_of_arrays = glad_gl_has_extension(exts, exts_i, "GL_ARB_arrays_of_arrays");
GLAD_GL_ARB_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_ARB_direct_state_access"); GLAD_GL_ARB_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_ARB_direct_state_access");
GLAD_GL_EXT_EGL_image_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_image_storage"); GLAD_GL_EXT_EGL_image_storage = glad_gl_has_extension(exts, exts_i, "GL_EXT_EGL_image_storage");
GLAD_GL_EXT_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_EXT_direct_state_access"); GLAD_GL_EXT_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_EXT_direct_state_access");
@@ -9571,3 +9575,4 @@ void gladLoaderUnloadGL(void) {
#endif #endif
#endif /* GLAD_GL_IMPLEMENTATION */ #endif /* GLAD_GL_IMPLEMENTATION */
+12 -9
View File
@@ -6,6 +6,8 @@ TARGET_FILE = os.path.join(
os.path.dirname(__file__), "..", "default", "inc_sentences.glsl" os.path.dirname(__file__), "..", "default", "inc_sentences.glsl"
) )
SENTENCE_MAX_LENGTH = 20
SENTENCES = [ SENTENCES = [
"forge", "forge",
"FORGE", "FORGE",
@@ -37,25 +39,26 @@ def code(char: str) -> str:
def convert(txt: str) -> str: def convert(txt: str) -> str:
out = [] out = []
for i in range(20): for i in range(SENTENCE_MAX_LENGTH):
out += [code(txt[i]) if i < len(txt) else "0x00"] out += [code(txt[i]) if i < len(txt) else "0x00"]
return f"{{{', '.join(out)}}}" return ', '.join(out)
def main() -> None: def main() -> None:
with open(TARGET_FILE, mode="w") as file: with open(TARGET_FILE, mode="w") as file:
file.write("#ifndef INC_SENTENCES\n") file.write("#ifndef INC_SENTENCES\n")
file.write("#define INC_SENTENCES\n\n") file.write("#define INC_SENTENCES\n\n")
file.write(f"#define SENTENCE_COUNT {len(SENTENCES)}\n\n") file.write(f"#define SENTENCE_COUNT {len(SENTENCES)}\n")
file.write("const int sentences[SENTENCE_COUNT][20] = {\n") file.write(f"#define SENTENCE_MAX_LENGTH {SENTENCE_MAX_LENGTH}\n\n")
for sentence in SENTENCES: file.write("const int sentences[] = int[SENTENCE_COUNT * SENTENCE_MAX_LENGTH](\n")
file.write(" " + convert(sentence) + "," + "\n") for i, sentence in enumerate(SENTENCES):
file.write("};\n\n") file.write(" " + convert(sentence) + ("," if i < len(SENTENCES) - 1 else "") + "\n")
file.write("const int lengths[SENTENCE_COUNT] = {\n") file.write(");\n\n")
file.write("const int lengths[] = int[SENTENCE_COUNT](\n")
file.write( file.write(
" " + ", ".join(str(len(sentence)) for sentence in SENTENCES) + "\n" " " + ", ".join(str(len(sentence)) for sentence in SENTENCES) + "\n"
) )
file.write("};\n") file.write(");\n")
file.write("#endif") file.write("#endif")
+69 -4
View File
@@ -11,6 +11,9 @@
#include "config.h" #include "config.h"
#include "string.h" #include "string.h"
#define STR_IMPL_(x) #x // stringify argument
#define STR(x) STR_IMPL_(x) // indirection to expand argument macros
static void print_help(int status_code) { static void print_help(int status_code) {
puts( puts(
PACKAGE PACKAGE
@@ -34,6 +37,7 @@ static void print_help(int status_code) {
"[-vs=SIZE] " "[-vs=SIZE] "
"[-vb=COUNT] " "[-vb=COUNT] "
"[-vr / -nvr] " "[-vr / -nvr] "
"[-vf=FOURCC] "
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
"[-is=SIZE] " "[-is=SIZE] "
"[-ls / -nls] " "[-ls / -nls] "
@@ -41,6 +45,13 @@ static void print_help(int status_code) {
"[-mr / -nmr] " "[-mr / -nmr] "
"[-tm] " "[-tm] "
"[-tf] " "[-tf] "
"[--x11] "
"[--wayland] "
"[--cocoa] "
"[--win32] "
"[-as / -nas] "
"[-oma=MAJOR] "
"[-omi=MINOR] "
"\n\n" "\n\n"
"Fusion Of Real-time Generative Effects.\n\n" "Fusion Of Real-time Generative Effects.\n\n"
"options:\n" "options:\n"
@@ -65,21 +76,34 @@ static void print_help(int status_code) {
" -vi, --video-in path to video capture device (multiple " " -vi, --video-in path to video capture device (multiple "
"allowed)\n" "allowed)\n"
" -vb, --video-buffers number of video buffers to use (default: " " -vb, --video-buffers number of video buffers to use (default: "
"2)\n" "1)\n"
" -vs, --video-size video capture desired height (default: " " -vs, --video-size video capture desired height (default: "
"internal texture height)\n" "internal texture height)\n"
" -vr, --video-reconnect auto-reconnect video (default)\n" " -vr, --video-reconnect auto-reconnect video (default)\n"
" -nvr, --no-video-reconnect do not auto-reconnect video\n" " -nvr, --no-video-reconnect do not auto-reconnect video\n"
" -vf, --video-fourcc video codec fourcc (default: YUYV)\n"
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
" -is, --internal-size internal texture height (default: 720)\n" " -is, --internal-size internal texture height (default: 720)\n"
" -ls, --load-state load saved state (default)\n" " -ls, --load-state load saved state (default)\n"
" -nls, --no-load-state do not load saved state\n" " -nls, --no-load-state do not load saved state\n"
" -ss, --save-state save state (default)\n" " -ss, --save-state save state (default)\n"
" -nss, --no-save-state do not save state\n" " -nss, --no-save-state do not save state\n"
" -as, --auto-save continuously save state (every ~10ms)\n"
" -nas, --no-auto-save do not continuously save state (default)\n"
" -mr, --midi-reconnect auto-reconnect midi (default)\n" " -mr, --midi-reconnect auto-reconnect midi (default)\n"
" -nmr, --no-midi-reconnect do not auto-reconnect midi\n" " -nmr, --no-midi-reconnect do not auto-reconnect midi\n"
" -tm, --trace-midi print midi code and values\n" " -tm, --trace-midi print midi code and values\n"
" -tf, --trace-fps print fps status of subsystems\n"); " -tf, --trace-fps print fps status of subsystems\n"
" --x11 force X11 GLFW backend\n"
" --wayland force Wayland GLFW backend\n"
" --cocoa force Cocoa GLFW backend\n"
" --win32 force Win32 GLFW backend\n"
" -oma, --opengl-major-version OpenGL major version "
"(default: " STR(
OPENGL_MAJOR_VERSION) ")\n"
" -omi, --opengl-minor-version OpenGL "
"minor version (default: " STR(
OPENGL_MINOR_VERSION) ")\n");
exit(status_code); exit(status_code);
} }
@@ -114,7 +138,7 @@ static unsigned int parse_uint(const char *arg, const char *value) {
tmp_value = (unsigned long long)atoll(value); tmp_value = (unsigned long long)atoll(value);
if (tmp_value >= UINT_MAX) { if (tmp_value > UINT_MAX) {
invalid_value(arg, value); invalid_value(arg, value);
} }
@@ -139,16 +163,21 @@ void args_parse(Parameters *params, int argc, char **argv) {
params->auto_random_cycle = 4; params->auto_random_cycle = 4;
#ifdef VIDEO_IN #ifdef VIDEO_IN
params->video_in.length = 0; params->video_in.length = 0;
params->video_buffers = 2; params->video_buffers = 1;
params->video_size = 0; params->video_size = 0;
params->video_reconnect = true; params->video_reconnect = true;
strlcpy(params->video_fourcc, "YUYV", 5);
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
params->internal_size = 720; params->internal_size = 720;
params->load_state = true; params->load_state = true;
params->save_state = true; params->save_state = true;
params->auto_save = false;
params->midi_reconnect = true; params->midi_reconnect = true;
params->trace_midi = false; params->trace_midi = false;
params->trace_fps = false; params->trace_fps = false;
params->glfw_backend = GLFW_BACKEND_ANY;
params->opengl_major = OPENGL_MAJOR_VERSION;
params->opengl_minor = OPENGL_MINOR_VERSION;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
arg = argv[i]; arg = argv[i];
@@ -159,8 +188,14 @@ void args_parse(Parameters *params, int argc, char **argv) {
puts(PACKAGE " " VERSION); puts(PACKAGE " " VERSION);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (is_arg(arg, "-p") || is_arg(arg, "--project")) { } else if (is_arg(arg, "-p") || is_arg(arg, "--project")) {
if (strlen(value) == 0) {
invalid_value(arg, value);
}
strlcpy(params->project_path, value, STR_LEN); strlcpy(params->project_path, value, STR_LEN);
} else if (is_arg(arg, "-c") || is_arg(arg, "--config")) { } else if (is_arg(arg, "-c") || is_arg(arg, "--config")) {
if (strlen(value) == 0) {
invalid_value(arg, value);
}
strlcpy(params->config_file, value, STR_LEN); strlcpy(params->config_file, value, STR_LEN);
} else if (is_arg(arg, "-hr") || is_arg(arg, "--hot-reload")) { } else if (is_arg(arg, "-hr") || is_arg(arg, "--hot-reload")) {
params->hot_reload = true; params->hot_reload = true;
@@ -203,6 +238,10 @@ void args_parse(Parameters *params, int argc, char **argv) {
params->save_state = true; params->save_state = true;
} else if (is_arg(arg, "-nss") || is_arg(arg, "--no-save-state")) { } else if (is_arg(arg, "-nss") || is_arg(arg, "--no-save-state")) {
params->save_state = false; params->save_state = false;
} else if (is_arg(arg, "-as") || is_arg(arg, "--auto-save")) {
params->auto_save = true;
} else if (is_arg(arg, "-nas") || is_arg(arg, "--no-auto-save")) {
params->auto_save = false;
} else if (is_arg(arg, "-mr") || is_arg(arg, "--midi-reconnect")) { } else if (is_arg(arg, "-mr") || is_arg(arg, "--midi-reconnect")) {
params->midi_reconnect = true; params->midi_reconnect = true;
} else if (is_arg(arg, "-nmr") || is_arg(arg, "--no-midi-reconnect")) { } else if (is_arg(arg, "-nmr") || is_arg(arg, "--no-midi-reconnect")) {
@@ -211,6 +250,24 @@ void args_parse(Parameters *params, int argc, char **argv) {
params->trace_midi = true; params->trace_midi = true;
} else if (is_arg(arg, "-tf") || is_arg(arg, "--trace-fps")) { } else if (is_arg(arg, "-tf") || is_arg(arg, "--trace-fps")) {
params->trace_fps = true; params->trace_fps = true;
} else if (is_arg(arg, "--x11")) {
params->glfw_backend = GLFW_BACKEND_X11;
} else if (is_arg(arg, "--wayland")) {
params->glfw_backend = GLFW_BACKEND_WAYLAND;
} else if (is_arg(arg, "--cocoa")) {
params->glfw_backend = GLFW_BACKEND_COCOA;
} else if (is_arg(arg, "--win32")) {
params->glfw_backend = GLFW_BACKEND_WIN32;
} else if (is_arg(arg, "-oma") || is_arg(arg, "--opengl-major-version")) {
params->opengl_major = parse_uint(arg, value);
if (params->opengl_major == 0) {
invalid_value(arg, value);
}
} else if (is_arg(arg, "-omi") || is_arg(arg, "--opengl-minor-version")) {
params->opengl_minor = parse_uint(arg, value);
if (params->opengl_major == 0) {
invalid_value(arg, value);
}
} else { } else {
#ifdef VIDEO_IN #ifdef VIDEO_IN
if (is_arg(arg, "-vi") || is_arg(arg, "--video-in")) { if (is_arg(arg, "-vi") || is_arg(arg, "--video-in")) {
@@ -218,6 +275,9 @@ void args_parse(Parameters *params, int argc, char **argv) {
log_error("maximum video input reached"); log_error("maximum video input reached");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (strlen(value) == 0) {
invalid_value(arg, value);
}
strlcpy(params->video_in.values[params->video_in.length++], value, strlcpy(params->video_in.values[params->video_in.length++], value,
STR_LEN); STR_LEN);
} else if (is_arg(arg, "-vb") || is_arg(arg, "--video-buffers")) { } else if (is_arg(arg, "-vb") || is_arg(arg, "--video-buffers")) {
@@ -234,6 +294,11 @@ void args_parse(Parameters *params, int argc, char **argv) {
params->video_reconnect = true; params->video_reconnect = true;
} else if (is_arg(arg, "-nvr") || is_arg(arg, "--no-video-reconnect")) { } else if (is_arg(arg, "-nvr") || is_arg(arg, "--no-video-reconnect")) {
params->video_reconnect = false; params->video_reconnect = false;
} else if (is_arg(arg, "-vf") || is_arg(arg, "--video-fourcc")) {
if (strlen(value) == 0) {
invalid_value(arg, value);
}
strlcpy(params->video_fourcc, value, 5);
} else { } else {
invalid_arg(arg); invalid_arg(arg);
} }
+14
View File
@@ -12,7 +12,21 @@ unsigned int arr_uint_index_of(UintArray array, unsigned int value) {
return ARRAY_NOT_FOUND; return ARRAY_NOT_FOUND;
} }
bool arr_string_match(StringArray array, const char *needle) {
for (unsigned int i = 0; i < array.length; i++) {
if (strncmp(array.values[i], needle, strlen(array.values[i])) == 0) {
return true;
}
}
return false;
}
unsigned int arr_uint_remap_index(UintArray offsets, unsigned int *index) { unsigned int arr_uint_remap_index(UintArray offsets, unsigned int *index) {
if (offsets.length == 0) {
return 0;
}
for (unsigned int i = offsets.length - 1; i > 0; i--) { for (unsigned int i = offsets.length - 1; i > 0; i--) {
if (*index >= offsets.values[i]) { if (*index >= offsets.values[i]) {
*index -= offsets.values[i]; *index -= offsets.values[i];
+2
View File
@@ -7,4 +7,6 @@ unsigned int arr_uint_index_of(UintArray array, unsigned int value);
unsigned int arr_uint_remap_index(UintArray offsets, unsigned int *index); unsigned int arr_uint_remap_index(UintArray offsets, unsigned int *index);
bool arr_string_match(StringArray array, const char *needle);
#endif /* ARR_H */ #endif /* ARR_H */
+26
View File
@@ -87,4 +87,30 @@
#define MAX_TAP_VALUES 10 #define MAX_TAP_VALUES 10
#endif #endif
/* STATE */
#ifndef STATE_AUTO_SAVE_SECONDS
#define STATE_AUTO_SAVE_SECONDS 0.1
#endif
/* OPENGL */
#ifndef OPENGL_MAJOR_VERSION
#define OPENGL_MAJOR_VERSION 4
#endif
#ifndef OPENGL_MINOR_VERSION
#define OPENGL_MINOR_VERSION 6
#endif
/* GLFW CONSTANTS */
#ifndef GLFW_BACKENDS
#define GLFW_BACKEND_ANY 0
#define GLFW_BACKEND_X11 1
#define GLFW_BACKEND_WAYLAND 2
#define GLFW_BACKEND_COCOA 3
#define GLFW_BACKEND_WIN32 4
#endif
#endif /* CONFIG_H */ #endif /* CONFIG_H */
+9 -3
View File
@@ -68,8 +68,7 @@ void config_file_read(ConfigFile *config, const char *path) {
char *line; char *line;
char *rest; char *rest;
config->map = hashmap_new(sizeof(ConfigFileItem), 0, 0, 0, item_hash, config->map = NULL;
item_compare, NULL, NULL);
file_read(&file, path); file_read(&file, path);
@@ -78,6 +77,9 @@ void config_file_read(ConfigFile *config, const char *path) {
return; return;
} }
config->map = hashmap_new(sizeof(ConfigFileItem), 0, 0, 0, item_hash,
item_compare, NULL, NULL);
config->error = false; config->error = false;
line = strtok_r(file.content, "\n", &rest); line = strtok_r(file.content, "\n", &rest);
@@ -138,4 +140,8 @@ unsigned int config_file_get_int(const ConfigFile *config, const char *key,
return (unsigned int)atoi(item->value); return (unsigned int)atoi(item->value);
} }
void config_file_free(const ConfigFile *config) { hashmap_free(config->map); } void config_file_free(const ConfigFile *config) {
if (config->map != NULL) {
hashmap_free(config->map);
}
}
+3 -3
View File
@@ -3,10 +3,10 @@
#ifndef CONSTANTS_H #ifndef CONSTANTS_H
#define CONSTANTS_H #define CONSTANTS_H
static char *vertex_shader_text = static const char *vertex_shader_text =
"#version 460\n" "#version 140\n"
"const mat4 mvp = " "const mat4 mvp = "
"{{2.,0.,0.,0.},{0.,2.,0.,0.},{0.,0.,2.,0.},{-1.,-1.,1.,1.}};\n" "mat4(vec4(2.,0.,0.,0.),vec4(0.,2.,0.,0.),vec4(0.,0.,2.,0.),vec4(-1.,-1.,1.,1.));\n"
"in vec2 vPos;\n" "in vec2 vPos;\n"
"out vec2 vUV;\n" "out vec2 vUV;\n"
"void main()\n" "void main()\n"
+21 -5
View File
@@ -26,6 +26,7 @@ bool file_should_update(const File *file) {
bool file_update(File *file) { bool file_update(File *file) {
long length; long length;
size_t read_length;
FILE *file_pointer; FILE *file_pointer;
// free remaining data // free remaining data
@@ -47,6 +48,12 @@ bool file_update(File *file) {
// read file length // read file length
fseek(file_pointer, 0, SEEK_END); fseek(file_pointer, 0, SEEK_END);
length = ftell(file_pointer); length = ftell(file_pointer);
if (length == -1L) {
file->error = true;
fclose(file_pointer);
log_error("Cannot get file length for '%s'", file->path);
return false;
}
// init buffer // init buffer
fseek(file_pointer, 0, SEEK_SET); fseek(file_pointer, 0, SEEK_SET);
file->content = malloc(length + 1); file->content = malloc(length + 1);
@@ -57,7 +64,13 @@ bool file_update(File *file) {
return false; return false;
} }
// read file // read file
fread(file->content, sizeof(char), length, file_pointer); read_length = fread(file->content, sizeof(char), length, file_pointer);
if (read_length != (unsigned)length) {
file->error = true;
fclose(file_pointer);
log_error("Cannot read complete file '%s'", file->path);
return false;
}
// close file // close file
fclose(file_pointer); fclose(file_pointer);
// append null byte // append null byte
@@ -96,10 +109,12 @@ void file_dump(const char *path, const char *content) {
fclose(file_pointer); fclose(file_pointer);
} }
void file_write(const char *path, const StringArray *lines) { void file_write(const char *path, const StringArray *lines, const bool log) {
FILE *file_pointer; FILE *file_pointer;
log_info("Writing %s...", path); if (log) {
log_info("Writing %s...", path);
}
// open file // open file
file_pointer = fopen(path, "w"); file_pointer = fopen(path, "w");
@@ -117,8 +132,9 @@ void file_write(const char *path, const StringArray *lines) {
fclose(file_pointer); fclose(file_pointer);
} }
void file_free(const File *file) { void file_free(File *file) {
if (!file->error) { if (!file->error && file->content != NULL) {
free(file->content); free(file->content);
file->content = NULL;
} }
} }
+2 -2
View File
@@ -9,10 +9,10 @@ bool file_should_update(const File *file);
bool file_update(File *file); bool file_update(File *file);
void file_write(const char *path, const StringArray *lines); void file_write(const char *path, const StringArray *lines, const bool log);
void file_dump(const char *path, const char *content); void file_dump(const char *path, const char *content);
void file_free(const File *file); void file_free(File *file);
#endif /* FILE_H */ #endif /* FILE_H */
+58 -28
View File
@@ -85,7 +85,8 @@ static void init_inputs() {
for (unsigned int i = 0; i < init_params.video_in.length; i++) { for (unsigned int i = 0; i < init_params.video_in.length; i++) {
video_init(&video_captures.values[i], init_params.video_in.values[i], video_init(&video_captures.values[i], init_params.video_in.values[i],
init_params.video_size, init_params.video_buffers); init_params.video_size, init_params.video_buffers,
init_params.video_fourcc, true);
if (!video_captures.values[i].error) { if (!video_captures.values[i].error) {
context.input_resolutions[i][0] = video_captures.values[i].width; context.input_resolutions[i][0] = video_captures.values[i].width;
@@ -101,15 +102,19 @@ static void start_video_background_read(VideoCapture *video_capture,
Context *context, int input_index, Context *context, int input_index,
bool trace_fps) { bool trace_fps) {
pthread_t thread; pthread_t thread;
struct VideoBackgroundReadArgs *process_args = VideoBackgroundReadArgs *process_args =
(struct VideoBackgroundReadArgs *)malloc( (VideoBackgroundReadArgs *)malloc(sizeof(VideoBackgroundReadArgs));
sizeof(struct VideoBackgroundReadArgs));
process_args->capture = video_capture; process_args->capture = video_capture;
process_args->context = context; process_args->context = context;
process_args->input_index = input_index; process_args->input_index = input_index;
process_args->trace_fps = trace_fps; process_args->trace_fps = trace_fps;
pthread_create(&thread, NULL, video_background_read, (void *)process_args); if (pthread_create(&thread, NULL, video_background_read,
pthread_detach(thread); (void *)process_args) == 0) {
pthread_detach(thread);
} else {
log_error("background video acquisition failed to start");
free(process_args);
}
} }
static void * static void *
@@ -121,7 +126,8 @@ background_reconnect_video_captures(__attribute__((unused)) void *args) {
if (video_captures.values[i].disconnected) { if (video_captures.values[i].disconnected) {
video_free(&video_captures.values[i]); video_free(&video_captures.values[i]);
video_init(&video_captures.values[i], init_params.video_in.values[i], video_init(&video_captures.values[i], init_params.video_in.values[i],
init_params.video_size, init_params.video_buffers); init_params.video_size, init_params.video_buffers,
init_params.video_fourcc, false);
if (!video_captures.values[i].error) { if (!video_captures.values[i].error) {
context.input_resolutions[i][0] = video_captures.values[i].width; context.input_resolutions[i][0] = video_captures.values[i].width;
@@ -147,8 +153,12 @@ static void start_video_captures() {
} }
} }
if (init_params.video_reconnect) { if (init_params.video_reconnect) {
pthread_create(&thread, NULL, background_reconnect_video_captures, NULL); if (pthread_create(&thread, NULL, background_reconnect_video_captures,
pthread_detach(thread); NULL) == 0) {
pthread_detach(thread);
} else {
log_info("background video capture reconnect failed to start");
}
} }
} }
@@ -192,26 +202,35 @@ static void midi_callback(unsigned char code, unsigned char value) {
static void start_state_background_write() { static void start_state_background_write() {
pthread_t thread; pthread_t thread;
struct StateBackgroundWriteArgs *process_args = StateBackgroundWriteArgs *process_args =
(struct StateBackgroundWriteArgs *)malloc( (StateBackgroundWriteArgs *)malloc(sizeof(StateBackgroundWriteArgs));
sizeof(struct StateBackgroundWriteArgs));
process_args->context = &context; process_args->context = &context;
process_args->state_config = project.state_config; process_args->state_config = project.state_config;
process_args->midi = &midi; process_args->midi = &midi;
pthread_create(&thread, NULL, state_background_write, process_args); process_args->auto_save = init_params.auto_save;
pthread_detach(thread); if (pthread_create(&thread, NULL, state_background_write, process_args) ==
0) {
pthread_detach(thread);
} else {
log_error("background writing failed to start");
free(process_args);
}
} }
static void start_midi_background_listen() { static void start_midi_background_listen() {
pthread_t thread; pthread_t thread;
struct MidiBackgroundListenArgs *process_args = MidiBackgroundListenArgs *process_args =
(struct MidiBackgroundListenArgs *)malloc( (MidiBackgroundListenArgs *)malloc(sizeof(MidiBackgroundListenArgs));
sizeof(struct MidiBackgroundListenArgs));
process_args->device = &midi; process_args->device = &midi;
process_args->context = &context; process_args->context = &context;
process_args->event_callback = midi_callback; process_args->event_callback = midi_callback;
pthread_create(&thread, NULL, midi_background_listen, process_args); if (pthread_create(&thread, NULL, midi_background_listen, process_args) ==
pthread_detach(thread); 0) {
pthread_detach(thread);
} else {
log_error("background midi acquisition failed to start");
free(process_args);
}
} }
static void *background_reconnect_midi(__attribute__((unused)) void *args) { static void *background_reconnect_midi(__attribute__((unused)) void *args) {
@@ -219,7 +238,8 @@ static void *background_reconnect_midi(__attribute__((unused)) void *args) {
while (!context.stop) { while (!context.stop) {
sleep(1); sleep(1);
if (!midi.connected) { if (!midi.connected) {
midi_open(&midi, config_file_get_str(&project.config, "MIDI_HW", "hw")); midi_open(&midi, config_file_get_str(&project.config, "MIDI_HW", "hw"),
false);
if (midi.connected) { if (midi.connected) {
start_midi_background_listen(); start_midi_background_listen();
} }
@@ -231,15 +251,18 @@ static void *background_reconnect_midi(__attribute__((unused)) void *args) {
static void init_midi() { static void init_midi() {
pthread_t thread; pthread_t thread;
midi_open(&midi, config_file_get_str(&project.config, "MIDI_HW", "hw")); midi_open(&midi, config_file_get_str(&project.config, "MIDI_HW", "hw"), true);
if (midi.connected) { if (midi.connected) {
start_midi_background_listen(); start_midi_background_listen();
} }
if (init_params.midi_reconnect) { if (init_params.midi_reconnect) {
pthread_create(&thread, NULL, background_reconnect_midi, NULL); if (pthread_create(&thread, NULL, background_reconnect_midi, NULL) == 0) {
pthread_detach(thread); pthread_detach(thread);
} else {
log_error("background midi reconnect failed to start");
}
} }
} }
@@ -264,13 +287,15 @@ static bool init(const Parameters *params) {
start_state_background_write(); start_state_background_write();
window_startup(error_callback); window_startup(error_callback, params->glfw_backend);
context.tex_resolution[0] = params->internal_size;
context.tex_resolution[1] = params->internal_size; context.tex_resolution[1] = params->internal_size;
if (params->output) { if (params->output) {
window_output = window_init(PACKAGE " " VERSION, params->output_screen, window_output = window_init(PACKAGE " " VERSION, params->output_screen,
params->windowed, NULL, key_callback); params->windowed, params->opengl_major,
params->opengl_minor, NULL, key_callback);
window_use(window_output, &context); window_use(window_output, &context);
@@ -282,7 +307,8 @@ static bool init(const Parameters *params) {
if (params->monitor) { if (params->monitor) {
window_monitor = window_monitor =
window_init(PACKAGE " " VERSION " (monitor)", params->monitor_screen, window_init(PACKAGE " " VERSION " (monitor)", params->monitor_screen,
params->windowed, window_output, key_callback); params->windowed, params->opengl_major,
params->opengl_minor, window_output, key_callback);
window_use(window_monitor, &context); window_use(window_monitor, &context);
@@ -292,6 +318,10 @@ static bool init(const Parameters *params) {
} }
#ifdef VIDEO_IN #ifdef VIDEO_IN
if (params->output && params->monitor) {
window_use(window_output, &context);
}
shaders_link_inputs(&program, &project, &video_captures, shaders_link_inputs(&program, &project, &video_captures,
init_params.video_buffers); init_params.video_buffers);
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
@@ -363,8 +393,6 @@ static void shutdown() {
state_save(&context, project.state_config); state_save(&context, project.state_config);
} }
shaders_free(&program);
if (window_output != NULL) { if (window_output != NULL) {
window_use(window_output, &context); window_use(window_output, &context);
@@ -377,6 +405,8 @@ static void shutdown() {
shaders_free_window(&program, init_params.output); shaders_free_window(&program, init_params.output);
} }
shaders_free(&program);
#ifdef VIDEO_IN #ifdef VIDEO_IN
free_video_captures(); free_video_captures();
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
+28 -10
View File
@@ -6,19 +6,30 @@
#include "config.h" #include "config.h"
void midi_open(MidiDevice *device, const char *name) { void snd_no_log(__attribute__((unused)) int prio,
__attribute__((unused)) int interface,
__attribute__((unused)) const char *file,
__attribute__((unused)) int line,
__attribute__((unused)) const char *function,
__attribute__((unused)) int errcode,
__attribute__((unused)) const char *fmt,
__attribute__((unused)) va_list arg) {}
void midi_open(MidiDevice *device, const char *name, bool log_error) {
strlcpy(device->name, name, STR_LEN); strlcpy(device->name, name, STR_LEN);
device->connected = false;
device->input = NULL; device->input = NULL;
device->output = NULL; device->output = NULL;
snd_rawmidi_open(&device->input, &device->output, name, SND_RAWMIDI_NONBLOCK); device->connected = snd_rawmidi_open(&device->input, &device->output, name,
SND_RAWMIDI_SYNC) == 0 &&
device->connected = device->input != NULL && device->output != NULL; device->input != NULL && device->output != NULL;
if (log_error) {
if (device->connected) { if (device->connected) {
log_info("(%s) MIDI open", name); log_info("(%s) MIDI open", name);
} else { } else {
log_warn("(%s) MIDI open failed", name); log_warn("(%s) MIDI open failed", name);
}
} }
} }
@@ -45,7 +56,7 @@ void midi_close(MidiDevice *device) {
} }
void *midi_background_listen(void *args) { void *midi_background_listen(void *args) {
MidiBackgroundReadArgs *process_args = (MidiBackgroundReadArgs *)args; MidiBackgroundListenArgs *process_args = (MidiBackgroundListenArgs *)args;
MidiDevice *device = process_args->device; MidiDevice *device = process_args->device;
Context *context = process_args->context; Context *context = process_args->context;
@@ -57,6 +68,12 @@ void *midi_background_listen(void *args) {
snd_rawmidi_info_malloc(&info); snd_rawmidi_info_malloc(&info);
if (info == NULL) {
log_error("(%s) failed to allocate MIDI info", device->name);
free(process_args);
pthread_exit(NULL);
}
while (!context->stop && snd_rawmidi_info(device->output, info) == 0) { while (!context->stop && snd_rawmidi_info(device->output, info) == 0) {
bytes_read = snd_rawmidi_read(device->input, buffer, 3); bytes_read = snd_rawmidi_read(device->input, buffer, 3);
if (bytes_read == 3) { if (bytes_read == 3) {
@@ -73,5 +90,6 @@ void *midi_background_listen(void *args) {
log_info("(%s) background acquisition stopped after error", device->name); log_info("(%s) background acquisition stopped after error", device->name);
midi_close(device); midi_close(device);
} }
free(process_args);
pthread_exit(NULL); pthread_exit(NULL);
} }
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef MIDI_H #ifndef MIDI_H
#define MIDI_H #define MIDI_H
void midi_open(MidiDevice *device, const char *name); void midi_open(MidiDevice *device, const char *name, bool log_error);
void midi_write(MidiDevice device, unsigned char code, unsigned char value); void midi_write(MidiDevice device, unsigned char code, unsigned char value);
void *midi_background_listen(void *args); void *midi_background_listen(void *args);
void midi_close(MidiDevice *device); void midi_close(MidiDevice *device);
+10 -1
View File
@@ -48,6 +48,8 @@ static bool parse_fragment_shader_file(Project *project, unsigned int i) {
include_end - project->fragment_shaders[i][0].content, include_end - project->fragment_shaders[i][0].content,
tmp_file.content); tmp_file.content);
free(project->fragment_shaders[i][0].content);
project->fragment_shaders[i][0].content = new_content; project->fragment_shaders[i][0].content = new_content;
file_free(&tmp_file); file_free(&tmp_file);
@@ -102,6 +104,12 @@ void project_init(Project *project, const char *project_path,
project->sub_counts.length = project->frag_count; project->sub_counts.length = project->frag_count;
for (unsigned int i = 0; i < project->frag_count; i++) {
for (unsigned int j = 0; j < MAX_SUB_FILE + 1; j++) {
project->fragment_shaders[i][j].content = NULL;
}
}
for (unsigned int i = 0; i < project->frag_count; i++) { for (unsigned int i = 0; i < project->frag_count; i++) {
project->sub_counts.values[i] = 0; project->sub_counts.values[i] = 0;
if (!read_fragment_shader_file(project, frag_prefix, i)) { if (!read_fragment_shader_file(project, frag_prefix, i)) {
@@ -134,9 +142,10 @@ void project_reload(Project *project, void (*reload_callback)(unsigned int)) {
} }
} }
void project_free(const Project *project) { void project_free(Project *project) {
for (unsigned int i = 0; i < project->frag_count; i++) { for (unsigned int i = 0; i < project->frag_count; i++) {
file_free(&project->fragment_shaders[i][0]); file_free(&project->fragment_shaders[i][0]);
// other sub files contents are freed at parse_fragment_shader_file
} }
config_file_free(&project->config); config_file_free(&project->config);
+1 -1
View File
@@ -8,6 +8,6 @@ void project_init(Project *project, const char *project_path,
void project_reload(Project *project, void (*reload_callback)(unsigned int)); void project_reload(Project *project, void (*reload_callback)(unsigned int));
void project_free(const Project *project); void project_free(Project *project);
#endif /* PROJECT_H */ #endif /* PROJECT_H */
+3 -3
View File
@@ -4,7 +4,7 @@ static unsigned long long mcg_state = 0xcafef00dd15ea5e5u; // Must be odd
static unsigned long long const multiplier = 6364136223846793005u; static unsigned long long const multiplier = 6364136223846793005u;
// https://en.wikipedia.org/wiki/Permuted_congruential_generator // https://en.wikipedia.org/wiki/Permuted_congruential_generator
static unsigned long rand(void) { static unsigned long fast_rand(void) {
unsigned long long x = mcg_state; unsigned long long x = mcg_state;
unsigned count = (unsigned)(x >> 61); unsigned count = (unsigned)(x >> 61);
@@ -15,9 +15,9 @@ static unsigned long rand(void) {
void rand_set_seed(unsigned long long seed) { void rand_set_seed(unsigned long long seed) {
mcg_state = 2 * seed + 1; mcg_state = 2 * seed + 1;
(void)rand(); (void)fast_rand();
} }
unsigned int rand_uint(const unsigned int max) { unsigned int rand_uint(const unsigned int max) {
return max == 0 ? 0 : (unsigned int)(rand() % max); return max == 0 ? 0 : (unsigned int)(fast_rand() % max);
} }
+41 -19
View File
@@ -24,7 +24,7 @@
#include <GLFW/glfw3native.h> #include <GLFW/glfw3native.h>
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
static const GLuint unused_uniform = (GLuint)-1; static const GLint UNUSED_UNIFORM = -1;
static bool check_glerror_ro(const char *context) { static bool check_glerror_ro(const char *context) {
unsigned int code; unsigned int code;
@@ -60,13 +60,13 @@ static void gl_debug_callback(GLenum source, GLenum type, GLuint id,
#endif /* GL_DEBUG */ #endif /* GL_DEBUG */
static bool check_eglerror_ro(const char *context) { static bool check_eglerror_ro(__attribute__((unused)) const char *context) {
#ifdef VIDEO_IN #ifdef VIDEO_IN
unsigned int code; unsigned int code;
code = eglGetError(); code = eglGetError();
if (code > 0 && code != EGL_SUCCESS) { if (code != EGL_SUCCESS) {
log_warn("EGL Error: %04x (%s)", code, context); log_warn("EGL Error: %04x (%s)", code, context);
return true; return true;
} }
@@ -105,6 +105,13 @@ static bool init_gl(ShaderProgram *program) {
glDebugMessageCallback(gl_debug_callback, NULL); glDebugMessageCallback(gl_debug_callback, NULL);
#endif /* GL_DEBUG */ #endif /* GL_DEBUG */
// print OpenGL info
log_info("[OpenGL] Vendor: %s", glGetString(GL_VENDOR));
log_info("[OpenGL] Renderer: %s", glGetString(GL_RENDERER));
log_info("[OpenGL] Version: %s", glGetString(GL_VERSION));
log_info("[OpenGL] Shading language: %s",
glGetString(GL_SHADING_LANGUAGE_VERSION));
#ifdef VIDEO_IN #ifdef VIDEO_IN
program->egl_display = glfwGetEGLDisplay(); program->egl_display = glfwGetEGLDisplay();
if (program->egl_display == EGL_NO_DISPLAY) { if (program->egl_display == EGL_NO_DISPLAY) {
@@ -245,12 +252,6 @@ static bool link_input_to_texture(ShaderProgram *program, VideoCapture *input,
return false; return false;
} }
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, input->width, input->height, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
if (check_glerror(program, "link_input_to_texture/glTexImage2D")) {
return false;
}
// https://registry.khronos.org/OpenGL/extensions/EXT/EXT_EGL_image_storage.txt // https://registry.khronos.org/OpenGL/extensions/EXT/EXT_EGL_image_storage.txt
glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, dma_image, NULL); glEGLImageTargetTexStorageEXT(GL_TEXTURE_2D, dma_image, NULL);
if (check_eglerror(program, if (check_eglerror(program,
@@ -411,7 +412,7 @@ static bool compile_shader(GLuint shader_id, const char *name,
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status_params); glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status_params);
check_glerror_ro("compile_shader/glGetShaderiv"); check_glerror_ro("compile_shader/glGetShaderiv");
glGetShaderInfoLog(shader_id, 1024, NULL, (GLchar *)&log); glGetShaderInfoLog(shader_id, STR_LEN, NULL, (GLchar *)log);
check_glerror_ro("compile_shader/glGetShaderInfoLog"); check_glerror_ro("compile_shader/glGetShaderInfoLog");
if (status_params == GL_FALSE) { if (status_params == GL_FALSE) {
@@ -462,6 +463,8 @@ static bool init_single_program(ShaderProgram *program, unsigned int i,
unsigned int index2; unsigned int index2;
char name[STR_LEN]; char name[STR_LEN];
const char *prefix; const char *prefix;
GLint link_status;
char link_log[STR_LEN];
program->programs[i] = glCreateProgram(); program->programs[i] = glCreateProgram();
if (check_glerror(program, "init_single_program/glCreateProgram")) { if (check_glerror(program, "init_single_program/glCreateProgram")) {
@@ -479,6 +482,19 @@ static bool init_single_program(ShaderProgram *program, unsigned int i,
return false; return false;
} }
glGetProgramiv(program->programs[i], GL_LINK_STATUS, &link_status);
if (check_glerror(program, "init_single_program/glGetProgramiv")) {
return false;
}
if (link_status != GL_TRUE) {
glGetProgramInfoLog(program->programs[i], STR_LEN, NULL, link_log);
if (check_glerror(program, "init_single_program/glGetProgramInfoLog")) {
return false;
}
log_error("Program %d link error: %s", i + 1, link_log);
return false;
}
// create uniforms pointers // create uniforms pointers
program->itime_locations[i] = glGetUniformLocation( program->itime_locations[i] = glGetUniformLocation(
program->programs[i], program->programs[i],
@@ -651,27 +667,27 @@ static void update_viewport(ShaderProgram *program, const Context *context) {
} }
} }
static void write_uniform_1f(GLuint location, float value) { static void write_uniform_1f(GLint location, float value) {
if (location != unused_uniform) { if (location != UNUSED_UNIFORM) {
glUniform1f(location, value); glUniform1f(location, value);
} }
} }
static void write_uniform_1i(GLuint location, unsigned int value) { static void write_uniform_1i(GLint location, unsigned int value) {
if (location != unused_uniform) { if (location != UNUSED_UNIFORM) {
glUniform1i(location, (const GLint)value); glUniform1i(location, (const GLint)value);
} }
} }
static void write_uniform_2f(GLuint location, const vec2 *value) { static void write_uniform_2f(GLint location, const vec2 *value) {
if (location != unused_uniform) { if (location != UNUSED_UNIFORM) {
glUniform2fv(location, 1, (const GLfloat *)value); glUniform2fv(location, 1, (const GLfloat *)value);
} }
} }
static void write_uniform_multi_3f(GLuint location, unsigned int count, static void write_uniform_multi_3f(GLint location, unsigned int count,
const vec3 *value) { const vec3 *value) {
if (location != unused_uniform) { if (location != UNUSED_UNIFORM) {
glUniform3fv(location, count, (const GLfloat *)value); glUniform3fv(location, count, (const GLfloat *)value);
} }
} }
@@ -759,7 +775,7 @@ static void use_program(const ShaderProgram *program, int i, bool output,
if (program->sub_locations[i * program->sub_variant_count * if (program->sub_locations[i * program->sub_variant_count *
program->sub_type_count + program->sub_type_count +
j * program->sub_variant_count + k] != j * program->sub_variant_count + k] !=
unused_uniform) { UNUSED_UNIFORM) {
subroutines[subcount++] = subroutines[subcount++] =
program->sub_locations[i * program->sub_variant_count * program->sub_locations[i * program->sub_variant_count *
program->sub_type_count + program->sub_type_count +
@@ -935,6 +951,12 @@ void shaders_free(const ShaderProgram *program) {
} }
check_glerror_ro("shaders_free/glDeleteProgram"); check_glerror_ro("shaders_free/glDeleteProgram");
glDeleteShader(program->vertex_shader);
for (unsigned int i = 0; i < program->frag_count; i++) {
glDeleteShader(program->fragment_shaders[i]);
}
check_glerror_ro("shaders_free/glDeleteShader");
glDeleteFramebuffers(program->frag_count, program->frame_buffers); glDeleteFramebuffers(program->frag_count, program->frame_buffers);
check_glerror_ro("shaders_free/glDeleteFramebuffers"); check_glerror_ro("shaders_free/glDeleteFramebuffers");
+226 -58
View File
@@ -12,6 +12,7 @@
#include "rand.h" #include "rand.h"
#include "state.h" #include "state.h"
#include "tempo.h" #include "tempo.h"
#include "timer.h"
static void safe_midi_write(MidiDevice midi, unsigned int code, static void safe_midi_write(MidiDevice midi, unsigned int code,
unsigned char value) { unsigned char value) {
@@ -98,11 +99,15 @@ static void randomize(Context *context, StateConfig state_config) {
l = state_config.values_offsets.values[part] + l = state_config.values_offsets.values[part] +
k * state_config.group_counts.values[part] + j; k * state_config.group_counts.values[part] + j;
if (arr_uint_index_of(state_config.fader_codes, if (arr_uint_index_of(state_config.random_ignored, (l * 3) + (i % 3)) ==
state_config.codes.values[i]) != ARRAY_NOT_FOUND) { ARRAY_NOT_FOUND) {
context->values[l][i % 3] = (float)rand_uint(MIDI_MAX + 1) / MIDI_MAX; if (arr_uint_index_of(state_config.fader_codes,
} else { state_config.codes.values[i]) !=
context->values[l][i % 3] = rand_uint(2) == 1 ? 1 : 0; ARRAY_NOT_FOUND) {
context->values[l][i % 3] = (float)rand_uint(MIDI_MAX + 1) / MIDI_MAX;
} else {
context->values[l][i % 3] = rand_uint(2) == 1 ? 1 : 0;
}
} }
} }
} }
@@ -175,50 +180,117 @@ static void load_from_index_file(Context *context, StateConfig state_config,
} }
static void save_to_file(const Context *context, StateConfig state_config, static void save_to_file(const Context *context, StateConfig state_config,
const char *state_file) { const char *state_file, const bool log) {
StringArray lines; StringArray lines;
log_info("Saving state to '%s'...", state_file); if (log) {
log_info("Saving state to '%s'...", state_file);
}
lines.length = 0; lines.length = 0;
snprintf(lines.values[lines.length++], STR_LEN, "time=%f", context->time);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "beats=%f",
context->tempo_total);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "demo=%d",
context->demo ? 1 : 0);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "auto_random=%d",
context->auto_random ? 1 : 0);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "auto_random_cycle=%d",
context->auto_random_cycle);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "tempo=%d", snprintf(lines.values[lines.length++], STR_LEN, "tempo=%d",
(unsigned int)context->tempo.tempo); (unsigned int)context->tempo.tempo);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "page=%d", context->page); snprintf(lines.values[lines.length++], STR_LEN, "page=%d", context->page);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "selected=%d", snprintf(lines.values[lines.length++], STR_LEN, "selected=%d",
context->selected); context->selected);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
for (unsigned int i = 0; i < context->state.length; i++) { for (unsigned int i = 0; i < context->state.length; i++) {
snprintf(lines.values[lines.length++], STR_LEN, "seed_%d=%d", i, snprintf(lines.values[lines.length++], STR_LEN, "seed_%d=%d", i,
context->seeds[i]); context->seeds[i]);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "state_%d=%d", i, snprintf(lines.values[lines.length++], STR_LEN, "state_%d=%d", i,
context->state.values[i]); context->state.values[i]);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
} }
for (unsigned int i = 0; i < state_config.group_active_counts.length; i++) { for (unsigned int i = 0; i < state_config.group_active_counts.length; i++) {
snprintf(lines.values[lines.length++], STR_LEN, "active_%d=%d", i, snprintf(lines.values[lines.length++], STR_LEN, "active_%d=%d", i,
context->active[i]); context->active[i]);
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
} }
for (unsigned int i = 0; i < state_config.value_count; i++) { for (unsigned int i = 0; i < state_config.value_count; i++) {
snprintf(lines.values[lines.length++], STR_LEN, "value_%d_x=%d", i, snprintf(lines.values[lines.length++], STR_LEN, "value_%d_x=%d", i,
(unsigned int)(context->values[i][0] * MIDI_MAX)); (unsigned int)(context->values[i][0] * MIDI_MAX));
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "value_%d_y=%d", i, snprintf(lines.values[lines.length++], STR_LEN, "value_%d_y=%d", i,
(unsigned int)(context->values[i][1] * MIDI_MAX)); (unsigned int)(context->values[i][1] * MIDI_MAX));
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
snprintf(lines.values[lines.length++], STR_LEN, "value_%d_z=%d", i, snprintf(lines.values[lines.length++], STR_LEN, "value_%d_z=%d", i,
(unsigned int)(context->values[i][2] * MIDI_MAX)); (unsigned int)(context->values[i][2] * MIDI_MAX));
if (lines.length > ARRAY_SIZE) {
log_error("Too many values to save");
return;
}
} }
file_write(state_file, &lines); file_write(state_file, &lines, log);
} }
static void save_to_default_file(const Context *context, static void save_to_default_file(const Context *context,
StateConfig state_config) { StateConfig state_config, const bool log) {
char state_file[STR_LEN]; char state_file[STR_LEN];
snprintf(state_file, STR_LEN, "%s.txt", state_config.save_file_prefix); snprintf(state_file, STR_LEN, "%s.txt", state_config.save_file_prefix);
save_to_file(context, state_config, state_file); save_to_file(context, state_config, state_file, log);
} }
static void save_to_index_file(const Context *context, StateConfig state_config, static void save_to_index_file(const Context *context, StateConfig state_config,
@@ -228,16 +300,22 @@ static void save_to_index_file(const Context *context, StateConfig state_config,
snprintf(state_file, STR_LEN, "%s.%d.txt", state_config.save_file_prefix, snprintf(state_file, STR_LEN, "%s.%d.txt", state_config.save_file_prefix,
index); index);
save_to_file(context, state_config, state_file); save_to_file(context, state_config, state_file, true);
} }
void state_parse_config(StateConfig *state_config, const ConfigFile *config) { void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
unsigned int offset; unsigned int offset;
unsigned int count; unsigned int count;
unsigned int length;
unsigned int value_offset;
StringArray ignored_codes;
char name[STR_LEN]; char name[STR_LEN];
state_config->select_page_codes.length = length = config_file_get_int(config, "SELECT_PAGE_COUNT", 0);
config_file_get_int(config, "SELECT_PAGE_COUNT", 0); if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->select_page_codes.length = length;
for (unsigned int i = 0; i < state_config->select_page_codes.length; i++) { for (unsigned int i = 0; i < state_config->select_page_codes.length; i++) {
snprintf(name, STR_LEN, "SELECT_PAGE_%d", i + 1); snprintf(name, STR_LEN, "SELECT_PAGE_%d", i + 1);
@@ -245,8 +323,11 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
config_file_get_int(config, name, UNSET_MIDI_CODE); config_file_get_int(config, name, UNSET_MIDI_CODE);
} }
state_config->select_item_codes.length = length = config_file_get_int(config, "SELECT_ITEM_COUNT", 0);
config_file_get_int(config, "SELECT_ITEM_COUNT", 0); if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->select_item_codes.length = length;
for (unsigned int i = 0; i < state_config->select_item_codes.length; i++) { for (unsigned int i = 0; i < state_config->select_item_codes.length; i++) {
snprintf(name, STR_LEN, "SELECT_ITEM_%d", i + 1); snprintf(name, STR_LEN, "SELECT_ITEM_%d", i + 1);
@@ -257,8 +338,11 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
state_config->state_max = state_config->select_page_codes.length * state_config->state_max = state_config->select_page_codes.length *
state_config->select_item_codes.length; state_config->select_item_codes.length;
state_config->select_frag_codes.length = length = config_file_get_int(config, "FRAG_COUNT", 1);
config_file_get_int(config, "FRAG_COUNT", 1); if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->select_frag_codes.length = length;
for (unsigned int i = 0; i < state_config->select_frag_codes.length; i++) { for (unsigned int i = 0; i < state_config->select_frag_codes.length; i++) {
snprintf(name, STR_LEN, "SELECT_FRAG_%d", i + 1); snprintf(name, STR_LEN, "SELECT_FRAG_%d", i + 1);
@@ -266,11 +350,26 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
config_file_get_int(config, name, UNSET_MIDI_CODE); config_file_get_int(config, name, UNSET_MIDI_CODE);
} }
length = config_file_get_int(config, "ARI_COUNT", 0);
if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
ignored_codes.length = length;
for (unsigned int i = 0; i < ignored_codes.length; i++) {
snprintf(name, STR_LEN, "ARI_%d", i + 1);
strlcpy(ignored_codes.values[i],
config_file_get_str(config, name, "unkown"), STR_LEN);
}
length = config_file_get_int(config, "GROUP_COUNT", 0);
if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->group_active_counts.length = state_config->group_counts.length = state_config->group_active_counts.length = state_config->group_counts.length =
state_config->group_active_offsets.length = state_config->group_active_offsets.length =
state_config->group_offsets.length = state_config->group_offsets.length =
state_config->values_offsets.length = state_config->values_offsets.length = length;
config_file_get_int(config, "GROUP_COUNT", 0);
count = 0; count = 0;
for (unsigned int i = 0; i < state_config->group_active_counts.length; i++) { for (unsigned int i = 0; i < state_config->group_active_counts.length; i++) {
@@ -307,27 +406,74 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
state_config->value_count = offset; state_config->value_count = offset;
length = count * 3;
if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->codes.length = count * 3; state_config->codes.length = count * 3;
state_config->random_ignored.length = 0;
for (unsigned int i = 0; i < state_config->group_counts.length; i++) { for (unsigned int i = 0; i < state_config->group_counts.length; i++) {
offset = state_config->group_offsets.values[i]; offset = state_config->group_offsets.values[i];
value_offset = state_config->values_offsets.values[i];
for (unsigned int j = 0; j < state_config->group_counts.values[i]; j++) { for (unsigned int j = 0; j < state_config->group_counts.values[i]; j++) {
snprintf(name, STR_LEN, "GROUP_%d_%d_X", i + 1, j + 1); if ((offset + j) * 3 < ARRAY_SIZE) {
state_config->codes.values[(offset + j) * 3] = snprintf(name, STR_LEN, "GROUP_%d_%d_X", i + 1, j + 1);
config_file_get_int(config, name, UNSET_MIDI_CODE); state_config->codes.values[(offset + j) * 3] =
config_file_get_int(config, name, UNSET_MIDI_CODE);
for (unsigned int k = 0;
k < state_config->group_active_counts.values[i]; k++) {
snprintf(name, STR_LEN, "GROUP_%d_%d_X_%d", i + 1, j + 1, k + 1);
if (arr_string_match(ignored_codes, name)) {
state_config->random_ignored
.values[state_config->random_ignored.length++] =
(value_offset + k * state_config->group_counts.values[i] + j) *
3;
}
}
}
snprintf(name, STR_LEN, "GROUP_%d_%d_Y", i + 1, j + 1); if ((offset + j) * 3 + 1 < ARRAY_SIZE) {
state_config->codes.values[(offset + j) * 3 + 1] = snprintf(name, STR_LEN, "GROUP_%d_%d_Y", i + 1, j + 1);
config_file_get_int(config, name, UNSET_MIDI_CODE); state_config->codes.values[(offset + j) * 3 + 1] =
config_file_get_int(config, name, UNSET_MIDI_CODE);
for (unsigned int k = 0;
k < state_config->group_active_counts.values[i]; k++) {
snprintf(name, STR_LEN, "GROUP_%d_%d_Y_%d", i + 1, j + 1, k + 1);
if (arr_string_match(ignored_codes, name)) {
state_config->random_ignored
.values[state_config->random_ignored.length++] =
(value_offset + k * state_config->group_counts.values[i] + j) *
3 +
1;
}
}
}
snprintf(name, STR_LEN, "GROUP_%d_%d_Z", i + 1, j + 1); if ((offset + j) * 3 + 2 < ARRAY_SIZE) {
state_config->codes.values[(offset + j) * 3 + 2] = snprintf(name, STR_LEN, "GROUP_%d_%d_Z", i + 1, j + 1);
config_file_get_int(config, name, UNSET_MIDI_CODE); state_config->codes.values[(offset + j) * 3 + 2] =
config_file_get_int(config, name, UNSET_MIDI_CODE);
for (unsigned int k = 0;
k < state_config->group_active_counts.values[i]; k++) {
snprintf(name, STR_LEN, "GROUP_%d_%d_Z_%d", i + 1, j + 1, k + 1);
if (arr_string_match(ignored_codes, name)) {
state_config->random_ignored
.values[state_config->random_ignored.length++] =
(value_offset + k * state_config->group_counts.values[i] + j) *
3 +
2;
}
}
}
} }
} }
state_config->fader_codes.length = length = config_file_get_int(config, "FADER_COUNT", 0);
config_file_get_int(config, "FADER_COUNT", 0); if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->fader_codes.length = length;
for (unsigned int i = 0; i < state_config->fader_codes.length; i++) { for (unsigned int i = 0; i < state_config->fader_codes.length; i++) {
snprintf(name, STR_LEN, "FADER_%d", i + 1); snprintf(name, STR_LEN, "FADER_%d", i + 1);
@@ -358,8 +504,11 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
config_file_get_int(config, "KEY_TEMPO_UP", 1265); config_file_get_int(config, "KEY_TEMPO_UP", 1265);
if (config_file_has(config, "KEY_LOAD_COUNT")) { if (config_file_has(config, "KEY_LOAD_COUNT")) {
state_config->key_load.length = length = config_file_get_int(config, "KEY_LOAD_COUNT", 0);
config_file_get_int(config, "KEY_LOAD_COUNT", 0); if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->key_load.length = length;
for (unsigned int i = 0; i < state_config->key_load.length; i++) { for (unsigned int i = 0; i < state_config->key_load.length; i++) {
snprintf(name, STR_LEN, "KEY_LOAD_%d", i + 1); snprintf(name, STR_LEN, "KEY_LOAD_%d", i + 1);
@@ -380,8 +529,11 @@ void state_parse_config(StateConfig *state_config, const ConfigFile *config) {
} }
if (config_file_has(config, "KEY_SAVE_COUNT")) { if (config_file_has(config, "KEY_SAVE_COUNT")) {
state_config->key_save.length = length = config_file_get_int(config, "KEY_SAVE_COUNT", 0);
config_file_get_int(config, "KEY_SAVE_COUNT", 0); if (length > ARRAY_SIZE) {
length = ARRAY_SIZE;
}
state_config->key_save.length = length;
for (unsigned int i = 0; i < state_config->key_save.length; i++) { for (unsigned int i = 0; i < state_config->key_save.length; i++) {
snprintf(name, STR_LEN, "KEY_SAVE_%d", i + 1); snprintf(name, STR_LEN, "KEY_SAVE_%d", i + 1);
@@ -409,6 +561,9 @@ static bool compute_event(Context *context, StateConfig state_config,
unsigned int j; unsigned int j;
unsigned int k; unsigned int k;
unsigned int part; unsigned int part;
bool found;
found = false;
// PAGE CHANGE // PAGE CHANGE
i = arr_uint_index_of(state_config.select_page_codes, code); i = arr_uint_index_of(state_config.select_page_codes, code);
@@ -417,7 +572,7 @@ static bool compute_event(Context *context, StateConfig state_config,
context->page = i; context->page = i;
update_page(context, state_config, midi); update_page(context, state_config, midi);
} }
return true; found = true;
} }
// TARGET CHANGE // TARGET CHANGE
@@ -427,7 +582,7 @@ static bool compute_event(Context *context, StateConfig state_config,
context->selected = i; context->selected = i;
update_page(context, state_config, midi); update_page(context, state_config, midi);
} }
return true; found = true;
} }
// ITEM CHANGE // ITEM CHANGE
@@ -438,7 +593,7 @@ static bool compute_event(Context *context, StateConfig state_config,
context->page * state_config.select_item_codes.length + i; context->page * state_config.select_item_codes.length + i;
update_page(context, state_config, midi); update_page(context, state_config, midi);
} }
return true; found = true;
} }
// ACTIVE CHANGE // ACTIVE CHANGE
@@ -450,7 +605,7 @@ static bool compute_event(Context *context, StateConfig state_config,
update_active(context, state_config, midi, true); update_active(context, state_config, midi, true);
update_values(context, state_config, midi); update_values(context, state_config, midi);
} }
return true; found = true;
} }
// VALUE CHANGE // VALUE CHANGE
@@ -472,7 +627,7 @@ static bool compute_event(Context *context, StateConfig state_config,
safe_midi_write(midi, code, MIDI_MAX); safe_midi_write(midi, code, MIDI_MAX);
} }
} }
return true; found = true;
} }
// TAP TEMPO // TAP TEMPO
@@ -481,7 +636,7 @@ static bool compute_event(Context *context, StateConfig state_config,
if (value > 0) { if (value > 0) {
tempo_tap(&context->tempo); tempo_tap(&context->tempo);
} }
return true; found = true;
} }
// OTHER KEYS // OTHER KEYS
@@ -491,7 +646,7 @@ static bool compute_event(Context *context, StateConfig state_config,
randomize(context, state_config); randomize(context, state_config);
update_values(context, state_config, midi); update_values(context, state_config, midi);
} }
return true; found = true;
} }
if (code == state_config.key_reset) { if (code == state_config.key_reset) {
@@ -500,25 +655,24 @@ static bool compute_event(Context *context, StateConfig state_config,
reset(context); reset(context);
update_values(context, state_config, midi); update_values(context, state_config, midi);
} }
return true; found = true;
} }
if (code == state_config.key_demo) { if (code == state_config.key_demo) {
if (value > 0) { if (value > 0) {
log_info((context->demo ? "[%d] Demo OFF" : "[%d] Demo ON"), code); context->auto_random = context->demo = !context->demo;
context->demo = !context->demo; log_info((context->demo ? "[%d] Demo ON" : "[%d] Demo OFF"), code);
} }
return true; found = true;
} }
if (code == state_config.key_autorand) { if (code == state_config.key_autorand) {
if (value > 0) { if (value > 0) {
log_info((context->auto_random ? "[%d] Auto Random OFF"
: "[%d] Auto Random ON"),
code);
context->auto_random = !context->auto_random; context->auto_random = !context->auto_random;
log_info("[%d] Auto Random %s", code,
context->auto_random ? "ON" : "OFF");
} }
return true; found = true;
} }
if (code == state_config.key_autorand_down) { if (code == state_config.key_autorand_down) {
@@ -528,7 +682,7 @@ static bool compute_event(Context *context, StateConfig state_config,
} }
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle); log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
} }
return true; found = true;
} }
if (code == state_config.key_autorand_up) { if (code == state_config.key_autorand_up) {
@@ -536,7 +690,7 @@ static bool compute_event(Context *context, StateConfig state_config,
context->auto_random_cycle += 1; context->auto_random_cycle += 1;
log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle); log_info("[%d] Auto Random Cycle: %d", code, context->auto_random_cycle);
} }
return true; found = true;
} }
if (code == state_config.key_tempo_up) { if (code == state_config.key_tempo_up) {
@@ -544,7 +698,7 @@ static bool compute_event(Context *context, StateConfig state_config,
tempo_set(&context->tempo, context->tempo.tempo + 1); tempo_set(&context->tempo, context->tempo.tempo + 1);
log_info("[%d] Tempo: %f", code, context->tempo); log_info("[%d] Tempo: %f", code, context->tempo);
} }
return true; found = true;
} }
if (code == state_config.key_tempo_down) { if (code == state_config.key_tempo_down) {
@@ -552,9 +706,9 @@ static bool compute_event(Context *context, StateConfig state_config,
if (context->tempo.tempo > 0) { if (context->tempo.tempo > 0) {
tempo_set(&context->tempo, context->tempo.tempo - 1); tempo_set(&context->tempo, context->tempo.tempo - 1);
} }
log_info("[%d] Tempo: %f", code, context->tempo); log_info("[%d] Tempo: %f", code, context->tempo.tempo);
} }
return true; found = true;
} }
// LOAD STATE // LOAD STATE
@@ -565,7 +719,7 @@ static bool compute_event(Context *context, StateConfig state_config,
log_info("[%d] Loading state %d", code, i + 1); log_info("[%d] Loading state %d", code, i + 1);
load_from_index_file(context, state_config, i + 1); load_from_index_file(context, state_config, i + 1);
} }
return true; found = true;
} }
// SAVE STATE // SAVE STATE
@@ -576,10 +730,10 @@ static bool compute_event(Context *context, StateConfig state_config,
log_info("[%d] Saving state %d", code, i + 1); log_info("[%d] Saving state %d", code, i + 1);
save_to_index_file(context, state_config, i + 1); save_to_index_file(context, state_config, i + 1);
} }
return true; found = true;
} }
return false; return found;
} }
void state_midi_event(Context *context, StateConfig state_config, void state_midi_event(Context *context, StateConfig state_config,
@@ -605,16 +759,20 @@ void *state_background_write(void *args) {
Context *context = process_args->context; Context *context = process_args->context;
StateConfig state_config = process_args->state_config; StateConfig state_config = process_args->state_config;
MidiDevice *midi = process_args->midi; MidiDevice *midi = process_args->midi;
bool auto_save = process_args->auto_save;
bool beat_active; bool beat_active;
bool last_active; bool last_active;
bool change; bool change;
bool last_change; bool last_change;
bool do_auto_save;
bool last_auto_save;
log_info("(state) background writing started"); log_info("(state) background writing started");
last_active = false; last_active = false;
last_change = false; last_change = false;
last_auto_save = false;
while (!context->stop) { while (!context->stop) {
beat_active = tempo_progress(&context->tempo, 1.0) < 0.5; beat_active = tempo_progress(&context->tempo, 1.0) < 0.5;
@@ -640,9 +798,19 @@ void *state_background_write(void *args) {
} }
last_change = change; last_change = change;
do_auto_save = fmod(context->time, STATE_AUTO_SAVE_SECONDS) <
STATE_AUTO_SAVE_SECONDS * 0.5;
if (auto_save && do_auto_save && !last_auto_save) {
save_to_default_file(context, state_config, false);
}
last_auto_save = do_auto_save;
} }
log_info("(state) background writing stopped by main thread"); log_info("(state) background writing stopped by main thread");
free(process_args);
pthread_exit(NULL); pthread_exit(NULL);
} }
@@ -679,5 +847,5 @@ void state_init(Context *context, StateConfig state_config, bool demo,
} }
void state_save(const Context *context, StateConfig state_config) { void state_save(const Context *context, StateConfig state_config) {
save_to_default_file(context, state_config); save_to_default_file(context, state_config, true);
} }
+9 -1
View File
@@ -15,7 +15,7 @@ unsigned int string_trim(char *str) {
start = 0; start = 0;
end = strnlen(str, STR_LEN) - 1; end = strnlen(str, STR_LEN) - 1;
if (end == 0) { if (end <= 0) {
return 0; return 0;
} }
@@ -62,11 +62,19 @@ char *string_replace_at(const char *src, unsigned int from, unsigned int to,
unsigned long rpl_len; unsigned long rpl_len;
char *dst; char *dst;
if (to < from) {
return "";
}
src_len = strnlen(src, STR_LEN * STR_LEN); src_len = strnlen(src, STR_LEN * STR_LEN);
rpl_len = strnlen(rpl, STR_LEN * STR_LEN); rpl_len = strnlen(rpl, STR_LEN * STR_LEN);
dst = malloc(src_len - (to - from) + rpl_len + 1); dst = malloc(src_len - (to - from) + rpl_len + 1);
if (dst == NULL) {
return "";
}
strlcpy(dst, src, from + 1); strlcpy(dst, src, from + 1);
strlcpy(dst + from, rpl, rpl_len + 1); strlcpy(dst + from, rpl, rpl_len + 1);
strlcpy(dst + from + rpl_len, src + to, src_len - to + 1); strlcpy(dst + from + rpl_len, src + to, src_len - to + 1);
+11 -11
View File
@@ -1,18 +1,18 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <sys/time.h> #include <time.h>
#include "types.h" #include "types.h"
#include "config.h" #include "config.h"
#include "tempo.h" #include "tempo.h"
static long now() { static long now_ms() {
struct timeval now; struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
gettimeofday(&now, NULL); return 0;
}
return now.tv_sec * 1000 + now.tv_usec / 1000; return 1000 * ts.tv_sec + ts.tv_nsec / 1e6;
} }
static void reset_tap_chain(Tempo *tempo, long t) { static void reset_tap_chain(Tempo *tempo, long t) {
@@ -93,7 +93,7 @@ static void add_tap_to_chain(Tempo *tempo, long t) {
void tempo_init(Tempo *tempo, float value) { void tempo_init(Tempo *tempo, float value) {
long t; long t;
t = now(); t = now_ms();
reset_tap_chain(tempo, t); reset_tap_chain(tempo, t);
@@ -105,7 +105,7 @@ void tempo_set(Tempo *tempo, float value) {
long t; long t;
long progress; long progress;
t = now(); t = now_ms();
progress = (t - tempo->last_reset) % tempo->beat_length; progress = (t - tempo->last_reset) % tempo->beat_length;
@@ -118,7 +118,7 @@ void tempo_set(Tempo *tempo, float value) {
void tempo_tap(Tempo *tempo) { void tempo_tap(Tempo *tempo) {
long t; long t;
t = now(); t = now_ms();
if (!is_chain_active(*tempo, t)) { if (!is_chain_active(*tempo, t)) {
reset_tap_chain(tempo, t); reset_tap_chain(tempo, t);
@@ -130,7 +130,7 @@ void tempo_tap(Tempo *tempo) {
double tempo_total(const Tempo *tempo) { double tempo_total(const Tempo *tempo) {
long t; long t;
t = now(); t = now_ms();
return (double)(t - tempo->last_reset) / (double)tempo->beat_length; return (double)(t - tempo->last_reset) / (double)tempo->beat_length;
} }
+11 -8
View File
@@ -1,4 +1,6 @@
#include <sys/time.h> #include <bits/time.h>
#include <limits.h>
#include <time.h>
#include "types.h" #include "types.h"
@@ -7,24 +9,25 @@
void timer_init(Timer *timer, const unsigned int target) { void timer_init(Timer *timer, const unsigned int target) {
timer->counter = 0; timer->counter = 0;
timer->target = target; timer->target = target;
clock_gettime(CLOCK_REALTIME, &timer->start);
gettimeofday(&timer->start, NULL);
} }
bool timer_inc(Timer *timer) { bool timer_inc(Timer *timer) {
timer->counter += 1; timer->counter += 1;
return timer->counter >= timer->target; return timer->counter == UINT_MAX || timer->counter >= timer->target;
} }
double timer_reset(Timer *timer) { double timer_reset(Timer *timer) {
struct timeval stop; struct timespec stop;
double secs; double secs;
double per_secs; double per_secs;
gettimeofday(&stop, NULL); if (clock_gettime(CLOCK_REALTIME, &stop) != 0) {
return 0.0;
}
secs = (double)(stop.tv_usec - timer->start.tv_usec) / 1000000 + secs = (double)(stop.tv_sec - timer->start.tv_sec) +
(double)(stop.tv_sec - timer->start.tv_sec); (double)(stop.tv_nsec - timer->start.tv_nsec) / 1e9;
per_secs = (double)timer->counter / secs; per_secs = (double)timer->counter / secs;
timer->start = stop; timer->start = stop;
+30 -23
View File
@@ -50,13 +50,18 @@ typedef struct Parameters {
unsigned int video_buffers; unsigned int video_buffers;
unsigned int video_size; unsigned int video_size;
bool video_reconnect; bool video_reconnect;
char video_fourcc[5];
#endif /* VIDEO_IN */ #endif /* VIDEO_IN */
unsigned int internal_size; unsigned int internal_size;
bool load_state; bool load_state;
bool save_state; bool save_state;
bool auto_save;
bool midi_reconnect; bool midi_reconnect;
bool trace_midi; bool trace_midi;
bool trace_fps; bool trace_fps;
unsigned int glfw_backend;
unsigned int opengl_major;
unsigned int opengl_minor;
} Parameters; } Parameters;
// file.c // file.c
@@ -100,34 +105,34 @@ typedef struct ShaderProgram {
GLuint frame_buffers[ARRAY_SIZE]; GLuint frame_buffers[ARRAY_SIZE];
GLuint fragment_shaders[ARRAY_SIZE]; GLuint fragment_shaders[ARRAY_SIZE];
GLuint itime_locations[ARRAY_SIZE]; GLint itime_locations[ARRAY_SIZE];
GLuint itempo_locations[ARRAY_SIZE]; GLint itempo_locations[ARRAY_SIZE];
GLuint ibeats_locations[ARRAY_SIZE]; GLint ibeats_locations[ARRAY_SIZE];
GLuint ifps_locations[ARRAY_SIZE]; GLint ifps_locations[ARRAY_SIZE];
GLuint ires_locations[ARRAY_SIZE]; GLint ires_locations[ARRAY_SIZE];
GLuint itexres_locations[ARRAY_SIZE]; GLint itexres_locations[ARRAY_SIZE];
GLuint iinres_locations[ARRAY_SIZE]; GLint iinres_locations[ARRAY_SIZE];
GLuint iinfmt_locations[ARRAY_SIZE]; GLint iinfmt_locations[ARRAY_SIZE];
GLuint iinfps_locations[ARRAY_SIZE]; GLint iinfps_locations[ARRAY_SIZE];
GLuint idemo_locations[ARRAY_SIZE]; GLint idemo_locations[ARRAY_SIZE];
GLuint iautorand_locations[ARRAY_SIZE]; GLint iautorand_locations[ARRAY_SIZE];
GLuint iautorandcycle_locations[ARRAY_SIZE]; GLint iautorandcycle_locations[ARRAY_SIZE];
GLuint iseed_locations[ARRAY_SIZE]; GLint iseed_locations[ARRAY_SIZE];
GLuint istate_locations[ARRAY_SIZE]; GLint istate_locations[ARRAY_SIZE];
GLuint ipage_locations[ARRAY_SIZE]; GLint ipage_locations[ARRAY_SIZE];
GLuint iselected_locations[ARRAY_SIZE]; GLint iselected_locations[ARRAY_SIZE];
GLuint iactive_locations[ARRAY_SIZE]; GLint iactive_locations[ARRAY_SIZE];
UintArray midi_lengths; UintArray midi_lengths;
GLuint igroup_locations[ARRAY_SIZE]; GLint igroup_locations[ARRAY_SIZE];
GLuint vpos_locations[ARRAY_SIZE]; GLint vpos_locations[ARRAY_SIZE];
GLuint textures_locations[ARRAY_SIZE]; GLint textures_locations[ARRAY_SIZE];
unsigned int sub_type_count; unsigned int sub_type_count;
unsigned int sub_variant_count; unsigned int sub_variant_count;
GLuint sub_locations[ARRAY_SIZE]; GLint sub_locations[ARRAY_SIZE];
unsigned int active_count; unsigned int active_count;
@@ -232,7 +237,7 @@ typedef struct MidiBackgroundListenArgs {
MidiDevice *device; MidiDevice *device;
Context *context; Context *context;
void (*event_callback)(unsigned char code, unsigned char value); void (*event_callback)(unsigned char code, unsigned char value);
} MidiBackgroundReadArgs; } MidiBackgroundListenArgs;
// state.c // state.c
@@ -250,6 +255,7 @@ typedef struct StateConfig {
UintArray codes; UintArray codes;
UintArray fader_codes; UintArray fader_codes;
UintArray values_offsets; UintArray values_offsets;
UintArray random_ignored;
unsigned int value_count; unsigned int value_count;
@@ -274,12 +280,13 @@ typedef struct StateBackgroundWriteArgs {
Context *context; Context *context;
StateConfig state_config; StateConfig state_config;
MidiDevice *midi; MidiDevice *midi;
bool auto_save;
} StateBackgroundWriteArgs; } StateBackgroundWriteArgs;
// timer.c // timer.c
typedef struct Timer { typedef struct Timer {
struct timeval start; struct timespec start;
unsigned int counter; unsigned int counter;
unsigned int target; unsigned int target;
} Timer; } Timer;
+81 -25
View File
@@ -16,7 +16,6 @@
#include "timer.h" #include "timer.h"
#include "video.h" #include "video.h"
static const unsigned int pixel_format = V4L2_PIX_FMT_YUYV;
static const enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; static const enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
static void ioctl_error(VideoCapture *video_capture, const char *operation, static void ioctl_error(VideoCapture *video_capture, const char *operation,
@@ -70,14 +69,31 @@ static void ioctl_error(VideoCapture *video_capture, const char *operation,
video_capture->error = true; video_capture->error = true;
} }
static void open_device(VideoCapture *video_capture, const char *name) { static void fourcc_to_string(unsigned int fourcc, char *str) {
str[0] = (char)(fourcc & 0xFF);
str[1] = (char)((fourcc >> 8) & 0xFF);
str[2] = (char)((fourcc >> 16) & 0xFF);
str[3] = (char)((fourcc >> 24) & 0xFF);
str[4] = '\0';
}
static int string_to_fourcc(const char *str) {
return (unsigned int)str[0] | ((unsigned int)str[1] << 8) |
((unsigned int)str[2] << 16) | ((unsigned int)str[3] << 24);
}
static void open_device(VideoCapture *video_capture, const char *name,
bool log_error) {
strlcpy(video_capture->name, name, STR_LEN); strlcpy(video_capture->name, name, STR_LEN);
video_capture->error = false; video_capture->error = false;
video_capture->fd = -1; video_capture->fd = -1;
video_capture->buf_count = 0;
video_capture->fd = open(name, O_RDWR | O_NONBLOCK); video_capture->fd = open(name, O_RDWR | O_NONBLOCK);
if (video_capture->fd == -1) { if (video_capture->fd == -1) {
log_warn("(%s) Cannot open device", name); if (log_error) {
log_warn("(%s) Cannot open device", name);
}
video_capture->error = true; video_capture->error = true;
} }
} }
@@ -108,7 +124,8 @@ static bool check_caps(VideoCapture *video_capture) {
} }
static bool get_available_sizes(VideoCapture *video_capture, static bool get_available_sizes(VideoCapture *video_capture,
unsigned int preferred_height) { unsigned int preferred_height,
unsigned int pixel_format) {
struct v4l2_frmsizeenum fmt_enum; struct v4l2_frmsizeenum fmt_enum;
unsigned int index; unsigned int index;
bool found = false; bool found = false;
@@ -161,8 +178,9 @@ static bool get_available_sizes(VideoCapture *video_capture,
return true; return true;
} }
static bool set_format(VideoCapture *video_capture) { static bool set_format(VideoCapture *video_capture, unsigned int pixel_format) {
struct v4l2_format fmt; struct v4l2_format fmt;
char fourcc[STR_LEN];
memset(&fmt, 0, sizeof(fmt)); memset(&fmt, 0, sizeof(fmt));
@@ -183,9 +201,9 @@ static bool set_format(VideoCapture *video_capture) {
video_capture->pixelformat = fmt.fmt.pix.pixelformat; video_capture->pixelformat = fmt.fmt.pix.pixelformat;
video_capture->bytesperline = fmt.fmt.pix.bytesperline; video_capture->bytesperline = fmt.fmt.pix.bytesperline;
log_info("(%s) Format fourcc: %c%c%c%c", video_capture->name, fourcc_to_string(fmt.fmt.pix.pixelformat, fourcc);
fmt.fmt.pix.pixelformat, fmt.fmt.pix.pixelformat >> 8,
fmt.fmt.pix.pixelformat >> 16, fmt.fmt.pix.pixelformat >> 24); log_info("(%s) Format fourcc: %s", video_capture->name, fourcc);
log_info("(%s) Resolution: %dx%d", video_capture->name, fmt.fmt.pix.width, log_info("(%s) Resolution: %dx%d", video_capture->name, fmt.fmt.pix.width,
fmt.fmt.pix.height); fmt.fmt.pix.height);
@@ -211,6 +229,9 @@ static bool request_buffers(VideoCapture *video_capture,
log_info("(%s) V4L2 Buffer Count: %d", video_capture->name, reqbuf.count); log_info("(%s) V4L2 Buffer Count: %d", video_capture->name, reqbuf.count);
video_capture->buf_count = reqbuf.count; video_capture->buf_count = reqbuf.count;
for (unsigned int i = 0; i < reqbuf.count; i++) {
video_capture->exp_fd[i] = -1;
}
return true; return true;
} }
@@ -262,7 +283,7 @@ static bool open_stream(VideoCapture *video_capture) {
return true; return true;
} }
static void create_image_buffer(const VideoCapture *video_capture, static bool create_image_buffer(VideoCapture *video_capture,
struct v4l2_buffer *buf, unsigned int index) { struct v4l2_buffer *buf, unsigned int index) {
memset(buf, 0, sizeof(*buf)); memset(buf, 0, sizeof(*buf));
@@ -270,15 +291,24 @@ static void create_image_buffer(const VideoCapture *video_capture,
buf->memory = V4L2_MEMORY_MMAP; buf->memory = V4L2_MEMORY_MMAP;
buf->index = index; buf->index = index;
ioctl(video_capture->fd, VIDIOC_QBUF, buf); if (ioctl(video_capture->fd, VIDIOC_QBUF, buf) == -1) {
ioctl_error(video_capture, "VIDIOC_QBUF", "Could not enqueue buffer");
return false;
}
return true;
} }
static void create_image_buffers(VideoCapture *video_capture) { static bool create_image_buffers(VideoCapture *video_capture) {
unsigned int i; unsigned int i;
for (i = 0; i < video_capture->buf_count; i++) { for (i = 0; i < video_capture->buf_count; i++) {
create_image_buffer(video_capture, &video_capture->buf[i], i); if (!create_image_buffer(video_capture, &video_capture->buf[i], i)) {
return false;
}
} }
return true;
} }
static void close_stream(const VideoCapture *video_capture) { static void close_stream(const VideoCapture *video_capture) {
@@ -290,11 +320,15 @@ static unsigned int read_video(VideoCapture *video_capture) {
if (ioctl(video_capture->fd, VIDIOC_DQBUF, if (ioctl(video_capture->fd, VIDIOC_DQBUF,
&video_capture->buf[video_capture->buf_index]) != -1) { &video_capture->buf[video_capture->buf_index]) != -1) {
ioctl(video_capture->fd, VIDIOC_QBUF, if (ioctl(video_capture->fd, VIDIOC_QBUF,
&video_capture->buf[video_capture->buf_index]); &video_capture->buf[video_capture->buf_index]) == -1) {
video_capture->buf_index = video_capture->error = true;
(video_capture->buf_index + 1) % video_capture->buf_count; return false;
return true; } else {
video_capture->buf_index =
(video_capture->buf_index + 1) % video_capture->buf_count;
return true;
}
} }
if (ioctl(video_capture->fd, VIDIOC_QUERYCAP, &cap) == -1) { if (ioctl(video_capture->fd, VIDIOC_QUERYCAP, &cap) == -1) {
@@ -305,38 +339,56 @@ static unsigned int read_video(VideoCapture *video_capture) {
} }
void video_init(VideoCapture *video_capture, const char *name, void video_init(VideoCapture *video_capture, const char *name,
unsigned int preferred_height, unsigned int buffer_count) { unsigned int preferred_height, unsigned int buffer_count,
open_device(video_capture, name); const char *video_fourcc, bool log_error) {
open_device(video_capture, name, log_error);
if (video_capture->error) { if (video_capture->error) {
return; return;
} }
if (!check_caps(video_capture)) { if (!check_caps(video_capture)) {
video_capture->error = true;
video_free(video_capture);
return; return;
} }
if (!get_available_sizes(video_capture, preferred_height)) { if (!get_available_sizes(video_capture, preferred_height,
string_to_fourcc(video_fourcc))) {
video_capture->error = true;
video_free(video_capture);
return; return;
} }
if (!set_format(video_capture)) { if (!set_format(video_capture, string_to_fourcc(video_fourcc))) {
video_capture->error = true;
video_free(video_capture);
return; return;
} }
if (!request_buffers(video_capture, buffer_count)) { if (!request_buffers(video_capture, buffer_count)) {
video_capture->error = true;
video_free(video_capture);
return; return;
} }
if (!export_buffers(video_capture)) { if (!export_buffers(video_capture)) {
video_capture->error = true;
video_free(video_capture);
return; return;
} }
if (!open_stream(video_capture)) { if (!open_stream(video_capture)) {
video_capture->error = true;
video_free(video_capture);
return; return;
} }
create_image_buffers(video_capture); if (!create_image_buffers(video_capture)) {
video_capture->error = true;
video_free(video_capture);
return;
}
} }
void *video_background_read(void *args) { void *video_background_read(void *args) {
@@ -376,20 +428,24 @@ void *video_background_read(void *args) {
video_capture->name); video_capture->name);
video_capture->disconnected = true; video_capture->disconnected = true;
context->input_formats[input_index] = 0; context->input_formats[input_index] = 0;
context->input_resolutions[input_index][0] = 0;
context->input_resolutions[input_index][1] = 0;
} }
free(process_args);
pthread_exit(NULL); pthread_exit(NULL);
} }
void video_free(const VideoCapture *video_capture) { void video_free(const VideoCapture *video_capture) {
unsigned int i; unsigned int i;
close_stream(video_capture);
for (i = 0; i < video_capture->buf_count; i++) { for (i = 0; i < video_capture->buf_count; i++) {
close(video_capture->exp_fd[i]); if (video_capture->exp_fd[i] != -1) {
close(video_capture->exp_fd[i]);
}
} }
if (video_capture->fd != -1) { if (video_capture->fd != -1) {
close_stream(video_capture);
close(video_capture->fd); close(video_capture->fd);
} }
} }
+2 -1
View File
@@ -6,7 +6,8 @@
#ifdef VIDEO_IN #ifdef VIDEO_IN
void video_init(VideoCapture *video_capture, const char *name, void video_init(VideoCapture *video_capture, const char *name,
unsigned int preferred_height, unsigned int buffer_count); unsigned int preferred_height, unsigned int buffer_count,
const char *video_fourcc, bool log_error);
void *video_background_read(void *args); void *video_background_read(void *args);
+47 -12
View File
@@ -7,7 +7,8 @@
#include "window.h" #include "window.h"
static void init_glfw(void (*error_callback)(int, const char *)) { static void init_glfw(void (*error_callback)(int, const char *),
const unsigned int backend) {
log_info("[GLFW] Initializing..."); log_info("[GLFW] Initializing...");
// set errors handler // set errors handler
@@ -16,6 +17,30 @@ static void init_glfw(void (*error_callback)(int, const char *)) {
// print current GLFW version // print current GLFW version
log_info("[GLFW] %s", glfwGetVersionString()); log_info("[GLFW] %s", glfwGetVersionString());
switch (backend) {
#ifdef GLFW_PLATFORM
case GLFW_BACKEND_X11:
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
log_info("[GLFW] platform: X11");
break;
case GLFW_BACKEND_WAYLAND:
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
log_info("[GLFW] platform: Wayland");
break;
case GLFW_BACKEND_COCOA:
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_COCOA);
log_info("[GLFW] platform: Cocoa");
break;
case GLFW_BACKEND_WIN32:
glfwInitHint(GLFW_PLATFORM, GLFW_BACKEND_WIN32);
log_info("[GLFW] platform: Win32");
break;
#endif /* GLFW_PLATFORM */
default:
log_info("[GLFW] platform: Any");
break;
}
// init GLFW // init GLFW
if (!glfwInit()) { if (!glfwInit()) {
log_error("[GLFW] Initialization failed"); log_error("[GLFW] Initialization failed");
@@ -44,7 +69,9 @@ static GLFWmonitor *get_monitor(unsigned char monitor_index) {
} }
static GLFWwindow * static GLFWwindow *
create_window(GLFWmonitor *monitor, const char *title, Window *shared_context, create_window(GLFWmonitor *monitor, const char *title,
const unsigned int opengl_major, const unsigned int opengl_minor,
Window *shared_context,
void (*key_callback)(Window *, int, int, int, int)) { void (*key_callback)(Window *, int, int, int, int)) {
GLFWwindow *window; GLFWwindow *window;
@@ -57,12 +84,14 @@ create_window(GLFWmonitor *monitor, const char *title, Window *shared_context,
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE); glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
// Context related hints // Context related hints
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, opengl_major);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, opengl_minor);
#ifdef GL_DEBUG #ifdef GL_DEBUG
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
#endif #endif
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if (opengl_major > 4 || (opengl_major == 3 && opengl_minor >= 2)) {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
// create fullscreen window in selected monitor // create fullscreen window in selected monitor
window = glfwCreateWindow(1, 1, title, monitor, shared_context); window = glfwCreateWindow(1, 1, title, monitor, shared_context);
@@ -86,8 +115,9 @@ create_window(GLFWmonitor *monitor, const char *title, Window *shared_context,
static void use_window(GLFWwindow *window) { glfwMakeContextCurrent(window); } static void use_window(GLFWwindow *window) { glfwMakeContextCurrent(window); }
void window_startup(void (*error_callback)(int, const char *)) { void window_startup(void (*error_callback)(int, const char *),
init_glfw(error_callback); const unsigned int backend) {
init_glfw(error_callback, backend);
} }
void window_terminate() { void window_terminate() {
@@ -96,17 +126,21 @@ void window_terminate() {
} }
Window *window_init(const char *title, unsigned char monitor_index, Window *window_init(const char *title, unsigned char monitor_index,
bool windowed, Window *shared_context, bool windowed, const unsigned int opengl_major,
const unsigned int opengl_minor, Window *shared_context,
void (*key_callback)(Window *, int, int, int, int)) { void (*key_callback)(Window *, int, int, int, int)) {
GLFWwindow *window; GLFWwindow *window;
GLFWmonitor *monitor; GLFWmonitor *monitor;
monitor = windowed ? NULL : get_monitor(monitor_index); monitor = windowed ? NULL : get_monitor(monitor_index);
window = create_window(monitor, title, shared_context, key_callback); window = create_window(monitor, title, opengl_major, opengl_minor,
shared_context, key_callback);
use_window(window); use_window(window);
glfwSwapInterval(0);
return window; return window;
} }
@@ -131,9 +165,10 @@ void window_use(Window *window, Context *context) {
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
context->resolution[0] = width; context->resolution[0] = width;
context->resolution[1] = height; context->resolution[1] = height;
context->tex_resolution[0] = if (height > 0) {
(int)(context->tex_resolution[1] * context->resolution[0] / context->tex_resolution[0] =
context->resolution[1]); (int)(context->tex_resolution[1] * width / height);
}
} }
void window_close(Window *window) { void window_close(Window *window) {
+3 -2
View File
@@ -3,12 +3,13 @@
#ifndef WINDOW_H #ifndef WINDOW_H
#define WINDOW_H #define WINDOW_H
void window_startup(void (*error_callback)(int, const char *)); void window_startup(void (*error_callback)(int, const char *), const unsigned int backend);
void window_terminate(); void window_terminate();
Window *window_init(const char *title, unsigned char monitor_index, Window *window_init(const char *title, unsigned char monitor_index,
bool windowed, Window *shared_context, bool windowed, const unsigned int opengl_major,
const unsigned int opengl_minor, Window *shared_context,
void (*key_callback)(Window *, int, int, int, int)); void (*key_callback)(Window *, int, int, int, int));
void window_update_title(Window *window, const char *title); void window_update_title(Window *window, const char *title);