#pragma once #include #include #include #include #include #include "glm/gtc/type_ptr.hpp" #include "Light.h" #include "SceneContext.h" #include "Loader.h" #include "Texture.h" enum ShaderFlags { NO_UNIFORM = 0, KD_FLAG = 1, KA_FLAG = 2, KS_FLAG = 4, SHINE_FLAG = 8, MVP_FLAG = 16, NORMAL_MAT_FLAG = 32, MODELVIEW_FLAG = 64, LIGHTS_FLAG = 128, MODEL_MATRIX_FLAG = 256, SKYBOX_TEX_FLAG = 512, }; class Shader { public: Shader() {}; Shader(const std::string vtx_name, const std::string frag_name); ~Shader(); int uniformFlags = KD_FLAG | KA_FLAG | KS_FLAG | SHINE_FLAG | MVP_FLAG | NORMAL_MAT_FLAG | MODELVIEW_FLAG | LIGHTS_FLAG; Light::LightType light_type = Light::LightType::BASE; Material mat; void enable(); void disable(); int addSubroutine(GLenum shadertype, const std::string uniformName); void enableSubroutine(const std::string uniformName); public: void setUniforms(SceneContext ctx); void addUniform(const std::string name, glm::vec3 data) { _program.use(); glUniform3fv(_program.addUniform(name), 1, glm::value_ptr(data)); } void addUniform(const std::string name, int data) { _program.use(); glUniform1i(_program.addUniform(name), data); } void addUniform(const std::string name, float data) { _program.use(); glUniform1fv(_program.addUniform(name), 1, &data); } void addUniform(const std::string name, glm::mat4x4 &data) { _program.use(); glUniformMatrix4fv(_program.addUniform(name), 1, GL_FALSE, glm::value_ptr(data)); } void applyTextureMaterial(Texture &tex) { if (mat.enabled) { addUniform("Ka", tex.mat.ka); addUniform("Kd", tex.mat.kd); addUniform("Ks", tex.mat.ks); } } private: void setMaterial(SceneContext ctx); void setCamera(SceneContext ctx); void setLights(SceneContext ctx); ShaderProgram _program; };