summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO16
-rw-r--r--src/assets.cc105
-rw-r--r--src/assets.h8
-rw-r--r--src/engine.cc49
-rw-r--r--src/engine.h10
-rw-r--r--src/mauri.cc43
-rw-r--r--src/objects/effect.cc10
-rw-r--r--src/objects/effect.h10
-rw-r--r--src/objects/material.cc7
-rw-r--r--src/objects/material.h5
-rw-r--r--src/objects/model.cc4
-rw-r--r--src/objects/model.h2
-rw-r--r--src/objects/object.cc59
-rw-r--r--src/objects/object.h6
-rw-r--r--src/objects/pass.cc159
-rw-r--r--src/objects/pass.h7
-rw-r--r--src/objects/scene.cc5
-rw-r--r--src/shader.cc25
-rw-r--r--src/util.h2
-rw-r--r--src/visualizer.cc59
-rw-r--r--src/visualizer.h19
21 files changed, 334 insertions, 276 deletions
diff --git a/TODO b/TODO
index 47a522f..4c80d9f 100644
--- a/TODO
+++ b/TODO
@@ -2,9 +2,15 @@
[x] pass parser as pointer everywhere
-[ ] cleanup visualizer code
+[x] cleanup visualizer code
+
+[ ] seperate program to extract scene.pkg
+
+[ ] gifs
+ - https://github.com/notscuffed/repkg/blob/master/RePKG.Application/Texture/TexFrameInfoContainerReader.cs
[ ] RG88 & R8 textures
+ - i think it works need to test more
[ ] Re-think parse/load stage, parse stage could possibly be 1 stage where textures and framebuffers,
generate itermediate objects then "load" could simply load and map the resources either to the
@@ -16,6 +22,12 @@ Broken:
[ ] ./mauri ../../../c/workshop_wallpapers/1703298496/scene.pkg
- xray only works in the middle
+[ ] ./mauri ../../../c/workshop_wallpapers/2216609166/scene.pkg
+ - left side not draw?
+
+[ ] ./mauri ../../../c/workshop_wallpapers/1938288759/scene.pkg
+ - visualizer not drawn correctly
+
[ ] ./mauri ../../../c/workshop_wallpapers/1778616550/scene.pkg
- first object has different blendmode, so we need to handle "combine" passes differently.
The final pass should draw to the objects framebuffer as well as to the combine buffer,
@@ -37,4 +49,6 @@ Broken:
- engine should be a shared library
- there should be a cli interface along with gui
+[ ] javascript scripting
+
[ ] particles
diff --git a/src/assets.cc b/src/assets.cc
index cbc2e9e..789ba2e 100644
--- a/src/assets.cc
+++ b/src/assets.cc
@@ -1,6 +1,7 @@
#include "assets.h"
#include "log.h"
#include "util.h"
+#include "texture.h"
#include <array>
#include <fstream>
@@ -8,13 +9,25 @@
using namespace Mauri;
+namespace Mauri
+{
+
+static AssetManager manager;
+
+AssetManager *asset_manager()
+{
+ return &manager;
+}
+
+} // namespace Mauri
+
Asset::Asset()
{
type = ASSET_VOID;
size = 0;
pos = 0;
data = nullptr;
- hash = 0;
+ lasset = nullptr;
}
static Asset asset_void = Asset();
@@ -25,7 +38,7 @@ Asset::Asset(const std::string &path, byte *begin, byte *end)
size = end - begin;
pos = 0;
data = begin;
- hash = std::hash<std::string>{}(path);
+ lasset = nullptr;
}
Asset::Asset(const std::string &path)
@@ -54,8 +67,6 @@ Asset::Asset(const std::string &path)
pos = 0;
type = ASSET_FILE;
-
- hash = std::hash<std::string>{}(path);
}
Asset::~Asset()
@@ -64,6 +75,18 @@ Asset::~Asset()
{
delete[] data;
}
+
+ if (lasset != nullptr)
+ {
+ switch (ltype)
+ {
+ case TEXTURE:
+ delete (Texture *)lasset;
+ break;
+ default:
+ break;
+ }
+ }
}
bool AssetManager::load_package(const std::string &path)
@@ -100,12 +123,17 @@ bool AssetManager::load_package(const std::string &path)
for (auto file : pkg_files)
{
- files.push_back(
- new Asset(std::string(file.path),
- pkg->ptr() + file.offset,
- pkg->ptr() + file.offset + file.length
- )
+ auto path = std::string(file.path);
+
+ auto asset = new Asset(path,
+ pkg->ptr() + file.offset,
+ pkg->ptr() + file.offset + file.length
);
+
+ asset->hash = std::hash<std::string>{}(path);
+
+ files.push_back(asset);
+
log_debug("loaded file (%s)", std::string(file.path).c_str());
}
@@ -118,18 +146,18 @@ Asset *AssetManager::get_file(const std::string &part, FileTypeHint hint)
switch (hint)
{
- case FileTypeHint::TEXTURE:
+ case TEXTURE:
path.insert(0, "materials/");
path.append(".tex");
break;
- case FileTypeHint::SHADER:
+ case SHADER:
path.insert(0, "shaders/");
break;
- case FileTypeHint::FRAGMENT_SHADER:
+ case FRAGMENT_SHADER:
path.insert(0, "shaders/");
path.append(".frag");
break;
- case FileTypeHint::VERTEX_SHADER:
+ case VERTEX_SHADER:
path.insert(0, "shaders/");
path.append(".vert");
break;
@@ -138,29 +166,50 @@ Asset *AssetManager::get_file(const std::string &part, FileTypeHint hint)
break;
}
+ Asset *asset = nullptr;
+
u64 hash = std::hash<std::string>{}(path);
for (auto &file : files)
{
if (file->hash == hash)
{
- return file;
+ asset = file;
+ break;
}
}
- path.insert(0, "assets/");
+ if (asset == nullptr)
+ {
+ path.insert(0, "assets/");
- Asset *asset = new Asset(path);
+ asset = new Asset(path);
+ asset->hash = hash;
- if (asset->type == ASSET_VOID)
- {
- delete asset;
- return &asset_void;
+ if (asset->type == ASSET_VOID)
+ {
+ delete asset;
+ return &asset_void;
+ }
+
+ files.push_back(asset);
}
- files.push_back(std::move(asset));
+ asset->ltype = hint;
- return files.back();
+ if (asset->lasset == nullptr)
+ {
+ switch (hint)
+ {
+ case TEXTURE:
+ asset->lasset = new Texture(asset);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return asset;
}
AssetManager::~AssetManager()
@@ -171,15 +220,3 @@ AssetManager::~AssetManager()
}
delete pkg;
}
-
-namespace Mauri
-{
-
-static AssetManager manager;
-
-AssetManager *asset_manager()
-{
- return &manager;
-}
-
-} // namespace Mauri
diff --git a/src/assets.h b/src/assets.h
index 14a76de..2f7677f 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -40,6 +40,10 @@ class Asset
// free'd along with this asset.
AssetType type;
+ // Info about loaded asset
+ FileTypeHint ltype;
+ void *lasset;
+
u32 size;
u64 hash;
@@ -99,14 +103,14 @@ class AssetManager
AssetManager() {};
~AssetManager();
+ std::vector<Asset *> files;
+
bool load_package(const std::string &path);
Asset *get_file(const std::string &part, FileTypeHint hint);
private:
Asset *pkg;
-
- std::vector<Asset *> files;
};
extern AssetManager *asset_manager();
diff --git a/src/engine.cc b/src/engine.cc
index ed4301a..b744f8d 100644
--- a/src/engine.cc
+++ b/src/engine.cc
@@ -1,4 +1,5 @@
#include "engine.h"
+#include "assets.h"
#include "context.h"
#include "json.h"
#include "shader.h"
@@ -8,6 +9,7 @@
#include "objects/object.h"
#include "objects/scene.h"
+#include "visualizer.h"
#include <glm/ext.hpp>
#include <glm/ext/matrix_transform.hpp>
@@ -48,8 +50,8 @@ void View::center(f32 w1, f32 h1)
camera_pos[1] = (scaled_height - h1) / -2.f;
}
-Engine::Engine(Scene *scene, Context *context, Parser *parser)
- : scene(scene), parser(parser), context(context)
+Engine::Engine(Scene *scene, Context *context, Parser *parser, bool audio)
+ : scene(scene), parser(parser), context(context), audio_enabled(audio)
{
view.width = scene->width;
view.height = scene->height;
@@ -74,34 +76,39 @@ Engine::Engine(Scene *scene, Context *context, Parser *parser)
default_model_flipped = glm::scale(default_model, (vec3){1.f, -1.f, 1.f});
scene->load(this);
-}
-Texture *Engine::get_texture(Asset *asset)
-{
- for (auto &texture : texture_cache)
+ if (audio_enabled)
{
- if (texture->hash == asset->hash)
- return texture;
+ visualizer = new Visualizer();
}
-
- texture_cache.emplace_back(new Texture(asset));
-
- return texture_cache.back();
}
Framebuffer *Engine::get_framebuffer(const std::string &name)
{
- return framebuffers[name];
+ for (auto &buffer : framebuffers)
+ {
+ if (buffer->name == name)
+ {
+ return buffer;
+ }
+ }
+
+ return nullptr;
}
Texture *Engine::get_framebuffer_texture(const std::string &name)
{
- return framebuffers[name]->texture;
+ auto buffer = get_framebuffer(name);
+
+ if (buffer != nullptr)
+ return buffer->texture;
+
+ return nullptr;
}
void Engine::create_framebuffer(std::string name, f32 width, f32 height, f32 scale)
{
- framebuffers[name] = new Framebuffer(name, width, height, scale);
+ framebuffers.emplace_back(new Framebuffer(name, width, height, scale));
}
void Engine::update()
@@ -133,8 +140,7 @@ void Engine::draw()
{
for (auto& buffer : framebuffers)
{
- if (buffer.second != nullptr)
- buffer.second->buffer->clear((vec4){0.f, 0.f, 0.f, 0.f});
+ buffer->buffer->clear((vec4){0.f, 0.f, 0.f, 0.f});
}
if (scene->clear_enabled)
@@ -185,14 +191,11 @@ Engine::~Engine()
{
for (auto &buffer : framebuffers)
{
- delete buffer.second;
- }
-
- for (auto &texture : texture_cache)
- {
- delete texture;
+ delete buffer;
}
delete default_object;
delete minimal_shader;
+
+ delete visualizer;
}
diff --git a/src/engine.h b/src/engine.h
index cb14cb8..8dc5093 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -43,14 +43,16 @@ struct View
class Engine
{
public:
- Engine(Scene *scene, Context *context, Parser *parser);
+ Engine(Scene *scene, Context *context, Parser *parser, bool visualizer);
~Engine();
Scene *scene;
Parser *parser;
Context *context;
+
Visualizer *visualizer;
+ bool audio_enabled;
View view;
@@ -63,13 +65,9 @@ class Engine
Shader *minimal_shader;
- std::vector<Texture *> texture_cache;
-
- Texture *get_texture(Asset *asset);
-
Framebuffer *combine_buffer;
- std::unordered_map<std::string, Framebuffer *> framebuffers;
+ std::vector<Framebuffer *> framebuffers;
void create_framebuffer(std::string name, f32 width, f32 height, f32 scale);
diff --git a/src/mauri.cc b/src/mauri.cc
index f66e9b3..f1493e4 100644
--- a/src/mauri.cc
+++ b/src/mauri.cc
@@ -18,14 +18,13 @@ using namespace Mauri;
static std::string scene_path = "scene.json";
+
s32 main(s32 argc, char *argv[])
{
srand(time(NULL));
gst_init(&argc, &argv);
- Visualizer *v = new Visualizer();
-
//Context *context = new ContextX11(2560, 1440, "mauri", true);
//Context *context = new ContextGLFW(720, 1280, "mauri", false);
Context *context = new ContextGLFW(1280, 720, "mauri", false);
@@ -46,45 +45,7 @@ s32 main(s32 argc, char *argv[])
//context->resize_window(scene->width, scene->height);
- Engine engine(scene, context, &parser);
- engine.visualizer = v;
-
- /*
- for (auto &user : parser.values)
- {
- std::cout << user.first << ":\n";
- for (auto &value : user.second)
- {
- std::cout << "\t" << value.name << ": ";
- switch (value.type)
- {
- case INT:
- std::cout << *((u32 *)value.v);
- break;
- case FLOAT:
- std::cout << *((f32 *)value.v);
- break;
- case VEC2:
- std::cout << (*((vec2 *)value.v))[0];
- break;
- case VEC3:
- std::cout << (*((vec3 *)value.v))[0];
- break;
- case VEC4:
- std::cout << (*((vec4 *)value.v))[0] << (*((vec4 *)value.v))[1];
- break;
- case BOOL:
- std::cout << *((bool *)value.v);
- break;
- case STRING:
- std::cout << *((std::string *)value.v);
- break;
- }
-
- std::cout << "\n";
- }
- }
- */
+ Engine engine(scene, context, &parser, true);
engine.run();
diff --git a/src/objects/effect.cc b/src/objects/effect.cc
index 33b72aa..1ab5a96 100644
--- a/src/objects/effect.cc
+++ b/src/objects/effect.cc
@@ -83,15 +83,15 @@ void Effect::draw(Engine *engine)
if (!visible)
return;
-#ifdef _DEBUG_
- //std::cout << name << ":\n";
+#if FRAME_STEP
+ std::cout << name << ":\n";
#endif
for (auto &pass : passes)
{
-#ifdef _DEBUG_
- //if (pass->shader != nullptr)
- // std::cout << "\t" << pass->shader->name << "\n";
+#if FRAME_STEP
+ if (pass->shader != nullptr)
+ std::cout << "\t" << pass->shader->name << "\n";
#endif
pass->draw(engine);
}
diff --git a/src/objects/effect.h b/src/objects/effect.h
index 40110a8..840830b 100644
--- a/src/objects/effect.h
+++ b/src/objects/effect.h
@@ -5,6 +5,7 @@
#include "engine.h"
#include "texture.h"
+#include "util.h"
namespace Mauri
{
@@ -27,19 +28,20 @@ class Effect
u32 id;
std::string name;
+ bool visible;
+
std::string buffer_id;
+ std::vector<RenderPass *> passes;
+
+
void load(Engine *engine, Object *object, bool last);
void draw(Engine *engine);
private:
- bool visible;
-
std::vector<Pass *> passes0;
std::vector<Pass *> passes1;
- std::vector<RenderPass *> passes;
-
std::vector<EffectBuffer> fbos;
};
diff --git a/src/objects/material.cc b/src/objects/material.cc
index 465fab1..b91a26a 100644
--- a/src/objects/material.cc
+++ b/src/objects/material.cc
@@ -29,7 +29,7 @@ Material::Material(Parser &p, const std::string &path)
}
}
-void Material::load(Engine *engine, Object *object, MaterialType type, Pass *pass, bool no_effects)
+void Material::load(Engine *engine, Object *object, MaterialType type, Pass *pass)
{
for (auto &pass0 : passes0)
{
@@ -44,7 +44,10 @@ void Material::load(Engine *engine, Object *object, MaterialType type, Pass *pas
_pass.object = object;
_pass.effect = nullptr;
- _pass.combine = no_effects && !object->passthrough && !object->fullscreen;
+ if (object->effects.size() == 0 && !object->passthrough)
+ _pass.combine = true;
+ else
+ _pass.combine = false;
pass0->load(engine, MATERIAL_ONLY_PASS, &_pass);
diff --git a/src/objects/material.h b/src/objects/material.h
index 0e46f7f..11a2c46 100644
--- a/src/objects/material.h
+++ b/src/objects/material.h
@@ -23,10 +23,9 @@ class Material
Material(Parser &p, const std::string &path);
~Material();
- void load(Engine *engine, Object *object, MaterialType type, Pass *pass, bool no_effects);
-
- private:
std::vector<Pass *> passes0;
+
+ void load(Engine *engine, Object *object, MaterialType type, Pass *pass);
};
} // namespace Mauri
diff --git a/src/objects/model.cc b/src/objects/model.cc
index f450d34..1ec7424 100644
--- a/src/objects/model.cc
+++ b/src/objects/model.cc
@@ -34,9 +34,9 @@ Model::Model(Parser &p, const std::string &path)
material = new Material(p, _material);
}
-void Model::load(Engine *engine, Object *object, bool no_effects)
+void Model::load(Engine *engine, Object *object)
{
- material->load(engine, object, MATERIAL_MODEL, NULL, no_effects);
+ material->load(engine, object, MATERIAL_MODEL, NULL);
}
Model::~Model()
diff --git a/src/objects/model.h b/src/objects/model.h
index e4a55ea..243de1f 100644
--- a/src/objects/model.h
+++ b/src/objects/model.h
@@ -24,7 +24,7 @@ class Model
f32 width;
f32 height;
- void load(Engine *engine, Object *object, bool no_effects);
+ void load(Engine *engine, Object *object);
private:
Material *material = nullptr;
diff --git a/src/objects/object.cc b/src/objects/object.cc
index 18bfdf0..1ed2053 100644
--- a/src/objects/object.cc
+++ b/src/objects/object.cc
@@ -130,17 +130,29 @@ void Object::load(Engine *engine)
gl_object = new RenderObject(OBJECT, size[0], size[1]);
gl_uv_object = new RenderObject(UV_SCALE, size[0], size[1]);
- //blend_shader = new Shader(engine->parser, "passthroughblend");
- //blend_shader->combos.push_back((Combo) { "TRANSFORM", 1 });
- //blend_shader->combos.push_back((Combo) { "BLENDMODE", color_blend_mode });
- //blend_shader->compile();
-
if (image != nullptr)
- image->load(engine, this, effects.size() == 0);
+ {
+ image->load(engine, this);
+ }
- for (s32 i = 0; i < effects.size(); i++)
+ if (effects.size() != 0)
{
- effects[i]->load(engine, this, i == (effects.size() - 1));
+ // Get last effect that is visible
+ // to know when to make a combine pass.
+ Effect *last_effect = effects[0];
+
+ for (auto &effect : effects)
+ {
+ if (effect->visible)
+ {
+ last_effect = effect;
+ }
+ }
+
+ for (auto &effect : effects)
+ {
+ effect->load(engine, this, effect == last_effect);
+ }
}
loaded = true;
@@ -158,14 +170,14 @@ void Object::draw(Engine *engine)
if (!visible)
return;
-#ifdef _DEBUG_
- //std::cout << name << " (model):\n";
+#if FRAME_STEP
+ std::cout << name << " (model):\n";
#endif
for (auto &pass : passes)
{
-#ifdef _DEBUG_
- //std::cout << "\t" << pass->shader->name << "\n";;
+#if FRAME_STEP
+ std::cout << "\t" << pass->shader->name << "\n";;
#endif
pass->draw(engine);
}
@@ -174,29 +186,6 @@ void Object::draw(Engine *engine)
{
effect->draw(engine);
}
-
- //if (!visible)
- // return;
-
- //engine->combine_buffer_a->buffer->bind();
-
- //blend_shader->bind(engine, &model);
- //gl_object->bind();
-
- //engine->get_framebuffer_texture(get_texture_buffer())->bind(0);
-
- //engine->combine_buffer_b->texture->bind(1);
-
- //Render::blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- //Render::color_mask(1.f, 1.f, 1.f, 1.f);
-
- //engine->view.default_viewport(engine->scene->width, engine->scene->height);
-
- //gl_object->draw();
-
- //engine->combine_buffer_a->buffer->blit(engine->combine_buffer_b->buffer->id,
- // engine->combine_buffer_a->buffer->width,
- // engine->combine_buffer_a->buffer->height);
}
std::string Object::get_target_buffer() const
diff --git a/src/objects/object.h b/src/objects/object.h
index 2ce7347..24796e5 100644
--- a/src/objects/object.h
+++ b/src/objects/object.h
@@ -56,15 +56,13 @@ class Object
std::string get_target_buffer() const;
std::string get_texture_buffer() const;
- Framebuffer *previous_buffer;
- Texture *previous_texture;
-
void swap_buffer()
{
buffer_switch = !buffer_switch;
}
std::vector<RenderPass *> passes;
+
std::vector<Effect *> effects;
void load(Engine *engine);
@@ -74,8 +72,6 @@ class Object
private:
Model *image = nullptr;
- Shader *blend_shader;
-
vec3 angles;
vec3 color;
diff --git a/src/objects/pass.cc b/src/objects/pass.cc
index 38e68e3..689dda4 100644
--- a/src/objects/pass.cc
+++ b/src/objects/pass.cc
@@ -2,6 +2,7 @@
#include <fmt/core.h>
#include <glm/fwd.hpp>
#include <glm/gtc/type_ptr.hpp>
+#include <jsoncpp/json/value.h>
#include <stdint.h>
#include <thread>
#include <type_traits>
@@ -72,8 +73,6 @@ Pass::Pass(Parser &p, json &root, PassStage stage)
break;
}
case MATERIAL_ONLY_PASS:
- target = "previous";
- [[fallthrough]];
case MATERIAL_PASS:
shader = root["shader"];
break;
@@ -123,12 +122,7 @@ void Pass::load(Engine *engine, PassStage stage, Pass *pass)
pass->source = source + pass->effect->buffer_id;
pass->target = target;
- if (pass->target == "previous")
- {
- pass->target = pass->object->get_target_buffer();
- pass->textures[0] = pass->object->get_texture_buffer();
- }
- else
+ if (!pass->target.empty())
pass->target.append(pass->effect->buffer_id);
for (int i = 0; i < MAX_TEXTURES; i++)
@@ -137,22 +131,18 @@ void Pass::load(Engine *engine, PassStage stage, Pass *pass)
continue;
if (binds[i] == "previous")
- pass->textures[i] = pass->object->get_texture_buffer();
+ pass->textures[i] = "";
else
pass->textures[i] = binds[i] + pass->effect->buffer_id;
}
- if (target == "previous")
- pass->object->swap_buffer();
-
if (material != nullptr)
- material->load(engine, pass->object, MATERIAL_EFFECT, pass, false);
+ {
+ material->load(engine, pass->object, MATERIAL_EFFECT, pass);
+ }
break;
case MATERIAL_ONLY_PASS:
- pass->target = pass->object->get_target_buffer();
- pass->object->swap_buffer();
- [[fallthrough]];
case MATERIAL_PASS:
pass->shader = shader;
break;
@@ -164,6 +154,7 @@ Pass::~Pass()
if (material != nullptr)
delete material;
+ // TODO: refcounted?
//for (auto &uniform : uniforms)
//{
// delete uniform;
@@ -173,11 +164,17 @@ Pass::~Pass()
RenderPass::RenderPass(Engine *engine, Pass *pass)
{
command = pass->command;
-
combine = pass->combine;
+ // This object contains information needed for
+ // getting previous framebuffer textures and targets.
+ object = pass->object;
+
if (command == COPY)
{
+ // Target and source is the only needed information
+ // for a COPY pass.
+
target = engine->get_framebuffer(pass->target);
source = engine->get_framebuffer(pass->source);
@@ -190,18 +187,25 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
for (int i = 0; i < MAX_TEXTURES; i++)
{
+ // If there is no texture at "i" use default shader from the texture.
if (pass->textures[i].empty() && !shader->textures[i].empty())
pass->textures[i] = shader->textures[i];
if (pass->textures[i].empty())
continue;
- auto asset = asset_manager()->get_file(pass->textures[i], TEXTURE);
+ // Check if texture is referencing a framebuffer.
+ textures[i] = engine->get_framebuffer_texture(pass->textures[i]);
- if (asset->type != ASSET_VOID)
- textures[i] = engine->get_texture(asset);
- else
- textures[i] = engine->get_framebuffer_texture(pass->textures[i]);
+ if (textures[i] == nullptr)
+ {
+ // The texture wasn't a framebuffer so try to load it from an asset.
+ auto asset = asset_manager()->get_file(pass->textures[i], TEXTURE);
+ if (asset->type != ASSET_VOID)
+ {
+ textures[i] = (Texture *)asset->lasset;
+ }
+ }
}
for (auto &shader_uniform : shader->uniforms)
@@ -213,6 +217,9 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
continue;
if (shader_uniform->name == uniform_override->name)
{
+ // Take value as reference because "uniform_override->value" points
+ // to the value stored in the parser. This allows changing that value
+ // to have instant effect.
shader_uniform->value = &uniform_override->value;
default_value = false;
break;
@@ -232,6 +239,14 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
auto index = uniform->uname[9] - '0';
if (textures[index] != nullptr)
uniform->value = &textures[index]->texture_res;
+ else
+ {
+ // If there is no texture at this index we assume this texture will
+ // be the previous framebuffer.
+ auto texture = engine->get_framebuffer_texture(object->get_texture_buffer());
+ if (texture != nullptr)
+ uniform->value = &texture->texture_res;
+ }
}
}
@@ -251,72 +266,74 @@ RenderPass::RenderPass(Engine *engine, Pass *pass)
shader->combos.push_back(pass_combo);
}
- /*
- for (auto &combo : shader->combos)
+ // If visualizer is not enabled disable audio logic
+ // on the shader.
+ if (!engine->audio_enabled)
{
- if (combo.name == "AUDIOPROCESSING")
- combo.value = 0;
+ for (auto &combo : shader->combos)
+ {
+ if (combo.name == "AUDIOPROCESSING")
+ combo.value = 0;
+ }
}
- */
+ // Compile shader only after all necessary combos are set.
shader->compile();
if (pass->effect == nullptr)
{
+ // The fullscreen shader doesn't use ModelViewProjectionMatrix,
if (pass->object->fullscreen)
+ {
model = &engine->default_model;
- else if (pass->object->passthrough || combine)
- model = &pass->object->model;
- else
- model = &pass->object->ortho;
-
- if (pass->object->fullscreen)
robject = engine->default_object;
+ }
+
+ // The passthrough shader uses ModelViewProjectionMatrix
+ // but, the texture is not scaled to a power of two.
else if (pass->object->passthrough)
- robject = pass->object->gl_object;
- else
- robject = pass->object->gl_uv_object;
- }
- else
- {
- if (combine && !pass->object->fullscreen)
{
+ model = &pass->object->model;
robject = pass->object->gl_object;
+ }
+
+ // If there is no effect and combine is set,
+ // we are forced to use a model which will
+ // correctly position the object.
+ else if (combine)
+ {
model = &pass->object->model;
+ robject = pass->object->gl_uv_object;
}
+
+ // The object with UV's that scale the texture
+ // also has the objects size on the verteices,
+ // so we need to use ortho for the model.
else
{
- robject = engine->default_object;
- model = &engine->default_model;
+ model = &pass->object->ortho;
+ robject = pass->object->gl_uv_object;
}
}
-
- /*
- // TODO fix this
- if (pass->effect == nullptr)
+ else
{
- if (pass->object->passthrough)
+ // When combine is set this is the final pass
+ // that needs to position the object on the screen.
+ // Except when fullscreen is set the object doesn't
+ // want to be positioned.
+ if (combine && !pass->object->fullscreen)
{
robject = pass->object->gl_object;
model = &pass->object->model;
}
- else if (pass->object->fullscreen)
+
+ // Default everything.
+ else
{
robject = engine->default_object;
model = &engine->default_model;
}
- else
- {
- robject = pass->object->gl_uv_object;
- model = &pass->object->ortho;
- }
- }
- else
- {
- robject = engine->default_object;
- model = &engine->default_model;
}
- */
}
void RenderPass::draw(Engine *engine)
@@ -327,8 +344,10 @@ void RenderPass::draw(Engine *engine)
if (combine)
_target = engine->combine_buffer;
- else
+ else if (target != nullptr)
_target = target;
+ else
+ _target = engine->get_framebuffer(object->get_target_buffer());
_target->buffer->bind();
@@ -339,6 +358,18 @@ void RenderPass::draw(Engine *engine)
{
if (textures[i] != nullptr)
textures[i]->bind(i);
+ else
+ {
+ // Assume this index will be the previous framebuffer.
+ auto texture = engine->get_framebuffer_texture(object->get_texture_buffer());
+ if (texture != nullptr)
+ texture->bind(i);
+ }
+ }
+
+ if (target == nullptr)
+ {
+ object->swap_buffer();
}
if (combine)
@@ -356,9 +387,11 @@ void RenderPass::draw(Engine *engine)
robject->draw();
- //_target->buffer->blit(0, engine->context->width, engine->context->height);
- //engine->context->swap_buffers();
- //std::this_thread::sleep_for(std::chrono::seconds(2));
+#if FRAME_STEP
+ _target->buffer->blit(0, engine->context->width, engine->context->height);
+ engine->context->swap_buffers();
+ std::this_thread::sleep_for(std::chrono::seconds(2));
+#endif
break;
}
diff --git a/src/objects/pass.h b/src/objects/pass.h
index 0211596..3e722b8 100644
--- a/src/objects/pass.h
+++ b/src/objects/pass.h
@@ -50,7 +50,7 @@ class Pass
PassCommand command = DRAW;
- std::string target = "previous";
+ std::string target;
std::string source;
Object *object;
@@ -78,6 +78,7 @@ class RenderPass
RenderPass(Engine *engine, Pass *pass);
~RenderPass();
+
Shader *shader = nullptr;
void draw(Engine *engine);
@@ -85,7 +86,7 @@ class RenderPass
private:
PassCommand command;
- bool combine;
+ Object *object;
Framebuffer *target;
Framebuffer *source;
@@ -93,6 +94,8 @@ class RenderPass
mat4x4 *model;
RenderObject *robject;
+ bool combine;
+
std::array<Texture *, MAX_TEXTURES> textures = {0};
};
diff --git a/src/objects/scene.cc b/src/objects/scene.cc
index 8bb2d70..d3819dc 100644
--- a/src/objects/scene.cc
+++ b/src/objects/scene.cc
@@ -43,11 +43,6 @@ Scene::Scene(Parser &p, const std::string &path)
{
if (object["image"].is_null())
continue;
- if (object["name"] == "Compose")
- {
- //std::cout << "Skiped\n";
- //continue;
- }
objects.emplace_back(new Object(p, object));
}
}
diff --git a/src/shader.cc b/src/shader.cc
index 80b928f..a524a2c 100644
--- a/src/shader.cc
+++ b/src/shader.cc
@@ -180,12 +180,18 @@ Shader::Shader(Parser *p, const std::string &name)
if (vs_asset->type != ASSET_VOID)
build_shader_source(p, vs_asset->as_string(), vs_source, true);
else
+ {
log_error("failed to load shader file (%s)", name.c_str());
+ return;
+ }
if (fs_asset->type != ASSET_VOID)
build_shader_source(p, fs_asset->as_string(), fs_source, true);
else
+ {
log_error("failed to load shader file (%s)", name.c_str());
+ return;
+ }
}
void Shader::bind(Engine *engine, mat4x4 *model)
@@ -220,18 +226,21 @@ void Shader::bind(Engine *engine, mat4x4 *model)
rshader->set_uniform("g_ModelViewProjectionMatrix", TYPE_MAT4, glm::value_ptr(_model));
rshader->set_uniform("g_ModelViewProjectionMatrixInverse", TYPE_MAT4, glm::value_ptr(_inverse));
- g_mutex_lock(&engine->visualizer->mutex);
+ if (engine->audio_enabled)
+ {
+ g_mutex_lock(&engine->visualizer->mutex);
- glUniform1fv(rshader->uniform_loc("g_AudioSpectrum64Left"), 64, &engine->visualizer->bars_64_left[0]);
- glUniform1fv(rshader->uniform_loc("g_AudioSpectrum64Right"), 64, &engine->visualizer->bars_64_right[0]);
+ glUniform1fv(rshader->uniform_loc("g_AudioSpectrum64Left"), 64, &engine->visualizer->bars_64_left[0]);
+ glUniform1fv(rshader->uniform_loc("g_AudioSpectrum64Right"), 64, &engine->visualizer->bars_64_right[0]);
- glUniform1fv(rshader->uniform_loc("g_AudioSpectrum32Left"), 32, &engine->visualizer->bars_32_left[0]);
- glUniform1fv(rshader->uniform_loc("g_AudioSpectrum32Right"), 32, &engine->visualizer->bars_32_right[0]);
+ glUniform1fv(rshader->uniform_loc("g_AudioSpectrum32Left"), 32, &engine->visualizer->bars_32_left[0]);
+ glUniform1fv(rshader->uniform_loc("g_AudioSpectrum32Right"), 32, &engine->visualizer->bars_32_right[0]);
- glUniform1fv(rshader->uniform_loc("g_AudioSpectrum16Left"), 16, &engine->visualizer->bars_16_left[0]);
- glUniform1fv(rshader->uniform_loc("g_AudioSpectrum16Right"), 16, &engine->visualizer->bars_16_right[0]);
+ glUniform1fv(rshader->uniform_loc("g_AudioSpectrum16Left"), 16, &engine->visualizer->bars_16_left[0]);
+ glUniform1fv(rshader->uniform_loc("g_AudioSpectrum16Right"), 16, &engine->visualizer->bars_16_right[0]);
- g_mutex_unlock(&engine->visualizer->mutex);
+ g_mutex_unlock(&engine->visualizer->mutex);
+ }
}
Shader::~Shader()
diff --git a/src/util.h b/src/util.h
index 1cd3903..8eb26ed 100644
--- a/src/util.h
+++ b/src/util.h
@@ -6,6 +6,8 @@
using namespace nlohmann;
+#define FRAME_STEP 0
+
typedef uint32_t u32;
typedef int32_t s32;
diff --git a/src/visualizer.cc b/src/visualizer.cc
index adfe851..349478b 100644
--- a/src/visualizer.cc
+++ b/src/visualizer.cc
@@ -1,3 +1,4 @@
+#include <X11/X.h>
#include <cmath>
#include <fftw3.h>
#include <numeric>
@@ -8,8 +9,10 @@
#include "fmt/format.h"
#include "gst/gstcaps.h"
#include "gst/gstelement.h"
+#include "gst/gstmemory.h"
#include "gst/gstsample.h"
#include "gst/gststructure.h"
+#include "gst/gstutils.h"
#include "log.h"
#include "objects/material.h"
#include "visualizer.h"
@@ -22,14 +25,14 @@ void Visualizer::calc_cutoff()
{
f64 freqconst = std::log10(low_freq_cap / (f64)high_freq_cap) / ((1.0 / (BAR_COUNT + 1.0)) - 1.0);
- for (s32 i = 0; i < BAR_COUNT; ++i)
+ for (s32 i = 0; i <= BAR_COUNT; ++i)
{
freqconst_per_bin[i] = high_freq_cap * std::pow(10.0, (freqconst * -1) +
(((i + 1.0) / (BAR_COUNT + 1.0)) * freqconst));
f64 freq = freqconst_per_bin[i] / (sample_rate / 2.0);
- low_cutoff[i] = std::floor(freq * (sample_count / 4));
+ low_cutoff[i] = std::floor(freq * (sample_count / 4.0));
if (i <= 0) continue;
@@ -55,8 +58,7 @@ void Visualizer::monstercat_smoothing(bool right)
{
f32 *bars = (right) ? (f32 *)bars_64_right_falloff : (f32 *)bars_64_left_falloff;
- std::vector<f32> smoothing_factors;
- smoothing_factors.reserve(BAR_COUNT);
+ std::array<f32, BAR_COUNT> smoothing_factors;
for (int i = 0; i < BAR_COUNT; ++i)
{
@@ -72,7 +74,9 @@ void Visualizer::monstercat_smoothing(bool right)
const auto weighted_value = bars[i] / smoothing_factors[(int)(std::abs(i - j))];
if (bars[j] < weighted_value)
+ {
bars[j] = weighted_value;
+ }
}
}
}
@@ -125,13 +129,13 @@ void Visualizer::update_bars(bool right)
*bar = std::pow(*bar, 0.5);
auto falloff_value = std::min(
- bars_falloff[i] * 0.90,
+ bars_falloff[i] * 0.85,
bars_falloff[i] - 1.0);
bars_falloff[i] = std::max((f32)falloff_value, *bar);
}
- monstercat_smoothing(right);
+ //monstercat_smoothing(right);
for (s32 i = 0; i < BAR_COUNT; i++)
{
@@ -171,9 +175,10 @@ void Visualizer::update_sample()
GstBuffer *buffer = gst_sample_get_buffer(sample);
- GstMemory *mem = gst_buffer_get_memory(buffer, 0);
+ GstMapInfo info;
+ gst_buffer_map(buffer, &info, GST_MAP_READ);
- Sample *samples = (Sample *)(mem + mem->offset);
+ Sample *samples = (Sample *)(info.data);
g_mutex_lock(&mutex);
@@ -199,22 +204,12 @@ void Visualizer::update()
g_mutex_unlock(&mutex);
}
-static void *update_thread(void *data)
-{
- Visualizer *v = (Visualizer *)data;
-
- while (true)
- {
- v->update();
- g_usleep(20000);
- }
-}
-
static GstFlowReturn new_sample_callback(GstElement *appsink, gpointer *udata)
{
Visualizer *v = (Visualizer *)udata;
v->update_sample();
+ v->update();
return GST_FLOW_OK;
}
@@ -256,6 +251,7 @@ Visualizer::Visualizer()
}
g_object_set(appsink, "emit-signals", TRUE, NULL);
+
g_object_set(pulsesrc, "device", "0", NULL);
gst_bin_add_many(GST_BIN(pipeline), pulsesrc, appsink, NULL);
@@ -272,8 +268,8 @@ Visualizer::Visualizer()
GstBuffer *buffer = gst_sample_get_buffer(sample);
GstCaps *caps = gst_sample_get_caps(sample);
-
GstStructure *structure = gst_caps_get_structure(caps, 0);
+
gst_structure_get_int(structure, "rate", &sample_rate);
gst_caps_unref(caps);
@@ -286,8 +282,8 @@ Visualizer::Visualizer()
out_left = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * sample_count);
out_right = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * sample_count);
- memset(bars_64_left_falloff, 0, sizeof(f32) * BAR_COUNT);
- memset(bars_64_right_falloff, 0, sizeof(f32) * BAR_COUNT);
+ memset(out_left, 0, sizeof(fftw_complex) * sample_count);
+ memset(out_right, 0, sizeof(fftw_complex) * sample_count);
calc_cutoff();
@@ -296,8 +292,23 @@ Visualizer::Visualizer()
g_signal_connect(appsink, "new-sample", G_CALLBACK(new_sample_callback), this);
- g_thread_new(NULL, update_thread, this);
- g_thread_new(NULL, main_thread, this);
+ thread = g_thread_new(NULL, main_thread, this);
}
+Visualizer::~Visualizer()
+{
+ fftw_free(in_left);
+ fftw_free(in_right);
+
+ fftw_free(out_left);
+ fftw_free(out_right);
+
+ gst_bus_post(bus, gst_message_new_eos(GST_OBJECT(pipeline)));
+
+ g_thread_join(thread);
+ gst_element_set_state(pipeline, GST_STATE_NULL);
+ gst_object_unref(pipeline);
+
+ g_mutex_clear(&mutex);
+}
diff --git a/src/visualizer.h b/src/visualizer.h
index 5155391..2094d8a 100644
--- a/src/visualizer.h
+++ b/src/visualizer.h
@@ -33,13 +33,14 @@ public:
f32 bars_64_left[BAR_COUNT];
f32 bars_64_right[BAR_COUNT];
- f32 bars_64_left_falloff[BAR_COUNT];
- f32 bars_64_right_falloff[BAR_COUNT];
+ f32 bars_64_left_falloff[BAR_COUNT] = {0};
+ f32 bars_64_right_falloff[BAR_COUNT] = {0};
GstElement *pipeline;
GstBus *bus;
GMutex mutex;
+ GThread *thread;
void update();
void update_sample();
@@ -47,8 +48,6 @@ public:
private:
GstElement *appsink;
- Sample *data;
-
f64 *in_left;
f64 *in_right;
@@ -58,20 +57,20 @@ private:
fftw_plan p_left;
fftw_plan p_right;
- f32 low_cutoff[BAR_COUNT];
- f32 high_cutoff[BAR_COUNT];
+ f32 low_cutoff[BAR_COUNT + 1] = {0};
+ f32 high_cutoff[BAR_COUNT + 1] = {0};
- f32 freqconst_per_bin[BAR_COUNT];
+ f32 freqconst_per_bin[BAR_COUNT + 1] = {0};
- u32 high_freq_cap = 22050;
- u32 low_freq_cap = 30;
+ u32 high_freq_cap = 25000;
+ u32 low_freq_cap = 20;
u32 sample_count;
s32 sample_rate;
void calc_cutoff();
- void update_bars(bool right);
void gaussian_blur(bool right);
+ void update_bars(bool right);
void monstercat_smoothing(bool right);
};