summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shaders/CMakeLists.txt14
-rw-r--r--shaders/moved.txt1
-rw-r--r--shaders/shaders.cc629
-rw-r--r--shaders/shaders.hh70
-rw-r--r--shaders/subpixel.cc22
-rw-r--r--shaders/subpixel.glsl90
-rw-r--r--shaders/vert_cube.glsl31
-rw-r--r--shaders/vert_quad.glsl23
-rw-r--r--shaders/vfog.cc35
-rw-r--r--shaders/vfog.glsl126
10 files changed, 1 insertions, 1040 deletions
diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt
deleted file mode 100644
index 2c061ce..0000000
--- a/shaders/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
-project(shaders)
-
-set(DEMO_NEEDS_DEAR_IMGUI TRUE)
-set(DEMO_NEEDS_SDL3 TRUE)
-include("${CMAKE_CURRENT_LIST_DIR}/../common/c_cpp/CMakeLists.txt")
-
-add_executable(shaders
- shaders.cc
-
- subpixel.cc
- vfog.cc
-)
-target_link_libraries(shaders PRIVATE common)
diff --git a/shaders/moved.txt b/shaders/moved.txt
new file mode 100644
index 0000000..152ab08
--- /dev/null
+++ b/shaders/moved.txt
@@ -0,0 +1 @@
+GLSL shader demos moved to https://fragcoord.xyz/u/kvog
diff --git a/shaders/shaders.cc b/shaders/shaders.cc
deleted file mode 100644
index 86dcfdb..0000000
--- a/shaders/shaders.cc
+++ /dev/null
@@ -1,629 +0,0 @@
-// SPDX-License-Identifier: 0BSD
-
-#define GLAD_GL_IMPLEMENTATION
-#include "shaders.hh"
-
-#define SDL_MAIN_USE_CALLBACKS
-#include <SDL3/SDL.h>
-#include <SDL3/SDL_main.h>
-#include <SDL3/SDL_opengl.h>
-
-#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
-#include "imgui_impl_opengl3.cpp"
-#include "imgui_impl_sdl3.cpp"
-
-#include <cctype>
-#include <cmath>
-#include <cstddef>
-
-// --------------------------------------------------------------------------------
-// Geometry
-// --------------------------------------------------------------------------------
-
-constexpr float Pi = 3.1415926535f;
-
-template <typename T>
-static inline T Min(T lhs, T rhs)
-{
- return (lhs < rhs) ? lhs : rhs;
-}
-
-template <typename T>
-static inline T Max(T lhs, T rhs)
-{
- return (lhs > rhs) ? lhs : rhs;
-}
-
-template <typename T>
-static inline T Clamp(T val, T vmin, T vmax)
-{
- return Min(Max(val, vmin), vmax);
-}
-
-static inline float Radians(float degrees)
-{
- return degrees * Pi / 180.0f;
-}
-
-class Vec2
-{
-public:
- float x = 0.0f;
- float y = 0.0f;
-public:
- Vec2() = default;
- Vec2(float x, float y) : x(x), y(y) { }
-};
-
-class Vec3
-{
-public:
- float x = 0.0f;
- float y = 0.0f;
- float z = 0.0f;
-public:
- Vec3() = default;
- Vec3(float x, float y, float z) : x(x), y(y), z(z) { }
-
- inline Vec3 operator+(const Vec3& rhs) const
- {
- return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
- }
-
- inline Vec3 operator-(const Vec3& rhs) const
- {
- return Vec3(x - rhs.x, y - rhs.y, z - rhs.z);
- }
-
- inline Vec3 operator*(float scalar) const
- {
- return Vec3(x * scalar, y * scalar, z * scalar);
- }
-
- inline float Length() const
- {
- return std::sqrtf(x * x + y * y + z * z);
- }
-
- inline Vec3 Normalize() const
- {
- float l = Length();
- if (l == 0.0f) { l = 1.0f; }
- return Vec3(x / l, y / l, z / l);
- }
-
- inline float Dot(const Vec3& rhs) const
- {
- return x * rhs.x + y * rhs.y + z * rhs.z;
- }
-
- inline Vec3 Cross(const Vec3& rhs) const
- {
- return Vec3(
- y * rhs.z - z * rhs.y,
- z * rhs.x - x * rhs.z,
- x * rhs.y - y * rhs.x
- );
- }
-public:
- static Vec3 FromEuler(Vec2 angles)
- {
- const float rx = Radians(angles.x);
- const float ry = Radians(angles.y);
- const float x = cosf(ry) * sinf(rx);
- const float y = sinf(ry);
- const float z = cosf(ry) * cosf(rx);
- return Vec3(x, y, z);
- }
-};
-
-class Vec4
-{
-public:
- float x = 0.0f;
- float y = 0.0f;
- float z = 0.0f;
- float w = 1.0f;
-public:
- Vec4() = default;
- Vec4(float x, float y, float z) : x(x), y(y), z(z), w(1.0f) { }
- Vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
-};
-
-class Mat4x4
-{
-private:
- float m[4 * 4];
-public:
- inline float& operator[](std::size_t s) { return m[s]; }
- inline float operator[](std::size_t s) const { return m[s]; }
-
- inline float* Base() { return m; }
-
- inline Mat4x4 operator*(const Mat4x4& rhs)
- {
- Mat4x4 r = { };
- for (int col = 0; col < 4; ++col) {
- for (int row = 0; row < 4; ++row) {
- r[col * 4 + row] =
- m[0 * 4 + row] * rhs[col * 4 + 0] +
- m[1 * 4 + row] * rhs[col * 4 + 1] +
- m[2 * 4 + row] * rhs[col * 4 + 2] +
- m[3 * 4 + row] * rhs[col * 4 + 3];
- }
- }
- return r;
- }
-public:
- static Mat4x4 LookAt(const Vec3& eye, const Vec3& at, const Vec3& up)
- {
- Vec3 f = (at - eye).Normalize();
- Vec3 s = f.Cross(up).Normalize();
- Vec3 u = s.Cross(f);
- Vec3 t = Vec3(-s.Dot(eye), -u.Dot(eye), f.Dot(eye));
-
- Mat4x4 m;
- m[ 0] = s.x; m[ 1] = u.x; m[ 2] = -f.x; m[ 3] = 0.0f;
- m[ 4] = s.y; m[ 5] = u.y; m[ 6] = -f.y; m[ 7] = 0.0f;
- m[ 8] = s.z; m[ 9] = u.z; m[10] = -f.z; m[11] = 0.0f;
- m[12] = t.x; m[13] = t.y; m[14] = t.z; m[15] = 1.0f;
-
- return m;
- }
-
- static Mat4x4 Perspective(float fov_deg, float aspect, float z_near, float z_far)
- {
- const float fov_cot = 1.0f / std::tanf(Radians(fov_deg) / 2.0f);
-
- Mat4x4 m = { };
-
- m[0*4+0] = fov_cot / aspect;
- m[1*4+1] = fov_cot;
- m[2*4+3] = -1.0f;
-
- m[2*4+2] = (z_far + z_near) / (z_near - z_far);
- m[3*4+2] = (2.0f * z_near * z_far) / (z_near - z_far);
-
- return m;
- }
-};
-
-// --------------------------------------------------------------------------------
-// Application
-// --------------------------------------------------------------------------------
-
-typedef struct Model Model;
-struct Model
-{
- GLuint vao;
- GLuint vbo;
- GLuint ibo;
- GLuint vs;
- int ibo_len;
- bool is_3d;
-};
-
-static struct
-{
- SDL_Window* wnd;
- bool ui_hidden;
- bool pause;
-
- int shader_index = 0;
-
- float cam_dist = 3.5f;
- Vec2 cam_ang = Vec2(0, 0);
-
- Model models[_MODEL_COUNT];
-} G = { };
-
-// Helper: Report errors via glGetError() after every OpenGL function call.
-// macOS does not support glDebugMessageCallback
-void AssertGL(GLenum error, const char* expr, int line)
-{
- if (error != GL_NO_ERROR) {
- const char* error_string;
- switch (error) {
-#define BIND_ERROR(name) case name: { error_string = #name; }; break;
- BIND_ERROR(GL_INVALID_ENUM);
- BIND_ERROR(GL_INVALID_VALUE);
- BIND_ERROR(GL_INVALID_OPERATION);
- BIND_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
- BIND_ERROR(GL_OUT_OF_MEMORY);
-#undef BIND_ERROR
- default: SDL_assert(0 && "Invalid GL_ERROR enum");
- }
- SDL_Log("[Line #%u] %s caused %s\n", line, expr, error_string);
- }
-}
-
-std::vector<Shader*>& GetShaders()
-{
- static std::vector<Shader*> s_shaders = { };
- return s_shaders;
-}
-
-SDL_AppResult SDLCALL SDL_AppInit(void**, int, char**)
-{
- if (!SDL_Init(SDL_INIT_VIDEO)) {
- SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
-
- Uint32 wflags = SDL_WINDOW_OPENGL |
- SDL_WINDOW_HIGH_PIXEL_DENSITY |
- SDL_WINDOW_RESIZABLE;
- G.wnd = SDL_CreateWindow("shaders", 1024, 768, wflags);
- if (!G.wnd) {
- SDL_Log("Failed to create window: %s", SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- if (!SDL_GL_CreateContext(G.wnd)) {
- SDL_Log("Failed to create OpenGL context: %s", SDL_GetError());
- return SDL_APP_FAILURE;
- }
- SDL_GL_SetSwapInterval(1);
-
- if (!gladLoadGL(SDL_GL_GetProcAddress)) {
- SDL_Log("Failed to load OpenGL functions");
- return SDL_APP_FAILURE;
- }
-
- // Quad mesh
- // 0 1
- // +------------+
- // | |
- // | |
- // | |
- // | |
- // | 3 | 2
- // +------------+
- //
- {
- Model* m = &G.models[MODEL_QUAD];
-
- GL(glGenVertexArrays(1, &m->vao));
- GL(glBindVertexArray(m->vao));
-
- GL(glGenBuffers(1, &m->vbo));
- GL(glBindBuffer(GL_ARRAY_BUFFER, m->vbo));
-
- GL(glGenBuffers(1, &m->ibo));
- GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo));
-
- struct V { Vec2 p; Vec2 t; };
- const V vdata[] = {
- { Vec2(-1.0f, 1.0f), Vec2(0, 1) },
- { Vec2( 1.0f, 1.0f), Vec2(1, 1) },
- { Vec2( 1.0f, -1.0f), Vec2(1, 0) },
- { Vec2(-1.0f, -1.0f), Vec2(0, 0) },
- };
- const uint16_t idata[] = {
- 0, 1, 2,
- 0, 2, 3,
- };
- GL(glBufferData(GL_ARRAY_BUFFER, sizeof(vdata), vdata, GL_STATIC_DRAW));
- GL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idata), idata, GL_STATIC_DRAW));
- GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(V), (void*)offsetof(V, p)));
- GL(glEnableVertexAttribArray(0));
- GL(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(V), (void*)offsetof(V, t)));
- GL(glEnableVertexAttribArray(1));
- m->ibo_len = COUNTOF(idata);
- m->is_3d = false;
- }
-
- // Cube mesh
- // +------------+
- // /| /|
- // / | / |
- // +------------+ |
- // | | | |
- // | | | |
- // | +---------|--+
- // | / | /
- // |/ |/
- // +------------+
- //
- {
- Model* m = &G.models[MODEL_CUBE];
-
- GL(glGenVertexArrays(1, &m->vao));
- GL(glBindVertexArray(m->vao));
-
- GL(glGenBuffers(1, &m->vbo));
- GL(glBindBuffer(GL_ARRAY_BUFFER, m->vbo));
-
- GL(glGenBuffers(1, &m->ibo));
- GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo));
-
- struct V { Vec3 p; Vec2 t; Vec3 n; };
- const V vdata[] = {
- // Front
- { Vec3(-1, 1, 1), Vec2(0, 1), Vec3(0, 0, 1) },
- { Vec3( 1, 1, 1), Vec2(1, 1), Vec3(0, 0, 1) },
- { Vec3( 1, -1, 1), Vec2(1, 0), Vec3(0, 0, 1) },
- { Vec3(-1, -1, 1), Vec2(0, 0), Vec3(0, 0, 1) },
- // Right
- { Vec3( 1, 1, 1), Vec2(0, 1), Vec3(1, 0, 0) },
- { Vec3( 1, 1, -1), Vec2(1, 1), Vec3(1, 0, 0) },
- { Vec3( 1, -1, -1), Vec2(1, 0), Vec3(1, 0, 0) },
- { Vec3( 1, -1, 1), Vec2(0, 0), Vec3(1, 0, 0) },
- // Back
- { Vec3( 1, 1, -1), Vec2(0, 1), Vec3(0, 0, -1) },
- { Vec3(-1, 1, -1), Vec2(1, 1), Vec3(0, 0, -1) },
- { Vec3(-1, -1, -1), Vec2(1, 0), Vec3(0, 0, -1) },
- { Vec3( 1, -1, -1), Vec2(0, 0), Vec3(0, 0, -1) },
- // Left
- { Vec3(-1, 1, -1), Vec2(0, 1), Vec3(-1, 0, 0) },
- { Vec3(-1, 1, 1), Vec2(1, 1), Vec3(-1, 0, 0) },
- { Vec3(-1, -1, 1), Vec2(1, 0), Vec3(-1, 0, 0) },
- { Vec3(-1, -1, -1), Vec2(0, 0), Vec3(-1, 0, 0) },
- // Top
- { Vec3(-1, 1, -1), Vec2(0, 1), Vec3(0, 1, 0) },
- { Vec3( 1, 1, -1), Vec2(1, 1), Vec3(0, 1, 0) },
- { Vec3( 1, 1, 1), Vec2(1, 0), Vec3(0, 1, 0) },
- { Vec3(-1, 1, 1), Vec2(0, 0), Vec3(0, 1, 0) },
- // Bottom
- { Vec3(-1, -1, 1), Vec2(0, 1), Vec3(0, -1, 0) },
- { Vec3( 1, -1, 1), Vec2(1, 1), Vec3(0, -1, 0) },
- { Vec3( 1, -1, -1), Vec2(1, 0), Vec3(0, -1, 0) },
- { Vec3(-1, -1, -1), Vec2(0, 0), Vec3(0, -1, 0) },
- };
- const uint16_t idata[] = {
- 0, 1, 2,
- 0, 2, 3,
- 4, 5, 6,
- 4, 6, 7,
- 8, 9, 10,
- 8, 10, 11,
- 12, 13, 14,
- 12, 14, 15,
- 16, 17, 18,
- 16, 18, 19,
- 20, 21, 22,
- 20, 22, 23,
- };
- GL(glBufferData(GL_ARRAY_BUFFER, sizeof(vdata), vdata, GL_STATIC_DRAW));
- GL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idata), idata, GL_STATIC_DRAW));
- GL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(V), (void*)offsetof(V, p)));
- GL(glEnableVertexAttribArray(0));
- GL(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(V), (void*)offsetof(V, t)));
- GL(glEnableVertexAttribArray(1));
- GL(glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(V), (void*)offsetof(V, n)));
- GL(glEnableVertexAttribArray(2));
- m->ibo_len = COUNTOF(idata);
- m->is_3d = true;
- }
-
- const char* vshaders[] = {
- "vert_quad.glsl",
- "vert_cube.glsl"
- };
- static_assert(COUNTOF(vshaders) == _MODEL_COUNT);
- for (size_t i = 0; i < COUNTOF(vshaders); ++i) {
- char* vs_src = (char*)SDL_LoadFile(vshaders[i], NULL);
- if (!vs_src) {
- SDL_Log("Failed to load vertex shader %s: %s", vshaders[i], SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- GLuint shader = GL(glCreateShader(GL_VERTEX_SHADER));
- GL(glShaderSource(shader, 1, &vs_src, NULL));
- GL(glCompileShader(shader));
-
- GLint compile_status = 0;
- GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status));
- if (compile_status != GL_TRUE) {
- char error[1024] = { 0 };
- GL(glGetShaderInfoLog(shader, sizeof(error), NULL, error));
- SDL_Log("Error compiling shader %s: %s", vshaders[i], error);
- return SDL_APP_FAILURE;
- }
-
- G.models[i].vs = shader;
- SDL_Log("Compiled vertex shader %s", vshaders[i]);
-
- SDL_free(vs_src);
- }
-
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGui_ImplSDL3_Init(G.wnd, 0, 0);
- ImGui_ImplOpenGL3_Init();
- ImGui::GetIO().IniFilename = NULL;
-
- return SDL_APP_CONTINUE;
-}
-
-SDL_AppResult SDLCALL SDL_AppIterate(void*)
-{
- int wnd_x = 0;
- int wnd_y = 0;
- SDL_GetWindowSizeInPixels(G.wnd, &wnd_x, &wnd_y);
-
- GL(glViewport(0, 0, wnd_x, wnd_y));
- GL(glEnable(GL_CULL_FACE));
- GL(glCullFace(GL_FRONT));
- GL(glEnable(GL_DEPTH_TEST));
- GL(glEnable(GL_BLEND));
- GL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
- GL(glClearColor(0.1f, 0.1f, 0.1f, 1.0f));
- GL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
-
- Shader* shader = GetShaders()[G.shader_index];
- Model* model = &G.models[shader->model];
-
- if (!shader->ready) {
- shader->program = GL(glCreateProgram());
-
- char* fs_src = (char*)SDL_LoadFile(shader->path, NULL);
- if (!fs_src) {
- SDL_Log("Failed to load fragment shader %s: %s", shader->path, SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- GLuint fs = GL(glCreateShader(GL_FRAGMENT_SHADER));
- GL(glShaderSource(fs, 1, &fs_src, NULL));
- GL(glCompileShader(fs));
-
- GLint compile_status = 0;
- GL(glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_status));
- if (compile_status != GL_TRUE) {
- char error[1024] = { 0 };
- GL(glGetShaderInfoLog(fs, sizeof(error), NULL, error));
- SDL_Log("Error compiling shader %s: %s", shader->path, error);
- return SDL_APP_FAILURE;
- }
-
- SDL_Log("Compiled fragment shader %s", shader->path);
-
- SDL_free(fs_src);
-
- GL(glAttachShader(shader->program, model->vs));
- GL(glAttachShader(shader->program, fs));
- GL(glLinkProgram(shader->program));
-
- GLint link_status = 0;
- GL(glGetProgramiv(shader->program, GL_LINK_STATUS, &link_status));
- if (link_status != GL_TRUE) {
- char error[1024] = { 0 };
- GL(glGetProgramInfoLog(shader->program, sizeof(error), NULL, error));
- SDL_Log("Error linking program %s: %s", shader->path, error);
- return SDL_APP_FAILURE;
- }
-
- SDL_Log("Linked program");
-
- shader->ready = true;
- }
-
- GL(glBindVertexArray(model->vao));
- GL(glUseProgram(shader->program));
-
- GLint u_id = -1;
- if ((u_id = glGetUniformLocation(shader->program, "u_res")) != -1) {
- GL(glUniform2f(u_id, (float)wnd_x, (float)wnd_y));
- }
- if ((u_id = glGetUniformLocation(shader->program, "u_time")) != -1) {
- if (!G.pause) {
- GL(glUniform1f(u_id, SDL_GetTicks() / 1e3f));
- }
- }
-
- if (model->is_3d) {
- const Vec3 cam = Vec3::FromEuler(G.cam_ang) * G.cam_dist;
- const Vec3 tgt = Vec3(0, 0, 0);
- const float fov = 75.0f;
-
- Mat4x4 m_look = Mat4x4::LookAt(cam, tgt, Vec3(0, 1, 0));
- Mat4x4 m_proj = Mat4x4::Perspective(fov, (float)wnd_x / (float)wnd_y, 0.1f, 100.0f);
- Mat4x4 m_view = m_proj * m_look;
-
- if ((u_id = glGetUniformLocation(shader->program, "u_vmat")) == -1) {
- SDL_Log("Warning: u_vmat uniform not found");
- } else {
- GL(glUniformMatrix4fv(u_id, 1, GL_FALSE, m_view.Base()));
- }
-
- if ((u_id = glGetUniformLocation(shader->program, "u_cam")) != -1) {
- GL(glUniform3f(u_id, cam.x, cam.y, cam.z));
- }
- }
-
- if (shader->uf_fn) {
- shader->uf_fn(shader);
- }
-
- GL(glDrawElements(GL_TRIANGLES, model->ibo_len, GL_UNSIGNED_SHORT, NULL));
-
- ImGui_ImplSDL3_NewFrame();
- ImGui_ImplOpenGL3_NewFrame();
- ImGui::NewFrame();
-
- int wnd_height = 0;
- SDL_GetWindowSize(G.wnd, NULL, &wnd_height);
- if (!G.ui_hidden) {
- ImGui::SetNextWindowPos(ImVec2(15.0f, 15.0f), ImGuiCond_Once);
- ImGui::SetNextWindowSize(ImVec2(300.0f, wnd_height - 30.0f), ImGuiCond_Once);
- ImGuiWindowFlags flags =
- ImGuiWindowFlags_NoTitleBar |
- ImGuiWindowFlags_NoMove |
- ImGuiWindowFlags_NoResize;
- if (ImGui::Begin("ControlsWindow", NULL, flags)) {
- if (ImGui::BeginCombo("Shader", GetShaders()[G.shader_index]->path)) {
- for (int i = 0; i < (int)GetShaders().size(); ++i) {
- if (ImGui::Selectable(GetShaders()[i]->path, i == G.shader_index)) {
- G.shader_index = i;
- }
- }
- ImGui::EndCombo();
- }
- ImGui::SeparatorText("Controls");
- ImGui::Text("Tab: Toggle UI");
- ImGui::Checkbox("Pause time", &G.pause);
-
- if (shader->ui_fn) {
- ImGui::SeparatorText("Uniforms");
- shader->ui_fn();
- }
- }
- ImGui::End();
- }
-
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-
- if (!SDL_GL_SwapWindow(G.wnd)) {
- SDL_Log("Failed to present window: %s", SDL_GetError());
- return SDL_APP_FAILURE;
- }
-
- return SDL_APP_CONTINUE;
-}
-
-SDL_AppResult SDLCALL SDL_AppEvent(void*, SDL_Event* event)
-{
- bool is_3d = G.models[GetShaders()[G.shader_index]->model].is_3d;
-
- ImGui_ImplSDL3_ProcessEvent(event);
- switch (event->type) {
- case SDL_EVENT_KEY_DOWN: {
- if (event->key.key == SDLK_TAB) {
- G.ui_hidden = !G.ui_hidden;
- }
- if (event->key.key == SDLK_SPACE) {
- G.pause = !G.pause;
- }
- } break;
- case SDL_EVENT_MOUSE_MOTION: {
- if (is_3d && (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_MASK(SDL_BUTTON_LEFT))) {
- const float sens = 0.4f;
- G.cam_ang.x -= event->motion.xrel * sens;
- G.cam_ang.y += event->motion.yrel * sens;
- G.cam_ang.y = Clamp(G.cam_ang.y, -89.0f, 89.0f);
- }
- } break;
- case SDL_EVENT_MOUSE_WHEEL: {
- if (is_3d) {
- G.cam_dist -= event->wheel.y * 0.1f;
- G.cam_dist = Max(G.cam_dist, 1.0f);
- }
- } break;
- case SDL_EVENT_QUIT: {
- return SDL_APP_SUCCESS;
- } break;
- }
- return SDL_APP_CONTINUE;
-}
-
-void SDLCALL SDL_AppQuit(void*, SDL_AppResult)
-{
- SDL_DestroyWindow(G.wnd);
-}
diff --git a/shaders/shaders.hh b/shaders/shaders.hh
deleted file mode 100644
index d23a13d..0000000
--- a/shaders/shaders.hh
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: 0BSD
-
-#ifndef _SHADERS_HH_
-#define _SHADERS_HH_
-
-#include "../common/c_cpp/thirdparty/glad33/glad33.h"
-#include "imgui.h"
-
-#include <algorithm>
-#include <cstring>
-#include <vector>
-
-#include <SDL3/SDL.h>
-
-#define COUNTOF(arr) (sizeof(arr) / sizeof(*(arr)))
-
-// Model type
-enum
-{
- MODEL_QUAD = 0,
- MODEL_CUBE,
- _MODEL_COUNT
-};
-
-struct Shader
-{
- const char* path;
- int model;
- void(*ui_fn)(void);
- void(*uf_fn)(Shader* prog);
-
- // Private
- bool ready = false;
- GLuint program;
-
- inline GLint get_required_uniform(const char* name)
- {
- GLint id = glGetUniformLocation(program, name);
- if (id == -1) {
- SDL_Log("Shader %s missing required uniform %s", path, name);
- }
- return id;
- }
-};
-
-std::vector<Shader*>& GetShaders();
-
-void AssertGL(GLenum error, const char* expr, int line);
-#define GL(expr) \
- expr; \
- for (GLenum _glcode; (_glcode = glGetError()) != GL_NO_ERROR; ) { \
- AssertGL(_glcode, #expr, __LINE__); \
- }
-
-
-class ShaderRegisterHelper
-{
-public:
- ShaderRegisterHelper(Shader* shader)
- {
- std::vector<Shader*>& shaders = GetShaders();
- shaders.push_back(shader);
- std::sort(shaders.begin(), shaders.end(), [](const Shader* a, const Shader* b) {
- return std::strcmp(a->path, b->path) < 0;
- });
- }
-};
-#define ENABLE_SHADER(shader) static ShaderRegisterHelper _shader_reg = ShaderRegisterHelper(&shader);
-
-#endif // _SHADERS_HH_
diff --git a/shaders/subpixel.cc b/shaders/subpixel.cc
deleted file mode 100644
index 73a5d51..0000000
--- a/shaders/subpixel.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "shaders.hh"
-
-static float u_quad[2] = { 256.0f, 2.0f };
-
-static void ui()
-{
- ImGui::SliderFloat("quad width", &u_quad[0], 1.0f, 512.0f);
- ImGui::SliderFloat("quad height", &u_quad[1], 1.0f, 512.0f);
-}
-
-static void uniforms(Shader* shader)
-{
- GL(glUniform2fv(shader->get_required_uniform("u_quad"), 1, u_quad));
-}
-
-static Shader subpixel = {
- .path = "subpixel.glsl",
- .model = MODEL_QUAD,
- .ui_fn = ui,
- .uf_fn = uniforms,
-};
-ENABLE_SHADER(subpixel);
diff --git a/shaders/subpixel.glsl b/shaders/subpixel.glsl
deleted file mode 100644
index df65b91..0000000
--- a/shaders/subpixel.glsl
+++ /dev/null
@@ -1,90 +0,0 @@
-#version 330 core
-
-// --------------------------------------------------------------------------------
-// Basic subpixel rendering with LCD filtering.
-// Assumes R-G-B LCD with no compositor scaling
-//
-// ref: https://www.shadertoy.com/view/NtVXWc (spinning quad)
-//
-// SPDX-License-Identifier: 0BSD
-// --------------------------------------------------------------------------------
-
-// --------------------------------------------------------------------------------
-// Uniforms
-// --------------------------------------------------------------------------------
-uniform float u_time;
-uniform vec2 u_res;
-uniform vec2 u_quad;
-
-// --------------------------------------------------------------------------------
-// Vertex outputs
-// --------------------------------------------------------------------------------
-in vec2 v_p;
-in vec2 v_t;
-
-// --------------------------------------------------------------------------------
-// Fragment outputs
-// --------------------------------------------------------------------------------
-out vec4 f_c;
-
-// --------------------------------------------------------------------------------
-// Entry point
-// --------------------------------------------------------------------------------
-
-vec2 rotate(vec2 v, float theta)
-{
- // ref: https://en.wikipedia.org/wiki/Rotation_matrix
- return mat2(cos(theta), -sin(theta), sin(theta), cos(theta)) * v;
-}
-
-float box_d(vec2 v)
-{
- return max(v.x, v.y);
-}
-
-float spinning_quad(vec2 pos)
-{
- pos = rotate(pos, u_time * -0.25f);
- vec2 halfsize = u_quad / 2.0f;
- vec2 q = abs(pos) - halfsize;
- return 1.0f - step(0.0f, box_d(q));
-}
-
-vec3 spinning_quad_subpixel(vec2 pos)
-{
- vec2 one_third_x = vec2(1.0f / 3.0f, 0.0f);
-
- float sL = spinning_quad(pos - one_third_x);
- float sC = spinning_quad(pos);
- float sR = spinning_quad(pos + one_third_x);
-
-#if 1
- // 3-tap low pass filter
- float weights[3] = float[3](0.25f, 0.50f, 0.25f);
- float r = weights[1] * sL + weights[0] * sC;
- float g = weights[0] * sL + weights[1] * sC + weights[2] * sR;
- float b = weights[0] * sC + weights[1] * sR;
-
- r *= (1.0f / 0.75f);
- b *= (1.0f / 0.75f);
-#else
- float r = sL;
- float g = sC;
- float b = sR;
-#endif
-
- return vec3(r, g, b);
-}
-
-void main()
-{
- vec2 cursor = gl_FragCoord.xy - (u_res / 2.0f);
-
- // top quad
- vec3 c1 = vec3(spinning_quad(cursor - vec2(0, u_res.y / 4.0f)));
-
- // bottom quad
- vec3 c2 = spinning_quad_subpixel(cursor + vec2(0, u_res.y / 4.0f));
-
- f_c = vec4(mix(c2, c1, step(u_res.y / 2.0f, gl_FragCoord.y)), 1.0f);
-}
diff --git a/shaders/vert_cube.glsl b/shaders/vert_cube.glsl
deleted file mode 100644
index 629b5cd..0000000
--- a/shaders/vert_cube.glsl
+++ /dev/null
@@ -1,31 +0,0 @@
-#version 330 core
-
-// --------------------------------------------------------------------------------
-// Uniforms
-// --------------------------------------------------------------------------------
-uniform mat4 u_vmat;
-
-// --------------------------------------------------------------------------------
-// Vertex inputs
-// --------------------------------------------------------------------------------
-layout (location = 0) in vec3 v_in_p;
-layout (location = 1) in vec2 v_in_t;
-layout (location = 2) in vec3 v_in_n;
-
-// --------------------------------------------------------------------------------
-// Vertex outputs
-// --------------------------------------------------------------------------------
-out vec3 v_p;
-out vec2 v_t;
-out vec3 v_n;
-
-// --------------------------------------------------------------------------------
-// Main
-// --------------------------------------------------------------------------------
-void main()
-{
- v_p = v_in_p;
- v_t = v_in_t;
- v_n = v_in_n;
- gl_Position = u_vmat * vec4(v_p, 1.0f);
-}
diff --git a/shaders/vert_quad.glsl b/shaders/vert_quad.glsl
deleted file mode 100644
index 611ae61..0000000
--- a/shaders/vert_quad.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-#version 330 core
-
-// --------------------------------------------------------------------------------
-// Vertex inputs
-// --------------------------------------------------------------------------------
-layout (location = 0) in vec2 v_in_p;
-layout (location = 1) in vec2 v_in_t;
-
-// --------------------------------------------------------------------------------
-// Vertex outputs
-// --------------------------------------------------------------------------------
-out vec2 v_p;
-out vec2 v_t;
-
-// --------------------------------------------------------------------------------
-// Main
-// --------------------------------------------------------------------------------
-void main()
-{
- v_p = v_in_p;
- v_t = v_in_t;
- gl_Position = vec4(v_p.x, v_p.y, -1.0f, 1.0f);
-}
diff --git a/shaders/vfog.cc b/shaders/vfog.cc
deleted file mode 100644
index 116d433..0000000
--- a/shaders/vfog.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "shaders.hh"
-
-static int u_mode = 0;
-static int u_steps = 8;
-static float u_sigma = 4.0f;
-
-static void ui()
-{
- const char* modes[] = { "basic", "vfade", "waves" };
- if (ImGui::BeginCombo("mode", modes[u_mode])) {
- for (int i = 0; i < (int)COUNTOF(modes); ++i) {
- if (ImGui::Selectable(modes[i], i == u_mode)) {
- u_mode = i;
- }
- }
- ImGui::EndCombo();
- }
- ImGui::SliderInt("steps", &u_steps, 1, 8);
- ImGui::InputFloat("sigma", &u_sigma);
-}
-
-static void uniforms(Shader* shader)
-{
- GL(glUniform1i(shader->get_required_uniform("u_mode"), u_mode));
- GL(glUniform1i(shader->get_required_uniform("u_steps"), u_steps));
- GL(glUniform1f(shader->get_required_uniform("u_sigma"), u_sigma));
-}
-
-static Shader vfog = {
- .path = "vfog.glsl",
- .model = MODEL_CUBE,
- .ui_fn = ui,
- .uf_fn = uniforms,
-};
-ENABLE_SHADER(vfog);
diff --git a/shaders/vfog.glsl b/shaders/vfog.glsl
deleted file mode 100644
index e92e957..0000000
--- a/shaders/vfog.glsl
+++ /dev/null
@@ -1,126 +0,0 @@
-#version 330 core
-
-// --------------------------------------------------------------------------------
-// Volumetric fog
-//
-// SPDX-License-Identifier: 0BSD
-// --------------------------------------------------------------------------------
-
-// --------------------------------------------------------------------------------
-// Uniforms
-// --------------------------------------------------------------------------------
-uniform float u_time;
-uniform vec3 u_cam;
-uniform int u_mode;
-uniform int u_steps;
-uniform float u_sigma;
-
-// --------------------------------------------------------------------------------
-// Vertex outputs
-// --------------------------------------------------------------------------------
-in vec3 v_p;
-in vec2 v_t;
-in vec3 v_n;
-
-// --------------------------------------------------------------------------------
-// Fragment outputs
-// --------------------------------------------------------------------------------
-out vec4 f_c;
-
-// -----------------------------------------------------------------------------
-// Ray-AABB intersection
-// ref: https://tavianator.com/2022/ray_box_boundary.html
-// -----------------------------------------------------------------------------
-bool intersect(vec3 ro, vec3 rd, vec3 bbmin, vec3 bbmax, out float t0, out float t1)
-{
- vec3 inv = 1.0f / rd;
- vec3 ta = (bbmin - ro) * inv;
- vec3 tb = (bbmax - ro) * inv;
- vec3 tmin = min(ta, tb);
- vec3 tmax = max(ta, tb);
- t0 = max(max(tmin.x, tmin.y), tmin.z);
- t1 = min(min(tmax.x, tmax.y), tmax.z);
- return t1 >= max(t0, 0.0f);
-}
-
-// -----------------------------------------------------------------------------
-// Mode 0: Basic volumetric fog
-// -----------------------------------------------------------------------------
-float sample_basic(vec3 pos)
-{
- return 1.0;
-}
-
-// -----------------------------------------------------------------------------
-// Mode 1: Fade along y axis
-// -----------------------------------------------------------------------------
-float sample_vfade(vec3 pos)
-{
- return 1.0f - pos.y;
-}
-
-// -----------------------------------------------------------------------------
-// Mode 2: Some waves
-// -----------------------------------------------------------------------------
-float sample_waves(vec3 pos)
-{
- // Fractal sum
- // ref: https://thebookofshaders.com/13/
- float h = 0.75f; // baseline
-
- // Big waves
- h += 0.08f * sin(pos.x * 2.0f + u_time);
- h += 0.08f * cos(pos.z * 2.0f + u_time * -1.1f);
-
- // Medium waves
- h += 0.05f * sin(pos.x * 5.0f + u_time * 1.7f);
- h += 0.05f * cos(pos.z * 4.0f + u_time * -2.0f);
-
- // Small but choppy waves
- h += 0.03f * sin(pos.x * 12.0f + u_time * 3.3f);
- h += 0.03f * cos(pos.z * 11.0f + u_time * -2.5f);
-
- return float(pos.y < h);
-}
-
-// --------------------------------------------------------------------------------
-// Entry point
-// --------------------------------------------------------------------------------
-void main()
-{
- vec3 bbmin = vec3(-1.0f);
- vec3 bbmax = vec3( 1.0f);
-
- vec3 ro = u_cam;
- vec3 rd = normalize(v_p - ro);
-
- float t0 = 0.0f;
- float t1 = 0.0f;
- if (!intersect(ro, rd, bbmin, bbmax, t0, t1)) {
- f_c = vec4(0.0f, 0.0f, 0.0f, 0.0f);
- return;
- }
-
- // Clamp entry point in front of camera
- float t_enter = max(t0, 0.0f);
- float t_exit = t1;
- float t_len = max(0.0f, t_exit - t_enter);
-
- float density = 0;
- for (int i = 0; i < u_steps; ++i) {
- float t = mix(t_enter, t_exit, (float(i) + 0.5f) / float(u_steps));
- vec3 p = ro + rd * t;
- switch (u_mode) {
- case 0: { density += sample_basic(p); } break;
- case 1: { density += sample_vfade(p); } break;
- case 2: { density += sample_waves(p); } break;
- }
- }
- density /= float(u_steps);
-
- // Beer-Lambert attenuation
- // ref: https://en.wikipedia.org/wiki/Beer%E2%80%93Lambert_law
- float a = 1.0f - exp(-u_sigma * t_len * density);
-
- f_c = vec4(vec3(1.0f), a);
-} \ No newline at end of file