Compare commits
3 Commits
12b81f1363
...
a86b620d2f
Author | SHA1 | Date |
---|---|---|
|
a86b620d2f | |
|
fe0833c467 | |
|
119b36cb2b |
|
@ -13,79 +13,26 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
/**
|
class shader_base {
|
||||||
* This part was made for this assignment and will likely be used in future projects
|
protected:
|
||||||
*/
|
|
||||||
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:
|
|
||||||
struct IntDefaultedToMinusOne {
|
struct IntDefaultedToMinusOne {
|
||||||
GLint i = -1;
|
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<std::string, IntDefaultedToMinusOne> uniformVars;
|
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
||||||
|
GLuint programID = 0;
|
||||||
static unsigned int createShader(const std::string& source, int type);
|
|
||||||
|
|
||||||
inline GLint getUniformLocation(const std::string &name) {
|
inline GLint getUniformLocation(const std::string &name) {
|
||||||
if (uniformVars[name].i != -1)
|
if (uniformVars[name].i != -1)
|
||||||
return uniformVars[name].i;
|
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());
|
int loc = glGetUniformLocation(programID, name.c_str());
|
||||||
uniformVars[name].i = loc;
|
uniformVars[name].i = loc;
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
inline void bind() const {
|
||||||
* Creates a shader
|
glUseProgram(programID);
|
||||||
* @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;
|
|
||||||
|
|
||||||
// set various data-types.
|
|
||||||
inline void setBool(const std::string &name, bool value) {
|
inline void setBool(const std::string &name, bool value) {
|
||||||
glUniform1i(getUniformLocation(name), (int) value);
|
glUniform1i(getUniformLocation(name), (int) value);
|
||||||
}
|
}
|
||||||
|
@ -107,8 +54,7 @@ class shader {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec4(const std::string &name, const blt::vec4 &vec) {
|
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.w());
|
||||||
glUniform4f(getUniformLocation(name), vec.x(), vec.y(), vec.z(), vec[3]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setVec2(const std::string &name, float x, float y) {
|
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) {
|
inline void setVec4(const std::string &name, float x, float y, float z, float w) {
|
||||||
glUniform4f(getUniformLocation(name), x, y, z, 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 {
|
inline void execute(int x, int y, int z) const {
|
||||||
glUseProgram(programID);
|
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();
|
~shader();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
std::string shader_geom = R"("
|
||||||
|
#version 460
|
||||||
|
|
||||||
|
layout (points) in;
|
||||||
|
layout (triangle_strip, max_vertices = 4) out;
|
||||||
|
|
||||||
|
in vec4 pos_[];
|
||||||
|
|
||||||
|
out vec2 uv_;
|
||||||
|
out float index;
|
||||||
|
|
||||||
|
const vec3 vertices[] = {
|
||||||
|
vec3(0.5f, 0.5f, 0.0f),
|
||||||
|
vec3(0.5f, -0.5f, 0.0f),
|
||||||
|
vec3(-0.5f, -0.5f, 0.0f),
|
||||||
|
vec3(-0.5f, 0.5f, 0.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform mat4 pvm;
|
||||||
|
uniform vec4 up;
|
||||||
|
uniform vec4 right;
|
||||||
|
|
||||||
|
void emitTransformed(vec3 pos){
|
||||||
|
// passthough index
|
||||||
|
index = pos_[0].w;
|
||||||
|
//gl_Position = pvm * vec4(pos_[0].xyz + vertices[0], 1.0);
|
||||||
|
gl_Position = pvm * vec4(pos, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const float quad_size = 0.5;
|
||||||
|
vec3 pos = pos_[0].xyz;
|
||||||
|
|
||||||
|
emitTransformed(pos + up.xyz * quad_size + right.xyz * quad_size);
|
||||||
|
uv_ = vec2(0, 0);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
emitTransformed(pos + up.xyz * quad_size - right.xyz * quad_size);
|
||||||
|
uv_ = vec2(0, 1);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
emitTransformed(pos - up.xyz * quad_size + right.xyz * quad_size);
|
||||||
|
uv_ = vec2(1, 0);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
emitTransformed(pos - up.xyz * quad_size - right.xyz * quad_size);
|
||||||
|
uv_ = vec2(1, 1);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
")";
|
||||||
|
#endif
|
|
@ -17,7 +17,7 @@ const float SPEED = 1.0f;
|
||||||
const float SPEED_FACTOR = 25.0f;
|
const float SPEED_FACTOR = 25.0f;
|
||||||
const float BOUNCE_FACTOR = 0.75f;
|
const float BOUNCE_FACTOR = 0.75f;
|
||||||
const float SPREAD = 4.5f;
|
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_min = vec2(-50, -50);
|
||||||
const vec2 p_max = vec2(50, 50);
|
const vec2 p_max = vec2(50, 50);
|
||||||
const vec3 inital_pos = vec3(0.0f, 1.0f, 0.0f);
|
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];
|
vec4 offsets[offset_size];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(location=0) uniform float deltaSeconds;
|
uniform float deltaSeconds;
|
||||||
|
|
||||||
void resetParticle(uint i, float w) {
|
void resetParticle(uint i, float w) {
|
||||||
particles[i].dir = inital_dir * SPEED_FACTOR + offsets[i % offset_size] * SPREAD;
|
particles[i].dir = inital_dir * SPEED_FACTOR + offsets[i % offset_size] * SPREAD;
|
||||||
|
|
|
@ -3,22 +3,18 @@
|
||||||
std::string shader_vert = R"("
|
std::string shader_vert = R"("
|
||||||
#version 460
|
#version 460
|
||||||
|
|
||||||
layout (location = 0) in vec3 vertex;
|
//layout (location = 0) in vec3 vertex;
|
||||||
layout (location = 1) in vec2 uv;
|
//layout (location = 1) in vec2 uv;
|
||||||
layout (location = 2) in vec4 pos;
|
layout (location = 0) in vec4 pos;
|
||||||
layout (location = 3) in vec4 dir;
|
layout (location = 1) in vec4 dir;
|
||||||
|
|
||||||
out vec2 uv_;
|
out vec4 pos_;
|
||||||
out float index;
|
|
||||||
|
|
||||||
uniform mat4 pvm;
|
uniform mat4 pvm;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// passthough the UV (OpenGL interpolates this per fragment)
|
// passthrough point position to geometry shader
|
||||||
uv_ = uv;
|
pos_ = pos;
|
||||||
index = pos.w;
|
|
||||||
// offset the vertex by the particle's position
|
|
||||||
gl_Position = pvm * vec4(vertex + pos.xyz, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
")";
|
")";
|
||||||
|
|
|
@ -80,7 +80,7 @@ shader::shader(const std::string& vertex, const std::string& fragment, const std
|
||||||
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
|
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
|
||||||
fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER);
|
fragmentShaderID = createShader(fragment_source, GL_FRAGMENT_SHADER);
|
||||||
if (load_geometry)
|
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
|
// bind them to a program
|
||||||
programID = glCreateProgram();
|
programID = glCreateProgram();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Licensed under GNU General Public License V3.0
|
* Licensed under GNU General Public License V3.0
|
||||||
* See LICENSE file for license detail
|
* See LICENSE file for license detail
|
||||||
*/
|
*/
|
||||||
#include <locale.h>
|
#include <clocale>
|
||||||
#include <high_perf/gl_util.h>
|
#include <high_perf/gl_util.h>
|
||||||
#include <modes/high_perf.h>
|
#include <modes/high_perf.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
#include "blt/std/memory.h"
|
#include "blt/std/memory.h"
|
||||||
#include <shaders/vertex.vert>
|
#include <shaders/vertex.vert>
|
||||||
#include <shaders/fragment.frag>
|
#include <shaders/fragment.frag>
|
||||||
|
#include <shaders/geometry.geom>
|
||||||
|
#include <blt/profiling/profiler.h>
|
||||||
#include <shaders/physics.comp>
|
#include <shaders/physics.comp>
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#include <stb_image_resize.h>
|
#include <stb_image_resize.h>
|
||||||
|
@ -54,7 +56,7 @@ const unsigned int TEXTURE_WIDTH = 512;
|
||||||
const unsigned int TEXTURE_HEIGHT = 512;
|
const unsigned int TEXTURE_HEIGHT = 512;
|
||||||
|
|
||||||
// -------{Particles}-------
|
// -------{Particles}-------
|
||||||
const unsigned int particle_count = 128 * 10000;
|
const unsigned int particle_count = 128 * 50000;
|
||||||
const unsigned int offset_count = 8192;
|
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.
|
// generally alignment to multiples of 4 floats helps performance, plus we can use that extra space for info we need.
|
||||||
|
@ -103,7 +105,7 @@ void runPhysicsShader(){
|
||||||
return;
|
return;
|
||||||
|
|
||||||
physics_shader->bind();
|
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);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleTranslationsBuffer);
|
||||||
physics_shader->execute(particle_count / 128, 1, 1);
|
physics_shader->execute(particle_count / 128, 1, 1);
|
||||||
|
|
||||||
|
@ -115,18 +117,37 @@ void render() {
|
||||||
perspectiveMatrix = blt::perspective(FOV, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 1000.0f);
|
perspectiveMatrix = blt::perspective(FOV, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 1000.0f);
|
||||||
auto pvm = perspectiveMatrix * viewMatrix;
|
auto pvm = perspectiveMatrix * viewMatrix;
|
||||||
|
|
||||||
runPhysicsShader();
|
auto inverseView = viewMatrix.transpose();
|
||||||
|
|
||||||
|
// we need the up and right vectors for fast geometry shader billboard
|
||||||
|
// thankfully they are easy to extract from our view matrix.
|
||||||
|
blt::vec4 up {inverseView.m01(), inverseView.m11(), inverseView.m21()};
|
||||||
|
blt::vec4 right {inverseView.m00(), inverseView.m10(), inverseView.m20()};
|
||||||
|
|
||||||
|
//
|
||||||
|
// up = viewMatrix * up;
|
||||||
|
// right = viewMatrix * right;
|
||||||
|
|
||||||
|
//BLT_TRACE("Up {%f, %f, %f} || Right {%f, %f, %f}", up.x(), up.y(), up.z(), right.x(), right.y(), right.z());
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("Particles", "Compute Shader");
|
||||||
|
runPhysicsShader();
|
||||||
|
BLT_END_INTERVAL("Particles", "Compute Shader");
|
||||||
|
|
||||||
|
BLT_START_INTERVAL("Particles", "Render");
|
||||||
instance_shader->bind();
|
instance_shader->bind();
|
||||||
|
instance_shader->setVec4("up", up);
|
||||||
|
instance_shader->setVec4("right", right);
|
||||||
instance_shader->setMatrix("pvm", pvm);
|
instance_shader->setMatrix("pvm", pvm);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, textureArrayID);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, textureArrayID);
|
||||||
|
|
||||||
glBindVertexArray(particleVAO);
|
glBindVertexArray(particleVAO);
|
||||||
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, particle_count);
|
//glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, particle_count);
|
||||||
|
glDrawArrays(GL_POINTS, 0, particle_count);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
BLT_END_INTERVAL("Particles", "Render");
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
|
@ -157,7 +178,7 @@ void init() {
|
||||||
blt::scoped_buffer<particle_record> translations{particle_count};
|
blt::scoped_buffer<particle_record> translations{particle_count};
|
||||||
blt::scoped_buffer<vec4> offsets{offset_count};
|
blt::scoped_buffer<vec4> offsets{offset_count};
|
||||||
blt::random<float> dir{-1, 1};
|
blt::random<float> dir{-1, 1};
|
||||||
blt::random<float> lifetime{0, 25};
|
blt::random<float> lifetime{0, 120};
|
||||||
|
|
||||||
BLT_TRACE("Creating particles");
|
BLT_TRACE("Creating particles");
|
||||||
for (int i = 0; i < particle_count; i++)
|
for (int i = 0; i < particle_count; i++)
|
||||||
|
@ -191,31 +212,31 @@ void init() {
|
||||||
BLT_TRACE("Uploading VBO data and assigning to VAO");
|
BLT_TRACE("Uploading VBO data and assigning to VAO");
|
||||||
glBindVertexArray(particleVAO);
|
glBindVertexArray(particleVAO);
|
||||||
|
|
||||||
// bind and upload vertices data to the GPU
|
// // bind and upload vertices data to the GPU
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
|
// glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 12, vertices, GL_STATIC_DRAW);
|
// glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 12, vertices, GL_STATIC_DRAW);
|
||||||
// tell OpenGL how to handle the vertex data when rendering the VAO, the vertices will be bound to slot 0.
|
// // tell OpenGL how to handle the vertex data when rendering the VAO, the vertices will be bound to slot 0.
|
||||||
// (we will tell OpenGL what variable uses slot 0 in the shader!)
|
// // (we will tell OpenGL what variable uses slot 0 in the shader!)
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*) 0);
|
// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*) 0);
|
||||||
// tell OpenGL we will be using the first VAO slot, prevents us from having to call it before rendering
|
// // tell OpenGL we will be using the first VAO slot, prevents us from having to call it before rendering
|
||||||
glEnableVertexAttribArray(0);
|
// glEnableVertexAttribArray(0);
|
||||||
|
//
|
||||||
|
//
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, uvsVBO);
|
// glBindBuffer(GL_ARRAY_BUFFER, uvsVBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, uvs, GL_STATIC_DRAW);
|
// glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, uvs, GL_STATIC_DRAW);
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*) 0);
|
// glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*) 0);
|
||||||
glEnableVertexAttribArray(1);
|
// glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
int translations_size = sizeof(particle_record) * particle_count;
|
int translations_size = sizeof(particle_record) * particle_count;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, particleTranslationsBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, particleTranslationsBuffer);
|
||||||
glBufferData(GL_ARRAY_BUFFER, translations_size, translations.buffer, GL_DYNAMIC_DRAW); // allocate some memory on the GPU
|
glBufferData(GL_ARRAY_BUFFER, translations_size, translations.buffer, GL_DYNAMIC_DRAW); // allocate some memory on the GPU
|
||||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(particle_record), (void*) 0);
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(particle_record), (void*) 0);
|
||||||
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(particle_record), (void*) offsetof(particle_record, dir));
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(particle_record), (void*) offsetof(particle_record, dir));
|
||||||
// tells opengl that we want to present this data per 1 instance instead of per vertex.
|
// tells opengl that we want to present this data per 1 instance instead of per vertex.
|
||||||
glVertexAttribDivisor(2, 1);
|
// glVertexAttribDivisor(2, 1);
|
||||||
glVertexAttribDivisor(3, 1);
|
// glVertexAttribDivisor(3, 1);
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(0);
|
||||||
glEnableVertexAttribArray(3);
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
// allow the particle buffer to be used in the computer shader!
|
// allow the particle buffer to be used in the computer shader!
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleTranslationsBuffer);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleTranslationsBuffer);
|
||||||
|
@ -226,8 +247,8 @@ void init() {
|
||||||
glBufferData(GL_SHADER_STORAGE_BUFFER, offset_count * sizeof(vec4), offsets.buffer, GL_STATIC_DRAW);
|
glBufferData(GL_SHADER_STORAGE_BUFFER, offset_count * sizeof(vec4), offsets.buffer, GL_STATIC_DRAW);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, particleOffsetsBuffer);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, particleOffsetsBuffer);
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesEBO);
|
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesEBO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(float) * 6, indices, GL_STATIC_DRAW);
|
// glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(float) * 6, indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
@ -257,7 +278,7 @@ void init() {
|
||||||
constexpr int channel_count = 4;
|
constexpr int channel_count = 4;
|
||||||
|
|
||||||
int level = 0;
|
int level = 0;
|
||||||
stbi_set_flip_vertically_on_load(true);
|
stbi_set_flip_vertically_on_load(false);
|
||||||
for (const std::string& texture_loc : texture_locations){
|
for (const std::string& texture_loc : texture_locations){
|
||||||
// load the texture
|
// load the texture
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
|
@ -309,13 +330,14 @@ void init() {
|
||||||
|
|
||||||
BLT_TRACE("Loading shaders");
|
BLT_TRACE("Loading shaders");
|
||||||
|
|
||||||
instance_shader = new shader(shader_vert, shader_frag, "", true);
|
instance_shader = new shader(shader_vert, shader_frag, shader_geom, true);
|
||||||
physics_shader = new compute_shader(shader_physics);
|
physics_shader = new compute_shader(shader_physics);
|
||||||
|
|
||||||
BLT_DEBUG("High performance subsystem init complete!");
|
BLT_DEBUG("High performance subsystem init complete!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
|
BLT_PRINT_PROFILE("Particles", blt::logging::NONE, true);
|
||||||
// cleanup opengl resources
|
// cleanup opengl resources
|
||||||
glDeleteVertexArrays(1, &particleVAO);
|
glDeleteVertexArrays(1, &particleVAO);
|
||||||
glDeleteBuffers(1, &particleTranslationsBuffer);
|
glDeleteBuffers(1, &particleTranslationsBuffer);
|
||||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -160,6 +160,13 @@ int main(int argc, char** argv) {
|
||||||
glutPassiveMotionFunc([](int x, int y) -> void {
|
glutPassiveMotionFunc([](int x, int y) -> void {
|
||||||
cam.mousePassiveMotion(x, y);
|
cam.mousePassiveMotion(x, y);
|
||||||
});
|
});
|
||||||
|
glutCloseFunc([]() -> void {
|
||||||
|
BLT_DEBUG("Program has exited, cleaning up resources");
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
BLT_DEBUG("Cleanup complete, have a good day!");
|
||||||
|
});
|
||||||
|
|
||||||
// display
|
// display
|
||||||
glutIdleFunc(render_i);
|
glutIdleFunc(render_i);
|
||||||
|
@ -184,12 +191,6 @@ int main(int argc, char** argv) {
|
||||||
BLT_DEBUG("Resource initialization complete!");
|
BLT_DEBUG("Resource initialization complete!");
|
||||||
|
|
||||||
glutMainLoop();
|
glutMainLoop();
|
||||||
|
|
||||||
BLT_DEBUG("Program has exited, cleaning up resources");
|
|
||||||
|
|
||||||
cleanup();
|
|
||||||
|
|
||||||
BLT_DEBUG("Cleanup complete, have a good day!");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue