summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-10-03 19:08:44 -0400
committerAndrew Opalach <andrew@akon.city> 2024-10-04 14:19:40 -0400
commit0bf9b26b87075448d49482fe4411739af765d872 (patch)
treee3f0e3312a92e5250fa72b410adb370734deca04 /src
parentacd44bb898996ff4e36b39b10e870e40bcaf2634 (diff)
downloadmauri-0bf9b26b87075448d49482fe4411739af765d872.tar.gz
mauri-0bf9b26b87075448d49482fe4411739af765d872.tar.bz2
mauri-0bf9b26b87075448d49482fe4411739af765d872.zip
Update codebase
Bring up-to-date with my other projects. Wallpaper engine behavior is mostly unchanged. Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
-rw-r--r--src/assets.cc38
-rw-r--r--src/assets.h29
-rw-r--r--src/context.cc43
-rw-r--r--src/context.h110
-rw-r--r--src/context_glfw.cc131
-rw-r--r--src/context_glfw.h34
-rw-r--r--src/context_null.h55
-rw-r--r--src/context_x11.cc302
-rw-r--r--src/context_x11.h64
-rw-r--r--src/engine.cc55
-rw-r--r--src/engine.h9
-rw-r--r--src/framebuffer.cc16
-rw-r--r--src/framebuffer.h23
-rw-r--r--src/gl.cc46
-rw-r--r--src/gl.h15
-rw-r--r--src/json.h40
-rw-r--r--src/log.h29
-rw-r--r--src/mauri.cc118
-rw-r--r--src/objects/effect.cc42
-rw-r--r--src/objects/effect.h5
-rw-r--r--src/objects/material.cc19
-rw-r--r--src/objects/material.h10
-rw-r--r--src/objects/model.cc25
-rw-r--r--src/objects/model.h4
-rw-r--r--src/objects/object.cc91
-rw-r--r--src/objects/object.h16
-rw-r--r--src/objects/pass.cc77
-rw-r--r--src/objects/pass.h26
-rw-r--r--src/objects/scene.cc43
-rw-r--r--src/objects/scene.h7
-rw-r--r--src/shader.cc138
-rw-r--r--src/shader.h6
-rw-r--r--src/texture.cc34
-rw-r--r--src/texture.h19
-rw-r--r--src/util.cc16
-rw-r--r--src/util.h62
-rw-r--r--src/vis.cc44
-rw-r--r--src/vis.h4
38 files changed, 696 insertions, 1149 deletions
diff --git a/src/assets.cc b/src/assets.cc
index f892662..baf3922 100644
--- a/src/assets.cc
+++ b/src/assets.cc
@@ -1,9 +1,8 @@
-#include <filesystem>
#include <fstream>
-#include <iostream>
+#include <filesystem>
-#include "texture.h"
#include "assets.h"
+#include "texture.h"
namespace Mauri
{
@@ -124,7 +123,7 @@ auto AssetManager::arm_package(const std::string &path, bool can_output) -> bool
byte *start = this->package->ptr() + asset.offset;
byte *end = start + asset.length;
this->assets[i] = new Asset(std::string(asset.path), start, end);
- debug("package file: (%s)", std::string(asset.path).c_str());
+ debug("package file: (%s)", this->assets[i]->path.c_str());
}
this->prepare_output = can_output;
@@ -144,6 +143,16 @@ auto AssetManager::unload_package() -> void
delete this->package;
}
+
+auto AssetManager::add_search_directory(const std::string &directory) -> bool
+{
+ if (!std::filesystem::is_directory(directory)) return false;
+
+ this->directories.push_back(directory);
+
+ return true;
+}
+
auto AssetManager::get_file(const std::string &part, AssetTypeHint hint) -> Asset *
{
std::string path = part;
@@ -185,15 +194,24 @@ auto AssetManager::get_file(const std::string &part, AssetTypeHint hint) -> Asse
if (!asset)
{
- path.insert(0, "assets/");
-
- asset = new Asset(path);
- asset->hash = hash;
+ for (std::string &dir : this->directories)
+ {
+ std::string attempt = dir + "/" + path;
+ asset = new Asset(attempt);
+ if (asset->type == ASSET_VOID)
+ {
+ delete asset;
+ asset = nullptr;
+ continue;
+ }
+ asset->hash = hash;
+ debug("found asset in: (%s)", dir.c_str());
+ break;
+ }
- if (asset->type == ASSET_VOID)
+ if (!asset)
{
error("failed to load asset: (%s)", path.c_str());
- delete asset;
return &asset_void;
}
diff --git a/src/assets.h b/src/assets.h
index 34e31df..498308a 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -1,17 +1,26 @@
#ifndef _ASSET_H
#define _ASSET_H
-#include <iostream>
-#include <sstream>
-#include <vector>
-
#include "util.h"
namespace Mauri
{
-enum AssetType { ASSET_VOID, ASSET_SLICE, ASSET_FILE };
-enum AssetTypeHint { NONE, TEXTURE, SHADER, FRAGMENT_SHADER, VERTEX_SHADER };
+enum AssetType
+{
+ ASSET_VOID = 0,
+ ASSET_SLICE,
+ ASSET_FILE
+};
+
+enum AssetTypeHint
+{
+ NONE = 0,
+ TEXTURE,
+ SHADER,
+ FRAGMENT_SHADER,
+ VERTEX_SHADER
+};
class Asset
{
@@ -86,19 +95,23 @@ struct PackageFile
class AssetManager
{
public:
- AssetManager() {}
- ~AssetManager() {}
+ AssetManager() = default;
+ ~AssetManager() = default;
auto get_file(const std::string &part, AssetTypeHint hint = NONE) -> Asset *;
auto arm_package(const std::string &path, bool can_output) -> bool;
auto unload_package() -> void;
+ auto add_search_directory(const std::string &directory) -> bool;
+
bool prepare_output;
auto write_files(const std::string &output_path) -> void;
private:
+ std::vector<std::string> directories;
+
Asset *package;
std::vector<Asset *> assets;
};
diff --git a/src/context.cc b/src/context.cc
index a89f8b0..8dcbdbb 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -12,49 +12,8 @@ auto context() -> Context *
auto set_context(Context *c) -> void
{
- if (context_)
- {
- delete context_;
- }
+ if (context_) delete context_;
context_ = c;
}
} // namespace Mauri
-
-using namespace Mauri;
-
-auto Context::print_gl_info() -> void
-{
- info("vendor: %s", glGetString(GL_VENDOR));
- info("renderer: %s", glGetString(GL_RENDERER));
- info("version: %s", glGetString(GL_VERSION));
-}
-
-auto Context::check_error() -> GLenum
-{
- GLenum error_code;
- while ((error_code = glGetError()) != GL_NO_ERROR)
- {
- std::string error;
- switch (error_code)
- {
- case GL_INVALID_ENUM:
- error = "INVALID_ENUM";
- break;
- case GL_INVALID_VALUE:
- error = "INVALID_VALUE";
- break;
- case GL_INVALID_OPERATION:
- error = "INVALID_OPERATION";
- break;
- case GL_OUT_OF_MEMORY:
- error = "OUT_OF_MEMORY";
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- error = "INVALID_FRAMEBUFFER_OPERATION";
- break;
- }
- error("gl error: %s", error.c_str());
- }
- return error_code;
-}
diff --git a/src/context.h b/src/context.h
index 93e5290..6919550 100644
--- a/src/context.h
+++ b/src/context.h
@@ -1,29 +1,76 @@
#ifndef _CONTEXT_H
#define _CONTEXT_H
-#include <chrono>
-
#include "gl.h"
+extern "C" {
+#include <stl/window.h>
+#include <aki/thread.h>
+}
+
namespace Mauri
{
+static bool pointer_pos_callback(void *userdata, f64 x, f64 y);
+static void should_close_callback(void *userdata);
+
class Context
{
public:
- Context() : start(std::chrono::system_clock::now()) {}
- virtual ~Context() {}
+ Context() : start(aki_get_timestamp()) {}
+ ~Context()
+ {
+ if (this->window) this->window->free(&this->window);
+ }
+
+ f64 pointer_x;
+ f64 pointer_y;
+
+ bool should_close = false;
+
+ auto create_window(s32 width, s32 height, const std::string &name, const std::string monitor) -> bool
+ {
+ this->window = stl_window_create();
+ this->window->pointer_pos_callback = pointer_pos_callback;
+ this->window->should_close_callback = should_close_callback;
+ this->window->userdata = this;
+ s32 flags = STELA_WINDOW_VSYNC | (monitor.empty() ? 0 : STELA_WINDOW_WALLPAPER);
+ if (!this->window->create_window(this->window, width, height, monitor.c_str(), name.c_str(), flags)) {
+ return false;
+ }
+ this->window->gl_make_current(this->window);
+ if (!this->window->gl_loader_load(this->window)) {
+ return false;
+ }
+ glEnable(GL_BLEND);
+ glEnable(GL_MULTISAMPLE);
+ return true;
+ }
- s32 width;
- s32 height;
+ auto width() -> s32
+ {
+ return this->window->width;
+ }
- virtual auto create_window(s32 width, s32 height, const std::string &name, bool background) -> bool = 0;
- virtual auto resize_window(s32 width, s32 height) -> void = 0;
- virtual auto should_close_window() const -> bool = 0;
- virtual auto close_window() -> void = 0;
+ auto height() -> s32
+ {
+ return this->window->height;
+ }
- virtual auto process_input() -> void = 0;
- virtual auto cursor_pos(f32 *x, f32 *y) -> void = 0;
+ auto resize_window(s32 width, s32 height) -> void
+ {
+ this->window->resize(this->window, width, height);
+ }
+
+ auto should_close_window() const -> bool
+ {
+ return this->should_close;
+ }
+
+ auto close_window() -> void
+ {
+ this->should_close = true;
+ }
auto is_draw_enabled() const -> bool
{
@@ -35,24 +82,47 @@ class Context
this->draw_enabled = enabled;
}
- virtual auto swap_buffers() -> void = 0;
+ auto poll() -> void
+ {
+ this->window->poll(this->window, false);
+ this->window->process_events(this->window);
+ }
- using us = std::chrono::microseconds;
+ auto swap_buffers() -> void
+ {
+ this->window->gl_swap_buffers(this->window);
+ };
auto current_time() const -> f64
{
- return std::chrono::duration_cast<us>(std::chrono::system_clock::now() - this->start).count() / 1000000.f;
+ return (aki_get_timestamp() - this->start) / 1000000.f;
}
- protected:
- auto print_gl_info() -> void;
- auto check_error() -> GLenum;
+ auto check_error() -> void
+ {
+ stl_gl_check_error();
+ }
private:
- bool draw_enabled = false;
- std::chrono::time_point<std::chrono::system_clock> start;
+ u64 start;
+ bool draw_enabled = true;
+ struct stl_window *window = nullptr;
};
+bool pointer_pos_callback(void *userdata, f64 x, f64 y)
+{
+ Context *c = (Context *)userdata;
+ c->pointer_x = x;
+ c->pointer_y = y;
+ return true;
+}
+
+void should_close_callback(void *userdata)
+{
+ Context *c = (Context *)userdata;
+ c->should_close = true;
+}
+
extern auto context() -> Context *;
extern auto set_context(Context *c) -> void;
diff --git a/src/context_glfw.cc b/src/context_glfw.cc
deleted file mode 100644
index cbaea23..0000000
--- a/src/context_glfw.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-#include "context_glfw.h"
-
-using namespace Mauri;
-
-static auto key_callback(GLFWwindow *window, s32 key, s32 scancode, s32 action, s32 mods) -> void
-{
- if (key == GLFW_KEY_B && action == GLFW_PRESS)
- {
- context()->set_draw_enabled(!context()->is_draw_enabled());
- }
-}
-
-auto ContextGLFW::create_window(s32 width, s32 height, const std::string &name, bool background) -> bool
-{
- if (!glfwInit())
- {
- error("failed to init glfw");
- return false;
- }
-
- this->width = width;
- this->height = height;
-
- // https://github.com/haasn/libplacebo/blob/master/demos/window_glfw.c#L178
- struct
- {
- s32 api;
- s32 major, minor;
- s32 glsl_ver;
- s32 profile;
- } gl_vers[] = {
- {GLFW_OPENGL_API, 4, 6, 460, GLFW_OPENGL_CORE_PROFILE},
- {GLFW_OPENGL_API, 4, 5, 450, GLFW_OPENGL_CORE_PROFILE},
- {GLFW_OPENGL_API, 4, 4, 440, GLFW_OPENGL_CORE_PROFILE},
- {GLFW_OPENGL_API, 4, 0, 400, GLFW_OPENGL_CORE_PROFILE},
- {GLFW_OPENGL_API, 3, 3, 330, GLFW_OPENGL_CORE_PROFILE},
- {GLFW_OPENGL_API, 3, 2, 150, GLFW_OPENGL_CORE_PROFILE},
- {GLFW_OPENGL_API, 3, 1, 140, 0},
- {GLFW_OPENGL_API, 3, 0, 130, 0},
- };
-
- glfwWindowHint(GLFW_SRGB_CAPABLE, GLFW_TRUE);
- //glfwWindowHint(GLFW_SAMPLES, 4);
-
- for (u32 i = 0; i < ARRAY_SIZE(gl_vers); i++)
- {
- glfwWindowHint(GLFW_CLIENT_API, gl_vers[i].api);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, gl_vers[i].major);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, gl_vers[i].minor);
- glfwWindowHint(GLFW_OPENGL_PROFILE, gl_vers[i].profile);
-#ifdef __APPLE__
- if (gl_vers[i].profile == GLFW_OPENGL_CORE_PROFILE)
- {
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- }
-#endif
- if ((this->window = glfwCreateWindow(this->width, this->height, name.c_str(), nullptr, nullptr)))
- {
- break;
- }
- }
-
- if (!this->window)
- {
- error("could not create gl context");
- return false;
- }
-
- glfwMakeContextCurrent(this->window);
-
- if (!gladLoadGL((GLADloadfunc)glfwGetProcAddress))
- {
- error("could not load gl");
- return false;
- }
-
- glEnable(GL_BLEND);
- glEnable(GL_MULTISAMPLE);
-
- this->print_gl_info();
-
- this->set_draw_enabled(true);
-
- glfwSetKeyCallback(this->window, key_callback);
-
- return true;
-}
-
-auto ContextGLFW::resize_window(s32 width, s32 height) -> void
-{
- if (width != this->width || height != this->height)
- {
- this->width = width;
- this->height = height;
- glfwSetWindowSize(this->window, this->width, this->height);
- }
-}
-
-auto ContextGLFW::should_close_window() const -> bool
-{
- return glfwWindowShouldClose(this->window);
-}
-
-auto ContextGLFW::close_window() -> void
-{
- glfwSetWindowShouldClose(this->window, GLFW_TRUE);
-}
-
-auto ContextGLFW::process_input() -> void
-{
- glfwPollEvents();
-}
-
-auto ContextGLFW::cursor_pos(f32 *x, f32 *y) -> void
-{
- f64 x_, y_;
- glfwGetCursorPos(this->window, &x_, &y_);
- *x = (f32)x_;
- *y = (f32)y_;
-}
-
-auto ContextGLFW::swap_buffers() -> void
-{
- glfwSwapBuffers(this->window);
-}
-
-ContextGLFW::~ContextGLFW()
-{
- if (this->window) glfwDestroyWindow(this->window);
- glfwTerminate();
-}
diff --git a/src/context_glfw.h b/src/context_glfw.h
deleted file mode 100644
index 1eb2991..0000000
--- a/src/context_glfw.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _CONTEXT_GLFW_HPP
-#define _CONTEXT_GLFW_HPP
-
-#define GLFW_INCLUDE_NONE
-#include <GLFW/glfw3.h>
-
-#include "context.h"
-
-namespace Mauri
-{
-
-class ContextGLFW : public Context
-{
- public:
- ContextGLFW() : Context() {}
- ~ContextGLFW();
-
- auto create_window(s32 width, s32 height, const std::string &name, bool background) -> bool;
- auto resize_window(s32 width, s32 height) -> void;
- auto should_close_window() const -> bool;
- auto close_window() -> void;
-
- auto process_input() -> void;
- auto cursor_pos(f32 *x, f32 *y) -> void;
-
- auto swap_buffers() -> void;
-
- private:
- GLFWwindow *window;
-};
-
-} // namespace Mauri
-
-#endif // _CONTEXT_GLFW_HPP
diff --git a/src/context_null.h b/src/context_null.h
deleted file mode 100644
index bcae058..0000000
--- a/src/context_null.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _CONTEXT_NULL
-#define _CONTEXT_NULL
-
-#include "context.h"
-
-namespace Mauri
-{
-
-class ContextNull : public Context
-{
-public:
- ContextNull() : Context() { this->set_draw_enabled(false); }
- ~ContextNull() {}
-
- auto create_window(s32 width, s32 height, const std::string &name, bool background) -> bool
- {
- return true;
- }
-
- auto resize_window(s32 width, s32 height) -> void
- {
- if (width != this->width || height != this->height)
- {
- this->width = width;
- this->height = height;
- }
- }
-
- auto should_close_window() const -> bool
- {
- return this->should_close;
- }
-
- auto close_window() -> void
- {
- this->should_close = true;
- }
-
- auto process_input() -> void {}
-
- auto cursor_pos(f32 *x, f32 *y) -> void
- {
- *y = 0.f;
- *x = 0.f;
- }
-
- auto swap_buffers() -> void {}
-
- private:
- bool should_close = true;
-};
-
-} // namespace Mauri
-
-#endif // _CONTEXT_NULL
diff --git a/src/context_x11.cc b/src/context_x11.cc
deleted file mode 100644
index 7975a4a..0000000
--- a/src/context_x11.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-#include "context_x11.h"
-
-using namespace Mauri;
-
-static Atom ATOM_WM_DELETE_WINDOW, ATOM__NET_ACTIVE_WINDOW;
-
-auto ContextX11::disable_input() -> void
-{
- XWMHints wmHint;
- wmHint.flags = InputHint | StateHint;
- wmHint.input = false;
- wmHint.initial_state = NormalState;
- XSetWMProperties(this->x11_d, this->window, NULL, NULL, NULL, 0, NULL, &wmHint, NULL);
-}
-
-auto ContextX11::create_window(s32 width, s32 height, const std::string &name, bool background) -> bool
-{
- this->x11_d = XOpenDisplay(NULL);
-
- ATOM_WM_DELETE_WINDOW = XInternAtom(this->x11_d, "WM_DELETE_WINDOW", true);
-
- if (!this->x11_d)
- {
- error("could not open display");
- return false;
- }
-
- s32 screen = XDefaultScreen(this->x11_d);
- Window root = RootWindow(this->x11_d, screen);
-
- static s32 gl_attrs[] = {
- GLX_X_RENDERABLE, True,
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
- GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
- GLX_DOUBLEBUFFER, True,
- GLX_RED_SIZE, 8,
- GLX_GREEN_SIZE, 8,
- GLX_BLUE_SIZE, 8,
- GLX_ALPHA_SIZE, 0,
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_SAMPLES, 0,
- None
- };
-
- GLint context_attrs[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 3,
- None
- };
-
- // https://github.com/jarcode-foss/glava/blob/master/glava/glx_wcb.c#L383
- s32 fb_sz, best = -1, samp = -1;
- GLXFBConfig *fbc = glXChooseFBConfig(this->x11_d, screen, gl_attrs, &fb_sz);
- if (!fbc)
- {
- error("no glX FB configs");
- return false;
- }
-
- for (s32 t = 0; t < fb_sz; t++)
- {
- XVisualInfo *xvi = glXGetVisualFromFBConfig(this->x11_d, fbc[t]);
- if (!xvi) continue;
-
- s32 samp_buf, samples;
- glXGetFBConfigAttrib(this->x11_d, fbc[t], GLX_SAMPLE_BUFFERS, &samp_buf);
- glXGetFBConfigAttrib(this->x11_d, fbc[t], GLX_SAMPLES, &samples);
-
- XRenderPictFormat *fmt = XRenderFindVisualFormat(this->x11_d, xvi->visual);
- if (!fmt) continue;
-
- if (best < 0 || (samp_buf && samples > samp))
- {
- best = t;
- samp = samples;
- }
-
- XFree(xvi);
- }
-
- if (best == -1)
- {
- error("could not find suitable XRender format");
- return false;
- }
-
- GLXFBConfig config = fbc[best];
- XFree(fbc);
-
- XVisualInfo *vi = glXGetVisualFromFBConfig(this->x11_d, config);
- Colormap cmap = XCreateColormap(this->x11_d, root, vi->visual, AllocNone);
- XSetWindowAttributes swa;
- swa.colormap = cmap;
- swa.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask |
- PropertyChangeMask | VisibilityChangeMask;
-
- swa.background_pixmap = None;
- swa.border_pixel = 0;
-
- this->window = XCreateWindow(this->x11_d, root, 0, 0, width, height, 0, vi->depth,
- InputOutput, vi->visual, CWColormap | CWEventMask | CWBackPixmap | CWBorderPixel, &swa);
-
- XFree(vi);
-
- //this->disable_input();
-
- XStoreName(this->x11_d, this->window, name.c_str());
-
- XChangeProperty(this->x11_d, this->window,
- XInternAtom(this->x11_d, "_NET_WM_NAME", False),
- XInternAtom(this->x11_d, "UTF8_STRING", False),
- 8, PropModeReplace, (unsigned char *)name.c_str(), name.length());
-
- XClassHint class_hint;
-
- class_hint.res_class = const_cast<char *>(name.c_str());
- class_hint.res_name = const_cast<char *>(name.c_str());
-
- XSetClassHint(this->x11_d, this->window, &class_hint);
-
- glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL;
- glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
- glXGetProcAddressARB((const GLubyte*) "glXCreateContextAttribsARB");
-
- if (!glXCreateContextAttribsARB) return false;
- if (!(this->glc = glXCreateContextAttribsARB(this->x11_d, config, 0, True, context_attrs)))
- {
- return false;
- }
-
- glXMakeCurrent(this->x11_d, this->window, this->glc);
-
- if (!gladLoadGL((GLADloadfunc)glXGetProcAddressARB))
- {
- error("could not load gl");
- return false;
- }
-
- if (background)
- {
- /*
- Atom desktop = XInternAtom(this->x11_d, "_NET_WM_DESKTOP", false);
- unsigned long all_desktops = XWIN_ALL_DESKTOPS;
- XChangeProperty(this->x11_d, this->window, desktop,
- XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&all_desktops, 1);
- */
-
- Atom net_wm_type = XInternAtom(this->x11_d, "_NET_WM_WINDOW_TYPE", false);
- Atom desktop_type = XInternAtom(this->x11_d, "_NET_WM_WINDOW_TYPE_DESKTOP", false);
- XChangeProperty(this->x11_d, this->window, net_wm_type,
- XA_ATOM, 32, PropModeReplace, (unsigned char*)&desktop_type, 1);
-
- /*
- XEvent event;
- event.xclient.type = ClientMessage;
- event.xclient.serial = 0;
- event.xclient.send_event = True;
- event.xclient.display = this->x11_d;
- event.xclient.window = this->window;
- event.xclient.message_type = XInternAtom(this->x11_d, "_NET_WM_STATE", false);
- event.xclient.format = 32;
-
- event.xclient.data.l[0] = _NET_WM_STATE_ADD;
- event.xclient.data.l[1] = XInternAtom(this->x11_d, "_NET_WM_STATE_BELOW", false);
- event.xclient.data.l[2] = 0; //unused.
- event.xclient.data.l[3] = 0;
- event.xclient.data.l[4] = 0;
-
- XSendEvent(this->x11_d, root, false,
- SubstructureRedirectMask|SubstructureNotifyMask, &event);
-
- event.xclient.data.l[1] = XInternAtom(this->x11_d, "_NET_WM_STATE_STICKY", false);
-
- XSendEvent(x11_d, root, false,
- SubstructureRedirectMask|SubstructureNotifyMask, &event);
-
- event.xclient.data.l[1] = XInternAtom(this->x11_d, "_NET_WM_STATE_FULLSCREEN", false);
- */
- }
-
- XSetWMProtocols(this->x11_d, this->window, &ATOM_WM_DELETE_WINDOW, 1);
-
- XMoveWindow(this->x11_d, this->window, 0, 0);
-
- XMapWindow(this->x11_d, this->window);
- XFlush(this->x11_d);
-
- glEnable(GL_BLEND);
- glEnable(GL_MULTISAMPLE);
-
- this->print_gl_info();
-
- this->set_draw_enabled(true);
-
- return true;
-}
-
-auto ContextX11::resize_window(s32 width, s32 height) -> void
-{
- if (width != this->width || height != this->height)
- {
- this->width = width;
- this->height = height;
- }
-}
-
-auto ContextX11::raise() -> void
-{
- XClientMessageEvent ev = {
- .type = ClientMessage,
- .serial = 0,
- .send_event = true,
- .display = this->x11_d,
- .window = this->window,
- .message_type = ATOM__NET_ACTIVE_WINDOW,
- .format = 32,
- .data = {.l = {1, 0, (long)this->window}}
- };
- XSendEvent(this->x11_d, DefaultRootWindow(this->x11_d), false, StructureNotifyMask, (XEvent *)&ev);
- XRaiseWindow(this->x11_d, this->window);
- XFlush(this->x11_d);
-}
-
-auto ContextX11::set_clickthrough() -> void
-{
- Window win = this->window, root = DefaultRootWindow(this->x11_d);
- while (win != None)
- {
- Region region;
- if ((region = XCreateRegion()))
- {
- XShapeCombineRegion(this->x11_d, this->window, ShapeInput, 0, 0, region, ShapeSet);
- XDestroyRegion(region);
- }
-
- Window parent, *children = NULL;
- u32 num_children;
- if (XQueryTree(this->x11_d, win, &root, &parent, &children, &num_children))
- {
- if (children) XFree(children);
- }
-
- win = (parent == root ? None : parent);
- }
-
- XFlush(this->x11_d);
-}
-
-auto ContextX11::close_window() -> void
-{
- this->should_close = true;
-}
-
-auto ContextX11::cursor_pos(float *x, float *y) -> void
-{
- u32 ret;
- s32 root_return_x, root_return_y;
- s32 win_return_x, win_return_y;
- Window root_return, child_return;
- XQueryPointer(this->x11_d, this->window, &root_return, &child_return,
- &root_return_x, &root_return_y, &win_return_x, &win_return_y, &ret);
- *x = (f32)win_return_x;
- *y = (f32)win_return_y;
-}
-
-auto ContextX11::process_input() -> void
-{
- XEvent xev;
- while (XPending(this->x11_d) > 0)
- {
- XNextEvent(this->x11_d, &xev);
- switch (xev.type)
- {
- case ClientMessage:
- if ((u64)xev.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW)
- {
- this->should_close = true;
- }
- break;
- case MapNotify:
- //set_clickthrough();
- XFlush(this->x11_d);
- break;
- }
- }
-}
-
-auto ContextX11::swap_buffers() -> void
-{
- glXSwapBuffers(this->x11_d, this->window);
-}
-
-ContextX11::~ContextX11()
-{
- if (this->x11_d)
- {
- glXMakeCurrent(this->x11_d, None, NULL);
- glXDestroyContext(this->x11_d, this->glc);
- XDestroyWindow(this->x11_d, this->window);
- XCloseDisplay(this->x11_d);
- }
-}
diff --git a/src/context_x11.h b/src/context_x11.h
deleted file mode 100644
index 6bf898f..0000000
--- a/src/context_x11.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _CONTEXT_X11_H
-#define _CONTEXT_X11_H
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xrender.h>
-#include <X11/extensions/shape.h>
-
-#include "context.h"
-
-#include <GL/glx.h>
-
-#define XWIN_ALL_DESKTOPS 0xFFFFFFFF
-
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-
-#define _NET_WM_STATE_REMOVE 0
-#define _NET_WM_STATE_ADD 1
-#define _NET_WM_STATE_TOGGLE 2
-
-typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, const s32 *);
-
-namespace Mauri
-{
-
-class ContextX11 : public Context
-{
- public:
- ContextX11() : Context() {}
- ~ContextX11();
-
- auto create_window(s32 width, s32 height, const std::string &name, bool background) -> bool;
- auto resize_window(s32 width, s32 height) -> void;
- auto should_close_window() const -> bool
- {
- return should_close;
- }
- auto close_window() -> void;
-
- auto process_input() -> void;
- auto cursor_pos(f32 *x, f32 *y) -> void;
-
- auto swap_buffers() -> void;
-
- private:
- bool should_close = false;
-
- auto raise() -> void;
-
- // Try to make the window shape 0x0 so that its unclickable.
- auto set_clickthrough() -> void;
-
- // Try to disable input by setting window hints.
- auto disable_input() -> void;
-
- Display *x11_d = nullptr;
- Window window;
- GLXContext glc;
-};
-
-} // namespace Mauri
-
-#endif // _CONTEXT_X11_H
diff --git a/src/engine.cc b/src/engine.cc
index 641ac15..ff90d65 100644
--- a/src/engine.cc
+++ b/src/engine.cc
@@ -1,9 +1,6 @@
-#include <thread>
-
-#include "context.h"
#include "engine.h"
+#include "context.h"
-#include "objects/object.h"
#include "objects/scene.h"
using namespace Mauri;
@@ -16,9 +13,8 @@ auto View::center_scale_viewport() -> void
auto View::center_viewport(f32 buffer_width, f32 buffer_height) -> void
{
- f32 w_pad = (this->width - buffer_width) / -2.f;
- f32 h_pad = (this->height - buffer_height) / -2.f;
- Render::set_viewport(w_pad, h_pad, buffer_width, buffer_height);
+ Render::set_viewport((this->width - buffer_width) / -2,
+ (this->height - buffer_height) / -2, buffer_width, buffer_height);
}
auto View::default_viewport(f32 buffer_width, f32 buffer_height) -> void
@@ -36,8 +32,6 @@ auto View::center(f32 buffer_width, f32 buffer_height) -> void
f32 scaled_width = this->width / this->scale;
f32 scaled_height = this->height / this->scale;
- //this->camera_pos[0] = ((scaled_width - buffer_width) / -2.f) + ((scaled_width - buffer_width) / 2.f);
- //this->camera_pos[1] = ((scaled_height - buffer_height) / -2.f) + ((scaled_height - buffer_height) / 2.f);
this->camera_pos[0] = ((scaled_width - buffer_width) / -2.f);
this->camera_pos[1] = ((scaled_height - buffer_height) / -2.f);
}
@@ -45,15 +39,6 @@ auto View::center(f32 buffer_width, f32 buffer_height) -> void
Engine::Engine(Scene *scene, f32 rate, bool audio)
: scene(scene), rate(rate), audio_enabled(audio)
{
- /*
- for (Object *object : scene->objects)
- {
- if (object->size[0] > this->view.width) this->view.width = object->size[0];
- if (object->size[1] > this->view.height) this->view.height = object->size[1];
- }
- */
- //std::cout << this->view.width << " " << this->view.height << "\n";
-
this->view.width = scene->width;
this->view.height = scene->height;
this->view.ortho_width = scene->width;
@@ -65,9 +50,11 @@ Engine::Engine(Scene *scene, f32 rate, bool audio)
this->view.texel_half_size[0] = .5f / this->view.width;
this->view.texel_half_size[1] = .5f / this->view.height;
- this->view.center(context()->width, context()->height);
+ this->view.center(context()->width(), context()->height());
+ this->view.camera_pos[0] += scene->cam.offset[0];
+ this->view.camera_pos[1] += scene->cam.offset[1];
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
if (this->audio_enabled)
{
this->vis = new Visualizer();
@@ -85,13 +72,13 @@ Engine::Engine(Scene *scene, f32 rate, bool audio)
this->create_framebuffer(COMBINE_BUFFER, this->view.width, this->view.height, 1.f);
this->combine_buffer = this->get_framebuffer(COMBINE_BUFFER);
+ this->create_framebuffer(MIPMAPPED_BUFFER, this->view.width, this->view.height, 1.f);
this->default_mat = glm::ortho(-1.f, 1.f, -1.f, 1.f, -3.f, 1.f);
this->default_mat = glm::scale(this->default_mat, vec3{1.f, 1.f, 0.001f});
- this->default_mat_flipped = glm::scale(this->default_mat, vec3{1.f, -1.f, 1.f});
this->default_object = new RenderObject(DEFAULT);
- this->default_object_flipped = new RenderObject(DEFAULT_FLIPPED);
+ this->flipped_object = new RenderObject(DEFAULT_FLIPPED);
this->fullscreen_object = new RenderObject(FULLSCREEN);
}
@@ -102,11 +89,6 @@ auto Engine::create_framebuffer(const std::string &name, f32 width, f32 height,
auto Engine::get_framebuffer(const std::string &name) -> Framebuffer *
{
- // Most likely wrong...
- if (name == "_rt_MipMappedFrameBuffer")
- {
- return this->combine_buffer;
- }
for (Framebuffer *buffer : this->framebuffers)
{
if (buffer->name == name) return buffer;
@@ -122,9 +104,8 @@ auto Engine::get_framebuffer_texture(const std::string &name) -> Texture *
auto Engine::update() -> void
{
- context()->process_input();
-
- context()->cursor_pos(&this->view.cursor_pos[0], &this->view.cursor_pos[1]);
+ this->view.cursor_pos[0] = (f32)context()->pointer_x;
+ this->view.cursor_pos[1] = (f32)context()->pointer_y;
this->view.cursor_pos[0] -= this->view.camera_pos[0];
this->view.cursor_pos[1] -= this->view.camera_pos[1];
@@ -151,23 +132,19 @@ auto Engine::draw() -> void
this->view.center_scale_viewport();
- this->default_object_flipped->bind();
- this->default_object_flipped->draw();
+ this->flipped_object->bind();
+ this->flipped_object->draw();
}
auto Engine::run() -> void
{
- const f32 TARGET_FPS = 60.f;
while (!context()->should_close_window())
{
this->time = context()->current_time();
+ context()->poll();
this->update();
this->draw();
context()->swap_buffers();
- while (context()->current_time() < this->time + 1.0f / TARGET_FPS)
- {
- std::this_thread::sleep_for(std::chrono::microseconds(500));
- }
}
}
@@ -179,10 +156,12 @@ Engine::~Engine()
}
delete this->shader;
+
delete this->default_object;
+ delete this->flipped_object;
delete this->fullscreen_object;
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
delete this->vis;
#endif
}
diff --git a/src/engine.h b/src/engine.h
index a1a063e..dc8c052 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -2,13 +2,13 @@
#define _ENGINE_H
#include "shader.h"
-#include "framebuffer.h"
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
#include "vis.h"
#endif
static const std::string COMBINE_BUFFER = "_rt_FullFrameBuffer";
+static const std::string MIPMAPPED_BUFFER = "_rt_MipMappedFrameBuffer";
namespace Mauri
{
@@ -53,17 +53,16 @@ class Engine
f32 time;
bool audio_enabled;
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
Visualizer *vis;
#endif
View view;
mat4x4 default_mat;
- mat4x4 default_mat_flipped;
RenderObject *default_object;
- RenderObject *default_object_flipped;
+ RenderObject *flipped_object;
RenderObject *fullscreen_object;
Shader *shader;
diff --git a/src/framebuffer.cc b/src/framebuffer.cc
deleted file mode 100644
index 210a052..0000000
--- a/src/framebuffer.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "framebuffer.h"
-
-using namespace Mauri;
-
-Framebuffer::Framebuffer(std::string name, s32 width, s32 height, f32 scale)
- : name(name)
-{
- this->buffer = new RenderFramebuffer(width, height, scale);
- this->texture = new Texture(this->buffer);
-}
-
-Framebuffer::~Framebuffer()
-{
- if (this->buffer) delete this->buffer;
- if (this->texture) delete this->texture;
-}
diff --git a/src/framebuffer.h b/src/framebuffer.h
deleted file mode 100644
index 734715a..0000000
--- a/src/framebuffer.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _FRAMEBUFFER_H
-#define _FRAMEBUFFER_H
-
-#include "texture.h"
-
-namespace Mauri
-{
-
-class Framebuffer
-{
- public:
- Framebuffer(std::string name, s32 width, s32 height, f32 scale);
- ~Framebuffer();
-
- std::string name;
-
- RenderFramebuffer *buffer;
- Texture *texture;
-};
-
-} // namespace Mauri
-
-#endif // _FRAMEBUFFER_H
diff --git a/src/gl.cc b/src/gl.cc
index 66690ba..6629ed6 100644
--- a/src/gl.cc
+++ b/src/gl.cc
@@ -1,7 +1,7 @@
+#include "gl.h"
#include "log.h"
#include "context.h"
#include "texture.h"
-#include "gl.h"
#include "objects/object.h"
@@ -12,6 +12,8 @@ auto uniform_type_to_string(UniformType type) -> std::string
{
switch (type)
{
+ case TYPE_UINT:
+ return "uint";
case TYPE_FLOAT:
return "float";
case TYPE_VEC4:
@@ -34,7 +36,8 @@ auto uniform_type_to_string(UniformType type) -> std::string
auto uniform_type_from_string(const std::string_view &s) -> UniformType
{
- if (s.compare(0, 5, "float") == 0) return TYPE_FLOAT;
+ if (s.compare(0, 4, "uint") == 0) return TYPE_UINT;
+ else if (s.compare(0, 5, "float") == 0) return TYPE_FLOAT;
else if (s.compare(0, 4, "vec4") == 0) return TYPE_VEC4;
else if (s.compare(0, 4, "vec3") == 0) return TYPE_VEC3;
else if (s.compare(0, 4, "vec2") == 0) return TYPE_VEC2;
@@ -184,20 +187,23 @@ RenderShader::RenderShader(const std::string &vs_source, const std::string &fs_s
this->program = glCreateProgram();
char error[256];
+ const char *c_str;
u32 vs_shader = glCreateShader(GL_VERTEX_SHADER);
- if (!compile(vs_shader, vs_source.c_str(), error))
+ c_str = vs_source.c_str();
+ if (!compile(vs_shader, c_str, error))
{
error("failed to compile vertex shader: (%s)", error);
- debug("\n%s", vs_source.c_str());
+ debug("\n%s\n", c_str);
return;
}
u32 fs_shader = glCreateShader(GL_FRAGMENT_SHADER);
- if (!compile(fs_shader, fs_source.c_str(), error))
+ c_str = fs_source.c_str();
+ if (!compile(fs_shader, c_str, error))
{
error("failed to compile fragment shader: (%s)", error);
- debug("\n%s", fs_source.c_str());
+ debug("\n%s\n", c_str);
return;
}
@@ -256,20 +262,21 @@ auto RenderShader::set_uniform(const std::string &name, UniformType type, void *
s32 loc = this->get_uniform_location(name);
if (loc == -1) return;
-#if UNIFORM_DEBUG
- std::cout << name << "(" << type << ")" << " "
- << ((f32 *)value)[0] << " " << ((f32 *)value)[1] << " "
- << ((f32 *)value)[2] << " " << ((f32 *)value)[3] << "\n";
+#ifdef UNIFORM_DEBUG
+ al_printf("%s(%i) %f %f %f %f\n", name.c_str(), type,
+ ((f32 *)value)[0], ((f32 *)value)[1],
+ ((f32 *)value)[2], ((f32 *)value)[3]);
#endif
switch (type)
{
- case TYPE_FLOAT:
- glUniform1f(loc, *((f32 *)value));
- break;
+ case TYPE_UINT:
case TYPE_SAMPLER2D:
glUniform1i(loc, (u32)(*((f32 *)value)));
break;
+ case TYPE_FLOAT:
+ glUniform1f(loc, *((f32 *)value));
+ break;
case TYPE_VEC2:
glUniform2fv(loc, 1, (f32 *)value);
break;
@@ -303,12 +310,15 @@ RenderTexture::RenderTexture(bool no_interp, bool clamp, bool filtering, s32 mm_
glGenTextures(1, &this->id);
glBindTexture(GL_TEXTURE_2D, this->id);
+ /*
if (filtering)
{
f32 aniso;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &aniso);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso);
}
+ */
+ (void)filtering;
if (no_interp)
{
@@ -441,11 +451,11 @@ RenderTexture::~RenderTexture()
RenderFramebuffer::RenderFramebuffer(s32 width, s32 height, f32 scale)
: width(width / scale), height(height / scale)
{
- if (!context()->is_draw_enabled()) return;
-
this->texture = new RenderTexture(false, true, false, 1);
-
this->texture->format = GL_RGBA;
+
+ if (!context()->is_draw_enabled()) return;
+
this->texture->upload(nullptr, this->width, this->height, 0);
glGenFramebuffers(1, &this->id);
@@ -503,8 +513,8 @@ auto Render::bind_framebuffer(s32 id) -> void
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
}
-auto Render::set_viewport(u32 wpad, u32 hpad, u32 width, u32 height) -> void
+auto Render::set_viewport(s32 x, s32 y, s32 width, s32 height) -> void
{
if (!context()->is_draw_enabled()) return;
- glViewport(wpad, hpad, width, height);
+ glViewport(x, y, width, height);
}
diff --git a/src/gl.h b/src/gl.h
index 9da72e7..600c58b 100644
--- a/src/gl.h
+++ b/src/gl.h
@@ -1,10 +1,20 @@
#ifndef _GL_H
#define _GL_H
-#include <glad/gl.h>
+extern "C" {
+#include <stl/gl.h>
+}
+
+#define GLM_ENABLE_EXPERIMENTAL
+#include <glm/glm.hpp>
+#include <glm/gtx/matrix_major_storage.hpp>
+#include <glm/gtc/type_ptr.hpp>
+#include <glm/gtx/string_cast.hpp>
#include "util.h"
+using namespace glm;
+
namespace Mauri
{
@@ -20,6 +30,7 @@ enum ObjectType
enum UniformType
{
TYPE_INVALID,
+ TYPE_UINT,
TYPE_FLOAT,
TYPE_VEC4,
TYPE_VEC3,
@@ -115,7 +126,7 @@ class Render
static auto blend_func(s32 sfactor, s32 dfactor) -> void;
static auto color_mask(f32 r, f32 g, f32 b, f32 a) -> void;
static auto bind_framebuffer(s32 id) -> void;
- static auto set_viewport(u32 wpad, u32 hpad, u32 width, u32 height) -> void;
+ static auto set_viewport(s32 x, s32 y, s32 width, s32 height) -> void;
};
} // namespace Mauri
diff --git a/src/json.h b/src/json.h
index 34b5e72..300f1b3 100644
--- a/src/json.h
+++ b/src/json.h
@@ -1,15 +1,35 @@
#ifndef _JSON_H
#define _JSON_H
-#include "util.h"
+#define JSON_NO_IO
+#undef array
+#include <nlohmann/json.hpp>
-#define str_vec4(s, v) sscanf(s, "%f %f %f %f", &(v)[0], &(v)[1], &(v)[2], &(v)[3])
-#define str_vec3(s, v) sscanf(s, "%f %f %f", &(v)[0], &(v)[1], &(v)[2])
-#define str_vec2(s, v) sscanf(s, "%f %f", &(v)[0], &(v)[1])
+#include "gl.h"
+
+using json = nlohmann::json;
+
+#define json_str_vec4(s, v) sscanf(s, "%f %f %f %f", &(v)[0], &(v)[1], &(v)[2], &(v)[3])
+#define json_str_vec3(s, v) sscanf(s, "%f %f %f", &(v)[0], &(v)[1], &(v)[2])
+#define json_str_vec2(s, v) sscanf(s, "%f %f", &(v)[0], &(v)[1])
+
+#define parse_fail(obj) do { \
+ delete obj; \
+ return nullptr; \
+} while (0)
namespace Mauri {
-enum JsonValueType { FLOAT, INT, VEC2, VEC3, VEC4, BOOL, STRING };
+enum JsonValueType
+{
+ INT = 0,
+ FLOAT,
+ VEC2,
+ VEC3,
+ VEC4,
+ BOOL,
+ STRING
+};
struct JsonValue
{
@@ -21,8 +41,8 @@ struct JsonValue
class Parser
{
public:
- Parser() {}
- ~Parser() {}
+ Parser() = default;
+ ~Parser() = default;
template<typename T>
static auto parse_value(const json &root, const std::string &name, void *out, const T &default_value) -> void
@@ -49,17 +69,17 @@ class Parser
}
else if constexpr (std::is_same<T, vec2>::value)
{
- if (value.is_string()) str_vec2(value.get<std::string>().c_str(), *((vec2 *)out));
+ if (value.is_string()) json_str_vec2(value.get<std::string>().c_str(), *((vec2 *)out));
}
else if constexpr (std::is_same<T, vec3>::value)
{
- if (value.is_string()) str_vec3(value.get<std::string>().c_str(), *((vec3 *)out));
+ if (value.is_string()) json_str_vec3(value.get<std::string>().c_str(), *((vec3 *)out));
}
else if constexpr (std::is_same<T, vec4>::value)
{
// Some uniforms are saved as a single number.
if (value.is_number()) (*((vec4 *)out))[0] = value.get<f32>();
- else if (value.is_string()) str_vec4(value.get<std::string>().c_str(), *((vec4 *)out));
+ else if (value.is_string()) json_str_vec4(value.get<std::string>().c_str(), *((vec4 *)out));
}
else if constexpr (std::is_same<T, bool>::value)
{
diff --git a/src/log.h b/src/log.h
index 34f6cd1..b7655ff 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,28 +1,13 @@
#ifndef _LOG_H
#define _LOG_H
-#include <stdio.h>
-#include <string.h>
+extern "C" {
+#include <al/log.h>
+}
-#define _PRINT(x, ...) printf(x, ##__VA_ARGS__)
-
-#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
-
-#define log_print(t, fmt, ...) \
- do \
- { \
- _PRINT("%s:%d %s(): ", __FILENAME__, __LINE__, __FUNCTION__); \
- _PRINT("%s -> " fmt "\n", t, ##__VA_ARGS__); \
- } while (0)
-
-#define info(fmt, ...) log_print("info", fmt, ##__VA_ARGS__)
-#define warn(fmt, ...) log_print("warn", fmt, ##__VA_ARGS__)
-#define error(fmt, ...) log_print("error", fmt, ##__VA_ARGS__)
-
-#ifdef _DEBUG_
-#define debug(fmt, ...) log_print("debug", fmt, ##__VA_ARGS__)
-#else
-#define debug(fmt, ...)
-#endif
+#define info(fmt, ...) al_log_info(NULL, fmt, ##__VA_ARGS__)
+#define warn(fmt, ...) al_log_warn(NULL, fmt, ##__VA_ARGS__)
+#define error(fmt, ...) al_log_error(NULL, fmt, ##__VA_ARGS__)
+#define debug(fmt, ...) al_log_debug(NULL, fmt, ##__VA_ARGS__)
#endif // _LOG_H
diff --git a/src/mauri.cc b/src/mauri.cc
index fb0cc4b..03e314f 100644
--- a/src/mauri.cc
+++ b/src/mauri.cc
@@ -1,45 +1,58 @@
-#include <args.h>
+#include <janus.h>
+extern "C" {
+#include <stl/window.h>
+#include <aki/common.h>
+}
+#include "context.h"
#include "assets.h"
#include "engine.h"
-#include "context.h"
-#include "context_null.h"
-
-#ifdef BUILD_GLFW
-#include "context_glfw.h"
-#endif
-
-#ifdef BUILD_X11
-#include "context_x11.h"
-#endif
-
#include "objects/scene.h"
using namespace Mauri;
+#ifndef _WIN32
auto main(s32 argc, char *argv[]) -> s32
+#else
+auto wmain(s32 argc, wchar_t **argv) -> s32
+#endif
{
- args::ArgParser args("Usage: ...", "0.12");
+ if (!aki_common_init() || !stl_global_init()) {
+ return EXIT_FAILURE;
+ }
+
+ janus::ArgParser args("Usage: ...", "0.12");
- args.option("path p", "");
- args.option("width w", "");
- args.option("height h", "");
- args.option("background b", "");
- args.option("output o", "");
+ args.newString("package p", "");
+ args.newString("directory d", "");
+ args.newInt("width w", 0);
+ args.newInt("height h", 0);
+ args.newInt("xoffset x", 0);
+ args.newInt("yoffset y", 0);
+ args.newString("monitor m", "");
+ args.newString("output o", "");
+#ifndef _WIN32
args.parse(argc, argv);
+#else
+ args.wparse(argc, argv);
+#endif
- if (!args.found("path"))
+ if (!(args.found("package") ^ args.found("directory")))
{
- std::cout << args.helptext << "\n";
+ al_printf("%s\n", args.helptext.c_str());
return EXIT_FAILURE;
}
- s32 width = -1;
- s32 height = -1;
+ s32 width = 640;
+ s32 height = 480;
+ s32 xoffset = 0;
+ s32 yoffset = 0;
- if (args.found("width")) width = args.value<s32>("width");
- if (args.found("height")) height = args.value<s32>("height");
+ if (args.found("width")) width = args.getInt("width");
+ if (args.found("height")) height = args.getInt("height");
+ if (args.found("xoffset")) xoffset = args.getInt("xoffset");
+ if (args.found("yoffset")) yoffset = args.getInt("yoffset");
if (width == 0 || height == 0)
{
@@ -47,68 +60,67 @@ auto main(s32 argc, char *argv[]) -> s32
return EXIT_FAILURE;
}
- bool background = false;
+ const std::string monitor = args.found("monitor") ? args.getString("monitor") : "";
- if (args.found("background"))
- {
- std::string opt = args.value<std::string>("background");
- str_to_lower(opt);
- background = opt == "true";
- }
-
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
gst_init(&argc, &argv);
#endif
- //Context *new_context = new ContextGLFW();
- Context *new_context = new ContextX11();
- if (!new_context->create_window(width > 0 ? width : 640, height > 0 ? height : 480, "mauri", background))
+ Context *new_context = new Context();
+ if (!new_context->create_window(width, height, "mauri", monitor))
{
return EXIT_FAILURE;
}
- if (!asset_manager()->arm_package(args.value("path"), args.found("output")))
+ if (args.found("package"))
{
- return EXIT_FAILURE;
+ if (!asset_manager()->arm_package(args.getString("package"), args.found("output")))
+ {
+ return EXIT_FAILURE;
+ }
+ }
+
+ asset_manager()->add_search_directory("./assets");
+
+ if (args.found("directory"))
+ {
+ asset_manager()->add_search_directory(args.getString("directory"));
}
set_context(new_context);
- Scene *scene = new Scene("scene.json");
+ Scene *scene = Scene::parse("scene.json");
+ if (!scene) return EXIT_FAILURE;
if (width <= 0) width = scene->width;
if (height <= 0) height = scene->height;
+ scene->offset_camera(xoffset, yoffset);
context()->resize_window(width, height);
Engine *engine = new Engine(scene, 1.f, true);
- std::chrono::time_point<std::chrono::system_clock> begin = std::chrono::system_clock::now();
+ u64 begin = aki_get_timestamp();
scene->load(engine);
- using us = std::chrono::microseconds;
- u64 duration = std::chrono::duration_cast<us>(std::chrono::system_clock::now() - begin).count();
- info("scene loaded in %fs", duration / 1000000.f);
+ u64 duration = aki_get_timestamp() - begin;
+ info("scene loaded in %.2fs", duration / 1000000.f);
- if (asset_manager()->prepare_output)
- {
- asset_manager()->write_files(args.value("output"));
- }
- else
- {
- engine->run();
- }
+ if (asset_manager()->prepare_output) asset_manager()->write_files(args.getString("output"));
+ else engine->run();
delete scene;
delete engine;
- asset_manager()->unload_package();
+ unload_shaders();
+
+ if (args.found("package")) asset_manager()->unload_package();
context()->close_window();
set_context(nullptr);
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
//gst_deinit();
#endif
diff --git a/src/objects/effect.cc b/src/objects/effect.cc
index 5542ccc..92f7dda 100644
--- a/src/objects/effect.cc
+++ b/src/objects/effect.cc
@@ -1,48 +1,58 @@
-#include "pass.h"
#include "effect.h"
+#include "pass.h"
using namespace Mauri;
-Effect::Effect(Parser &pr, const json &root)
+auto Effect::parse(Parser &pr, const json &root) -> Effect *
{
+ Effect *effect = new Effect();
+
Asset *asset = asset_manager()->get_file(root["file"]);
- if (asset->type == ASSET_VOID) return;
+ if (asset->type == ASSET_VOID) parse_fail(effect);
- const json &file = json::parse(asset->as_string());
- if (file.is_discarded()) return;
+ const json &file = json::parse(asset->as_string(), nullptr, false);
+ if (file.is_discarded()) parse_fail(effect);
- pr.map_value<u32>(root, "id", &this->id, 0);
- pr.map_value<bool>(root, "visible", &this->visible, true);
- pr.map_value<std::string>(file, "name", &this->name, "");
+ pr.map_value<u32>(root, "id", &effect->id, 0);
+ pr.map_value<bool>(root, "visible", &effect->visible, true);
+ pr.map_value<std::string>(file, "name", &effect->name, "");
if (root.contains("passes"))
{
for (const json &pass0 : root["passes"])
{
- this->passes0.emplace_back(new Pass(pr, pass0, EFFECT0_PASS));
+ Pass *pass = Pass::parse(pr, pass0, EFFECT0_PASS);
+ if (pass) effect->passes0.emplace_back(pass);
}
}
+ if (effect->passes0.size() == 0) parse_fail(effect);
+
if (file.contains("passes"))
{
for (const json &pass1 : file["passes"])
{
- this->passes1.emplace_back(new Pass(pr, pass1, EFFECT1_PASS));
+ Pass *pass = Pass::parse(pr, pass1, EFFECT1_PASS);
+ if (pass) effect->passes1.emplace_back(pass);
}
}
+ if (effect->passes1.size() == 0) parse_fail(effect);
+
if (file.contains("fbos"))
{
for (const json &fbo : file["fbos"])
{
- this->fbos.emplace_back(EffectBuffer{fbo["name"], fbo.contains("scale") ? (f32)fbo["scale"] : 1.f });
+ effect->fbos.emplace_back(EffectBuffer{fbo["name"], fbo.contains("scale") ? (f32)fbo["scale"] : 1.f });
}
}
+
+ return effect;
}
auto Effect::load(Engine *engine, Object *object, bool last) -> void
{
- this->buffer_id = str_format("_%i_%i", object->id, this->id);
+ this->buffer_id = "_" + std::to_string(object->id) + "_" + std::to_string(this->id);
for (const EffectBuffer &fbo : this->fbos)
{
@@ -82,14 +92,14 @@ auto Effect::draw(Engine *engine) -> void
{
if (!this->visible) return;
-#if FRAME_STEP
- std::cout << this->name << ":\n";
+#ifdef FRAME_STEP
+ al_printf("%s\n", this->name.c_str());
#endif
for (RenderPass *pass : this->passes)
{
-#if FRAME_STEP
- if (pass->shader) std::cout << "\t" << pass->shader->origin()->name << "\n";
+#ifdef FRAME_STEP
+ if (pass->shader) al_printf("\t%s\n", pass->shader->origin()->name.c_str());
#endif
pass->draw(engine);
}
diff --git a/src/objects/effect.h b/src/objects/effect.h
index cb53a04..710fc51 100644
--- a/src/objects/effect.h
+++ b/src/objects/effect.h
@@ -3,7 +3,6 @@
#include "../json.h"
#include "../engine.h"
-#include "../texture.h"
namespace Mauri
{
@@ -20,7 +19,7 @@ class RenderPass;
class Effect
{
public:
- Effect(Parser &pr, const json &root);
+ Effect() = default;
~Effect();
u32 id;
@@ -32,6 +31,8 @@ class Effect
std::vector<RenderPass *> passes;
+ static auto parse(Parser &pr, const json &root) -> Effect *;
+
auto load(Engine *engine, Object *object, bool last) -> void;
auto draw(Engine *engine) -> void;
diff --git a/src/objects/material.cc b/src/objects/material.cc
index b17a102..e3e3e02 100644
--- a/src/objects/material.cc
+++ b/src/objects/material.cc
@@ -1,23 +1,28 @@
-#include "pass.h"
#include "material.h"
+#include "pass.h"
using namespace Mauri;
-Material::Material(Parser &pr, const std::string &path)
+auto Material::parse(Parser &pr, const std::string &path) -> Material *
{
+ Material *material = new Material();
+
Asset *asset = asset_manager()->get_file(path);
- if (asset->type == ASSET_VOID) return;
+ if (asset->type == ASSET_VOID) parse_fail(material);
- const json &root = json::parse(asset->as_string());
- if (root.is_discarded()) return;
+ const json &root = json::parse(asset->as_string(), nullptr, false);
+ if (root.is_discarded()) parse_fail(material);
if (root.contains("passes"))
{
- for (const json &pass : root["passes"])
+ for (const json &pass0 : root["passes"])
{
- this->passes0.push_back(new Pass(pr, pass, MATERIAL_PASS));
+ Pass *pass = Pass::parse(pr, pass0, MATERIAL_PASS);
+ if (pass) material->passes0.push_back(pass);
}
}
+
+ return material;
}
auto Material::load(Engine *engine, Object *object, MaterialType type, Pass *pass) -> void
diff --git a/src/objects/material.h b/src/objects/material.h
index cfea216..a0edca7 100644
--- a/src/objects/material.h
+++ b/src/objects/material.h
@@ -7,16 +7,22 @@
namespace Mauri
{
-enum MaterialType { MATERIAL_MODEL, MATERIAL_EFFECT };
+enum MaterialType
+{
+ MATERIAL_MODEL = 0,
+ MATERIAL_EFFECT
+};
class Pass;
class Material
{
public:
- Material(Parser &pr, const std::string &path);
+ Material() = default;
~Material();
+ static auto parse(Parser &pr, const std::string &path) -> Material *;
+
std::vector<Pass *> passes0;
auto load(Engine *engine, Object *object, MaterialType type, Pass *pass) -> void;
diff --git a/src/objects/model.cc b/src/objects/model.cc
index b916ec7..830bdaf 100644
--- a/src/objects/model.cc
+++ b/src/objects/model.cc
@@ -2,22 +2,27 @@
using namespace Mauri;
-Model::Model(Parser &pr, const std::string &path)
+auto Model::parse(Parser &pr, const std::string &path) -> Model *
{
+ Model *model = new Model();
+
Asset *asset = asset_manager()->get_file(path);
- if (asset->type == ASSET_VOID) return;
+ if (asset->type == ASSET_VOID) parse_fail(model);
+
+ const json &root = json::parse(asset->as_string(), nullptr, false);
+ if (root.is_discarded()) parse_fail(model);
- const json &root = json::parse(asset->as_string());
- if (root.is_discarded()) return;
+ pr.map_value<bool>(root, "autosize", &model->autosize, false);
+ pr.map_value<bool>(root, "fullscreen", &model->fullscreen, false);
+ pr.map_value<bool>(root, "passthrough", &model->passthrough, false);
- pr.map_value<bool>(root, "autosize", &this->autosize, false);
- pr.map_value<bool>(root, "fullscreen", &this->fullscreen, false);
- pr.map_value<bool>(root, "passthrough", &this->passthrough, false);
+ pr.map_value<f32>(root, "width", &model->width, 0.f);
+ pr.map_value<f32>(root, "height", &model->height, 0.f);
- pr.map_value<f32>(root, "width", &this->width, 0.f);
- pr.map_value<f32>(root, "height", &this->height, 0.f);
+ if (root.contains("material")) model->material = Material::parse(pr, root["material"]);
+ if (!model->material) parse_fail(model);
- if (root.contains("material")) this->material = new Material(pr, root["material"]);
+ return model;
}
auto Model::load(Engine *engine, Object *object) -> void
diff --git a/src/objects/model.h b/src/objects/model.h
index f6b532a..d000bd7 100644
--- a/src/objects/model.h
+++ b/src/objects/model.h
@@ -9,7 +9,7 @@ namespace Mauri
class Model
{
public:
- Model(Parser &pr, const std::string &path);
+ Model() = default;
~Model();
bool autosize = true;
@@ -19,6 +19,8 @@ class Model
f32 width;
f32 height;
+ static auto parse(Parser &pr, const std::string &path) -> Model *;
+
auto load(Engine *engine, Object *object) -> void;
private:
diff --git a/src/objects/object.cc b/src/objects/object.cc
index ac64a25..d648b63 100644
--- a/src/objects/object.cc
+++ b/src/objects/object.cc
@@ -1,21 +1,21 @@
-#include "../context.h"
-
-#include "pass.h"
-#include "scene.h"
#include "object.h"
+#include "scene.h"
+#include "pass.h"
using namespace Mauri;
-Object::Object(Parser &pr, const json &root)
+auto Object::parse(Parser &pr, const json &root) -> Object *
{
- pr.map_value<u32>(root, "id", &this->id, 0);
- pr.map_value<std::string>(root, "name", &this->name, "");
+ Object *object = new Object();
+
+ pr.map_value<u32>(root, "id", &object->id, 0);
+ pr.map_value<std::string>(root, "name", &object->name, "");
if (root.contains("dependencies"))
{
for (const json &id : root["dependencies"])
{
- this->deps.push_back(id);
+ object->deps.push_back(id);
}
}
@@ -23,11 +23,11 @@ Object::Object(Parser &pr, const json &root)
// object or are repeated. This could be handled be sorting objects
// on the scene in order of deps but I'm not sure if that would
// break other things.
- auto it = this->deps.begin();
- while (it != this->deps.end())
+ auto it = object->deps.begin();
+ while (it != object->deps.end())
{
- bool remove = ((u32)(*it) == id);
- for (auto rt = this->deps.begin(); rt != this->deps.end(); ++rt)
+ bool remove = ((u32)(*it) == object->id);
+ for (auto rt = object->deps.begin(); rt != object->deps.end(); ++rt)
{
if (rt != it && *rt == *it)
{
@@ -35,44 +35,48 @@ Object::Object(Parser &pr, const json &root)
break;
}
}
- if (remove) this->deps.erase(it);
+ if (remove) object->deps.erase(it);
else it++;
}
- pr.map_value<bool>(root, "visible", &this->visible, true);
- pr.map_value<vec3>(root, "angles", &this->angles, vec3(0.f));
- pr.map_value<vec2>(root, "size", &this->size, vec2(0.f));
- pr.map_value<vec3>(root, "scale", &this->scale, vec3(0.f));
- pr.map_value<vec3>(root, "origin", &this->origin, vec3(0.f));
- if (this->origin[2] != 0.f)
+ pr.map_value<bool>(root, "visible", &object->visible, true);
+ pr.map_value<vec3>(root, "angles", &object->angles, vec3(0.f));
+ pr.map_value<vec2>(root, "size", &object->size, vec2(0.f));
+ pr.map_value<vec3>(root, "scale", &object->scale, vec3(1.f));
+ pr.map_value<vec3>(root, "origin", &object->origin, vec3(0.f));
+ if (object->origin[2] != 0.f)
{
warn("non 0 origin[2]");
- this->origin[2] = 0.f;
+ object->origin[2] = 0.f;
}
- pr.map_value<vec3>(root, "color", &this->color, vec3(0.f));
- pr.map_value<f32>(root, "alpha", &this->alpha, 1.f);
- pr.map_value<s32>(root, "colorBlendMode", &this->color_blend_mode, 0);
+ pr.map_value<vec3>(root, "color", &object->color, vec3(0.f));
+ pr.map_value<f32>(root, "alpha", &object->alpha, 1.f);
+ pr.map_value<s32>(root, "colorBlendMode", &object->color_blend_mode, 0);
- this->color4 = vec4{this->color[0], this->color[1], this->color[2], this->alpha};
+ object->color4 = vec4{object->color[0], object->color[1], object->color[2], object->alpha};
if (root.contains("image"))
{
const json &image = root["image"];
- if (image.is_string()) this->model = new Model(pr, image);
+ if (image.is_string()) object->model = Model::parse(pr, image);
+ if (!object->model) parse_fail(object);
}
if (root.contains("config"))
{
- pr.map_value<bool>(root["config"], "passthrough", &this->passthrough, false);
+ pr.map_value<bool>(root["config"], "passthrough", &object->passthrough, false);
}
if (root.contains("effects"))
{
for (const json &effect : root["effects"])
{
- this->effects.emplace_back(new Effect(pr, effect));
+ Effect *eff = Effect::parse(pr, effect);
+ if (eff) object->effects.emplace_back(eff);
}
}
+
+ return object;
}
auto Object::load(Engine *engine) -> void
@@ -110,8 +114,9 @@ auto Object::load(Engine *engine) -> void
if (this->size[1] == 0.f) this->size[1] = engine->scene->height;
}
- this->buffer_a = str_format("_rt_imageLayerComposite_%i_a", this->id);
- this->buffer_b = str_format("_rt_imageLayerComposite_%i_b", this->id);
+ const std::string buffer_name = "_rt_imageLayerComposite_" + std::to_string(this->id) + "_";
+ this->buffer_a = buffer_name + "a";
+ this->buffer_b = buffer_name + "b";
engine->create_framebuffer(this->buffer_a, this->size[0], this->size[1], 1.f);
engine->create_framebuffer(this->buffer_b, this->size[0], this->size[1], 1.f);
@@ -151,23 +156,7 @@ auto Object::load(Engine *engine) -> void
blend_pass.combos.push_back(Combo("BLENDMODE", this->color_blend_mode));
blend_pass.combos.push_back(Combo("TRANSFORM", 1));
- RenderPass *pass = new RenderPass(engine, &blend_pass);
- this->effects.back()->passes.emplace_back(pass);
-
- /*
- blend_pass.combine = true;
-
- blend_pass.target = "";
- blend_pass.textures[1] = "";
- blend_pass.shader = "minimal";
-
- blend_pass.combos.clear();
-
- pass = new RenderPass(engine, &blend_pass);
- //pass->mat = &engine->default_mat;
- //pass->render_object = engine->default_object;
- this->effects.back()->passes.emplace_back(pass);
- */
+ this->effects.back()->passes.emplace_back(new RenderPass(engine, &blend_pass));
}
this->loaded = true;
@@ -183,7 +172,7 @@ auto Object::create_objects(Engine *engine, Texture *texture) -> void
{
// Something about positioning is wrong, affects most gifs.
}
- if (this->passthrough)
+ if (this->passthrough && !this->fullscreen)
{
this->model_model = this->combine_model;
this->model_model = glm::rotate(this->model_model, this->angles[0], vec3{1.f, 0.f, 0.f});
@@ -204,16 +193,16 @@ auto Object::create_objects(Engine *engine, Texture *texture) -> void
auto Object::draw_internal(Engine *engine) -> void
{
-#if FRAME_STEP
- std::cout << this->name << " (model):\n";
+#ifdef FRAME_STEP
+ al_printf("%s (model):\n", this->name.c_str());
#endif
this->buffer_switch = true;
for (RenderPass *pass : this->passes)
{
-#if FRAME_STEP
- std::cout << "\t" << pass->shader->origin()->name << "\n";;
+#ifdef FRAME_STEP
+ al_printf("\t%s\n", pass->shader->origin()->name.c_str());
#endif
pass->draw(engine);
}
diff --git a/src/objects/object.h b/src/objects/object.h
index a171fae..9c9f60c 100644
--- a/src/objects/object.h
+++ b/src/objects/object.h
@@ -7,13 +7,21 @@
namespace Mauri
{
-enum ObjectAlignment { CENTER };
-enum BlendMode { TRANSLUCENT, NORMAL };
+enum ObjectAlignment
+{
+ CENTER = 0
+};
+
+enum BlendMode
+{
+ TRANSLUCENT = 0,
+ NORMAL
+};
class Object
{
public:
- Object(Parser &pr, const json &root);
+ Object() = default;
~Object();
u32 id;
@@ -42,6 +50,8 @@ class Object
RenderObject *model_object = nullptr;
RenderObject *combine_object = nullptr;
+ static auto parse(Parser &pr, const json &root) -> Object *;
+
auto get_target_buffer() const -> const std::string &;
auto get_texture_buffer() const -> const std::string &;
diff --git a/src/objects/pass.cc b/src/objects/pass.cc
index 49533e1..04e23d5 100644
--- a/src/objects/pass.cc
+++ b/src/objects/pass.cc
@@ -1,38 +1,37 @@
-#include <thread>
-
#include "../gl.h"
-#include "../context.h"
-#include "scene.h"
#include "pass.h"
using namespace Mauri;
-Pass::Pass(Parser &pr, const json &root, PassStage stage)
+auto Pass::parse(Parser &pr, const json &root, PassStage stage) -> Pass *
{
+ Pass *pass = new Pass();
+
switch (stage)
{
case EFFECT0_PASS:
break;
case EFFECT1_PASS:
{
- if (root.contains("material")) this->material = new Material(pr, root["material"]);
+ if (root.contains("material")) pass->material = Material::parse(pr, root["material"]);
+ if (!pass->material) parse_fail(pass);
if (root.contains("command"))
{
const json command = root["command"];
- if (command == "copy") this->command = COPY;
+ if (command == "copy") pass->command = COPY;
}
- if (root.contains("target")) this->target = root["target"];
- if (root.contains("source")) this->source = root["source"];
+ if (root.contains("target")) pass->target = root["target"];
+ if (root.contains("source")) pass->source = root["source"];
- this->binds[0] = "previous";
+ pass->binds[0] = "previous";
if (root.contains("bind"))
{
for (const json &bind : root["bind"])
{
- this->binds[bind["index"]] = bind["name"];
+ pass->binds[bind["index"]] = bind["name"];
}
}
@@ -40,7 +39,10 @@ Pass::Pass(Parser &pr, const json &root, PassStage stage)
}
case MATERIAL_ONLY_PASS:
case MATERIAL_PASS:
- this->shader = root["shader"];
+ pass->shader = root["shader"];
+ if (pass->shader == "genericimage4") {
+ pass->shader = "genericimage2";
+ }
break;
}
@@ -51,7 +53,7 @@ Pass::Pass(Parser &pr, const json &root, PassStage stage)
{
UniformOverride *uniform = new UniformOverride{vec4(0.f), value.key()};
pr.map_value<vec4>(uniforms, value.key(), &uniform->value, vec4(0.f));
- this->uniforms.push_back(uniform);
+ pass->uniforms.push_back(uniform);
}
}
@@ -60,7 +62,7 @@ Pass::Pass(Parser &pr, const json &root, PassStage stage)
const json textures = root["textures"];
for (u32 i = 0; i < textures.size(); i++)
{
- if (textures[i].is_string()) this->textures[i] = textures[i];
+ if (textures[i].is_string()) pass->textures[i] = textures[i];
}
}
@@ -68,9 +70,11 @@ Pass::Pass(Parser &pr, const json &root, PassStage stage)
{
for (const auto &combo : root["combos"].items())
{
- this->combos.emplace_back(Combo(combo.key(), combo.value()));
+ pass->combos.emplace_back(Combo(combo.key(), combo.value()));
}
}
+
+ return pass;
}
auto Pass::load(Engine *engine, PassStage stage, Pass *pass) -> void
@@ -169,7 +173,7 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
pass->combos.push_back(Combo(this->shader->origin()->texture_combos[i], !pass->textures[i].empty()));
}
- if (!this->shader->origin()->textures[i].empty() && pass->textures[i].empty())
+ if (pass->textures[i].empty() && !this->shader->origin()->textures[i].empty())
{
pass->textures[i] = this->shader->origin()->textures[i];
}
@@ -193,9 +197,12 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
}
}
- if (i == 0 && this->textures[0] && this->model)
+ if (this->model && i == 0 && this->textures[0])
{
- if (this->textures[0]->is_gif()) pass->combos.push_back(Combo("SPRITESHEET", 1));
+ if (this->textures[0]->is_gif())
+ {
+ pass->combos.push_back(Combo("SPRITESHEET", 1));
+ }
this->object->create_objects(engine, this->textures[0]);
objects_created = true;
}
@@ -267,41 +274,41 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
}
}
-#if _DEBUG_
+#ifdef _DEBUG_
debug("PASS (%s)", this->command == COPY ? "copy" : "draw");
- debug(" object: %s (passthrough: %i, fullscreen %i)", this->object->name.c_str(),
+ debug(" object: %s (passthrough: %d, fullscreen %d)", this->object->name.c_str(),
this->object->passthrough, this->object->fullscreen);
- //debug(" visible: %i", );
- debug(" shader: %s", this->shader->origin()->name.c_str());
- debug(" target: %s", pass->target.c_str());
- debug(" textures (%i):", this->shader->origin()->texture_count);
+ debug(" visible: %d", this->object->visible);
+ debug(" shader: %s", this->shader->origin()->name.c_str());
+ debug(" target: %s", pass->target.c_str());
+ debug(" textures (%u):", this->shader->origin()->texture_count);
for (u32 i = 0; i < this->shader->origin()->texture_count; i++)
{
switch (this->texture_types[i])
{
case STATIC:
- if (pass->textures[i].empty() && !this->shader->textures[i].empty())
+ if (pass->textures[i].empty() && !this->shader->origin()->textures[i].empty())
{
- debug(" %s (DEFAULT)", this->shader->textures[i].c_str());
+ debug(" [%u] %s (DEFAULT)", i, this->shader->origin()->textures[i].c_str());
}
else
{
- debug(" %s", pass->textures[i].c_str());
+ debug(" [%u] %s", i, pass->textures[i].c_str());
}
break;
case PREVIOUS:
- debug(" previous");
+ debug(" [%u] previous", i);
break;
}
}
- debug(" uniforms (%li)", this->shader->uniforms.size());
+ debug(" uniforms (%u)", this->shader->uniforms.size());
for (Uniform *uniform : this->shader->uniforms)
{
- debug(" %s %s %s", uniform_type_to_string(uniform->type).c_str(),
+ debug(" %s %s %s", uniform_type_to_string(uniform->type).c_str(),
uniform->uname.c_str(), glm::to_string(*uniform->value).c_str());
}
- debug(" model: %i", this->model);
- debug(" combine: %i", this->combine);
+ debug(" model: %d", this->model);
+ debug(" combine: %d", this->combine);
#endif
}
@@ -341,10 +348,10 @@ auto RenderPass::draw(Engine *engine) -> void
this->render_object->draw();
-#if FRAME_STEP
- adjusted_target->buffer->blit(0, context()->width, context()->height);
+#ifdef FRAME_STEP
+ adjusted_target->buffer->blit(0, context()->width(), context()->height());
context()->swap_buffers();
- std::this_thread::sleep_for(std::chrono::seconds(1));
+ aki_thread_sleep(AKI_TS_FROM_USEC(1000000));
#endif
break;
}
diff --git a/src/objects/pass.h b/src/objects/pass.h
index a2b3124..5012ed5 100644
--- a/src/objects/pass.h
+++ b/src/objects/pass.h
@@ -8,10 +8,25 @@
namespace Mauri
{
-enum PassStage { EFFECT0_PASS, EFFECT1_PASS, MATERIAL_PASS, MATERIAL_ONLY_PASS };
-enum PassCommand { DRAW, COPY };
+enum PassStage
+{
+ EFFECT0_PASS = 0,
+ EFFECT1_PASS,
+ MATERIAL_PASS,
+ MATERIAL_ONLY_PASS
+};
+
+enum PassCommand
+{
+ DRAW = 0,
+ COPY
+};
-enum TextureType { STATIC, PREVIOUS };
+enum TextureType
+{
+ STATIC = 0,
+ PREVIOUS
+};
struct UniformOverride
{
@@ -22,8 +37,7 @@ struct UniformOverride
class Pass
{
public:
- Pass() {}
- Pass(Parser &pr, const json &root, PassStage stage);
+ Pass() = default;
~Pass();
bool intermediate;
@@ -47,6 +61,8 @@ class Pass
std::vector<UniformOverride *> uniforms;
std::vector<Combo> combos;
+ static auto parse(Parser &pr, const json &root, PassStage stage) -> Pass *;
+
auto load(Engine *engine, PassStage stage, Pass *pass) -> void;
private:
diff --git a/src/objects/scene.cc b/src/objects/scene.cc
index 06412f5..b7d1192 100644
--- a/src/objects/scene.cc
+++ b/src/objects/scene.cc
@@ -2,37 +2,48 @@
using namespace Mauri;
-Scene::Scene(const std::string &path)
+auto Scene::parse(const std::string &path) -> Scene *
{
+ Scene *scene = new Scene();
+
Asset *asset = asset_manager()->get_file(path);
- if (asset->type == ASSET_VOID) return;
+ if (asset->type == ASSET_VOID) parse_fail(scene);
- const json &root = json::parse(asset->as_string());
- if (root.is_discarded()) return;
+ const json &root = json::parse(asset->as_string(), nullptr, false);
+ if (root.is_discarded()) parse_fail(scene);
- Parser &pr = this->parser;
+ Parser &pr = scene->parser;
const json &camera = root["camera"];
- pr.map_value<vec3>(camera, "center", &this->cam.center, vec3(0.f));
- pr.map_value<vec3>(camera, "eye", &this->cam.eye, vec3(0.f));
- pr.map_value<vec3>(camera, "up", &this->cam.up, vec3(0.f));
+ pr.map_value<vec3>(camera, "center", &scene->cam.center, vec3(0.f));
+ pr.map_value<vec3>(camera, "eye", &scene->cam.eye, vec3(0.f));
+ pr.map_value<vec3>(camera, "up", &scene->cam.up, vec3(0.f));
const json &general = root["general"];
- pr.map_value<bool>(general, "clearenabled", &this->clear_enabled, true);
- pr.map_value<vec4>(general, "clearcolor", &this->clear_color, vec4(1.f));
- pr.map_value<f32>(general, "nearz", &this->nearz, -1.f);
- pr.map_value<f32>(general, "farz", &this->farz, 1.f);
+ pr.map_value<bool>(general, "clearenabled", &scene->clear_enabled, true);
+ pr.map_value<vec4>(general, "clearcolor", &scene->clear_color, vec4(1.f));
+ pr.map_value<f32>(general, "nearz", &scene->nearz, -1.f);
+ pr.map_value<f32>(general, "farz", &scene->farz, 1.f);
const json &ortho = general["orthogonalprojection"];
- pr.map_value<s32>(ortho, "width", &this->width, 0);
- pr.map_value<s32>(ortho, "height", &this->height, 0);
+ pr.map_value<s32>(ortho, "width", &scene->width, 0);
+ pr.map_value<s32>(ortho, "height", &scene->height, 0);
for (const json &object : root["objects"])
{
if (!object.contains("image") || object["image"].is_null()) continue;
- //if (object["name"] == "ICUE") continue;
- this->objects.emplace_back(new Object(pr, object));
+ if (object["name"] == "ICUE") continue;
+ Object *obj = Object::parse(scene->parser, object);
+ if (obj) scene->objects.emplace_back(obj);
}
+
+ return scene;
+}
+
+auto Scene::offset_camera(s32 x, s32 y) -> void
+{
+ this->cam.offset[0] = x;
+ this->cam.offset[1] = y;
}
auto Scene::get_object_by_id(u32 id) -> Object *
diff --git a/src/objects/scene.h b/src/objects/scene.h
index 7b3d07a..2472fda 100644
--- a/src/objects/scene.h
+++ b/src/objects/scene.h
@@ -11,12 +11,13 @@ struct Camera
vec3 center;
vec3 eye;
vec3 up;
+ vec2 offset = vec2(0.f);
};
class Scene
{
public:
- Scene(const std::string &path);
+ Scene() = default;
~Scene();
Parser parser;
@@ -32,6 +33,10 @@ class Scene
bool clear_enabled;
vec4 clear_color;
+ static auto parse(const std::string &path) -> Scene *;
+
+ auto offset_camera(s32 x, s32 y) -> void;
+
auto get_object_by_id(u32 id) -> Object *;
auto load(Engine *engine) -> void;
diff --git a/src/shader.cc b/src/shader.cc
index 0a2d568..2820b57 100644
--- a/src/shader.cc
+++ b/src/shader.cc
@@ -1,9 +1,8 @@
-#include <sstream>
-
-#include "json.h"
#include "shader.h"
+#include "gl.h"
+#include "json.h"
-#include "objects/scene.h"
+#include "objects/object.h"
static const char *compat = \
// "#define mul(x, y) ((y) * (x))\n"
@@ -38,15 +37,21 @@ static std::unordered_map<u64, RenderShader *> render_shader_map;
auto get_shader(const std::string &name) -> Shader *
{
- if (shader_map.contains(name))
- {
- return new Shader(shader_map[name]);
- }
+ auto rshader = shader_map.find(name);
+ if (rshader != shader_map.end()) return new Shader(rshader->second);
Shader *shader = new Shader(name);
shader_map[name] = shader;
return shader;
}
+extern auto unload_shaders() -> void
+{
+ for (auto &entry : render_shader_map)
+ {
+ delete entry.second;
+ }
+}
+
} // namespace Mauri
using namespace Mauri;
@@ -74,36 +79,61 @@ Shader::Shader(Shader *origin)
this->origin_ = origin;
}
-static auto simple_audio_bars_hack(std::string_view &line) -> void
+static auto simple_audio_bars_hack(std::string_view &line) -> const std::string_view
{
- if (line == " uint barFreq1 = frequency % RESOLUTION;")
+ if (line == " uint barFreq1 = frequency % RESOLUTION;\r\n")
+ {
+ return " uint barFreq1 = uint(mod(frequency, RESOLUTION));\r\n";
+ }
+ else if (line == " uint barFreq2 = (barFreq1 + 1) % RESOLUTION;\r\n")
+ {
+ return " uint barFreq2 = uint(mod((barFreq1 + 1u), RESOLUTION));\r\n";
+ }
+ else if (line == " int bar = step(shapeCoord.y, 0.5 * lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1L, barVolume2L, smoothstep(0, 1, fract(frequency)))));\r\n")
{
- line = " uint barFreq1 = uint(mod(frequency, RESOLUTION));";
+ return " float bar = step(shapeCoord.y, 0.5 * lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1L, barVolume2L, smoothstep(0, 1, fract(frequency)))));\r\n";
}
- else if (line == " uint barFreq2 = (barFreq1 + 1) % RESOLUTION;")
+ else if (line == " int bar = step(1 - shapeCoord.y, lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1, barVolume2, smoothstep(0, 1, fract(frequency)))));\r\n")
{
- line = " uint barFreq2 = uint(mod((barFreq1 + 1u), RESOLUTION));";
+ return " float bar = step(1 - shapeCoord.y, lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1, barVolume2, smoothstep(0, 1, fract(frequency)))));\r\n";
}
- else if (line == " int bar = step(shapeCoord.y, 0.5 * lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1L, barVolume2L, smoothstep(0, 1, fract(frequency)))));")
+ else if (line == " int bar = step(1 - shapeCoord.y, barHeight);\r\n")
{
- line = " float bar = step(shapeCoord.y, 0.5 * lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1L, barVolume2L, smoothstep(0, 1, fract(frequency)))));";
+ return " float bar = step(1 - shapeCoord.y, barHeight);\r\n";
}
- else if (line == " int bar = step(1 - shapeCoord.y, lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1, barVolume2, smoothstep(0, 1, fract(frequency)))));")
+ else if (line == " int barLeft = step(shapeCoord.y, barHeightLeft);\r\n")
{
- line = " float bar = step(1 - shapeCoord.y, lerp(g_BarBounds.x, g_BarBounds.y, lerp(barVolume1, barVolume2, smoothstep(0, 1, fract(frequency)))));";
+ return " float barLeft = step(shapeCoord.y, barHeightLeft);\r\n";
}
- else if (line == " int bar = step(1 - shapeCoord.y, barHeight);")
+ else if (line == " int barRight = step(1 - shapeCoord.y, barHeightRight);\r\n")
{
- line = " float bar = step(1 - shapeCoord.y, barHeight);";
+ return " float barRight = step(1 - shapeCoord.y, barHeightRight);\r\n";
}
- else if (line == " int barLeft = step(shapeCoord.y, barHeightLeft);")
+ else if (line == " shapeCoord.x += endAngle - startAngle < 0.0;\r\n")
{
- line = " float barLeft = step(shapeCoord.y, barHeightLeft);";
+ return " shapeCoord.x += endAngle - int(startAngle < 0.0);\r\n";
}
- else if (line == " int barRight = step(1 - shapeCoord.y, barHeightRight);")
+ else if (line == " bar *= shapeCoord.x > 0.0 && shapeCoord.x * sign(endAngle - startAngle) < 1.0;\r\n")
{
- line = " float barRight = step(1 - shapeCoord.y, barHeightRight);";
+ return " bar *= int(shapeCoord.x > 0.0 && shapeCoord.x * sign(endAngle - startAngle) < 1.0);\r\n";
}
+ return line;
+}
+
+static auto bokeh_blur_hack(std::string_view &line) -> const std::string_view
+{
+ if (line == " depth *= (depth < blurPreciseLimit) * 6.0;\r\n")
+ {
+ return " depth *= int(depth < blurPreciseLimit) * 6.0;\r\n";
+ }
+ return line;
+}
+
+static auto apply_hacks(std::string_view line) -> const std::string_view
+{
+ line = simple_audio_bars_hack(line);
+ line = bokeh_blur_hack(line);
+ return line;
}
auto Shader::build_shader_source(const std::string_view &isource, std::stringstream &out) -> void
@@ -112,11 +142,18 @@ auto Shader::build_shader_source(const std::string_view &isource, std::stringstr
std::stringstream prefix;
- for (const auto &range : std::ranges::split_view(isource, std::string_view("\r\n")))
- {
- std::string_view line = std::string_view(range.data(), range.size());
+ auto cursor = isource.begin();
+ auto end = isource.end();
- simple_audio_bars_hack(line);
+ while (cursor != end)
+ {
+ auto end_of_line = std::find(cursor, end, '\n');
+ if (end_of_line != end) {
+ end_of_line++;
+ }
+ std::string_view raw_line = std::string_view(cursor, end_of_line - cursor);
+ cursor += raw_line.length();
+ const std::string_view line = apply_hacks(raw_line);
bool cut_line = false;
bool prepend_line = false;
@@ -257,7 +294,7 @@ auto Shader::build_shader_source(const std::string_view &isource, std::stringstr
{
size_t open = line.find('{');
std::string_view combo = line.substr(open, line.length() - open);
- const json &root = json::parse(combo);
+ const json &root = json::parse(combo, nullptr, false);
if (!root.is_discarded())
{
if (root.contains("default"))
@@ -274,8 +311,8 @@ auto Shader::build_shader_source(const std::string_view &isource, std::stringstr
if (!cut_line)
{
- if (prepend_line) prefix << line << "\n";
- else out << line << "\n";
+ if (prepend_line) prefix << line;
+ else out << line;
}
}
@@ -285,12 +322,12 @@ auto Shader::build_shader_source(const std::string_view &isource, std::stringstr
auto Combo::to_string() const -> const std::string
{
- return str_format("#define %s %i\n", this->name.c_str(), this->value);
+ return "#define " + this->name + " " + std::to_string(this->value) + "\n";
}
auto Variable::to_string() const -> const std::string
{
- return str_format("varying %s %s;\n", uniform_type_to_string(this->type).c_str(), this->name.c_str());
+ return "varying " + uniform_type_to_string(this->type) + " " + this->name + ";\n";
}
auto Shader::compile(const std::vector<Combo> &combo_overrides) -> RenderShader *
@@ -306,7 +343,6 @@ auto Shader::compile(const std::vector<Combo> &combo_overrides) -> RenderShader
{
shader_combo.value = combo.value;
add = false;
- break;
}
}
if (add) adjusted_combos.push_back(combo);
@@ -321,27 +357,25 @@ auto Shader::compile(const std::vector<Combo> &combo_overrides) -> RenderShader
u64 hash = std::hash<std::string>{}(this->origin()->name + combos_str.str());
- if (!render_shader_map.contains(hash))
- {
- std::stringstream preamble;
-
- preamble << version;
- preamble << compat;
+ auto rshader = render_shader_map.find(hash);
+ if (rshader != render_shader_map.end()) return rshader->second;
- preamble << combos_str.str();
+ std::stringstream preamble;
- for (const Variable &variable : this->origin()->variables)
- {
- preamble << variable.to_string();
- }
+ preamble << version;
+ preamble << compat;
- std::string vs_source = preamble.str() + mul + this->origin()->vs_source.str();
- std::string fs_source = preamble.str() + this->origin()->fs_source.str();
+ preamble << combos_str.str();
- render_shader_map[hash] = new RenderShader(vs_source, fs_source);
+ for (const Variable &variable : this->origin()->variables)
+ {
+ preamble << variable.to_string();
}
- return render_shader_map[hash];
+ std::string vs_source = preamble.str() + mul + this->origin()->vs_source.str();
+ std::string fs_source = preamble.str() + this->origin()->fs_source.str();
+
+ return render_shader_map[hash] = new RenderShader(vs_source, fs_source);
}
auto Shader::bind(RenderShader *shader, Engine *engine, Object *object, mat4x4 *model,
@@ -408,7 +442,7 @@ auto Shader::bind(RenderShader *shader, Engine *engine, Object *object, mat4x4 *
shader->set_uniform("g_Color4", TYPE_VEC4, glm::value_ptr(object->color4));
}
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
if (engine->audio_enabled)
{
engine->vis->update();
@@ -436,11 +470,15 @@ auto Shader::bind(RenderShader *shader, Engine *engine, Object *object, mat4x4 *
glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Left"), 16, empty_bars.data());
glUniform1fv(shader->get_uniform_location("g_AudioSpectrum16Right"), 16, empty_bars.data());
#endif
-#ifdef BUILD_AUDIO
+#ifdef HAVE_AUDIO
}
#endif
}
Shader::~Shader()
{
+ for (Uniform *uniform : this->uniforms)
+ {
+ delete uniform;
+ }
}
diff --git a/src/shader.h b/src/shader.h
index 1ce4209..c3b2738 100644
--- a/src/shader.h
+++ b/src/shader.h
@@ -24,10 +24,9 @@ struct Uniform
struct Combo
{
- Combo(const std::string &name, s32 value)
- : name(name), value(value)
+ Combo(const std::string &name, s32 value) : name(name), value(value)
{
- str_to_upper(this->name);
+ std::transform(this->name.begin(), this->name.end(), this->name.begin(), ::toupper);
}
std::string name;
s32 value;
@@ -80,6 +79,7 @@ private:
};
extern auto get_shader(const std::string &name) -> Shader *;
+extern auto unload_shaders() -> void;
} // namespace Mauri
diff --git a/src/texture.cc b/src/texture.cc
index 21dfd90..8b7aa23 100644
--- a/src/texture.cc
+++ b/src/texture.cc
@@ -1,12 +1,16 @@
+_Pragma("GCC diagnostic push")
+_Pragma("GCC diagnostic ignored \"-Wunused-function\"")
+_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"")
#define STB_IMAGE_WRITE_IMPLEMENTATION
-#define STBI_NO_FAILURE_STRINGS
-#define STB_IMAGE_STATIC
+#define STB_IMAGE_WRITE_STATIC
#include <stb_image_write.h>
#define STB_IMAGE_IMPLEMENTATION
+#define STB_IMAGE_STATIC
#define STBI_NO_STDIO
+#define STBI_NO_FAILURE_STRINGS
#include <stb_image.h>
-
+_Pragma("GCC diagnostic pop")
#include <lz4.h>
#include <s3tc.h>
@@ -194,10 +198,7 @@ Texture::Texture(Asset *asset)
std::string_view gif_container = asset->reads(9);
u32 gif_frame_count = asset->read<u32>();
- if (gif_container.compare(0, 8, "TEXS0002") == 0)
- {
- //this->flags.m.IS_GIF = 0;
- }
+ if (gif_container.compare(0, 8, "TEXS0002") == 0) {}
else if (gif_container.compare(0, 8, "TEXS0003") == 0)
{
this->gif_width = asset->read<u32>();
@@ -275,8 +276,10 @@ auto Texture::save_to_file(const std::string &filename) -> void
{
for (u32 i = 0; i < this->textures.size(); i++)
{
- stbi_write_png((filename + std::to_string(i)).c_str(), this->textures[i]->width, this->textures[i]->height,
- 4, this->textures[i]->pixels.data(), 4 * this->textures[i]->width);
+ u32 width = this->textures[i]->width;
+ u32 height = this->textures[i]->height;
+ u32 *data = this->textures[i]->pixels.data();
+ stbi_write_png((filename + std::to_string(i)).c_str(), width, height, 4, data, 4 * width);
}
}
@@ -284,3 +287,16 @@ Texture::~Texture()
{
if (!this->wrapped) delete this->texture;
}
+
+Framebuffer::Framebuffer(std::string name, s32 width, s32 height, f32 scale)
+ : name(name)
+{
+ this->buffer = new RenderFramebuffer(width, height, scale);
+ this->texture = new Texture(this->buffer);
+}
+
+Framebuffer::~Framebuffer()
+{
+ if (this->buffer) delete this->buffer;
+ if (this->texture) delete this->texture;
+}
diff --git a/src/texture.h b/src/texture.h
index c552037..e68ce1f 100644
--- a/src/texture.h
+++ b/src/texture.h
@@ -7,7 +7,12 @@
namespace Mauri
{
-enum TextureVersion { TEXB0001, TEXB0002, TEXB0003 };
+enum TextureVersion
+{
+ TEXB0001 = 0,
+ TEXB0002,
+ TEXB0003
+};
enum TextureFormat
{
@@ -79,6 +84,18 @@ class Texture
std::vector<TextureFrame> frames;
};
+class Framebuffer
+{
+ public:
+ Framebuffer(std::string name, s32 width, s32 height, f32 scale);
+ ~Framebuffer();
+
+ std::string name;
+
+ RenderFramebuffer *buffer;
+ Texture *texture;
+};
+
} // namespace Mauri
#endif // _TEXTURE_H
diff --git a/src/util.cc b/src/util.cc
deleted file mode 100644
index 8a02572..0000000
--- a/src/util.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "util.h"
-
-namespace Mauri
-{
-
-auto str_to_lower(std::string &s) -> void
-{
- transform(s.begin(), s.end(), s.begin(), ::tolower);
-}
-
-auto str_to_upper(std::string &s) -> void
-{
- transform(s.begin(), s.end(), s.begin(), ::toupper);
-}
-
-} // namespace Mauri
diff --git a/src/util.h b/src/util.h
index c0c4084..6548a9b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,58 +1,26 @@
#ifndef _UTIL_H
#define _UTIL_H
-#include <stdint.h>
+extern "C" {
+#include <al/types.h>
+}
-#include <glm/glm.hpp>
-#include <glm/gtx/matrix_major_storage.hpp>
-#include <glm/gtc/type_ptr.hpp>
-#include <glm/gtx/string_cast.hpp>
-#include <nlohmann/json.hpp>
+#undef array
+#include <array>
+#include <vector>
+#include <unordered_map>
+#include <sstream>
+#include <algorithm>
+#include <cmath>
#include "log.h"
-using namespace glm;
-using namespace nlohmann;
-
-#define FRAME_STEP 0
-#define UNIFORM_DEBUG 0
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
-typedef uint32_t u32;
-typedef int32_t s32;
-
-typedef uint64_t u64;
-typedef int64_t s64;
-
-typedef uint16_t u16;
-typedef int16_t s16;
-
-typedef uint8_t u8;
-typedef int8_t s8;
-
-typedef float f32;
-typedef double f64;
-
-typedef unsigned char byte;
-
-namespace Mauri
-{
-
-template<typename ... Args>
-static auto str_format(const std::string &format, Args ... args) -> std::string
-{
- s32 size_s = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1;
- if (size_s <= 0) { return ""; }
- auto size = static_cast<size_t>(size_s);
- std::unique_ptr<char[]> buf(new char[size]);
- std::snprintf(buf.get(), size, format.c_str(), args ...);
- return std::string(buf.get(), buf.get() + size - 1);
-}
+// Pause after every pass.
+//#define FRAME_STEP
-auto str_to_lower(std::string &s) -> void;
-auto str_to_upper(std::string &s) -> void;
+// Print uniforms each frame.
+//#define UNIFORM_DEBUG
-} // namespace Mauri
+typedef uint8_t byte;
#endif // _UTIL_H
diff --git a/src/vis.cc b/src/vis.cc
index 7b52808..062bb62 100644
--- a/src/vis.cc
+++ b/src/vis.cc
@@ -1,5 +1,3 @@
-#include <cmath>
-
#include "vis.h"
using namespace Mauri;
@@ -129,7 +127,11 @@ auto Visualizer::update() -> void
g_mutex_lock(&this->mutex);
- if (!this->sample) return;
+ if (!this->sample)
+ {
+ g_mutex_unlock(&this->mutex);
+ return;
+ }
GstBuffer *buffer = gst_sample_get_buffer(sample);
@@ -199,21 +201,24 @@ auto Visualizer::update_sample() -> void
this->sample_processed = false;
}
-static auto new_sample_callback(GstElement *appsink, gpointer *data) -> GstFlowReturn
+static auto sample_callback(GstElement *appsink, gpointer *data) -> GstFlowReturn
{
Visualizer *vis = (Visualizer *)data;
+
g_mutex_lock(&vis->mutex);
vis->update_sample();
g_mutex_unlock(&vis->mutex);
+
return GST_FLOW_OK;
}
+/*
static auto main_thread(void *data) -> void *
{
Visualizer *vis = (Visualizer *)data;
- GstMessage *msg = gst_bus_timed_pop_filtered(vis->bus,
- GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
+ GstMessageType filter = (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
+ GstMessage *msg = gst_bus_timed_pop_filtered(vis->bus, GST_CLOCK_TIME_NONE, filter);
if (!msg) return 0;
@@ -230,6 +235,7 @@ static auto main_thread(void *data) -> void *
return 0;
}
+*/
auto Visualizer::run() -> bool
{
@@ -253,34 +259,34 @@ auto Visualizer::run() -> bool
gst_element_set_state(this->pipeline, GST_STATE_PLAYING);
- this->bus = gst_pipeline_get_bus(GST_PIPELINE(this->pipeline));
-
- this->signal_handler = g_signal_connect(this->appsink, "new-sample",
- G_CALLBACK(new_sample_callback), this);
+ this->signal_handler = g_signal_connect(this->appsink, "new-sample", G_CALLBACK(sample_callback), this);
- this->thread = g_thread_new(nullptr, main_thread, this);
+ //this->bus = gst_pipeline_get_bus(GST_PIPELINE(this->pipeline));
+ //this->thread = g_thread_new(nullptr, main_thread, this);
return true;
}
Visualizer::~Visualizer()
{
- if (this->in_left) fftw_free(this->in_left);
- if (this->in_right) fftw_free(this->in_right);
- if (this->out_left) fftw_free(this->out_left);
- if (this->out_right) fftw_free(this->out_right);
-
- g_mutex_clear(&this->mutex);
-
/*
gst_bus_post(this->bus, gst_message_new_eos(GST_OBJECT(this->pipeline)));
g_thread_join(this->thread);
gst_object_unref(this->bus);
+ */
+
+ g_signal_handler_disconnect(this->appsink, this->signal_handler);
//gst_element_set_state(this->pipeline, GST_STATE_NULL);
//gst_element_get_state(this->pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE);
//gst_object_unref(this->pipeline);
if (this->sample) gst_sample_unref(this->sample);
- */
+
+ if (this->in_left) fftw_free(this->in_left);
+ if (this->in_right) fftw_free(this->in_right);
+ if (this->out_left) fftw_free(this->out_left);
+ if (this->out_right) fftw_free(this->out_right);
+
+ g_mutex_clear(&this->mutex);
}
diff --git a/src/vis.h b/src/vis.h
index 65261c7..5d8f38c 100644
--- a/src/vis.h
+++ b/src/vis.h
@@ -1,9 +1,9 @@
#ifndef _VISUALIZER_H
#define _VISUALIZER_H
-#include <atomic>
-#include <fftw3.h>
#include <gst/gst.h>
+#include <fftw3.h>
+#include <atomic>
#include "util.h"