#pragma once #include "renderer_api/renderer_api.h" #include "../libs/glm/glm/glm.hpp" #include #include #include #include uint16_t constexpr shader_const_hash(const char* input) { return *input ? static_cast(*input) + 33 * shader_const_hash(input + 1) : 5381; } bool check_uniform_uniqueness(); enum class kShaderUniform : uint16_t { MVP = shader_const_hash("mvp"), Tex = shader_const_hash("tex"), TexFG = shader_const_hash("tex_fg"), TexBG = shader_const_hash("tex_bg"), TexMix = shader_const_hash("tex_mix"), TexMixA = shader_const_hash("tex_mix_alpha"), TexMask = shader_const_hash("tex_mask"), TexDual = shader_const_hash("tex_dual"), TexStroke = shader_const_hash("tex_stroke"), TexPattern = shader_const_hash("tex_pattern"), PatternOffset = shader_const_hash("pattern_offset"), PatternAlpha = shader_const_hash("pattern_alpha"), MixAlpha = shader_const_hash("mix_alpha"), Opacity = shader_const_hash("opacity"), Wet = shader_const_hash("wet"), Lock = shader_const_hash("lock"), Col = shader_const_hash("col"), Tof = shader_const_hash("tof"), Tsz = shader_const_hash("tsz"), Alpha = shader_const_hash("alpha"), Mask = shader_const_hash("mask"), Resolution = shader_const_hash("resolution"), Highlight = shader_const_hash("highlight"), BlendMode = shader_const_hash("blend_mode"), DualBlendMode = shader_const_hash("dual_blend_mode"), Noise = shader_const_hash("noise"), Direction = shader_const_hash("dir"), UseDual = shader_const_hash("use_dual"), UsePattern = shader_const_hash("use_pattern"), LightDir = shader_const_hash("light_dir"), Mode = shader_const_hash("mode"), Ambient = shader_const_hash("ambient"), PatternInvert = shader_const_hash("pattern_invert"), PatternScale = shader_const_hash("pattern_scale"), PatternBright = shader_const_hash("pattern_bright"), PatternContrast = shader_const_hash("pattern_contr"), PatternDepth = shader_const_hash("pattern_depth"), PatternBlendMode = shader_const_hash("patt_blend_mode"), Colorize = shader_const_hash("colorize"), DualAlpha = shader_const_hash("dual_alpha"), UseFragcoord = shader_const_hash("use_fragcoord"), DrawOutline = shader_const_hash("draw_outline"), }; enum class kShader : uint16_t { Color = shader_const_hash("color"), ColorQuad = shader_const_hash("color-quad"), ColorTri = shader_const_hash("color-tri"), ColorHue = shader_const_hash("color-hue"), Texture = shader_const_hash("texture"), TextureMask = shader_const_hash("texture-mask"), TextureColorize = shader_const_hash("texture-colorize"), TextureAlpha= shader_const_hash("texture-alpha"), TextureBlend= shader_const_hash("texture-blend"), CompErase = shader_const_hash("comp-erase"), CompDraw = shader_const_hash("comp-draw"), UVs = shader_const_hash("uvs"), UVs_2 = shader_const_hash("uvs2"), Font = shader_const_hash("font"), Atlas = shader_const_hash("atlas"), Stroke = shader_const_hash("stroke"), StrokePad = shader_const_hash("stroke-pad"), StrokeDilate= shader_const_hash("stroke-dilate"), StrokePreview = shader_const_hash("stroke-preview"), Checkerboard= shader_const_hash("checkerboard"), Equirect = shader_const_hash("equirect"), BrushStroke = shader_const_hash("brush-stroke"), VertexColor = shader_const_hash("vertex-color"), Lambert = shader_const_hash("lambert"), LambertLightmap = shader_const_hash("lambert-lightmap"), BakeUV = shader_const_hash("bakeuv"), }; class Shader { std::map m_deps; std::string m_path; std::map m_umap; unsigned int prog; std::string read(const std::string& path); public: kShader name; void parse_error(const std::string& msg, const std::string& code); bool load(const std::string& path); bool reload(); bool create(const std::string& vertex, const std::string& fragment); void destroy(); void use(); void u_vec4(kShaderUniform id, const glm::vec4& v); void u_vec3(kShaderUniform id, const glm::vec3& v); void u_vec2(kShaderUniform id, const glm::vec2& v); void u_mat4(kShaderUniform id, const glm::mat4& m); void u_int(kShaderUniform id, int i); void u_int(const char* uniform_name, int i); void u_float(kShaderUniform id, float f); int GetAttribLocation(const char* attribute_name); }; class ShaderManager { static std::map m_shaders; static Shader* m_current; static pp::renderer::RenderDeviceFeatures m_render_device_features; public: static bool ext_framebuffer_fetch; static bool ext_float32; static bool ext_float32_linear; static bool ext_float16; static bool ext_map_aligned; static bool load(kShader id, const std::string& path); static bool reload(); static bool create(kShader id, const std::string& vertex, const std::string& fragment); static void use(kShader id); static void use(const char* name); static Shader* get(kShader id); static void u_vec4(kShaderUniform id, const glm::vec4& v); static void u_vec3(kShaderUniform id, const glm::vec3& v); static void u_vec2(kShaderUniform id, const glm::vec2& v); static void u_mat4(kShaderUniform id, const glm::mat4& m); static void u_int(kShaderUniform id, int i); static void u_int(const char* name, int i); static void u_float(kShaderUniform id, float f); static void set_render_device_features(pp::renderer::RenderDeviceFeatures features) noexcept; static pp::renderer::RenderDeviceFeatures render_device_features() noexcept; static void invalidate(); };