This commit is contained in:
commit
70d1d18615
|
@ -0,0 +1,12 @@
|
|||
# Compilation
|
||||
*.o
|
||||
*.data
|
||||
*.wasm
|
||||
build/
|
||||
Cakefoot.x86_64
|
||||
|
||||
# Auto complete
|
||||
compile_commands.json
|
||||
|
||||
# SPACEBOX
|
||||
BPmono.ttf
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "lib/sb"]
|
||||
path = lib/sb
|
||||
url = https://open.shampoo.ooo/shampoo/spacebox
|
|
@ -0,0 +1,188 @@
|
|||
# >> Cakefoot <<
|
||||
#
|
||||
# This Makefile is used to create a Linux, web, or Android build.
|
||||
#
|
||||
# The [SPACEBOX] game framework source code from <https://open.shampoo.ooo/shampoo/spacebox> is required.
|
||||
|
||||
#########
|
||||
# Paths #
|
||||
#########
|
||||
|
||||
# Location of project specific source files
|
||||
SRC_DIR := src/
|
||||
|
||||
# Locations of [SPACEBOX] source and its packaged dependencies
|
||||
SB_DIR := lib/sb/
|
||||
SB_SRC_DIR := $(SB_DIR)src/
|
||||
SB_LIB_DIR := $(SB_DIR)lib/
|
||||
SDLGFX2_DIR := $(SB_LIB_DIR)sdl2-gfx/
|
||||
GLEW_DIR := $(SB_LIB_DIR)glew/
|
||||
|
||||
# C and C++ compiler commands
|
||||
CC := clang
|
||||
CXX := clang++
|
||||
|
||||
# Location of SDL config program. See README.md for how to compile the SDL library and this utility.
|
||||
SDLCONFIG := $(HOME)/local/sdl/bin/sdl2-config
|
||||
|
||||
# Include BPmono.ttf in the project
|
||||
CREATE_FONT_SYMLINK := ln -nsf $(SB_DIR)"BPmono.ttf" .
|
||||
|
||||
#############################
|
||||
# Based on above parameters #
|
||||
#############################
|
||||
|
||||
SDL_CFLAGS = $(shell $(SDLCONFIG) --cflags)
|
||||
SDL_LFLAGS := $(shell $(SDLCONFIG) --libs)
|
||||
SB_H_FILES := $(wildcard $(addprefix $(SB_SRC_DIR),*.hpp))
|
||||
SB_O_FILES := $(filter-out $(addprefix $(SB_SRC_DIR),filesystem.o Connection.o Switch.o Carousel.o time_it.o),$(SB_H_FILES:.hpp=.o))
|
||||
SRC_H_FILES := $(wildcard $(addprefix $(SRC_DIR),*.hpp))
|
||||
SRC_O_FILES := $(SRC_H_FILES:.hpp=.o)
|
||||
|
||||
##################################################################
|
||||
# Object files for [SPACEBOX], its dependencies, and the project #
|
||||
##################################################################
|
||||
|
||||
$(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
|
||||
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
|
||||
$(CC) $< $(CFLAGS) -c -o $@
|
||||
|
||||
$(SB_SRC_DIR)extension.o : $(addprefix $(SB_SRC_DIR),Box.hpp Segment.hpp Color.hpp filesystem.hpp Pixels.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)Node.o : $(addprefix $(SB_SRC_DIR),Game.hpp Configuration.hpp Delegate.hpp Display.hpp Input.hpp Box.hpp Audio.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)Sprite.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Animation.hpp Color.hpp extension.hpp Pixels.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)Game.o : $(addprefix $(SB_SRC_DIR),extension.hpp Node.hpp Sprite.hpp Recorder.hpp Input.hpp Configuration.hpp \
|
||||
Delegate.hpp Audio.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)Animation.o : $(addprefix $(SB_SRC_DIR),Node.hpp Timer.hpp)
|
||||
$(SB_SRC_DIR)Recorder.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Configuration.hpp Delegate.hpp Animation.hpp extension.hpp)
|
||||
$(SB_SRC_DIR)Input.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Configuration.hpp Delegate.hpp)
|
||||
$(SB_SRC_DIR)Configuration.o : $(addprefix $(SB_SRC_DIR),Node.hpp Animation.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)Delegate.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Input.hpp)
|
||||
$(SB_SRC_DIR)Display.o : $(addprefix $(SB_SRC_DIR),Node.hpp Game.hpp Box.hpp Configuration.hpp Delegate.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)Box.o : $(addprefix $(SB_SRC_DIR),extension.hpp Segment.hpp)
|
||||
$(SB_SRC_DIR)Segment.o : $(addprefix $(SB_SRC_DIR),extension.hpp Box.hpp)
|
||||
$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp Log.hpp utility.hpp)
|
||||
$(SB_SRC_DIR)Audio.o : $(addprefix $(SB_SRC_DIR),Node.hpp Display.hpp Configuration.hpp Box.hpp filesystem.hpp extension.hpp)
|
||||
$(SB_SRC_DIR)GLObject.o : $(addprefix $(SB_SRC_DIR),Log.hpp)
|
||||
$(SB_SRC_DIR)Texture.o : $(addprefix $(SB_SRC_DIR),GLObject.hpp filesystem.hpp Log.hpp)
|
||||
$(SB_SRC_DIR)VBO.o : $(addprefix $(SB_SRC_DIR),Log.hpp GLObject.hpp Attributes.hpp extension.hpp)
|
||||
$(SB_SRC_DIR)Attributes.o : $(addprefix $(SB_SRC_DIR),Log.hpp extension.hpp)
|
||||
$(SB_SRC_DIR)Model.o : $(addprefix $(SB_SRC_DIR),extension.hpp Attributes.hpp Texture.hpp utility.hpp Carousel.hpp)
|
||||
$(SRC_DIR)Cakefoot.o : $(SRC_H_FILES) $(SB_H_FILES)
|
||||
%.o : %.cpp %.hpp
|
||||
$(CXX) $(CXXFLAGS) $< -c -o $@
|
||||
|
||||
###############
|
||||
# Linux build #
|
||||
###############
|
||||
|
||||
Cakefoot.x86_64 : CFLAGS = -g -Wall -Wextra -O1 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) $(SDL_CFLAGS) \
|
||||
-I $(HOME)/ext/software/emsdk/upstream/emscripten/system/include
|
||||
Cakefoot.x86_64 : CXXFLAGS = $(CFLAGS) --std=c++17
|
||||
Cakefoot.x86_64 : LFLAGS = $(SDL_LFLAGS) -Wl,--enable-new-dtags -lpthread -lGL -lGLESv2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs
|
||||
Cakefoot.x86_64 : $(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) $(SB_O_FILES) $(SRC_O_FILES)
|
||||
$(CREATE_FONT_SYMLINK)
|
||||
$(CXX) $^ $(LFLAGS) -D__LINUX__ -o Cakefoot.x86_64
|
||||
|
||||
#############
|
||||
# Web build #
|
||||
#############
|
||||
|
||||
# Use Emscripten to output JavaScript
|
||||
|
||||
EMSCRIPTENHOME = $(HOME)/ext/software/emsdk/upstream/emscripten
|
||||
EMSCRIPTEN_CFLAGS = -O0 -Wall -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS="['png', 'jpg']" -s USE_SDL_TTF=2 -s USE_SDL_MIXER=2 \
|
||||
--no-heap-copy -I $(SB_LIB_DIR) -I $(SB_SRC_DIR)
|
||||
EMSCRIPTEN_LFLAGS = -s MIN_WEBGL_VERSION=2 -s EXPORTED_FUNCTIONS="['_main', '_malloc']" -s ALLOW_MEMORY_GROWTH=1 -s FULL_ES3=1 \
|
||||
-sLLD_REPORT_UNDEFINED -sNO_DISABLE_EXCEPTION_CATCHING
|
||||
EMSCRIPTEN_PRELOADS = --preload-file "BPmono.ttf"@/ --preload-file "config.json"@/ --preload-file "resource/"@/"resource/" \
|
||||
--preload-file "src/shaders/"@/"src/shaders/"
|
||||
|
||||
cakefoot.js : CC = $(EMSCRIPTENHOME)/emcc
|
||||
cakefoot.js : CXX = $(EMSCRIPTENHOME)/em++
|
||||
cakefoot.js : CFLAGS = $(EMSCRIPTEN_CFLAGS)
|
||||
cakefoot.js : CXXFLAGS = $(CFLAGS) --std=c++17
|
||||
cakefoot.js : $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) $(SB_O_FILES) $(SRC_O_FILES)
|
||||
$(CREATE_FONT_SYMLINK)
|
||||
$(CXX) $^ $(CXXFLAGS) $(EMSCRIPTEN_LFLAGS) $(EMSCRIPTEN_PRELOADS) -o cakefoot.js
|
||||
|
||||
#################
|
||||
# Android build #
|
||||
#################
|
||||
|
||||
# Detailed info on how this build target was originally created for the fill_screen demo is in README.md at the root of the repository. It
|
||||
# requires the Android SDK and the source packages for SDL. The paths below should be edited to match the local system. Icon creation requires
|
||||
# Imagemagick's convert tool from <https://imagemagick.org/>.
|
||||
|
||||
SDL_SRC := $(HOME)/ext/software/SDL2-2.26.3
|
||||
SDL_IMAGE_SRC := $(HOME)/ext/software/SDL2_image-2.6.2-android
|
||||
SDL_MIXER_SRC := $(HOME)/ext/software/SDL2_mixer-2.6.2-android
|
||||
SDL_TTF_SRC := $(HOME)/ext/software/SDL2_ttf-2.20.1-android
|
||||
SDL_ANDROID_PROJECT := $(SDL_SRC)/android-project
|
||||
ANDROID_MK := app/jni/src/Android.mk
|
||||
ANDROID_APP_MK := app/jni/Application.mk
|
||||
ANDROID_MANIFEST := app/src/main/AndroidManifest.xml
|
||||
ANDROID_SDK := $(HOME)/local/Android
|
||||
ANDROID_PACKAGE := ooo.shampoo.foam
|
||||
ANDROID_BUILD_DIR := build/android/$(ANDROID_PACKAGE)
|
||||
ANDROID_CLASS := Cakefoot
|
||||
ANDROID_CLASS_DIR := app/src/main/java/$(subst .,/,$(ANDROID_PACKAGE))
|
||||
|
||||
# The skeleton for the Android build is based on the SDL android-project. The libraries are symlinked in. If the script that rewrites the skeleton
|
||||
# has changed, start with a fresh skeleton. Use the SPACEBOX revise skeleton script to edit the SDL android-project parameters.
|
||||
$(ANDROID_BUILD_DIR): $(SDL_SRC)/android-project/ $(SB_SRC_DIR)/android/revise_skeleton.sh
|
||||
-mkdir -p $(ANDROID_BUILD_DIR)
|
||||
rsync -ar $(SDL_SRC)/android-project/ $(ANDROID_BUILD_DIR)
|
||||
ln -nsf $(SDL_SRC) $(ANDROID_BUILD_DIR)/app/jni/SDL
|
||||
ln -nsf $(SDL_IMAGE_SRC) $(ANDROID_BUILD_DIR)/app/jni/SDL2_image
|
||||
ln -nsf $(SDL_MIXER_SRC) $(ANDROID_BUILD_DIR)/app/jni/SDL2_mixer
|
||||
ln -nsf $(SDL_TTF_SRC) $(ANDROID_BUILD_DIR)/app/jni/SDL2_ttf
|
||||
$(SB_SRC_DIR)/android/revise_skeleton.sh $(ANDROID_PACKAGE) $(ANDROID_BUILD_DIR) $(ANDROID_MANIFEST) $(ANDROID_APP_MK) $(ANDROID_MK) $(ANDROID_CLASS) \
|
||||
$(ANDROID_APP_NAME) $(ANDROID_MIN_TARGET) $(ANDROID_NDK) "Cakefoot" "21" "24.0.8215888" $(SB_SRC_DIR) $(SB_LIB_DIR) $(SRC_DIR)
|
||||
ln -nsf $(OPENCV_ANDROID_SDK)/sdk/native/libs $(ANDROID_BUILD_DIR)/app/jni/src/opencv
|
||||
ln -nsf $(CURL_ANDROID)/jni/build/curl $(ANDROID_BUILD_DIR)/app/jni/src/curl
|
||||
ln -nsf $(CURL_ANDROID)/jni/build/openssl $(ANDROID_BUILD_DIR)/app/jni/src/openssl
|
||||
sed -i "s/^APP_CPPFLAGS.*/& -nostartfiles/" "$(ANDROID_BUILD_DIR)/$(ANDROID_APP_MK)"
|
||||
sed -i "s/org.libsdl.app/$(ANDROID_PACKAGE)/" "$(ANDROID_BUILD_DIR)/app/build.gradle" "$(ANDROID_BUILD_DIR)/$(ANDROID_MANIFEST)"
|
||||
|
||||
# Extend the SDLActivity class
|
||||
$(ANDROID_BUILD_DIR)/$(ANDROID_CLASS_DIR)/$(ANDROID_CLASS).java: $(SB_SRC_DIR)/android/main_class.sh
|
||||
$(SB_SRC_DIR)/android/main_class.sh $(ANDROID_PACKAGE) $(ANDROID_CLASS) $(ANDROID_BUILD_DIR)/$(ANDROID_CLASS_DIR)
|
||||
|
||||
# Generate icon
|
||||
$(ANDROID_BUILD_DIR)/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: $(SB_SRC_DIR)/android/generate_icon.sh $(SB_DIR)/icon
|
||||
$(SB_SRC_DIR)/android/generate_icon.sh $(ANDROID_BUILD_DIR) "$(SB_DIR)/icon/foreground.png" "$(SB_DIR)/icon/background.png"
|
||||
|
||||
# Custom assets
|
||||
$(ANDROID_BUILD_DIR)/app/src/main/assets: config*.json $(shell find resource/) $(shell find src/shaders)
|
||||
-mkdir -p $(ANDROID_BUILD_DIR)/app/src/main/assets
|
||||
rsync -ar --relative config*.json resource src/shaders $(ANDROID_BUILD_DIR)/app/src/main/assets
|
||||
|
||||
# Run gradle and generate an APK
|
||||
$(ANDROID_BUILD_DIR)/app-debug.apk: $(ANDROID_BUILD_DIR) $(ANDROID_BUILD_DIR)/$(ANDROID_CLASS_DIR)/$(ANDROID_CLASS).java \
|
||||
$(ANDROID_BUILD_DIR)/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml $(ANDROID_BUILD_DIR)/app/src/main/assets
|
||||
ANDROID_SDK_ROOT=$(ANDROID_SDK) $(ANDROID_BUILD_DIR)/gradlew -p $(ANDROID_BUILD_DIR) build
|
||||
ln -nsf app/build/outputs/apk/debug/app-debug.apk $(ANDROID_BUILD_DIR)
|
||||
ln -nsf app/build/outputs/apk/debug/app-release-unsigned.apk $(ANDROID_BUILD_DIR)
|
||||
|
||||
#########################
|
||||
# Clean up object files #
|
||||
#########################
|
||||
|
||||
clean :
|
||||
-find $(SRC_DIR) -iname "*.o" -delete
|
||||
|
||||
clean-all : clean
|
||||
-find $(SB_SRC_DIR) -iname "*.o" -delete
|
||||
-find $(SB_LIB_DIR) -iname "*.o" -delete
|
||||
|
||||
#############
|
||||
# compiledb #
|
||||
#############
|
||||
|
||||
# Generate a clang JSON compilation database file. This can be useful for example for code completion. It requires a
|
||||
# compiledb binary (https://pypi.org/project/compiledb/). It should be generated manually every time a file is added,
|
||||
# renamed, or the compilation flags change. The generated database is based on the Linux build.
|
||||
|
||||
PATH_TO_COMPILEDB = $(HOME)/ext/software/compiledb/bin/compiledb
|
||||
compiledb :
|
||||
-$(PATH_TO_COMPILEDB) -n make Cakefoot.x86_64 -k
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"display":
|
||||
{
|
||||
"dimensions": [864, 486],
|
||||
"framerate": 60,
|
||||
"title": "Cakefoot",
|
||||
"debug": false,
|
||||
"render driver": "opengl",
|
||||
"show-cursor": true
|
||||
},
|
||||
|
||||
"configuration":
|
||||
{
|
||||
"auto-refresh": true
|
||||
},
|
||||
|
||||
"recording":
|
||||
{
|
||||
"screenshot-directory": "local/screenshots",
|
||||
"video-directory": "local/video",
|
||||
"enabled": true,
|
||||
"write-mp4": true,
|
||||
"video-frame-length": 33.333,
|
||||
"max-video-memory": 2000,
|
||||
"mp4-pixel-format": "yuv420p"
|
||||
},
|
||||
|
||||
"input":
|
||||
{
|
||||
"suppress-any-key-on-mods": true
|
||||
},
|
||||
|
||||
"log":
|
||||
{
|
||||
"enabled": true,
|
||||
"output-directory": "/var/log/sb/",
|
||||
"debug-to-stdout": true,
|
||||
"debug-to-file": true,
|
||||
"info-file-name": "cakefoot_info.log",
|
||||
"debug-file-name": "cakefoot_debug.log"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"display":
|
||||
{
|
||||
"render driver": "opengles2"
|
||||
},
|
||||
|
||||
"recording":
|
||||
{
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
"log":
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3ba3be449618ef2a7a5a46cef61492d57d04ed82
|
|
@ -0,0 +1,183 @@
|
|||
/* >> Cakefoot << */
|
||||
|
||||
#if defined(__ANDROID__) || defined(ANDROID)
|
||||
#include <android/asset_manager_jni.h>
|
||||
#endif
|
||||
|
||||
#include "Cakefoot.hpp"
|
||||
|
||||
Cakefoot::Cakefoot()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
SDL_SetHint(SDL_HINT_ORIENTATIONS, "Portrait");
|
||||
#endif
|
||||
|
||||
start_button.scale(0.5f);
|
||||
start_button.on_state_change([&](bool state, int count){
|
||||
if (state)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Hello, " << state << " World! " << count;
|
||||
sb::Log::log(message);
|
||||
start_button.press(1);
|
||||
}
|
||||
});
|
||||
|
||||
/* subscribe to command events */
|
||||
delegate().subscribe(&Cakefoot::respond, this);
|
||||
delegate().subscribe(&Cakefoot::respond, this, SDL_MOUSEMOTION);
|
||||
delegate().subscribe(&Cakefoot::respond, this, SDL_MOUSEBUTTONDOWN);
|
||||
|
||||
/* loading GL context for 3D */
|
||||
load_gl_context();
|
||||
|
||||
/* Load a pointer cursor from the system library that will be freed automatically */
|
||||
poke = std::shared_ptr<SDL_Cursor>(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND), SDL_FreeCursor);
|
||||
}
|
||||
|
||||
void Cakefoot::load_gl_context()
|
||||
{
|
||||
super::load_gl_context();
|
||||
|
||||
/* Generate a vertex array object ID, bind it as current (requirement of OpenGL) */
|
||||
vao.generate();
|
||||
vao.bind();
|
||||
|
||||
/* Generate ID for the vertex buffer object that will hold all vertex data. Using one buffer for all attributes, data
|
||||
* will be copied in one after the other. */
|
||||
vbo.generate();
|
||||
vbo.bind();
|
||||
|
||||
/* Load shader program */
|
||||
GLuint vertex_shader = load_shader("src/shaders/shader.vert", GL_VERTEX_SHADER);
|
||||
GLuint fragment_shader = load_shader("src/shaders/shader.frag", GL_FRAGMENT_SHADER);
|
||||
shader_program = glCreateProgram();
|
||||
glAttachShader(shader_program, vertex_shader);
|
||||
glAttachShader(shader_program, fragment_shader);
|
||||
sb::Plane::position->bind(0, shader_program, "vertex_position");
|
||||
sb::Plane::uv->bind(1, shader_program, "vertex_uv");
|
||||
sb::Plane::color->bind(2, shader_program, "vertex_color");
|
||||
sb::Log::gl_errors("after loading shaders");
|
||||
|
||||
/* Fill VBO with attribute data */
|
||||
vbo.allocate(start_button.size(), GL_STATIC_DRAW);
|
||||
vbo.add(*sb::Plane::position);
|
||||
vbo.add(*sb::Plane::uv);
|
||||
vbo.add(*sb::Plane::color);
|
||||
sb::Log::gl_errors("after filling VBO");
|
||||
|
||||
/* link shaders */
|
||||
link_shader(shader_program);
|
||||
glUseProgram(shader_program);
|
||||
sb::Log::gl_errors("after linking");
|
||||
|
||||
/* store uniform locations after linking */
|
||||
uniform["mvp"] = glGetUniformLocation(shader_program, "mvp");
|
||||
uniform["time"] = glGetUniformLocation(shader_program, "time");
|
||||
uniform["effect"] = glGetUniformLocation(shader_program, "effect");
|
||||
uniform["uv transformation"] = glGetUniformLocation(shader_program, "uv_transformation");
|
||||
uniform["coordinate bound"] = glGetUniformLocation(shader_program, "coordinate_bound");
|
||||
uniform["model texture"] = glGetUniformLocation(shader_program, "model_texture");
|
||||
uniform["texture enabled"] = glGetUniformLocation(shader_program, "texture_enabled");
|
||||
|
||||
/* enable alpha rendering */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
sb::Log::gl_errors("after uniform locations");
|
||||
}
|
||||
|
||||
void Cakefoot::respond(SDL_Event& event)
|
||||
{
|
||||
/* Mouse interface */
|
||||
if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
/* Get mouse coordinates in pixel resolution and NDC */
|
||||
glm::vec2 mouse_pixel = event.type == SDL_MOUSEBUTTONDOWN ? glm::vec2{event.button.x, event.button.y} :
|
||||
glm::vec2{event.motion.x, event.motion.y};
|
||||
glm::vec2 mouse_ndc {
|
||||
float(mouse_pixel.x) / window_box().width() * 2.0f - 1.0f, (1.0f - float(mouse_pixel.y) / window_box().height()) * 2.0f - 1.0f
|
||||
};
|
||||
|
||||
/* Collide with start button */
|
||||
bool over_start_button = start_button.collide(mouse_ndc);
|
||||
|
||||
/* Check for press */
|
||||
if (over_start_button)
|
||||
{
|
||||
/* Set cursor to pokey finger */
|
||||
if (SDL_GetCursor() != poke.get())
|
||||
{
|
||||
SDL_SetCursor(poke.get());
|
||||
}
|
||||
|
||||
/* Respond to a click */
|
||||
if (event.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
/* Reset cursor to default arrow */
|
||||
// SDL_SetCursor(SDL_GetDefaultCursor());
|
||||
start_button.press(0);
|
||||
}
|
||||
}
|
||||
else if (SDL_GetCursor() == poke.get())
|
||||
{
|
||||
SDL_SetCursor(SDL_GetDefaultCursor());
|
||||
}
|
||||
}
|
||||
else if (sb::Delegate::compare(event, "reset"))
|
||||
{
|
||||
sb::Log::log("Goodbye, World!");
|
||||
}
|
||||
}
|
||||
|
||||
void Cakefoot::destroy_texture(GLuint* texture_id)
|
||||
{
|
||||
/* not sure why SDL_Log works here but SDL_LogDebug and SDL_LogInfo don't */
|
||||
std::ostringstream message;
|
||||
message << "destroying texture ID " << *texture_id;
|
||||
sb::Log::log(message);
|
||||
glDeleteTextures(1, texture_id);
|
||||
}
|
||||
|
||||
void Cakefoot::update()
|
||||
{
|
||||
sb::Log::gl_errors("at beginning of update");
|
||||
/* Time in seconds the game has running for */
|
||||
float time_seconds = SDL_GetTicks() / 1000.0f;
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* flat shader uniforms: time, texture ID, disabled HSV blend, scroll on */
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUniform1f(uniform["time"], time_seconds);
|
||||
glUniformMatrix4fv(uniform["mvp"], 1, GL_FALSE, &glm::mat4(1)[0][0]);
|
||||
|
||||
/* calculate the transformation matrix for displaying pudding in viewport */
|
||||
model = glm::rotate(model, 0.0f, Y_UNIT_NORMAL_3D);
|
||||
projection = glm::perspective(glm::radians(40.0f * 1 / window_box().aspect()), window_box().aspect(), 0.1f, 100.0f);
|
||||
mvp = projection * VIEW_MATRIX * model;
|
||||
|
||||
/* uniforms */
|
||||
// glUniformMatrix4fv(uniform["mvp"], 1, GL_FALSE, &mvp[0][0]);
|
||||
|
||||
/* draw pudding model */
|
||||
// glEnable(GL_DEPTH_TEST);
|
||||
|
||||
/* draws bg vertices and texture */
|
||||
// cake_model.enable();
|
||||
start_button.draw(uniform["mvp"], uniform["texture enabled"]);
|
||||
// glDrawArrays(GL_TRIANGLES, 0, cake_model.attributes("position")->count());
|
||||
|
||||
/* Display */
|
||||
SDL_GL_SwapWindow(window());
|
||||
sb::Log::gl_errors("at end of update");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Cakefoot game = Cakefoot();
|
||||
game.run();
|
||||
game.quit();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
/* >> Cakefoot << */
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Needed for functions in glm/gtx/ */
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
|
||||
/* Standard library includes */
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
// #include <algorithm>
|
||||
// #include <thread>
|
||||
// #include <mutex>
|
||||
#include <memory>
|
||||
// #include <stdexcept>
|
||||
#include <functional>
|
||||
// #include <chrono>
|
||||
|
||||
/* Include Game.hpp before any other SDL-related headers because it defines SDL_MAIN_HANDLED */
|
||||
#include "Game.hpp"
|
||||
|
||||
/* SPACEBOX external libraries included in source package */
|
||||
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
||||
#include "json/json.hpp"
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtx/matrix_decompose.hpp"
|
||||
#include "glm/gtc/matrix_access.hpp"
|
||||
|
||||
/* SPACEBOX classes and functions */
|
||||
#include "Color.hpp"
|
||||
#include "extension.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "Animation.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "GLObject.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "Attributes.hpp"
|
||||
#include "VBO.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "Box.hpp"
|
||||
#include "Switch.hpp"
|
||||
|
||||
/*!
|
||||
* A Pad is a Plane which can be clicked to launch an arbitrary user function. It can be sized and placed by setting its
|
||||
* translation and scale values.
|
||||
*
|
||||
* Each instance:
|
||||
*
|
||||
* - Shares vertices and UV in VBO
|
||||
* - Has its own Texture representing the button on-screen
|
||||
* - Has its own response to click
|
||||
* - Shares mouse collision code
|
||||
* - Has its own translate + scale transformation
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* glm::vec3 w = glm::mat3({{1, 0, 0}, {0, 1, 0}, {-0.6739, -0.74, 1}}) * glm::mat3({{.1, 0, 0}, {0, .1 * (460.0 / 768.0), 0}, {0, 0, 1}}) *
|
||||
* glm::vec3({-1, -1, 1});
|
||||
* std::cout << w << std::endl << glm::translate(glm::vec3{-0.6739, -0.74, 0}) *
|
||||
* glm::scale(glm::vec3{.1, .1 * (460.0 / 768.0), 1}) * glm::vec4{-1, -1, 0, 1} << std::endl;
|
||||
* Pad p {background.current(), {-0.6739f, -0.74f}, 0.1f, get_display().window_box().aspect(), std::function<void()>()};
|
||||
* const std::vector<glm::vec2>& p_position = *p.attributes("position");
|
||||
* glm::vec4 final_position = p.transformation() * glm::vec4{p_position[2].x, p_position[2].y, 0, 1};
|
||||
* std::cout << p.transformation() << std::endl << final_position << std::endl;
|
||||
* assert(final_position == glm::vec4({w.x, w.y, 0, 1}));
|
||||
*/
|
||||
template<typename return_type = void, typename... arguments>
|
||||
class Pad : public sb::Plane
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
inline static const glm::vec3 ROTATION_AXIS {0.0f, 0.0f, 1.0f};
|
||||
using Reaction = std::function<return_type(bool, arguments...)>;
|
||||
sb::Switch<return_type, arguments...> connection;
|
||||
Box collision_box;
|
||||
float rotation_angle = 0.0f, scale_factor = 1.0f, scale_ratio = 1.0f;
|
||||
glm::vec2 translation_vector {0.0f, 0.0f};
|
||||
|
||||
|
||||
/*!
|
||||
* Set the transformation matrix for the pad object by applying the scale to the translation and the rotation to the
|
||||
* resulting matrix, meaning the transformations will be applied to the pad in the order of: translate, scale, and
|
||||
* rotate. The collision box will be scaled and moved to fit around the position coordinates that would result from
|
||||
* applying this transformation to the position coordinates.
|
||||
*/
|
||||
void transform()
|
||||
{
|
||||
glm::vec3 scale { scale_factor, scale_factor, 1.0f };
|
||||
if (scale_ratio > 1.0f)
|
||||
{
|
||||
scale.x /= scale_ratio;
|
||||
}
|
||||
else if (scale_ratio < 1.0f)
|
||||
{
|
||||
scale.y *= scale_ratio;
|
||||
}
|
||||
collision_box.size(2.0f * glm::vec2{scale.x, scale.y}, true);
|
||||
collision_box.center(translation_vector);
|
||||
sb::Model::transformation(glm::translate(glm::vec3{translation_vector.x, translation_vector.y, 0.0f}) *
|
||||
glm::scale(scale) * glm::rotate(rotation_angle, ROTATION_AXIS));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Construct a Pad object without a texture.
|
||||
*
|
||||
* @overload Pad(sb::Texture, glm::vec2, flat, float, Reaction, float)
|
||||
*/
|
||||
Pad(glm::vec2 translation = {0.0f, 0.0f}, float scale = 1.0f, float ratio = 1.0f, Reaction on_state_change = Reaction(), float rotation = 0.0f)
|
||||
{
|
||||
this->translation(translation);
|
||||
this->scale(scale, ratio);
|
||||
if (rotation)
|
||||
{
|
||||
this->rotation(rotation);
|
||||
}
|
||||
this->on_state_change(on_state_change);
|
||||
collision_box.invert_y(true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Construct a Pad from a texture, a translation amount, a scale factor, and a reaction function. The translation is relative
|
||||
* to (0.0, 0.0), and the scale is relative to the superclass Plane object, which has opposite corners at (-1.0, -1.0) and
|
||||
* (1.0, 1.0). The texture is the graphic that displays in the Pad location. The reaction must accept a boolean as its first
|
||||
* argument, which will be the state of the contained Switch object.
|
||||
*
|
||||
* @param texture pad display graphic
|
||||
* @param translation x, y amount to translate the pad position
|
||||
* @param scale amount to scale both x and y
|
||||
* @param ratio ratio to adjust scale of x and y
|
||||
* @param on_state_change reaction function which accepts a boolean as its first argument
|
||||
* @param rotation angle in radians to rotate the pad
|
||||
*/
|
||||
Pad(sb::Texture texture, glm::vec2 translation = {0.0f, 0.0f}, float scale = 1.0f, float ratio = 1.0f,
|
||||
Reaction on_state_change = Reaction(), float rotation = 0.0f) : Pad(translation, scale, ratio, on_state_change, rotation)
|
||||
{
|
||||
this->texture(texture);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set angle in radians the pad will be rotated. The pad will be rotated around its center. The collision box will not
|
||||
* change, so the box will not contain the entire pad if the angle is not a multiple of pi/2. The pad's transformation
|
||||
* matrix will automatically be set to incorporate this rotation transformation.
|
||||
*
|
||||
* @param angle angle in radians to rotate pad
|
||||
*/
|
||||
void rotation(float angle)
|
||||
{
|
||||
rotation_angle = angle;
|
||||
transform();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the scale using a factor and ratio that will transform the pad in the X and Y dimensions. The ratio will determine
|
||||
* how much each axis is scaled. If the ratio is above one, the X-axis's scale will be divided by the ratio. If the ratio
|
||||
* is below one, the Y-axis's scale will be multiplied by the aspect ratio. If the aspect ratio of the window is given,
|
||||
* this will force the pad to display as a square, and the ratio will be relative to the shorter axis. The collision box
|
||||
* will be scaled by the same factors. The pad's transformation matrix will automatically be set to incorporate this
|
||||
* scale transformation.
|
||||
*
|
||||
* @param factor amount to scale in both x and y directions
|
||||
* @param ratio amount to adjust scaling, set to the window aspect ratio to make the pad appear square
|
||||
*/
|
||||
void scale(float factor, float ratio = 1.0f)
|
||||
{
|
||||
scale_factor = factor;
|
||||
scale_ratio = ratio;
|
||||
transform();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set a translation for the pad object in the X and Y dimension using a 2d vector. The collision box will be moved by the
|
||||
* same translation. The pad's transformation matrix will automatically be set to incorporate this translation
|
||||
* transformation.
|
||||
*
|
||||
* @param translation x, y distance to translate the pad
|
||||
*/
|
||||
void translation(const glm::vec2& translation)
|
||||
{
|
||||
translation_vector = translation;
|
||||
transform();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set the function that will run when a pad object is clicked.
|
||||
*
|
||||
* @param on_state_change reaction function which accepts a boolean as its first argument
|
||||
*/
|
||||
void on_state_change(Reaction reaction)
|
||||
{
|
||||
connection.on_state_change(reaction);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns true if the point at given position collides with the pad's collision box.
|
||||
*
|
||||
* @param position x, y coordinate to check for collision with Pad::collision_box
|
||||
* @return true if the point is inside Pad::collision_box, false otherwise
|
||||
*/
|
||||
bool collide(const glm::vec2& position) const
|
||||
{
|
||||
return collision_box.collide(position);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Set transformation uniform, bind texture, and draw vertices.
|
||||
*
|
||||
* @param uniform_id transformation uniform ID
|
||||
* @param texture_flag_uniform_id uniform ID for boolean enabling or disabling texture display
|
||||
*/
|
||||
void draw(GLuint uniform_id, GLuint texture_flag_uniform_id)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_id, 1, GL_FALSE, &transformation()[0][0]);
|
||||
if (!textures().empty())
|
||||
{
|
||||
glUniform1i(texture_flag_uniform_id, true);
|
||||
texture().bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
glUniform1i(texture_flag_uniform_id, false);
|
||||
}
|
||||
enable();
|
||||
glDrawArrays(GL_TRIANGLES, 0, attributes("position")->count());
|
||||
disable();
|
||||
}
|
||||
|
||||
return_type press(arguments... args)
|
||||
{
|
||||
return connection.flip(args...);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The main game object. There is currently only support for one of these to exist at a time.
|
||||
*/
|
||||
class Cakefoot : public Game
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
/* Defines for effect IDs that will be passed to the shader program. Since EFFECT_COUNT is last and every value
|
||||
* is the default integer, it will be set to the number of effects available. */
|
||||
enum Effect
|
||||
{
|
||||
EFFECT_NONE,
|
||||
EFFECT_COUNT
|
||||
};
|
||||
|
||||
/* Defines for UV transformations available in the fragment shader program */
|
||||
enum UVTransformation
|
||||
{
|
||||
UV_NONE,
|
||||
UV_SQUIRCLE
|
||||
};
|
||||
|
||||
/* Convention for calling parent class in a consistent way across classes */
|
||||
typedef Game super;
|
||||
|
||||
/* Constants */
|
||||
inline static const glm::vec3 ZERO_VECTOR_3D {0, 0, 0};
|
||||
inline static const glm::vec3 Y_UNIT_NORMAL_3D {0, 1, 0};
|
||||
inline static const glm::mat4 VIEW_MATRIX = glm::lookAt({4.0f, 2.0f, 1.0f}, {0.0f, -0.325f, 0.0f}, Y_UNIT_NORMAL_3D);
|
||||
|
||||
/* Member variables */
|
||||
std::shared_ptr<SDL_Cursor> poke;
|
||||
int effect_id = EFFECT_NONE;
|
||||
std::map<std::string, GLuint> uniform;
|
||||
GLuint shader_program;
|
||||
glm::mat4 projection, model {1.0f}, mvp;
|
||||
sb::VAO vao;
|
||||
sb::VBO vbo;
|
||||
Pad<void, int> start_button;
|
||||
sb::Plane cake_model;
|
||||
|
||||
/*!
|
||||
* Create GL context via super class and load vertices, UV data, and shaders.
|
||||
*/
|
||||
void load_gl_context();
|
||||
|
||||
/*!
|
||||
* Call GL's delete texture function, and print a debug statement for testing. This is defined as a static member
|
||||
* function and uses the SDL logging function instead of the inherited logging functions from Node since the object
|
||||
* may not be allocated at destruction time (?)
|
||||
*
|
||||
* @param texture_id GL texture ID being destroyed
|
||||
*/
|
||||
static void destroy_texture(GLuint* texture_id);
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Initialize a Cakefoot instance
|
||||
*/
|
||||
Cakefoot();
|
||||
|
||||
/*!
|
||||
* Respond to command events
|
||||
*/
|
||||
void respond(SDL_Event&);
|
||||
|
||||
/*!
|
||||
* Update parameters and draw the screen
|
||||
*/
|
||||
void update();
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
* Create a Cakewalk instance and launch its mainloop.
|
||||
*
|
||||
* @return Always returns 0
|
||||
*/
|
||||
int main();
|
|
@ -0,0 +1,44 @@
|
|||
#version 300 es
|
||||
|
||||
/* _______________ ,--------------------------------------------------------.
|
||||
//`````````````\\ \ \
|
||||
//~~~~~~~~~~~~~~~\\ \ by @ohsqueezy & @sleepin \
|
||||
//=================\\ \ [ohsqueezy.itch.io] [sleepin.itch.io] \
|
||||
// \\ \ \
|
||||
// \\ \ zlib licensed code at [git.nugget.fun/nugget/gunkiss] \
|
||||
// ☆ GUNKISS ☆ \\ \ \
|
||||
//_________________________\\ `--------------------------------------------------------*/
|
||||
|
||||
/* The precision declaration is required by OpenGL ES */
|
||||
precision mediump float;
|
||||
|
||||
in vec2 uv;
|
||||
uniform sampler2D base_texture;
|
||||
uniform vec3 blend_min_hsv;
|
||||
uniform float time;
|
||||
uniform bool scroll;
|
||||
out vec4 outputColor;
|
||||
|
||||
/* from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl, licensed under WTFPL */
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if (scroll)
|
||||
{
|
||||
ivec2 texture_size = textureSize(base_texture, 0);
|
||||
float speed = time * 35.0;
|
||||
outputColor = texelFetch(base_texture, ivec2(mod(vec2(gl_FragCoord.x + speed, gl_FragCoord.y - speed), vec2(texture_size))), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputColor = texture(base_texture, uv);
|
||||
}
|
||||
/* apply blending, leaving alpha unchanged */
|
||||
outputColor.xyz = min(outputColor.xyz, hsv2rgb(blend_min_hsv));
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#version 300 es
|
||||
|
||||
/* _______________ ,--------------------------------------------------------.
|
||||
//`````````````\\ \ \
|
||||
//~~~~~~~~~~~~~~~\\ \ by @ohsqueezy & @sleepin \
|
||||
//=================\\ \ [ohsqueezy.itch.io] [sleepin.itch.io] \
|
||||
// \\ \ \
|
||||
// \\ \ zlib licensed code at [git.nugget.fun/nugget/gunkiss] \
|
||||
// ☆ GUNKISS ☆ \\ \ \
|
||||
//_________________________\\ `--------------------------------------------------------*/
|
||||
|
||||
/* The precision declaration is required by OpenGL ES */
|
||||
precision mediump float;
|
||||
|
||||
in vec2 in_position;
|
||||
in vec2 vertex_uv;
|
||||
uniform mat4 transformation;
|
||||
out vec2 uv;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = transformation * vec4(in_position, 0, 1);
|
||||
uv = vertex_uv;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
#version 300 es
|
||||
|
||||
/* >> Cakefoot by https://foam.shampoo.ooo/ << */
|
||||
|
||||
/* The precision declaration is required by OpenGL ES */
|
||||
precision mediump float;
|
||||
|
||||
#define TRANSFORMATION_NONE 0
|
||||
#define TRANSFORMATION_SQUIRCLE 1
|
||||
|
||||
in vec2 fragment_uv;
|
||||
in vec3 ex_color;
|
||||
in float x_center_proximity;
|
||||
in vec3 original_coordinates;
|
||||
in vec3 clip_coordinates;
|
||||
uniform sampler2D pudding_texture;
|
||||
uniform int uv_transformation;
|
||||
uniform float coordinate_bound;
|
||||
out vec4 output_color;
|
||||
|
||||
/* [-coordinate_bound, coordinate_bound] arbitrary box coordinates to [-1, 1] normalized coordinates */
|
||||
vec2 normalize_coordinates(vec2 coordinates)
|
||||
{
|
||||
return coordinates / coordinate_bound;
|
||||
}
|
||||
|
||||
/* [-1, 1] box coordinates to [0, 1] UV coordinates */
|
||||
vec2 coordinates_to_uv(vec2 coordinates)
|
||||
{
|
||||
return (1.0 + coordinates) / 2.0;
|
||||
}
|
||||
|
||||
/* coordinates in circle with radius <= 1 to box coordinates in [-1, 1] */
|
||||
vec2 circle_to_box(vec2 circle)
|
||||
{
|
||||
float u = circle.x;
|
||||
float v = circle.y;
|
||||
float u_sq = pow(u, 2.0);
|
||||
float v_sq = pow(v, 2.0);
|
||||
float rt_2 = sqrt(2.0);
|
||||
float x = 0.5 * sqrt(2.0 + 2.0 * u * rt_2 + u_sq - v_sq) - 0.5 * sqrt(2.0 - 2.0 * u * rt_2 + u_sq - v_sq);
|
||||
float y = 0.5 * sqrt(2.0 + 2.0 * v * rt_2 - u_sq + v_sq) - 0.5 * sqrt(2.0 - 2.0 * v * rt_2 - u_sq + v_sq);
|
||||
return vec2(x, y);
|
||||
}
|
||||
|
||||
/* Apply color passed in from the vertex shader, compressing to one of 16 colors. Add retro effect
|
||||
* by alternately darkening and lightening 2x2 pixel areas in a checker pattern. Add shadowing by
|
||||
* brightening the color based on how near it is to the center in the X-dimension */
|
||||
void retro()
|
||||
{
|
||||
vec3 shadowed = min(ex_color, 1.0);
|
||||
float dx = abs(floor(gl_FragCoord[0]) - 480.0) / 480.0;
|
||||
if (int(floor(gl_FragCoord[0] / 2.0) + floor(gl_FragCoord[1]) / 2.0) % 2 == 0)
|
||||
{
|
||||
output_color = vec4(shadowed * 1.2, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_color = vec4(shadowed * 0.7, 1);
|
||||
}
|
||||
output_color[0] = float(int(output_color[0] * 4.0)) / 4.0;
|
||||
output_color[1] = float(int(output_color[1] * 4.0)) / 4.0;
|
||||
output_color[2] = float(int(output_color[2] * 4.0)) / 4.0;
|
||||
output_color *= x_center_proximity;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = fragment_uv;
|
||||
// if (uv_transformation == TRANSFORMATION_SQUIRCLE)
|
||||
// {
|
||||
// vec2 normalized_circle_coordinates = normalize_coordinates(vec2(original_coordinates.x, original_coordinates.z));
|
||||
// uv = coordinates_to_uv(circle_to_box(normalized_circle_coordinates));
|
||||
// }
|
||||
output_color = texture(pudding_texture, uv);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#version 300 es
|
||||
|
||||
/* >> Cakefoot by https://foam.shampoo.ooo/ << */
|
||||
|
||||
/* The precision declaration is required by OpenGL ES */
|
||||
precision mediump float;
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define AMPLITUDE 0.2
|
||||
#define PERIOD .5
|
||||
#define WAVELENGTH 2.5
|
||||
#define EFFECT_NONE 0
|
||||
#define EFFECT_SNAKE 1
|
||||
#define EFFECT_WOBBLE 2
|
||||
|
||||
in vec3 vertex_position;
|
||||
in vec3 vertex_color;
|
||||
in vec2 vertex_uv;
|
||||
uniform mat4 mvp;
|
||||
uniform float time;
|
||||
uniform int effect;
|
||||
out vec3 ex_color;
|
||||
out float x_center_proximity;
|
||||
out vec2 fragment_uv;
|
||||
out vec3 original_coordinates;
|
||||
out vec3 clip_coordinates;
|
||||
|
||||
/* Offset X-coordinate according to the time step and Y-coordinate to create a wobble effect when run on
|
||||
* flattened coordinates (after projection matrix has been applied) */
|
||||
void wobble()
|
||||
{
|
||||
gl_Position.x += sin(time * 10.0) * vertex_position.y / 2.0;
|
||||
}
|
||||
|
||||
/* Contort the X-coordinate according the time step and Y-coordinate using the sine function. This contorts
|
||||
* the model into a sine wave along the Y-axis. It also moves the sine wave along the Y-axis using the time
|
||||
* step uniform. The shape can be edited by changing the defintions for amplitude (maximum distance from
|
||||
* Y-axis), wavelength (length in GL model coordinates between peaks), and period (amount of time in
|
||||
* seconds it takes to loop through one wavelength cycle). */
|
||||
void snake()
|
||||
{
|
||||
gl_Position = vec4(
|
||||
vertex_position.x + AMPLITUDE * sin(2.0 * PI / PERIOD * (time + vertex_position.y * PERIOD / WAVELENGTH)), vertex_position.yz, 1);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// if (effect == EFFECT_SNAKE)
|
||||
// {
|
||||
// snake();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
gl_Position = vec4(vertex_position, 1);
|
||||
// }
|
||||
gl_Position = mvp * gl_Position;
|
||||
// if (effect == EFFECT_WOBBLE)
|
||||
// {
|
||||
// wobble();
|
||||
// }
|
||||
/* passing to fragment program */
|
||||
ex_color = vertex_color;
|
||||
x_center_proximity = 1.8 - abs(vertex_position[0]);
|
||||
fragment_uv = vertex_uv;
|
||||
original_coordinates = vertex_position;
|
||||
clip_coordinates = gl_Position.xyz;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
#version 300 es
|
||||
|
||||
/* >> Cakefoot by https://foam.shampoo.ooo/ << */
|
||||
|
||||
/* The precision declaration is required by OpenGL ES */
|
||||
precision mediump float;
|
||||
|
||||
#define TRANSFORMATION_NONE 0
|
||||
#define TRANSFORMATION_SQUIRCLE 1
|
||||
|
||||
in vec2 fragment_uv;
|
||||
in vec3 ex_color;
|
||||
in float x_center_proximity;
|
||||
in vec3 original_coordinates;
|
||||
in vec3 clip_coordinates;
|
||||
uniform sampler2D model_texture;
|
||||
uniform int uv_transformation;
|
||||
uniform float coordinate_bound;
|
||||
uniform bool texture_enabled;
|
||||
out vec4 output_color;
|
||||
|
||||
/* [-coordinate_bound, coordinate_bound] arbitrary box coordinates to [-1, 1] normalized coordinates */
|
||||
vec2 normalize_coordinates(vec2 coordinates)
|
||||
{
|
||||
return coordinates / coordinate_bound;
|
||||
}
|
||||
|
||||
/* [-1, 1] box coordinates to [0, 1] UV coordinates */
|
||||
vec2 coordinates_to_uv(vec2 coordinates)
|
||||
{
|
||||
return (1.0 + coordinates) / 2.0;
|
||||
}
|
||||
|
||||
/* coordinates in circle with radius <= 1 to box coordinates in [-1, 1] */
|
||||
vec2 circle_to_box(vec2 circle)
|
||||
{
|
||||
float u = circle.x;
|
||||
float v = circle.y;
|
||||
float u_sq = pow(u, 2.0);
|
||||
float v_sq = pow(v, 2.0);
|
||||
float rt_2 = sqrt(2.0);
|
||||
float x = 0.5 * sqrt(2.0 + 2.0 * u * rt_2 + u_sq - v_sq) - 0.5 * sqrt(2.0 - 2.0 * u * rt_2 + u_sq - v_sq);
|
||||
float y = 0.5 * sqrt(2.0 + 2.0 * v * rt_2 - u_sq + v_sq) - 0.5 * sqrt(2.0 - 2.0 * v * rt_2 - u_sq + v_sq);
|
||||
return vec2(x, y);
|
||||
}
|
||||
|
||||
/* Apply color passed in from the vertex shader, compressing to one of 16 colors. Add retro effect
|
||||
* by alternately darkening and lightening 2x2 pixel areas in a checker pattern. Add shadowing by
|
||||
* brightening the color based on how near it is to the center in the X-dimension */
|
||||
void retro()
|
||||
{
|
||||
vec3 shadowed = min(ex_color, 1.0);
|
||||
float dx = abs(floor(gl_FragCoord[0]) - 480.0) / 480.0;
|
||||
if (int(floor(gl_FragCoord[0] / 2.0) + floor(gl_FragCoord[1]) / 2.0) % 2 == 0)
|
||||
{
|
||||
output_color = vec4(shadowed * 1.2, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_color = vec4(shadowed * 0.7, 1);
|
||||
}
|
||||
output_color[0] = float(int(output_color[0] * 4.0)) / 4.0;
|
||||
output_color[1] = float(int(output_color[1] * 4.0)) / 4.0;
|
||||
output_color[2] = float(int(output_color[2] * 4.0)) / 4.0;
|
||||
output_color *= x_center_proximity;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// if (uv_transformation == TRANSFORMATION_SQUIRCLE)
|
||||
// {
|
||||
// vec2 normalized_circle_coordinates = normalize_coordinates(vec2(original_coordinates.x, original_coordinates.z));
|
||||
// fragment_uv = coordinates_to_uv(circle_to_box(normalized_circle_coordinates));
|
||||
// }
|
||||
output_color = mix(vec4(ex_color, 1), texture(model_texture, fragment_uv) * vec4(ex_color, 1), float(texture_enabled));
|
||||
// output_color = float(texture_enabled) * texture(model_texture, fragment_uv) * vec4(1, 0, 0, 0) + (1.0 - float(texture_enabled)) * vec4(1, 0, 0, 0);
|
||||
// output_color = (1.0 - float(texture_enabled)) * vec4(ex_color, 1);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#version 300 es
|
||||
|
||||
/* >> Cakefoot by https://foam.shampoo.ooo/ << */
|
||||
|
||||
/* The precision declaration is required by OpenGL ES */
|
||||
precision mediump float;
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define AMPLITUDE 0.2
|
||||
#define PERIOD .5
|
||||
#define WAVELENGTH 2.5
|
||||
#define EFFECT_NONE 0
|
||||
#define EFFECT_SNAKE 1
|
||||
#define EFFECT_WOBBLE 2
|
||||
|
||||
in vec3 vertex_position;
|
||||
in vec3 vertex_color;
|
||||
in vec2 vertex_uv;
|
||||
uniform mat4 mvp;
|
||||
uniform float time;
|
||||
uniform int effect;
|
||||
out vec3 ex_color;
|
||||
out float x_center_proximity;
|
||||
out vec2 fragment_uv;
|
||||
out vec3 original_coordinates;
|
||||
out vec3 clip_coordinates;
|
||||
|
||||
/* Offset X-coordinate according to the time step and Y-coordinate to create a wobble effect when run on
|
||||
* flattened coordinates (after projection matrix has been applied) */
|
||||
void wobble()
|
||||
{
|
||||
gl_Position.x += sin(time * 10.0) * vertex_position.y / 2.0;
|
||||
}
|
||||
|
||||
/* Contort the X-coordinate according the time step and Y-coordinate using the sine function. This contorts
|
||||
* the model into a sine wave along the Y-axis. It also moves the sine wave along the Y-axis using the time
|
||||
* step uniform. The shape can be edited by changing the defintions for amplitude (maximum distance from
|
||||
* Y-axis), wavelength (length in GL model coordinates between peaks), and period (amount of time in
|
||||
* seconds it takes to loop through one wavelength cycle). */
|
||||
void snake()
|
||||
{
|
||||
gl_Position = vec4(
|
||||
vertex_position.x + AMPLITUDE * sin(2.0 * PI / PERIOD * (time + vertex_position.y * PERIOD / WAVELENGTH)), vertex_position.yz, 1);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// if (effect == EFFECT_SNAKE)
|
||||
// {
|
||||
// snake();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
gl_Position = vec4(vertex_position, 1);
|
||||
// }
|
||||
gl_Position = mvp * gl_Position;
|
||||
// if (effect == EFFECT_WOBBLE)
|
||||
// {
|
||||
// wobble();
|
||||
// }
|
||||
/* passing to fragment program */
|
||||
ex_color = vertex_color;
|
||||
x_center_proximity = 1.8 - abs(vertex_position[0]);
|
||||
fragment_uv = vertex_uv;
|
||||
original_coordinates = vertex_position;
|
||||
clip_coordinates = gl_Position.xyz;
|
||||
}
|
Loading…
Reference in New Issue