From 617fec827652d216e2d1e5015f816c4400655d73 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 21 May 2018 21:16:56 +0200 Subject: Abstract texture display buffer, shader --- src/compute_shader.h | 8 ++-- src/graphic_shader.h | 6 +-- src/main.cc | 90 +++++++++++----------------------------- src/particle_vertex_buffer.h | 4 +- src/shader/display_fragment.glsl | 11 +++++ src/shader/display_vertex.glsl | 12 ++++++ src/texture_buffer.h | 4 +- src/texture_display_buffer.h | 59 ++++++++++++++++++++++++++ src/util.h | 7 ++++ 9 files changed, 124 insertions(+), 77 deletions(-) create mode 100644 src/shader/display_fragment.glsl create mode 100644 src/shader/display_vertex.glsl create mode 100644 src/texture_display_buffer.h diff --git a/src/compute_shader.h b/src/compute_shader.h index a7e997a..9f5c5cb 100644 --- a/src/compute_shader.h +++ b/src/compute_shader.h @@ -18,7 +18,7 @@ public: } }; - Guard use() { + Guard use() const { return Guard(_id); } @@ -31,17 +31,17 @@ public: glDeleteProgram(_id); } - GLuint setUniform(const std::string& name, float x, float y) { + 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) { + void workOn(GLuint buffer) const { glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, buffer); } - void dispatch(std::size_t dimX) { + void dispatch(std::size_t dimX) const { glDispatchCompute(dimX, 1, 1); } }; diff --git a/src/graphic_shader.h b/src/graphic_shader.h index 0422ec9..c93e61b 100644 --- a/src/graphic_shader.h +++ b/src/graphic_shader.h @@ -18,7 +18,7 @@ public: } }; - Guard use() { + Guard use() const { return Guard(_id); } @@ -32,13 +32,13 @@ public: glDeleteProgram(_id); } - GLuint setUniform(const std::string& name, int value) { + 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, glm::mat4& M) { + 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 7b4415b..691f900 100644 --- a/src/main.cc +++ b/src/main.cc @@ -5,19 +5,24 @@ #include #include -#include #include +#include "particle_vertex_buffer.h" +#include "texture_display_buffer.h" + #include "graphic_shader.h" #include "compute_shader.h" #include "texture_buffer.h" -#include "particle_vertex_buffer.h" #include "shader/vertex.glsl" #include "shader/fragment.glsl" #include "shader/compute.glsl" +#include "shader/display_vertex.glsl" +#include "shader/display_fragment.glsl" + const std::size_t particle_count = 100000; +const auto max_ups = 50; int window_width = 800; int window_height = 600; @@ -30,18 +35,20 @@ std::unique_ptr particleBuffer; void updateMVP() { world_width = 20.f; world_height = world_width / window_width * window_height; + glm::mat4 projection = glm::ortho( -(world_width /2), world_width/2, -(world_height/2), world_height/2, 0.1f, 100.0f ); + glm::mat4 view = glm::lookAt( glm::vec3(0,0,20), glm::vec3(0,0,0), glm::vec3(0,1,0) ); - glm::mat4 model = glm::mat4(1.0f); - MVP = projection * view * model; + + MVP = projection * view; } void window_size_callback(GLFWwindow*, int width, int height) { @@ -102,73 +109,26 @@ int main() { updateMVP(); - GraphicShader sceneShader(VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE); - GraphicShader displayShader(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; - } - )", R"( - #version 330 core - out vec4 FragColor; - in vec2 TexCoords; - uniform sampler2D screen_texture; - - void main() { - FragColor = texture(screen_texture, TexCoords); - } - )"); - - sceneShader.setUniform("MVP", MVP); - displayShader.setUniform("screen_texture", 0); - - textureBuffer = std::make_unique(window_width, window_height); + textureBuffer = std::make_unique( + window_width, window_height); particleBuffer = std::make_unique( makeInitialParticles(particle_count)); + GraphicShader sceneShader(VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE); + ComputeShader computeShader(COMPUTE_SHADER_CODE); computeShader.workOn(particleBuffer->getBuffer()); - const std::vector quad_buffer_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 - }; - - GLuint QuadVertexArrayID; - GLuint QuadVertexBufferID; - - glGenVertexArrays(1, &QuadVertexArrayID); - glGenBuffers(1, &QuadVertexBufferID); - - glBindVertexArray(QuadVertexArrayID); - glBindBuffer(GL_ARRAY_BUFFER, QuadVertexBufferID); - glBufferData( - GL_ARRAY_BUFFER, - quad_buffer_data.size() * sizeof(GLfloat), - quad_buffer_data.data(), - GL_STATIC_DRAW - ); + GraphicShader displayShader(DISPLAY_VERTEX_SHADER_CODE, + DISPLAY_FRAGMENT_SHADER_CODE); + displayShader.setUniform("screen_texture", 0); - 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 displayBuffer(textureBuffer->getTexture()); auto lastFrame = std::chrono::high_resolution_clock::now(); do { - // update particles at most 50 times per second - if ( std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - lastFrame).count() >= 20 ) { + if ( util::millisecondsSince(lastFrame) >= 1000/max_ups ) { auto guard = computeShader.use(); computeShader.setUniform("world", world_width, world_height); @@ -181,21 +141,19 @@ int main() { auto texGuard = textureBuffer->use(); auto sdrGuard = sceneShader.use(); - glClear(GL_COLOR_BUFFER_BIT); - sceneShader.setUniform("MVP", MVP); + glClear(GL_COLOR_BUFFER_BIT); + particleBuffer->draw(); } { auto guard = displayShader.use(); - glBindVertexArray(QuadVertexArrayID); - glBindTexture(GL_TEXTURE_2D, textureBuffer->getTexture()); - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLES, 0, 6); + + displayBuffer.draw(); } glfwSwapBuffers(window); diff --git a/src/particle_vertex_buffer.h b/src/particle_vertex_buffer.h index 58daf38..25855a2 100644 --- a/src/particle_vertex_buffer.h +++ b/src/particle_vertex_buffer.h @@ -30,10 +30,10 @@ public: ~ParticleVertexBuffer() { glDeleteBuffers(1, &_buffer); - glDeleteVertexArrays(1, &_buffer); + glDeleteVertexArrays(1, &_array); } - void draw() { + void draw() const { glBindVertexArray(_array); glDrawArrays(GL_POINTS, 0, 3*_data.size()); } diff --git a/src/shader/display_fragment.glsl b/src/shader/display_fragment.glsl new file mode 100644 index 0000000..8b98ce1 --- /dev/null +++ b/src/shader/display_fragment.glsl @@ -0,0 +1,11 @@ +static const std::string DISPLAY_FRAGMENT_SHADER_CODE = R"( +#version 330 core + +out vec4 FragColor; +in vec2 TexCoords; +uniform sampler2D screen_texture; + +void main() { + FragColor = texture(screen_texture, TexCoords); +} +)"; diff --git a/src/shader/display_vertex.glsl b/src/shader/display_vertex.glsl new file mode 100644 index 0000000..60bbfc7 --- /dev/null +++ b/src/shader/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/texture_buffer.h b/src/texture_buffer.h index d6cce53..8afe240 100644 --- a/src/texture_buffer.h +++ b/src/texture_buffer.h @@ -17,7 +17,7 @@ public: } }; - Guard use() { + Guard use() const { return Guard(_id); } @@ -42,7 +42,7 @@ public: glDeleteFramebuffers(1, &_id); } - void resize(std::size_t width, std::size_t height) { + void resize(std::size_t width, std::size_t height) const { auto guard = use(); glViewport(0, 0, width, height); diff --git a/src/texture_display_buffer.h b/src/texture_display_buffer.h new file mode 100644 index 0000000..530b99d --- /dev/null +++ b/src/texture_display_buffer.h @@ -0,0 +1,59 @@ +#pragma once + +#include + +class TextureDisplayBuffer { +private: + const std::vector _data; + + GLuint _texture; + GLuint _array; + GLuint _buffer; + +public: + TextureDisplayBuffer(GLuint texture): + _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 + }, + _texture(texture) { + 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 { + glBindVertexArray(_array); + glBindTexture(GL_TEXTURE_2D, _texture); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + + GLuint getBuffer() const { + return _buffer; + } +}; diff --git a/src/util.h b/src/util.h index 7aec674..05e9303 100644 --- a/src/util.h +++ b/src/util.h @@ -1,9 +1,16 @@ #pragma once +#include #include namespace util { +double millisecondsSince(std::chrono::time_point& pit) { + return std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - pit + ).count(); +} + GLint getUniform(GLuint program, const std::string& name) { const GLint uniform = glGetUniformLocation(program, name.c_str()); if ( uniform == -1 ) { -- cgit v1.2.3