Shaders now are managed by a manger that can do hot reloading and it also will detect a bad shader and use an ERROR shader so you know it's busted visually.
parent
a5b8e411e3
commit
35ced58cc9
@ -0,0 +1,18 @@ |
|||||||
|
uniform vec2 u_resolution; |
||||||
|
uniform vec2 u_mouse; |
||||||
|
uniform float u_duration; |
||||||
|
uniform float u_time; |
||||||
|
uniform float u_time_end; |
||||||
|
uniform sampler2D texture; |
||||||
|
uniform bool is_shape; |
||||||
|
|
||||||
|
void main() { |
||||||
|
if(is_shape) { |
||||||
|
vec4 color = vec4(1.0, 0.0, 0.0, 1.0); |
||||||
|
gl_FragColor = gl_Color * color; |
||||||
|
} else { |
||||||
|
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy); |
||||||
|
vec4 color = vec4(1.0, 0.0, 0.0, 1.0); |
||||||
|
gl_FragColor = gl_Color * color * pixel; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
#include "shaders.hpp" |
||||||
|
#include <SFML/Graphics/Image.hpp> |
||||||
|
#include "dbc.hpp" |
||||||
|
#include <fmt/core.h> |
||||||
|
#include "config.hpp" |
||||||
|
#include "constants.hpp" |
||||||
|
#include <memory> |
||||||
|
|
||||||
|
namespace shaders { |
||||||
|
using std::shared_ptr, std::make_shared; |
||||||
|
|
||||||
|
static ShaderManager SMGR; |
||||||
|
static bool initialized = false; |
||||||
|
|
||||||
|
|
||||||
|
bool load_shader(std::string name, nlohmann::json& settings) { |
||||||
|
std::string file_name = settings["file_name"]; |
||||||
|
auto ptr = std::make_shared<sf::Shader>(); |
||||||
|
bool good = ptr->loadFromFile(file_name, sf::Shader::Type::Fragment); |
||||||
|
if(good) SMGR.shaders.try_emplace(name, name, file_name, ptr); |
||||||
|
return good; |
||||||
|
} |
||||||
|
|
||||||
|
void init() { |
||||||
|
if(!initialized) { |
||||||
|
initialized = true; |
||||||
|
Config config("assets/shaders.json"); |
||||||
|
bool good = load_shader("ERROR", config["ERROR"]); |
||||||
|
dbc::check(good, "Failed to load ERROR shader. Look in assets/shaders.json"); |
||||||
|
|
||||||
|
for(auto& [name, settings] : config.json().items()) { |
||||||
|
if(name == "ERROR") continue; |
||||||
|
|
||||||
|
dbc::check(!SMGR.shaders.contains(name), |
||||||
|
fmt::format("shader name '{}' duplicated in assets/shaders.json", name)); |
||||||
|
good = load_shader(name, settings); |
||||||
|
|
||||||
|
if(!good) { |
||||||
|
dbc::log(fmt::format("failed to load shader {}", name)); |
||||||
|
SMGR.shaders.insert_or_assign(name, SMGR.shaders.at("ERROR")); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
sf::Shader* get(std::string name) { |
||||||
|
dbc::check(initialized, "you forgot to shaders::init()"); |
||||||
|
dbc::check(SMGR.shaders.contains(name), |
||||||
|
fmt::format("shader name '{}' not in assets/shaders.json", name)); |
||||||
|
|
||||||
|
auto& rec = SMGR.shaders.at(name); |
||||||
|
return rec.ptr.get(); |
||||||
|
} |
||||||
|
|
||||||
|
void reload() { |
||||||
|
initialized = false; |
||||||
|
SMGR.shaders.clear(); |
||||||
|
init(); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,26 @@ |
|||||||
|
#pragma once |
||||||
|
#include <cstdint> |
||||||
|
#include <vector> |
||||||
|
#include <string> |
||||||
|
#include <SFML/Graphics.hpp> |
||||||
|
#include <unordered_map> |
||||||
|
#include <memory> |
||||||
|
#include "matrix.hpp" |
||||||
|
#include <nlohmann/json.hpp> |
||||||
|
|
||||||
|
namespace shaders { |
||||||
|
struct Record { |
||||||
|
std::string name; |
||||||
|
std::string file_name; |
||||||
|
std::shared_ptr<sf::Shader> ptr = nullptr; |
||||||
|
}; |
||||||
|
|
||||||
|
struct ShaderManager { |
||||||
|
std::unordered_map<std::string, Record> shaders; |
||||||
|
}; |
||||||
|
|
||||||
|
void init(); |
||||||
|
bool load_shader(std::string& name, nlohmann::json& settings); |
||||||
|
sf::Shader* get(std::string name); |
||||||
|
void reload(); |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
#include <catch2/catch_test_macros.hpp> |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <string> |
||||||
|
#include "shaders.hpp" |
||||||
|
|
||||||
|
using namespace fmt; |
||||||
|
|
||||||
|
TEST_CASE("shader loading/init works", "[shaders]") { |
||||||
|
shaders::init(); |
||||||
|
|
||||||
|
sf::Shader* ui_shader = shaders::get("ui_shader"); |
||||||
|
auto other_test = shaders::get("ui_shader"); |
||||||
|
|
||||||
|
REQUIRE(ui_shader != nullptr); |
||||||
|
REQUIRE(ui_shader == other_test); |
||||||
|
|
||||||
|
shaders::reload(); |
||||||
|
|
||||||
|
// auto after_reload = shaders::get("ui_shader");
|
||||||
|
// REQUIRE(ui_shader != after_reload);
|
||||||
|
// REQUIRE(other_test != after_reload);
|
||||||
|
} |
Loading…
Reference in new issue