diff --git a/BaseGLProject/Loader.h b/BaseGLProject/Loader.h index 3bb789f..de5e02a 100644 --- a/BaseGLProject/Loader.h +++ b/BaseGLProject/Loader.h @@ -390,6 +390,21 @@ public: return uniformMap[uniformName]; } + std::map _subroutine_map; + + int addSubroutine(GLenum shadertype, const std::string uniformName) + { + _subroutine_map[uniformName] = glGetSubroutineIndex(programId, shadertype, uniformName.c_str()); + return _subroutine_map[uniformName]; + } + + void enableSubroutine(const std::string uniformName) + { + use(); + glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &_subroutine_map[uniformName]); + disable(); + } + }; // End of class #endif // SHADER_PROGRAM_HPP \ No newline at end of file diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp index f484958..9a32c2b 100644 --- a/BaseGLProject/MyGLWindow.cpp +++ b/BaseGLProject/MyGLWindow.cpp @@ -139,6 +139,13 @@ void MyGlWindow::multipassSetup() _multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex"); _multipassManager.setDrawBuffers(); + + _multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "depthing"); + _multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "blurring"); + _multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "sharpening"); + _multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "sepia"); + _multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "grayscale"); + _multipassManager.shader.addSubroutine(GL_FRAGMENT_SHADER, "sobel_filter"); } void MyGlWindow::setup() @@ -235,7 +242,7 @@ void MyGlWindow::draw() for (auto it = meshes.begin(); it != meshes.end(); it++) (*it).second->draw(_scnctx); - _multipassManager.shader.addUniform("sobel", true); + _multipassManager.shader.enableSubroutine("sobel_filter"); _multipassManager.drawResultToScreen(_scnctx); //skybox.draw(shaders["Skybox"], _scnctx); } diff --git a/BaseGLProject/Shader.cpp b/BaseGLProject/Shader.cpp index 8f5d587..1b127b6 100644 --- a/BaseGLProject/Shader.cpp +++ b/BaseGLProject/Shader.cpp @@ -19,6 +19,16 @@ void Shader::disable() _program.disable(); } +int Shader::addSubroutine(GLenum shadertype, const std::string uniformName) +{ + return _program.addSubroutine(shadertype, uniformName); +} + +void Shader::enableSubroutine(const std::string uniformName) +{ + return _program.enableSubroutine(uniformName); +} + void Shader::setMaterial(SceneContext ctx) { if ((uniformFlags & ShaderFlags::KA_FLAG) == ShaderFlags::KA_FLAG) diff --git a/BaseGLProject/Shader.h b/BaseGLProject/Shader.h index c60c641..e6c455a 100644 --- a/BaseGLProject/Shader.h +++ b/BaseGLProject/Shader.h @@ -40,6 +40,9 @@ public: void enable(); void disable(); + int addSubroutine(GLenum shadertype, const std::string uniformName); + void enableSubroutine(const std::string uniformName); + public: void setUniforms(SceneContext ctx); @@ -78,7 +81,6 @@ private: void setMaterial(SceneContext ctx); void setCamera(SceneContext ctx); void setLights(SceneContext ctx); - -private: + ShaderProgram _program; }; \ No newline at end of file diff --git a/BaseGLProject/textureViewer.frag b/BaseGLProject/textureViewer.frag index 2f7aa68..3f178b9 100644 --- a/BaseGLProject/textureViewer.frag +++ b/BaseGLProject/textureViewer.frag @@ -5,12 +5,10 @@ in vec2 uv; out vec4 final_color; uniform sampler2D tex; -uniform bool depth; -uniform bool blur; -uniform bool sharpen; -uniform bool sepia; -uniform bool grayscale; -uniform bool sobel; + + +subroutine vec4 shading_t(vec4 color); +subroutine uniform shading_t Shading; const float f = 1.0 / 300.0; @@ -20,45 +18,65 @@ vec2 offsets[9] = vec2[]( vec2(-f, -f), vec2(0.0, -f), vec2(f, -f) ); -float blur_kernel[9] = float[]( - 1.0 / 16, 2.0 / 16, 1.0 / 16, - 2.0 / 16, 4.0 / 16, 2.0 / 16, - 1.0 / 16, 2.0 / 16, 1.0 / 16 -); +subroutine(shading_t) +vec4 sepia(vec4 color) +{ + return vec4(color.r * .393 + color.g * .769 + color.b * .189, + color.r * .349 + color.g * .686 + color.b * .168, + color.r * .272 + color.g * .534 + color.b * .131, 1.0); +} -float sharp_kernel[9] = float[]( - -1, -1, -1, - -1, 9, -1, - -1, -1, -1 -); +subroutine(shading_t) +vec4 grayscale(vec4 color) +{ + float average = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722; + return vec4(average, average, average, 1); +} -float LinearizeDepth(in vec2 uv) +subroutine(shading_t) +vec4 depthing(vec4 color) { float zNear = 0.1f; // zNear of your perspective projection float zFar = 2000.0f; // zFar of your perspective projection - float depth = texture(tex, uv).x; - return (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear)); + float depth = color.x; + float r = (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear)); + return vec4(r, r, r, 1); } -vec3 blurring_func(in vec2 uv) +subroutine(shading_t) +vec4 blurring(vec4 color) { + float blur_kernel[9] = float[]( + 1.0 / 16, 2.0 / 16, 1.0 / 16, + 2.0 / 16, 4.0 / 16, 2.0 / 16, + 1.0 / 16, 2.0 / 16, 1.0 / 16 + ); + vec3 texblur = vec3(0,0,0); for (int i = 0; i < 9; i++) texblur += vec3(texture(tex, uv + offsets[i]).rgb * blur_kernel[i]); - return texblur; + return vec4(texblur, 1); } -vec4 sharpening_func(in vec2 uv) +subroutine(shading_t) +vec4 sharpening(vec4 color) { - vec4 texsharp = vec4(0,0,0,0); + float sharp_kernel[9] = float[]( + -1, -1, -1, + -1, 9, -1, + -1, -1, -1 + ); + + vec3 texsharp = vec3(0,0,0); for (uint i = 0; i < 9; i++) - texsharp += texture(tex, uv + offsets[i]).rgba * sharp_kernel[i]; + texsharp += texture(tex, uv + offsets[i]).rgb * sharp_kernel[i]; - return texsharp; + return vec4(texsharp, 1); } -vec3 sobel_filter(vec3 color) +subroutine(shading_t) +vec4 sobel_filter(vec4 color) { float sobel_x[9] = float[]( -1, 0, 1, @@ -81,42 +99,45 @@ vec3 sobel_filter(vec3 color) vec_y += texture(tex, uv + offsets[i]).rgb * sobel_y[i]; } - return sqrt(vec_x * vec_x + vec_y * vec_y); + vec4 sobeled = vec4(sqrt(vec_x * vec_x + vec_y * vec_y), 1); + return grayscale(sobeled); } void main() { //rrra because depth textures are not usual textures, they have only one channel - final_color = (depth) ? texture(tex, uv).rrra : texture(tex, uv).rgba; - - if (depth) { - float d; - d = LinearizeDepth(uv); - final_color = vec4(d,d,d,1.0); - } - else if (blur) - { - final_color = vec4(blurring_func(uv), 1); - } - else if (sharpen) - { - final_color = vec4(sharpening_func(uv)); - } - else if (sepia) - { - final_color = vec4(final_color.r * .393 + final_color.g * .769 + final_color.b * .189, - final_color.r * .349 + final_color.g * .686 + final_color.b * .168, - final_color.r * .272 + final_color.g * .534 + final_color.b * .131, 1.0); - } - else if (grayscale) - { - float average = final_color.r * 0.2126 + final_color.g * 0.7152 + final_color.b * 0.0722; - final_color = vec4(average, average, average, 1.0); - } - else if (sobel) - { - vec3 sobeled = sobel_filter(final_color.rgb); - float average = sobeled.r * 0.2126 + sobeled.g * 0.7152 + sobeled.b * 0.0722; - final_color = vec4(average, average, average, 1.0); - } + final_color = texture(tex, uv).rgba; + + final_color = Shading(final_color); + +// if (depth) { +// float d; +// d = LinearizeDepth(uv); +// final_color = vec4(d,d,d,1.0); +// } +// else if (blur) +// { +// final_color = vec4(blurring_func(uv), 1); +// } +// else if (sharpen) +// { +// final_color = vec4(sharpening_func(uv)); +// } +// else if (sepia) +// { +// final_color = vec4(final_color.r * .393 + final_color.g * .769 + final_color.b * .189, +// final_color.r * .349 + final_color.g * .686 + final_color.b * .168, +// final_color.r * .272 + final_color.g * .534 + final_color.b * .131, 1.0); +// } +// else if (grayscale) +// { +// float average = final_color.r * 0.2126 + final_color.g * 0.7152 + final_color.b * 0.0722; +// final_color = vec4(average, average, average, 1.0); +// } +// else if (sobel) +// { +// vec3 sobeled = sobel_filter(final_color.rgb); +// float average = sobeled.r * 0.2126 + sobeled.g * 0.7152 + sobeled.b * 0.0722; +// final_color = vec4(average, average, average, 1.0); +// } } \ No newline at end of file