diff --git a/include/high_perf/gl_util.h b/include/high_perf/gl_util.h index 17d8292..ce0e454 100644 --- a/include/high_perf/gl_util.h +++ b/include/high_perf/gl_util.h @@ -13,79 +13,26 @@ #include #include -/** - * This part was made for this assignment and will likely be used in future projects - */ -class compute_shader { - private: - GLuint shaderID = 0; - GLuint programID = 0; - public: - explicit compute_shader(const std::string& shader_source, bool loadAsString = true); - inline void bind() const { - glUseProgram(programID); - } - inline void execute(int x, int y, int z) const { - bind(); - glDispatchCompute(x, y, z); - } - ~compute_shader(); -}; - -/** - * Note: This is taken from my final project, - * https://github.com/Tri11Paragon/COSC-3P98-Final-Project/blob/main/include/render/gl.h - */ - -class shader { - private: +class shader_base { + protected: struct IntDefaultedToMinusOne { GLint i = -1; }; - // we can have shaders of many types in OpenGL - GLuint programID = 0; - // but we will only make use of these two for now - GLuint vertexShaderID = 0; - GLuint fragmentShaderID = 0; - // while these will remain unused. (Webgl2 apparently doesn't support them despite being based on GL4.3? that's a TODO!) - GLuint geometryShaderID = 0; - // this would be very useful however it is highly unlikely webgl will support it - // im leaving some of this stuff in here because I might expand the native application to use some of it. - // im trying to keep the web and native versions the same though - GLuint tessellationShaderID = 0; std::unordered_map uniformVars; - - static unsigned int createShader(const std::string& source, int type); + GLuint programID = 0; inline GLint getUniformLocation(const std::string &name) { if (uniformVars[name].i != -1) return uniformVars[name].i; - // caching the result is a lot faster since it won't change after the shader is created. - // TODO: look into this: https://webglfundamentals.org/webgl/lessons/webgl-qna-how-can-i-get-all-the-uniforms-and-uniformblocks.html int loc = glGetUniformLocation(programID, name.c_str()); uniformVars[name].i = loc; return loc; } - public: - /** - * Creates a shader - * @param vertex vertex shader source or file - * @param fragment fragment shader source or file - * @param geometry geometry shader source or file (optional) - * @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false) - */ - shader(const std::string &vertex, const std::string &fragment, const std::string &geometry = "", bool load_as_string = true); + inline void bind() const { + glUseProgram(programID); + } - shader(shader&& move) noexcept; - - // used to set the location of VAOs to the in variables in opengl shaders. - void bindAttribute(int attribute, const std::string &name) const; - - // used to set location of shared UBOs like the perspective and view matrix - void setUniformBlockLocation(const std::string &name, int location) const; - - // set various data-types. inline void setBool(const std::string &name, bool value) { glUniform1i(getUniformLocation(name), (int) value); } @@ -107,8 +54,7 @@ class shader { } inline void setVec4(const std::string &name, const blt::vec4 &vec) { - // TODO: edit BLT to include a w component - glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec[3]); + glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec.w()); } inline void setVec2(const std::string &name, float x, float y) { @@ -122,11 +68,60 @@ class shader { inline void setVec4(const std::string &name, float x, float y, float z, float w) { glUniform4f(getUniformLocation(name), x, y, z, w); } +}; + +/** + * This part was made for this assignment and will likely be used in future projects + */ +class compute_shader : public shader_base { + private: + GLuint shaderID = 0; + public: + explicit compute_shader(const std::string& shader_source, bool loadAsString = true); - inline void bind() const { - glUseProgram(programID); + inline void execute(int x, int y, int z) const { + bind(); + glDispatchCompute(x, y, z); } + ~compute_shader(); +}; + +/** + * Note: This is taken from my final project, + * https://github.com/Tri11Paragon/COSC-3P98-Final-Project/blob/main/include/render/gl.h + */ + +class shader : public shader_base { + private: + GLuint vertexShaderID = 0; + GLuint fragmentShaderID = 0; + // while these will remain unused. (Webgl2 apparently doesn't support them despite being based on GL4.3? that's a TODO!) + GLuint geometryShaderID = 0; + // this would be very useful however it is highly unlikely webgl will support it + // im leaving some of this stuff in here because I might expand the native application to use some of it. + // im trying to keep the web and native versions the same though + GLuint tessellationShaderID = 0; + + static unsigned int createShader(const std::string& source, int type); + public: + /** + * Creates a shader + * @param vertex vertex shader source or file + * @param fragment fragment shader source or file + * @param geometry geometry shader source or file (optional) + * @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false) + */ + shader(const std::string &vertex, const std::string &fragment, const std::string &geometry = "", bool load_as_string = true); + + shader(shader&& move) noexcept; + + // used to set the location of VAOs to the in variables in opengl shaders. + void bindAttribute(int attribute, const std::string &name) const; + + // used to set location of shared UBOs like the perspective and view matrix + void setUniformBlockLocation(const std::string &name, int location) const; + ~shader(); }; diff --git a/include/shaders/geometry.geom b/include/shaders/geometry.geom new file mode 100644 index 0000000..0471b0d --- /dev/null +++ b/include/shaders/geometry.geom @@ -0,0 +1,8 @@ +#version 460 + +layout (points) in; +layout (triangle_strip, max_vertices = 4) out; + +void main() { + +} diff --git a/include/shaders/physics.comp b/include/shaders/physics.comp index 473acd0..9471338 100644 --- a/include/shaders/physics.comp +++ b/include/shaders/physics.comp @@ -17,7 +17,7 @@ const float SPEED = 1.0f; const float SPEED_FACTOR = 25.0f; const float BOUNCE_FACTOR = 0.75f; const float SPREAD = 4.5f; -const float particle_lifetime = 10.0f; +const float particle_lifetime = 120.0f; const vec2 p_min = vec2(-50, -50); const vec2 p_max = vec2(50, 50); const vec3 inital_pos = vec3(0.0f, 1.0f, 0.0f); @@ -33,7 +33,7 @@ layout (std430, binding=1) buffer offset_buffer { vec4 offsets[offset_size]; }; -layout(location=0) uniform float deltaSeconds; +uniform float deltaSeconds; void resetParticle(uint i, float w) { particles[i].dir = inital_dir * SPEED_FACTOR + offsets[i % offset_size] * SPREAD; diff --git a/src/high_perf/gl_util.cpp b/src/high_perf/gl_util.cpp index aececff..fbcde4b 100644 --- a/src/high_perf/gl_util.cpp +++ b/src/high_perf/gl_util.cpp @@ -80,7 +80,7 @@ shader::shader(const std::string& vertex, const std::string& fragment, const std vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER); fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER); if (load_geometry) - BLT_ERROR("Unable to load geometry shader because webgl doesn't support it!"); + geometryShaderID = createShader(geometry_source, GL_GEOMETRY_SHADER); // bind them to a program programID = glCreateProgram(); diff --git a/src/high_perf/high_perf.cpp b/src/high_perf/high_perf.cpp index 2c18a6a..1955aba 100644 --- a/src/high_perf/high_perf.cpp +++ b/src/high_perf/high_perf.cpp @@ -55,7 +55,7 @@ const unsigned int TEXTURE_WIDTH = 512; const unsigned int TEXTURE_HEIGHT = 512; // -------{Particles}------- -const unsigned int particle_count = 128 * 10000; +const unsigned int particle_count = 128 * 5000; const unsigned int offset_count = 8192; // generally alignment to multiples of 4 floats helps performance, plus we can use that extra space for info we need. @@ -104,7 +104,7 @@ void runPhysicsShader(){ return; physics_shader->bind(); - glUniform1f(0, (float)((double) getDelta() / 1000000000.0)); + physics_shader->setFloat("deltaSeconds", (float)((double) getDelta() / 1000000000.0)); glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleTranslationsBuffer); physics_shader->execute(particle_count / 128, 1, 1); @@ -161,7 +161,7 @@ void init() { blt::scoped_buffer translations{particle_count}; blt::scoped_buffer offsets{offset_count}; blt::random dir{-1, 1}; - blt::random lifetime{0, 25}; + blt::random lifetime{0, 120}; BLT_TRACE("Creating particles"); for (int i = 0; i < particle_count; i++)