From 84bcd409a3743e933d039a9b3e073030fd2630df Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Wed, 23 May 2018 19:06:47 +0200 Subject: Implement particle trails using overlaying textures --- src/main.cc | 54 +++++++++++++++++++++++++++++----------- src/shader/display_fragment.glsl | 25 ++++++++++++++++--- src/shader/vertex.glsl | 3 ++- src/texture_buffer.h | 1 + src/texture_display_buffer.h | 15 ++++++----- 5 files changed, 74 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/main.cc b/src/main.cc index 691f900..034d026 100644 --- a/src/main.cc +++ b/src/main.cc @@ -6,6 +6,7 @@ #include #include +#include #include "particle_vertex_buffer.h" #include "texture_display_buffer.h" @@ -21,15 +22,16 @@ #include "shader/display_vertex.glsl" #include "shader/display_fragment.glsl" -const std::size_t particle_count = 100000; -const auto max_ups = 50; +const unsigned int particle_count = 5000; +const unsigned int max_ups = 100; +const unsigned int texture_count = 10; -int window_width = 800; -int window_height = 600; +unsigned int window_width = 800; +unsigned int window_height = 600; float world_width, world_height; glm::mat4 MVP; -std::unique_ptr textureBuffer; +std::vector> textureBuffers; std::unique_ptr particleBuffer; void updateMVP() { @@ -55,7 +57,9 @@ void window_size_callback(GLFWwindow*, int width, int height) { window_width = width; window_height = height; - textureBuffer->resize(width, height); + for ( auto& textureBuffer : textureBuffers ) { + textureBuffer->resize(width, height); + } updateMVP(); } @@ -109,8 +113,11 @@ int main() { updateMVP(); - textureBuffer = std::make_unique( - window_width, window_height); + for ( unsigned int i = 0; i < texture_count; ++i ) { + textureBuffers.emplace_back( + new TextureBuffer(window_width, window_height)); + } + particleBuffer = std::make_unique( makeInitialParticles(particle_count)); @@ -121,11 +128,16 @@ int main() { GraphicShader displayShader(DISPLAY_VERTEX_SHADER_CODE, DISPLAY_FRAGMENT_SHADER_CODE); - displayShader.setUniform("screen_texture", 0); + TextureDisplayBuffer displayBuffer; - TextureDisplayBuffer displayBuffer(textureBuffer->getTexture()); + auto lastFrame = std::chrono::high_resolution_clock::now(); + auto lastRotate = std::chrono::high_resolution_clock::now(); + bool justRotated = true; - auto lastFrame = std::chrono::high_resolution_clock::now(); + std::vector textures; + for ( auto& textureBuffer : textureBuffers ) { + textures.emplace_back(textureBuffer->getTexture()); + } do { if ( util::millisecondsSince(lastFrame) >= 1000/max_ups ) { @@ -137,13 +149,23 @@ int main() { lastFrame = std::chrono::high_resolution_clock::now(); } + if ( util::millisecondsSince(lastRotate) >= 1000/10 ) { + std::rotate(textures.begin(), textures.end()-1, textures.end()); + std::rotate(textureBuffers.begin(), textureBuffers.end()-1, textureBuffers.end()); + justRotated = true; + lastRotate = std::chrono::high_resolution_clock::now(); + } + { - auto texGuard = textureBuffer->use(); + auto texGuard = textureBuffers[0]->use(); auto sdrGuard = sceneShader.use(); sceneShader.setUniform("MVP", MVP); - glClear(GL_COLOR_BUFFER_BIT); + if ( justRotated ) { + glClear(GL_COLOR_BUFFER_BIT); + justRotated = false; + } particleBuffer->draw(); } @@ -151,9 +173,13 @@ int main() { { auto guard = displayShader.use(); + for ( unsigned int i = 0; i < textures.size(); ++i ) { + displayShader.setUniform("screen_texture_" + std::to_string(i), i); + } + glClear(GL_COLOR_BUFFER_BIT); - displayBuffer.draw(); + displayBuffer.draw(textures); } glfwSwapBuffers(window); diff --git a/src/shader/display_fragment.glsl b/src/shader/display_fragment.glsl index 8b98ce1..03986a0 100644 --- a/src/shader/display_fragment.glsl +++ b/src/shader/display_fragment.glsl @@ -1,11 +1,30 @@ static const std::string DISPLAY_FRAGMENT_SHADER_CODE = R"( -#version 330 core +#version 460 out vec4 FragColor; in vec2 TexCoords; -uniform sampler2D screen_texture; + +uniform sampler2D screen_texture_0; +uniform sampler2D screen_texture_1; +uniform sampler2D screen_texture_2; +uniform sampler2D screen_texture_3; +uniform sampler2D screen_texture_4; +uniform sampler2D screen_texture_5; +uniform sampler2D screen_texture_6; +uniform sampler2D screen_texture_7; +uniform sampler2D screen_texture_8; +uniform sampler2D screen_texture_9; void main() { - FragColor = texture(screen_texture, TexCoords); + FragColor = texture(screen_texture_0, TexCoords) + + 0.9 * texture(screen_texture_1, TexCoords) + + 0.8 * texture(screen_texture_2, TexCoords) + + 0.7 * texture(screen_texture_3, TexCoords) + + 0.6 * texture(screen_texture_4, TexCoords) + + 0.5 * texture(screen_texture_5, TexCoords) + + 0.4 * texture(screen_texture_6, TexCoords) + + 0.3 * texture(screen_texture_7, TexCoords) + + 0.2 * texture(screen_texture_8, TexCoords) + + 0.1 * texture(screen_texture_9, TexCoords); } )"; diff --git a/src/shader/vertex.glsl b/src/shader/vertex.glsl index 8ab6ccb..2d4009a 100644 --- a/src/shader/vertex.glsl +++ b/src/shader/vertex.glsl @@ -3,6 +3,7 @@ uniform mat4 MVP; void main() { gl_Position = MVP * vec4(gl_Vertex.xy, 0.0, 1.0); - gl_FrontColor = vec4(max(1. - gl_Vertex.z/5., 0.1), 0., 0., 0.); + //gl_FrontColor = vec4(max(1. - gl_Vertex.z/5., 0.1), 0., 0., 0.); + gl_FrontColor = vec4(1., 0., 0., 0.); } )"; diff --git a/src/texture_buffer.h b/src/texture_buffer.h index 8afe240..08c617b 100644 --- a/src/texture_buffer.h +++ b/src/texture_buffer.h @@ -46,6 +46,7 @@ public: 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); } diff --git a/src/texture_display_buffer.h b/src/texture_display_buffer.h index 530b99d..25fd319 100644 --- a/src/texture_display_buffer.h +++ b/src/texture_display_buffer.h @@ -6,12 +6,11 @@ class TextureDisplayBuffer { private: const std::vector _data; - GLuint _texture; GLuint _array; GLuint _buffer; public: - TextureDisplayBuffer(GLuint texture): + TextureDisplayBuffer(): _data{ -1.f, 1.f, 0.f, 1.f, -1.f, -1.f, 0.f, 0.f, @@ -20,8 +19,7 @@ public: -1.f, 1.f, 0.f, 1.f, 1.f, -1.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f - }, - _texture(texture) { + } { glGenVertexArrays(1, &_array); glGenBuffers(1, &_buffer); @@ -47,9 +45,14 @@ public: glDeleteVertexArrays(1, &_array); } - void draw() const { + void draw(const std::vector& textures) const { glBindVertexArray(_array); - glBindTexture(GL_TEXTURE_2D, _texture); + + for ( unsigned int i = 0; i < textures.size(); ++i ) { + glActiveTexture(GL_TEXTURE0+i); + glBindTexture(GL_TEXTURE_2D, textures[i]); + } + glDrawArrays(GL_TRIANGLES, 0, 6); } -- cgit v1.2.3