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 --- CMakeLists.txt | 4 ++ src/buffer/frame/texture_framebuffer.h | 62 +++++++++++++++++++++++ src/buffer/vertex/particle_vertex_buffer.h | 44 ++++++++++++++++ src/buffer/vertex/texture_display_vertex_buffer.h | 57 +++++++++++++++++++++ src/compute_shader.h | 47 ----------------- src/glfw/guard.h | 20 ++++++++ src/glfw/window.h | 62 +++++++++++++++++++++++ src/glfw_guard.h | 20 -------- src/graphic_shader.h | 52 ------------------- src/main.cc | 53 +++++++++++-------- src/particle_vertex_buffer.h | 44 ---------------- 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 +++++++++++++++++++ src/texture_buffer.h | 56 -------------------- src/texture_display_buffer.h | 57 --------------------- src/util.h | 40 --------------- src/window.h | 62 ----------------------- 28 files changed, 528 insertions(+), 501 deletions(-) create mode 100644 src/buffer/frame/texture_framebuffer.h create mode 100644 src/buffer/vertex/particle_vertex_buffer.h create mode 100644 src/buffer/vertex/texture_display_vertex_buffer.h delete mode 100644 src/compute_shader.h create mode 100644 src/glfw/guard.h create mode 100644 src/glfw/window.h delete mode 100644 src/glfw_guard.h delete mode 100644 src/graphic_shader.h delete mode 100644 src/particle_vertex_buffer.h 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 delete mode 100644 src/texture_buffer.h delete mode 100644 src/texture_display_buffer.h delete mode 100644 src/window.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a89f50..6415420 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,10 @@ set( "${CMAKE_CXX_FLAGS} -std=c++17 -W -Wall -Wextra -Winline -pedantic" ) +include_directories( + src/ +) + add_executable( computicle src/main.cc diff --git a/src/buffer/frame/texture_framebuffer.h b/src/buffer/frame/texture_framebuffer.h new file mode 100644 index 0000000..31153ff --- /dev/null +++ b/src/buffer/frame/texture_framebuffer.h @@ -0,0 +1,62 @@ +#pragma once + +class TextureFramebuffer { +private: + GLuint _id; + GLuint _texture; + + bool _good = false; + +public: + struct Guard { + const GLuint _id; + + Guard(GLuint id): _id(id) { + glBindFramebuffer(GL_FRAMEBUFFER, _id); + } + ~Guard() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + }; + + Guard use() const { + return Guard(_id); + } + + TextureFramebuffer(std::size_t width, std::size_t height) { + glGenFramebuffers(1, &_id); + + auto guard = use(); + + glGenTextures(1, &_texture); + glBindTexture(GL_TEXTURE_2D, _texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0); + + if ( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE ) { + _good = true; + } + } + + ~TextureFramebuffer() { + glDeleteFramebuffers(1, &_id); + } + + bool isGood() const { + return _good; + } + + void resize(std::size_t width, std::size_t height) const { + auto guard = use(); + + glViewport(0, 0, width, height); + glBindTexture(GL_TEXTURE_2D, _texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)0); + } + + GLuint getTexture() const { + return _texture; + } +}; diff --git a/src/buffer/vertex/particle_vertex_buffer.h b/src/buffer/vertex/particle_vertex_buffer.h new file mode 100644 index 0000000..25855a2 --- /dev/null +++ b/src/buffer/vertex/particle_vertex_buffer.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +class ParticleVertexBuffer { +private: + std::vector _data; + + GLuint _array; + GLuint _buffer; + +public: + ParticleVertexBuffer(std::vector&& data): + _data{ std::move(data) } { + glGenVertexArrays(1, &_array); + glGenBuffers(1, &_buffer); + + glBindVertexArray(_array); + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + glBufferData( + GL_ARRAY_BUFFER, + _data.size() * sizeof(GLfloat), + _data.data(), + GL_STATIC_DRAW + ); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + } + + ~ParticleVertexBuffer() { + glDeleteBuffers(1, &_buffer); + glDeleteVertexArrays(1, &_array); + } + + void draw() const { + glBindVertexArray(_array); + glDrawArrays(GL_POINTS, 0, 3*_data.size()); + } + + GLuint getBuffer() const { + return _buffer; + } +}; diff --git a/src/buffer/vertex/texture_display_vertex_buffer.h b/src/buffer/vertex/texture_display_vertex_buffer.h new file mode 100644 index 0000000..6d4eec2 --- /dev/null +++ b/src/buffer/vertex/texture_display_vertex_buffer.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +class TextureDisplayVertexBuffer { +private: + const std::vector _data; + + GLuint _array; + GLuint _buffer; + +public: + TextureDisplayVertexBuffer(): + _data{ + -1.f, 1.f, 0.f, 1.f, + -1.f, -1.f, 0.f, 0.f, + 1.f, -1.f, 1.f, 0.f, + + -1.f, 1.f, 0.f, 1.f, + 1.f, -1.f, 1.f, 0.f, + 1.f, 1.f, 1.f, 1.f + } { + glGenVertexArrays(1, &_array); + glGenBuffers(1, &_buffer); + + glBindVertexArray(_array); + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + glBufferData( + GL_ARRAY_BUFFER, + _data.size() * sizeof(GLfloat), + _data.data(), + GL_STATIC_DRAW + ); + + glEnableVertexAttribArray(0); + glVertexAttribPointer( + 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer( + 1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)(2*sizeof(GLfloat))); + } + + ~TextureDisplayVertexBuffer() { + glDeleteBuffers(1, &_buffer); + glDeleteVertexArrays(1, &_array); + } + + void draw(const std::vector& textures) const { + glBindVertexArray(_array); + glBindTextures(textures[0], textures.size(), textures.data()); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + + GLuint getBuffer() const { + return _buffer; + } +}; diff --git a/src/compute_shader.h b/src/compute_shader.h deleted file mode 100644 index 9f5c5cb..0000000 --- a/src/compute_shader.h +++ /dev/null @@ -1,47 +0,0 @@ -#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/glfw/guard.h b/src/glfw/guard.h new file mode 100644 index 0000000..37d3ffb --- /dev/null +++ b/src/glfw/guard.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +class GlfwGuard { +private: + bool _good = false; +public: + GlfwGuard() { + _good = glfwInit(); + } + ~GlfwGuard() { + glfwTerminate(); + } + + bool isGood() const { + return _good; + } +}; diff --git a/src/glfw/window.h b/src/glfw/window.h new file mode 100644 index 0000000..794dd5f --- /dev/null +++ b/src/glfw/window.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +class Window { +private: + bool _good = false; + int _width = 800; + int _height = 600; + + GLFWwindow* const _handle; + +public: + Window(const std::string& title): + _handle(glfwCreateWindow(_width, _height, title.c_str(), NULL, NULL)) { + if ( _handle != nullptr ) { + glfwMakeContextCurrent(_handle); + if ( glewInit() == GLEW_OK ) { + _good = true; + } + glfwMakeContextCurrent(nullptr); + } + } + + bool isGood() const { + return _good; + } + + int getWidth() const { + return _width; + } + + int getHeight() const { + return _height; + } + + template + void init(F f) { + glfwMakeContextCurrent(_handle); + f(); + glfwMakeContextCurrent(nullptr); + } + + template + void render(F loop) { + glfwMakeContextCurrent(_handle); + + while ( glfwGetKey(_handle, GLFW_KEY_ESCAPE ) != GLFW_PRESS && + glfwWindowShouldClose(_handle) == 0 ) { + glfwGetWindowSize(_handle, &_width, &_height); + + loop(); + + glfwSwapBuffers(_handle); + glfwPollEvents(); + } + + glfwMakeContextCurrent(nullptr); + } + +}; diff --git a/src/glfw_guard.h b/src/glfw_guard.h deleted file mode 100644 index 37d3ffb..0000000 --- a/src/glfw_guard.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -class GlfwGuard { -private: - bool _good = false; -public: - GlfwGuard() { - _good = glfwInit(); - } - ~GlfwGuard() { - glfwTerminate(); - } - - bool isGood() const { - return _good; - } -}; diff --git a/src/graphic_shader.h b/src/graphic_shader.h deleted file mode 100644 index c67dc01..0000000 --- a/src/graphic_shader.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "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; - } -}; diff --git a/src/main.cc b/src/main.cc index b2262e6..9f32bc3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -5,22 +5,25 @@ #include #include -#include "glfw_guard.h" -#include "window.h" +#include "glfw/guard.h" +#include "glfw/window.h" -#include "particle_vertex_buffer.h" -#include "texture_display_buffer.h" +#include "buffer/frame/texture_framebuffer.h" -#include "graphic_shader.h" -#include "compute_shader.h" -#include "texture_buffer.h" +#include "buffer/vertex/particle_vertex_buffer.h" +#include "buffer/vertex/texture_display_vertex_buffer.h" -#include "shader/vertex.glsl" -#include "shader/fragment.glsl" -#include "shader/compute.glsl" +#include "shader/wrap/graphic_shader.h" +#include "shader/wrap/compute_shader.h" -#include "shader/display_vertex.glsl" -#include "shader/display_fragment.glsl" +#include "shader/code/vertex.glsl" +#include "shader/code/fragment.glsl" +#include "shader/code/compute.glsl" + +#include "shader/code/display_vertex.glsl" +#include "shader/code/display_fragment.glsl" + +#include "util.h" const unsigned int particle_count = 2500; const unsigned int max_ups = 100; @@ -95,10 +98,10 @@ int main() { glm::mat4 MVP = getMVP(world_width, world_height); - std::vector> texture_buffers; + std::vector> texture_framebuffers; std::unique_ptr particle_buffer; - std::unique_ptr display_buffer; + std::unique_ptr display_buffer; std::unique_ptr scene_shader; std::unique_ptr compute_shader; @@ -106,13 +109,13 @@ int main() { window.init([&]() { for ( unsigned int i = 0; i < texture_count; ++i ) { - texture_buffers.emplace_back( - new TextureBuffer(window_width, window_height)); + texture_framebuffers.emplace_back( + new TextureFramebuffer(window_width, window_height)); } particle_buffer = std::make_unique( makeInitialParticles(particle_count, world_width, world_height)); - display_buffer = std::make_unique(); + display_buffer = std::make_unique(); scene_shader = std::make_unique( VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE); @@ -124,12 +127,20 @@ int main() { DISPLAY_VERTEX_SHADER_CODE, DISPLAY_FRAGMENT_SHADER_CODE); }); + if ( std::any_of(texture_framebuffers.cbegin(), texture_framebuffers.cend(), + [](auto& texture_framebuffer) -> bool { + return !texture_framebuffer->isGood(); + }) ) { + std::cerr << "Texture framebuffer error" << std::endl; + return -1; + } + auto lastFrame = std::chrono::high_resolution_clock::now(); auto lastRotate = std::chrono::high_resolution_clock::now(); bool justRotated = true; std::vector textures; - for ( const auto& texture_buffer : texture_buffers ) { + for ( const auto& texture_buffer : texture_framebuffers ) { textures.emplace_back(texture_buffer->getTexture()); } @@ -142,7 +153,7 @@ int main() { MVP = getMVP(world_width, world_height); - for ( auto& texture_buffer : texture_buffers ) { + for ( auto& texture_buffer : texture_framebuffers ) { texture_buffer->resize(window_width, window_height); } } @@ -158,14 +169,14 @@ int main() { if ( util::millisecondsSince(lastRotate) >= 1000/10 ) { std::rotate(textures.begin(), textures.end()-1, textures.end()); - std::rotate(texture_buffers.begin(), texture_buffers.end()-1, texture_buffers.end()); + std::rotate(texture_framebuffers.begin(), texture_framebuffers.end()-1, texture_framebuffers.end()); justRotated = true; lastRotate = std::chrono::high_resolution_clock::now(); } { - auto texGuard = texture_buffers[0]->use(); + auto texGuard = texture_framebuffers[0]->use(); auto sdrGuard = scene_shader->use(); scene_shader->setUniform("MVP", MVP); diff --git a/src/particle_vertex_buffer.h b/src/particle_vertex_buffer.h deleted file mode 100644 index 25855a2..0000000 --- a/src/particle_vertex_buffer.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include - -class ParticleVertexBuffer { -private: - std::vector _data; - - GLuint _array; - GLuint _buffer; - -public: - ParticleVertexBuffer(std::vector&& data): - _data{ std::move(data) } { - glGenVertexArrays(1, &_array); - glGenBuffers(1, &_buffer); - - glBindVertexArray(_array); - glBindBuffer(GL_ARRAY_BUFFER, _buffer); - glBufferData( - GL_ARRAY_BUFFER, - _data.size() * sizeof(GLfloat), - _data.data(), - GL_STATIC_DRAW - ); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - } - - ~ParticleVertexBuffer() { - glDeleteBuffers(1, &_buffer); - glDeleteVertexArrays(1, &_array); - } - - void draw() const { - glBindVertexArray(_array); - glDrawArrays(GL_POINTS, 0, 3*_data.size()); - } - - GLuint getBuffer() const { - return _buffer; - } -}; 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; + } +}; diff --git a/src/texture_buffer.h b/src/texture_buffer.h deleted file mode 100644 index 08c617b..0000000 --- a/src/texture_buffer.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -class TextureBuffer { -private: - GLuint _id; - GLuint _texture; - -public: - struct Guard { - const GLuint _id; - - Guard(GLuint id): _id(id) { - glBindFramebuffer(GL_FRAMEBUFFER, _id); - } - ~Guard() { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - }; - - Guard use() const { - return Guard(_id); - } - - TextureBuffer(std::size_t width, std::size_t height) { - glGenFramebuffers(1, &_id); - - auto guard = use(); - - glGenTextures(1, &_texture); - glBindTexture(GL_TEXTURE_2D, _texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0); - - if ( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ) { - std::cerr << "Texture framebuffer error" << std::endl; - } - } - - ~TextureBuffer() { - glDeleteFramebuffers(1, &_id); - } - - void resize(std::size_t width, std::size_t height) const { - auto guard = use(); - - glViewport(0, 0, width, height); - glBindTexture(GL_TEXTURE_2D, _texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)0); - } - - GLuint getTexture() const { - return _texture; - } -}; diff --git a/src/texture_display_buffer.h b/src/texture_display_buffer.h deleted file mode 100644 index b38f9c0..0000000 --- a/src/texture_display_buffer.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include - -class TextureDisplayBuffer { -private: - const std::vector _data; - - GLuint _array; - GLuint _buffer; - -public: - TextureDisplayBuffer(): - _data{ - -1.f, 1.f, 0.f, 1.f, - -1.f, -1.f, 0.f, 0.f, - 1.f, -1.f, 1.f, 0.f, - - -1.f, 1.f, 0.f, 1.f, - 1.f, -1.f, 1.f, 0.f, - 1.f, 1.f, 1.f, 1.f - } { - glGenVertexArrays(1, &_array); - glGenBuffers(1, &_buffer); - - glBindVertexArray(_array); - glBindBuffer(GL_ARRAY_BUFFER, _buffer); - glBufferData( - GL_ARRAY_BUFFER, - _data.size() * sizeof(GLfloat), - _data.data(), - GL_STATIC_DRAW - ); - - glEnableVertexAttribArray(0); - glVertexAttribPointer( - 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer( - 1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (void*)(2*sizeof(GLfloat))); - } - - ~TextureDisplayBuffer() { - glDeleteBuffers(1, &_buffer); - glDeleteVertexArrays(1, &_array); - } - - void draw(const std::vector& textures) const { - glBindVertexArray(_array); - glBindTextures(textures[0], textures.size(), textures.data()); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - - GLuint getBuffer() const { - return _buffer; - } -}; diff --git a/src/util.h b/src/util.h index 05e9303..1863563 100644 --- a/src/util.h +++ b/src/util.h @@ -1,7 +1,6 @@ #pragma once #include -#include namespace util { @@ -11,43 +10,4 @@ double millisecondsSince(std::chrono::time_point 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/window.h b/src/window.h deleted file mode 100644 index 794dd5f..0000000 --- a/src/window.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include -#include - -class Window { -private: - bool _good = false; - int _width = 800; - int _height = 600; - - GLFWwindow* const _handle; - -public: - Window(const std::string& title): - _handle(glfwCreateWindow(_width, _height, title.c_str(), NULL, NULL)) { - if ( _handle != nullptr ) { - glfwMakeContextCurrent(_handle); - if ( glewInit() == GLEW_OK ) { - _good = true; - } - glfwMakeContextCurrent(nullptr); - } - } - - bool isGood() const { - return _good; - } - - int getWidth() const { - return _width; - } - - int getHeight() const { - return _height; - } - - template - void init(F f) { - glfwMakeContextCurrent(_handle); - f(); - glfwMakeContextCurrent(nullptr); - } - - template - void render(F loop) { - glfwMakeContextCurrent(_handle); - - while ( glfwGetKey(_handle, GLFW_KEY_ESCAPE ) != GLFW_PRESS && - glfwWindowShouldClose(_handle) == 0 ) { - glfwGetWindowSize(_handle, &_width, &_height); - - loop(); - - glfwSwapBuffers(_handle); - glfwPollEvents(); - } - - glfwMakeContextCurrent(nullptr); - } - -}; -- cgit v1.2.3