From f728e4c8d202de241673a13ce61570b6acb4bba7 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Fri, 25 May 2018 23:47:27 +0200 Subject: Restructure source directory --- src/shader/code/compute.glsl | 62 +++++++++++++++++++++++++++++++++++ src/shader/code/display_fragment.glsl | 15 +++++++++ src/shader/code/display_vertex.glsl | 12 +++++++ src/shader/code/fragment.glsl | 5 +++ src/shader/code/vertex.glsl | 8 +++++ src/shader/compute.glsl | 62 ----------------------------------- src/shader/display_fragment.glsl | 15 --------- src/shader/display_vertex.glsl | 12 ------- src/shader/fragment.glsl | 5 --- src/shader/util.h | 46 ++++++++++++++++++++++++++ src/shader/vertex.glsl | 8 ----- src/shader/wrap/compute_shader.h | 47 ++++++++++++++++++++++++++ src/shader/wrap/graphic_shader.h | 52 +++++++++++++++++++++++++++++ 13 files changed, 247 insertions(+), 102 deletions(-) create mode 100644 src/shader/code/compute.glsl create mode 100644 src/shader/code/display_fragment.glsl create mode 100644 src/shader/code/display_vertex.glsl create mode 100644 src/shader/code/fragment.glsl create mode 100644 src/shader/code/vertex.glsl delete mode 100644 src/shader/compute.glsl delete mode 100644 src/shader/display_fragment.glsl delete mode 100644 src/shader/display_vertex.glsl delete mode 100644 src/shader/fragment.glsl create mode 100644 src/shader/util.h delete mode 100644 src/shader/vertex.glsl create mode 100644 src/shader/wrap/compute_shader.h create mode 100644 src/shader/wrap/graphic_shader.h (limited to 'src/shader') diff --git a/src/shader/code/compute.glsl b/src/shader/code/compute.glsl new file mode 100644 index 0000000..eaf5579 --- /dev/null +++ b/src/shader/code/compute.glsl @@ -0,0 +1,62 @@ +static const std::string COMPUTE_SHADER_CODE = R"( +#version 430 + +layout (local_size_x = 1) in; +layout (std430, binding=1) buffer bufferA{ float data[]; }; + +uniform vec2 world; + +// ODE solver + +vec2 f(vec2); // field definition is to be appended + +vec2 explicitEuler(float h, vec2 v) { + return v + h * f(v); +} + +vec2 classicalRungeKutta(float h, vec2 v) { + const vec2 k1 = f(v); + const vec2 k2 = f(v + h/2. * k1); + const vec2 k3 = f(v + h/2. * k2); + const vec2 k4 = f(v + h * k3); + + return v + h * (1./6.*k1 + 1./3.*k2 + 1./3.*k3 + 1./6.*k4); +} + +// pseudo random numbers for particle placement + +float rand(vec2 v){ + return fract(sin(dot(v, vec2(12.9898,78.233))) * 43758.5453); +} + +float mapUnitToWorldX(float s) { + return -(world.x/2.) + s * world.x; +} + +float mapUnitToWorldY(float s) { + return -(world.y/2.) + s * world.y; +} + +bool insideWorld(vec2 v) { + return v.x > -world.x/2. + && v.x < world.x/2. + && v.y > -world.y/2. + && v.y < world.y/2.; +} + +void main() { + const uint i = 3*gl_GlobalInvocationID.x; + const vec2 v = vec2(data[i+0], data[i+1]); + const vec2 w = classicalRungeKutta(0.01, v); + + if ( data[i+2] < 5. && insideWorld(v) ) { + data[i+0] = w.x; + data[i+1] = w.y; + data[i+2] += 0.01; + } else { + data[i+0] = mapUnitToWorldX(rand(v)); + data[i+1] = mapUnitToWorldY(rand(w)); + data[i+2] = rand(v+w) * 5.; + } +} +)"; diff --git a/src/shader/code/display_fragment.glsl b/src/shader/code/display_fragment.glsl new file mode 100644 index 0000000..b731ebe --- /dev/null +++ b/src/shader/code/display_fragment.glsl @@ -0,0 +1,15 @@ +static const std::string DISPLAY_FRAGMENT_SHADER_CODE = R"( +#version 460 + +out vec4 FragColor; +in vec2 TexCoords; + +uniform sampler2D screen_textures[64]; +uniform int screen_textures_size; + +void main() { + for ( int i = 0; i < screen_textures_size; ++i ) { + FragColor += (1.0 - i*1.0/screen_textures_size) * texture(screen_textures[i], TexCoords); + } +} +)"; diff --git a/src/shader/code/display_vertex.glsl b/src/shader/code/display_vertex.glsl new file mode 100644 index 0000000..60bbfc7 --- /dev/null +++ b/src/shader/code/display_vertex.glsl @@ -0,0 +1,12 @@ +static const std::string DISPLAY_VERTEX_SHADER_CODE = R"( +#version 330 core + +layout (location = 0) in vec2 screen_vertex; +layout (location = 1) in vec2 texture_vertex; +out vec2 TexCoords; + +void main() { + gl_Position = vec4(screen_vertex, 0.0, 1.0); + TexCoords = texture_vertex; +} +)"; diff --git a/src/shader/code/fragment.glsl b/src/shader/code/fragment.glsl new file mode 100644 index 0000000..37e18bd --- /dev/null +++ b/src/shader/code/fragment.glsl @@ -0,0 +1,5 @@ +static const std::string FRAGMENT_SHADER_CODE = R"( +void main() { + gl_FragColor = gl_Color; +} +)"; diff --git a/src/shader/code/vertex.glsl b/src/shader/code/vertex.glsl new file mode 100644 index 0000000..4c307d8 --- /dev/null +++ b/src/shader/code/vertex.glsl @@ -0,0 +1,8 @@ +static const std::string VERTEX_SHADER_CODE = R"( +uniform mat4 MVP; + +void main() { + gl_Position = MVP * vec4(gl_Vertex.xy, 0.0, 1.0); + gl_FrontColor = vec4(1., 0., 0., 0.); +} +)"; diff --git a/src/shader/compute.glsl b/src/shader/compute.glsl deleted file mode 100644 index eaf5579..0000000 --- a/src/shader/compute.glsl +++ /dev/null @@ -1,62 +0,0 @@ -static const std::string COMPUTE_SHADER_CODE = R"( -#version 430 - -layout (local_size_x = 1) in; -layout (std430, binding=1) buffer bufferA{ float data[]; }; - -uniform vec2 world; - -// ODE solver - -vec2 f(vec2); // field definition is to be appended - -vec2 explicitEuler(float h, vec2 v) { - return v + h * f(v); -} - -vec2 classicalRungeKutta(float h, vec2 v) { - const vec2 k1 = f(v); - const vec2 k2 = f(v + h/2. * k1); - const vec2 k3 = f(v + h/2. * k2); - const vec2 k4 = f(v + h * k3); - - return v + h * (1./6.*k1 + 1./3.*k2 + 1./3.*k3 + 1./6.*k4); -} - -// pseudo random numbers for particle placement - -float rand(vec2 v){ - return fract(sin(dot(v, vec2(12.9898,78.233))) * 43758.5453); -} - -float mapUnitToWorldX(float s) { - return -(world.x/2.) + s * world.x; -} - -float mapUnitToWorldY(float s) { - return -(world.y/2.) + s * world.y; -} - -bool insideWorld(vec2 v) { - return v.x > -world.x/2. - && v.x < world.x/2. - && v.y > -world.y/2. - && v.y < world.y/2.; -} - -void main() { - const uint i = 3*gl_GlobalInvocationID.x; - const vec2 v = vec2(data[i+0], data[i+1]); - const vec2 w = classicalRungeKutta(0.01, v); - - if ( data[i+2] < 5. && insideWorld(v) ) { - data[i+0] = w.x; - data[i+1] = w.y; - data[i+2] += 0.01; - } else { - data[i+0] = mapUnitToWorldX(rand(v)); - data[i+1] = mapUnitToWorldY(rand(w)); - data[i+2] = rand(v+w) * 5.; - } -} -)"; diff --git a/src/shader/display_fragment.glsl b/src/shader/display_fragment.glsl deleted file mode 100644 index b731ebe..0000000 --- a/src/shader/display_fragment.glsl +++ /dev/null @@ -1,15 +0,0 @@ -static const std::string DISPLAY_FRAGMENT_SHADER_CODE = R"( -#version 460 - -out vec4 FragColor; -in vec2 TexCoords; - -uniform sampler2D screen_textures[64]; -uniform int screen_textures_size; - -void main() { - for ( int i = 0; i < screen_textures_size; ++i ) { - FragColor += (1.0 - i*1.0/screen_textures_size) * texture(screen_textures[i], TexCoords); - } -} -)"; diff --git a/src/shader/display_vertex.glsl b/src/shader/display_vertex.glsl deleted file mode 100644 index 60bbfc7..0000000 --- a/src/shader/display_vertex.glsl +++ /dev/null @@ -1,12 +0,0 @@ -static const std::string DISPLAY_VERTEX_SHADER_CODE = R"( -#version 330 core - -layout (location = 0) in vec2 screen_vertex; -layout (location = 1) in vec2 texture_vertex; -out vec2 TexCoords; - -void main() { - gl_Position = vec4(screen_vertex, 0.0, 1.0); - TexCoords = texture_vertex; -} -)"; diff --git a/src/shader/fragment.glsl b/src/shader/fragment.glsl deleted file mode 100644 index 37e18bd..0000000 --- a/src/shader/fragment.glsl +++ /dev/null @@ -1,5 +0,0 @@ -static const std::string FRAGMENT_SHADER_CODE = R"( -void main() { - gl_FragColor = gl_Color; -} -)"; diff --git a/src/shader/util.h b/src/shader/util.h new file mode 100644 index 0000000..7aec674 --- /dev/null +++ b/src/shader/util.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +namespace util { + +GLint getUniform(GLuint program, const std::string& name) { + const GLint uniform = glGetUniformLocation(program, name.c_str()); + if ( uniform == -1 ) { + std::cerr << "Could not bind uniform " << name << std::endl; + } + return uniform; +} + +GLint compileShader(const std::string& source, GLenum type) { + GLint shader = glCreateShader(type); + + if ( !shader ) { + std::cerr << "Cannot create a shader of type " << type << std::endl; + exit(-1); + } + + const char* source_data = source.c_str(); + const int source_length = source.size(); + + glShaderSource(shader, 1, &source_data, &source_length); + glCompileShader(shader); + + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if ( !compiled ) { + std::cerr << "Cannot compile shader" << std::endl; + GLint maxLength = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + std::vector errorLog(maxLength); + glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]); + for( auto c : errorLog ) { + std::cerr << c; + } + std::cerr << std::endl; + } + + return shader; +} + +} diff --git a/src/shader/vertex.glsl b/src/shader/vertex.glsl deleted file mode 100644 index 4c307d8..0000000 --- a/src/shader/vertex.glsl +++ /dev/null @@ -1,8 +0,0 @@ -static const std::string VERTEX_SHADER_CODE = R"( -uniform mat4 MVP; - -void main() { - gl_Position = MVP * vec4(gl_Vertex.xy, 0.0, 1.0); - gl_FrontColor = vec4(1., 0., 0., 0.); -} -)"; diff --git a/src/shader/wrap/compute_shader.h b/src/shader/wrap/compute_shader.h new file mode 100644 index 0000000..9f5c5cb --- /dev/null +++ b/src/shader/wrap/compute_shader.h @@ -0,0 +1,47 @@ +#pragma once + +#include "util.h" + +class ComputeShader { +private: + const GLuint _id; + +public: + struct Guard { + const GLuint _id; + + Guard(GLuint id): _id(id) { + glUseProgram(_id); + } + ~Guard() { + glUseProgram(0); + } + }; + + Guard use() const { + return Guard(_id); + } + + ComputeShader(const std::string& src): + _id(glCreateProgram()) { + glAttachShader(_id, util::compileShader(src, GL_COMPUTE_SHADER)); + glLinkProgram(_id); + }; + ~ComputeShader() { + glDeleteProgram(_id); + } + + GLuint setUniform(const std::string& name, float x, float y) const { + GLuint id = util::getUniform(_id, name); + glUniform2f(id, x, y); + return id; + } + + void workOn(GLuint buffer) const { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffer); + } + + void dispatch(std::size_t dimX) const { + glDispatchCompute(dimX, 1, 1); + } +}; diff --git a/src/shader/wrap/graphic_shader.h b/src/shader/wrap/graphic_shader.h new file mode 100644 index 0000000..03249d5 --- /dev/null +++ b/src/shader/wrap/graphic_shader.h @@ -0,0 +1,52 @@ +#pragma once + +#include "shader/util.h" + +class GraphicShader { +private: + const GLuint _id; + +public: + struct Guard { + const GLuint _id; + + Guard(GLuint id): _id(id) { + glUseProgram(_id); + } + ~Guard() { + glUseProgram(0); + } + }; + + Guard use() const { + return Guard(_id); + } + + GraphicShader(const std::string& vertex, const std::string fragment): + _id(glCreateProgram()) { + glAttachShader(_id, util::compileShader(vertex, GL_VERTEX_SHADER)); + glAttachShader(_id, util::compileShader(fragment, GL_FRAGMENT_SHADER)); + glLinkProgram(_id); + }; + ~GraphicShader() { + glDeleteProgram(_id); + } + + GLuint setUniform(const std::string& name, int value) const { + GLuint id = util::getUniform(_id, name); + glUniform1i(id, value); + return id; + } + + GLuint setUniform(const std::string& name, const std::vector& v) const { + GLuint id = util::getUniform(_id, name); + glUniform1iv(id, v.size(), reinterpret_cast(v.data())); + return id; + } + + GLuint setUniform(const std::string& name, glm::mat4& M) const { + GLuint id = util::getUniform(_id, name); + glUniformMatrix4fv(id, 1, GL_FALSE, &M[0][0]); + return id; + } +}; -- cgit v1.2.3