08: Add first particle system prototype
Also update the README.md
This commit is contained in:
parent
351286d16a
commit
7a218edcce
|
@ -15,8 +15,7 @@ out float _ctt;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 origined_position = origin.xyz + position.xyz;
|
vec3 origined_position = origin.xyz + position.xyz;
|
||||||
origined_position *= 0.2;
|
|
||||||
//gl_Position = projection_matrix * view_matrix * position;
|
|
||||||
gl_Position = projection_matrix * view_matrix * vec4(origined_position, 1.0);
|
gl_Position = projection_matrix * view_matrix * vec4(origined_position, 1.0);
|
||||||
_color = color;
|
_color = color;
|
||||||
_texture_position = texture_position;
|
_texture_position = texture_position;
|
||||||
|
|
|
@ -25,52 +25,16 @@ int main() {
|
||||||
|
|
||||||
std::vector<Sprite> sprites;
|
std::vector<Sprite> sprites;
|
||||||
|
|
||||||
int limit_x = 10;
|
Sprite sprite(main_renderer);
|
||||||
int limit_y = 10;
|
sprite.bake();
|
||||||
float scale = 0.2;
|
|
||||||
|
|
||||||
for (int i = -limit_x/2; i < limit_x/2; i++) {
|
sprite.origin = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
for (int j = -limit_y/2; j < limit_y/2; j++) {
|
|
||||||
Sprite new_sprite(main_renderer);
|
|
||||||
new_sprite.bake();
|
|
||||||
|
|
||||||
float r = (float) rand() / (float) RAND_MAX;
|
|
||||||
float g = (float) rand() / (float) RAND_MAX;
|
|
||||||
float b = (float) rand() / (float) RAND_MAX;
|
|
||||||
|
|
||||||
new_sprite.color = glm::vec4(r, g, b, 1.0f);
|
|
||||||
new_sprite.origin = glm::vec4(i*scale, j*scale, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
sprites.push_back(new_sprite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window.window)) {
|
while (!glfwWindowShouldClose(window.window)) {
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
for (int i = 0; i < sprites.size(); i++) {
|
sprite.update();
|
||||||
// randomly update their position by little
|
|
||||||
float x = ((float) rand() / (float) RAND_MAX) * 0.5;
|
|
||||||
float y = ((float) rand() / (float) RAND_MAX) * 0.5;
|
|
||||||
|
|
||||||
int x_side = rand() % 2;
|
|
||||||
int y_side = rand() % 2;
|
|
||||||
|
|
||||||
if (x_side == 0)
|
|
||||||
sprites[i].origin.x += x;
|
|
||||||
else
|
|
||||||
sprites[i].origin.x -= x;
|
|
||||||
|
|
||||||
if (y_side == 0)
|
|
||||||
sprites[i].origin.y += y;
|
|
||||||
else
|
|
||||||
sprites[i].origin.y -= y;
|
|
||||||
|
|
||||||
|
|
||||||
sprites[i].update();
|
|
||||||
}
|
|
||||||
|
|
||||||
main_renderer.logic();
|
main_renderer.logic();
|
||||||
main_renderer.batch();
|
main_renderer.batch();
|
||||||
|
|
||||||
|
|
BIN
08-particle-system/.imgs/showcase.png
Normal file
BIN
08-particle-system/.imgs/showcase.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
28
08-particle-system/Makefile
Normal file
28
08-particle-system/Makefile
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
CC=g++
|
||||||
|
CFLAGS=-std=c++20 `pkg-config --cflags glfw3 glew glm`
|
||||||
|
LDFLAGS=`pkg-config --libs glfw3 glew glm`
|
||||||
|
TARGET=boilerplate
|
||||||
|
SDIR=src
|
||||||
|
ADIR=assets
|
||||||
|
ODIR=build
|
||||||
|
|
||||||
|
SRC=$(shell find $(SDIR) -type f -name *.cpp)
|
||||||
|
OBJ=$(SRC:.cpp=.o)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: default
|
||||||
|
$(TARGET): $(OBJ)
|
||||||
|
mkdir -p build
|
||||||
|
cp -rf $(ADIR) $(ODIR)/
|
||||||
|
$(CC) -o $(ODIR)/$@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CC) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
run:
|
||||||
|
$(ODIR)/$(TARGET)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f $(ODIR)/$(TARGET) $(OBJ)
|
10
08-particle-system/README.md
Normal file
10
08-particle-system/README.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src=".imgs/showcase.png" width="300" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Particle System OpenGL
|
||||||
|
|
||||||
|
Contains a particle system abstraction on top of the previous OpenGL boilerplate code (`07-boilerplate`).
|
||||||
|
|
||||||
|
Each particle system is supposed (although not necessary) to have 1 renderer fully for itself.
|
||||||
|
Meaning that all the particles will be batched into 1 draw call.
|
BIN
08-particle-system/assets/brick.jpg
Normal file
BIN
08-particle-system/assets/brick.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 MiB |
BIN
08-particle-system/assets/particle.png
Normal file
BIN
08-particle-system/assets/particle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
08-particle-system/assets/player/idle.png
Normal file
BIN
08-particle-system/assets/player/idle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
08-particle-system/assets/player/run.png
Normal file
BIN
08-particle-system/assets/player/run.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
12
08-particle-system/assets/shaders/default_fragment.glsl
Normal file
12
08-particle-system/assets/shaders/default_fragment.glsl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
in vec4 _color;
|
||||||
|
in vec2 _texture_position;
|
||||||
|
in float _ctt;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = texture(sampler, _texture_position) * (_color * _ctt);
|
||||||
|
}
|
26
08-particle-system/assets/shaders/default_vertex.glsl
Normal file
26
08-particle-system/assets/shaders/default_vertex.glsl
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec4 position;
|
||||||
|
layout (location = 1) in vec4 origin;
|
||||||
|
layout (location = 2) in vec4 size;
|
||||||
|
layout (location = 3) in vec4 color;
|
||||||
|
layout (location = 4) in vec2 texture_position;
|
||||||
|
layout (location = 5) in float ctt;
|
||||||
|
|
||||||
|
uniform mat4 view_matrix;
|
||||||
|
uniform mat4 projection_matrix;
|
||||||
|
|
||||||
|
out vec4 _color;
|
||||||
|
out vec2 _texture_position;
|
||||||
|
out float _ctt;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 origined_position = origin.xyz + position.xyz;
|
||||||
|
|
||||||
|
origined_position *= size.xyz;
|
||||||
|
|
||||||
|
gl_Position = projection_matrix * view_matrix * vec4(origined_position, 1.0);
|
||||||
|
_color = color;
|
||||||
|
_texture_position = texture_position;
|
||||||
|
_ctt = ctt;
|
||||||
|
}
|
13
08-particle-system/assets/shaders/fragment.glsl
Normal file
13
08-particle-system/assets/shaders/fragment.glsl
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 color;
|
||||||
|
in vec2 tex_coord;
|
||||||
|
|
||||||
|
uniform sampler2D sampler;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = texture(sampler, tex_coord);
|
||||||
|
// color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
if (color.a < 0.1)
|
||||||
|
discard;
|
||||||
|
}
|
14
08-particle-system/assets/shaders/vertex.glsl
Normal file
14
08-particle-system/assets/shaders/vertex.glsl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 pos;
|
||||||
|
layout (location = 1) in vec2 texture_coord;
|
||||||
|
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
out vec2 tex_coord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * view * vec4(pos.xyz, 1.0);
|
||||||
|
tex_coord = texture_coord;
|
||||||
|
}
|
BIN
08-particle-system/assets/smoke.png
Normal file
BIN
08-particle-system/assets/smoke.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
BIN
08-particle-system/boilerplate.trace
Normal file
BIN
08-particle-system/boilerplate.trace
Normal file
Binary file not shown.
22
08-particle-system/src/base/common.cpp
Normal file
22
08-particle-system/src/base/common.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
std::string read_file(const char *path) {
|
||||||
|
std::string content;
|
||||||
|
std::ifstream fs(path, std::ios::in);
|
||||||
|
|
||||||
|
if(!fs.is_open()) {
|
||||||
|
std::cerr << "Error: Could not read file " << path << ". File does not exist." << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line = "";
|
||||||
|
while(!fs.eof()) {
|
||||||
|
std::getline(fs, line);
|
||||||
|
content.append(line + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.close();
|
||||||
|
return content;
|
||||||
|
}
|
5
08-particle-system/src/base/common.hpp
Normal file
5
08-particle-system/src/base/common.hpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string read_file(const char *path);
|
0
08-particle-system/src/base/force/force.cpp
Normal file
0
08-particle-system/src/base/force/force.cpp
Normal file
2
08-particle-system/src/base/force/force.hpp
Normal file
2
08-particle-system/src/base/force/force.hpp
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#pragma once
|
||||||
|
|
11
08-particle-system/src/base/graphics/graphics.hpp
Normal file
11
08-particle-system/src/base/graphics/graphics.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define DEFAULT_POSITION_ATTRIBUTE 0
|
||||||
|
#define DEFAULT_ORIGIN_ATTRIBUTE 1
|
||||||
|
#define DEFAULT_SIZE_ATTRIBUTE 2
|
||||||
|
#define DEFAULT_COLOR_ATTRIBUTE 3
|
||||||
|
#define DEFAULT_TEXTURE_ATTRIBUTE 4
|
||||||
|
#define DEFAULT_CTT_ATTRIBUTE 5
|
||||||
|
|
||||||
|
#define QUAD 6
|
||||||
|
#define DEFAULT_VBO_SIZE QUAD * 1000000 // unit: rows of RenderData
|
38
08-particle-system/src/base/graphics/program.cpp
Normal file
38
08-particle-system/src/base/graphics/program.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "program.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
|
||||||
|
Program::Program() {
|
||||||
|
this->id = glCreateProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Program::add_shader(const char *path, unsigned int type) {
|
||||||
|
Shader new_shader;
|
||||||
|
unsigned int ret = new_shader.load(path, type);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return RET_ERR;
|
||||||
|
|
||||||
|
this->shaders.push_back(new_shader);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Program::link() {
|
||||||
|
for (int shader = 0; shader < this->shaders.size(); shader++)
|
||||||
|
glAttachShader(this->id, this->shaders[shader].id);
|
||||||
|
|
||||||
|
glLinkProgram(this->id);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char info_log[512];
|
||||||
|
glGetProgramiv(this->id, GL_LINK_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
glGetProgramInfoLog(this->id, 512, NULL, info_log);
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
14
08-particle-system/src/base/graphics/program.hpp
Normal file
14
08-particle-system/src/base/graphics/program.hpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "shader.hpp"
|
||||||
|
|
||||||
|
struct Program {
|
||||||
|
GLuint id;
|
||||||
|
std::vector<Shader> shaders;
|
||||||
|
|
||||||
|
Program();
|
||||||
|
int add_shader(const char *path, unsigned int type);
|
||||||
|
int link();
|
||||||
|
};
|
206
08-particle-system/src/base/graphics/renderer.cpp
Normal file
206
08-particle-system/src/base/graphics/renderer.cpp
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
#include <optional>
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
|
#include <glm/mat4x4.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include "../../other/stb_image.h"
|
||||||
|
#include "renderer.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
#include "graphics.hpp"
|
||||||
|
|
||||||
|
Renderer::Renderer(Window &window) : window(window) {
|
||||||
|
this->batch_buffer = std::vector<struct RendererData>();
|
||||||
|
this->window = window;
|
||||||
|
|
||||||
|
glGenBuffers(1, &this->vertex_buffer_id);
|
||||||
|
glGenVertexArrays(1, &this->array_buffer_id);
|
||||||
|
glGenTextures(1, &this->texture_id);
|
||||||
|
|
||||||
|
this->view_matrix = glm::mat4(1.0f);
|
||||||
|
this->projection_matrix = glm::mat4(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Renderer::setup_attributes() {
|
||||||
|
glVertexAttribPointer(
|
||||||
|
DEFAULT_POSITION_ATTRIBUTE,
|
||||||
|
4,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(struct RendererData),
|
||||||
|
(void *) offsetof(RendererData, vertex)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(DEFAULT_POSITION_ATTRIBUTE);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
DEFAULT_ORIGIN_ATTRIBUTE,
|
||||||
|
4,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(struct RendererData),
|
||||||
|
(void *) offsetof(RendererData, origin)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(DEFAULT_ORIGIN_ATTRIBUTE);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
DEFAULT_SIZE_ATTRIBUTE,
|
||||||
|
4,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(struct RendererData),
|
||||||
|
(void *) offsetof(RendererData, size)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(DEFAULT_SIZE_ATTRIBUTE);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
DEFAULT_COLOR_ATTRIBUTE,
|
||||||
|
4,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(struct RendererData),
|
||||||
|
(void *) offsetof(RendererData, color)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(DEFAULT_COLOR_ATTRIBUTE);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
DEFAULT_TEXTURE_ATTRIBUTE,
|
||||||
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(struct RendererData),
|
||||||
|
(void *) offsetof(RendererData, tex)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(DEFAULT_TEXTURE_ATTRIBUTE);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
DEFAULT_CTT_ATTRIBUTE,
|
||||||
|
1,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(struct RendererData),
|
||||||
|
(void *) offsetof(RendererData, ctt_ratio)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(DEFAULT_CTT_ATTRIBUTE);
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Renderer::setup(std::optional<Program> program) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (program != std::nullopt)
|
||||||
|
this->program = program.value();
|
||||||
|
else {
|
||||||
|
Program new_program = Program();
|
||||||
|
|
||||||
|
ret = new_program.add_shader("assets/shaders/default_vertex.glsl", GL_VERTEX_SHADER);
|
||||||
|
if (ret != RET_OK) {
|
||||||
|
LOG(LOG_ERR, "Failed adding vertex shader to program");
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new_program.add_shader("assets/shaders/default_fragment.glsl", GL_FRAGMENT_SHADER);
|
||||||
|
if (ret != RET_OK) {
|
||||||
|
LOG(LOG_ERR, "Failed adding fragment shader to program");
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = new_program.link();
|
||||||
|
if (ret != RET_OK) {
|
||||||
|
LOG(LOG_ERR, "Failed linking program");
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->program = new_program;
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::blend();
|
||||||
|
|
||||||
|
glBindVertexArray(this->array_buffer_id);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer_id);
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(struct RendererData) * DEFAULT_VBO_SIZE, nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
setup_attributes();
|
||||||
|
|
||||||
|
// setup matrices
|
||||||
|
this->view_matrix = glm::translate(this->view_matrix, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||||
|
|
||||||
|
// setup textures
|
||||||
|
glBindTexture(GL_TEXTURE_2D, this->texture_id);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Renderer::load_texture(std::string location, GLenum format) {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int channels;
|
||||||
|
|
||||||
|
unsigned char *data = stbi_load(location.c_str(), &width, &height, &channels, 0);
|
||||||
|
if (!data)
|
||||||
|
return RET_ERR;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, this->texture_id);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
stbi_image_free(data);
|
||||||
|
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::draw(struct RendererData data) {
|
||||||
|
if (batch_buffer.size() >= DEFAULT_VBO_SIZE) {
|
||||||
|
LOG(LOG_WARN, "Batch buffer limit reached!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
batch_buffer.push_back(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::batch() {
|
||||||
|
glUseProgram(this->program.id);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(this->program.id, "view_matrix"), 1, GL_FALSE, &this->view_matrix[0][0]);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(this->program.id, "projection_matrix"), 1, GL_FALSE, &this->projection_matrix[0][0]);
|
||||||
|
glUniform1i(glGetUniformLocation(this->program.id, "sampler"), 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, this->texture_id);
|
||||||
|
|
||||||
|
glBindVertexArray(this->array_buffer_id);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer_id);
|
||||||
|
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, batch_buffer.size() * sizeof(struct RendererData), batch_buffer.data());
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, DEFAULT_VBO_SIZE);
|
||||||
|
|
||||||
|
batch_buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::logic() {
|
||||||
|
int window_width;
|
||||||
|
int window_height;
|
||||||
|
float half_width;
|
||||||
|
float half_height;
|
||||||
|
|
||||||
|
this->window.get_size(&window_width, &window_height);
|
||||||
|
|
||||||
|
half_width = window_width / 2.0f;
|
||||||
|
half_height = window_height / 2.0f;
|
||||||
|
|
||||||
|
this->projection_matrix = glm::ortho(-half_width/100, half_width/100, -half_height/100, half_height/100, 0.1f, 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::~Renderer() {
|
||||||
|
glDisableVertexAttribArray(DEFAULT_POSITION_ATTRIBUTE);
|
||||||
|
glDisableVertexAttribArray(DEFAULT_COLOR_ATTRIBUTE);
|
||||||
|
glDisableVertexAttribArray(DEFAULT_TEXTURE_ATTRIBUTE);
|
||||||
|
glDisableVertexAttribArray(DEFAULT_CTT_ATTRIBUTE);
|
||||||
|
}
|
52
08-particle-system/src/base/graphics/renderer.hpp
Normal file
52
08-particle-system/src/base/graphics/renderer.hpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <optional>
|
||||||
|
#include <glm/mat4x4.hpp>
|
||||||
|
#include "program.hpp"
|
||||||
|
#include "../window/window.hpp"
|
||||||
|
|
||||||
|
struct RendererData {
|
||||||
|
glm::vec4 vertex;
|
||||||
|
glm::vec4 origin;
|
||||||
|
glm::vec4 size;
|
||||||
|
glm::vec4 color;
|
||||||
|
glm::vec2 tex;
|
||||||
|
float ctt_ratio; // color to texture ratio (i.e. how much does the collor affect the texture)
|
||||||
|
};
|
||||||
|
|
||||||
|
class Renderer {
|
||||||
|
public:
|
||||||
|
Renderer(Window &window);
|
||||||
|
~Renderer();
|
||||||
|
|
||||||
|
int setup_attributes();
|
||||||
|
int setup(std::optional<Program> program = std::nullopt);
|
||||||
|
void logic();
|
||||||
|
|
||||||
|
int load_texture(std::string location, GLenum format);
|
||||||
|
void draw(struct RendererData data);
|
||||||
|
void batch();
|
||||||
|
|
||||||
|
inline static void blend() {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
inline static void clear(glm::vec4 color) {
|
||||||
|
glClearColor(color.r, color.g, color.b, color.a);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<struct RendererData> batch_buffer;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint array_buffer_id;
|
||||||
|
GLuint vertex_buffer_id;
|
||||||
|
GLuint texture_id;
|
||||||
|
|
||||||
|
glm::mat4 view_matrix;
|
||||||
|
glm::mat4 projection_matrix;
|
||||||
|
|
||||||
|
Window &window;
|
||||||
|
Program program;
|
||||||
|
};
|
33
08-particle-system/src/base/graphics/shader.cpp
Normal file
33
08-particle-system/src/base/graphics/shader.cpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "shader.hpp"
|
||||||
|
#include "../common.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
|
||||||
|
unsigned int Shader::load(const char *path, unsigned int type) {
|
||||||
|
std::string source_s = read_file(path);
|
||||||
|
const char *source = source_s.c_str();
|
||||||
|
|
||||||
|
unsigned int new_shader = glCreateShader(type);
|
||||||
|
if (!new_shader)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
glShaderSource(new_shader, 1, &source, NULL);
|
||||||
|
glCompileShader(new_shader);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char info_log[512];
|
||||||
|
glGetShaderiv(new_shader, GL_COMPILE_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
glGetShaderInfoLog(new_shader, 512, NULL, info_log);
|
||||||
|
std::cout << "Error: failed compiling new shader " << info_log << std::endl;
|
||||||
|
LOG(LOG_ERR, "Failed compiling new shader");
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->id = new_shader;
|
||||||
|
this->type = type;
|
||||||
|
|
||||||
|
return new_shader;
|
||||||
|
}
|
8
08-particle-system/src/base/graphics/shader.hpp
Normal file
8
08-particle-system/src/base/graphics/shader.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct Shader {
|
||||||
|
unsigned int id;
|
||||||
|
unsigned int type;
|
||||||
|
|
||||||
|
unsigned int load(const char *path, unsigned int type);
|
||||||
|
};
|
12
08-particle-system/src/base/macros.hpp
Normal file
12
08-particle-system/src/base/macros.hpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define LOG_DEBUG "debug"
|
||||||
|
#define LOG_WARN "warning"
|
||||||
|
#define LOG_ERR "error"
|
||||||
|
|
||||||
|
#define LOG(level, ...) std::cout << "[" << __TIME__ << " " << level << "]: " << __VA_ARGS__ << std::endl;
|
||||||
|
|
||||||
|
#define RET_OK 0
|
||||||
|
#define RET_ERR -1
|
38
08-particle-system/src/base/particle-system/fog-system.cpp
Normal file
38
08-particle-system/src/base/particle-system/fog-system.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
#include "particle-system.hpp"
|
||||||
|
#include "fog-system.hpp"
|
||||||
|
|
||||||
|
extern glm::vec4 generate_origin(Rectangle rect);
|
||||||
|
extern float randomize();
|
||||||
|
|
||||||
|
void FogSystem::logic() {
|
||||||
|
for (int i = 0; i < this->particles.size(); i++) {
|
||||||
|
Particle &particle = this->particles[i];
|
||||||
|
Sprite &sprite = particle.sprite;
|
||||||
|
|
||||||
|
sprite.origin += particle.force * this->speed;
|
||||||
|
particle.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (int) this->data.spawn_rate; i++)
|
||||||
|
this->spawn_particle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FogSystem::spawn_particle() {
|
||||||
|
glm::vec4 new_force = this->data.default_force;
|
||||||
|
new_force.x = (randomize() - 0.5f) * 0.02f;
|
||||||
|
new_force.y = randomize() * new_force.y;
|
||||||
|
|
||||||
|
Particle new_particle(this->renderer, new_force);
|
||||||
|
|
||||||
|
glm::vec4 new_origin = generate_origin(this->data.spawn_area);
|
||||||
|
|
||||||
|
new_particle.sprite.origin = new_origin;
|
||||||
|
new_particle.sprite.size = this->data.default_size;
|
||||||
|
new_particle.sprite.color = this->data.default_color;
|
||||||
|
|
||||||
|
this->particles.push_back(new_particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
FogSystem::~FogSystem() {
|
||||||
|
}
|
18
08-particle-system/src/base/particle-system/fog-system.hpp
Normal file
18
08-particle-system/src/base/particle-system/fog-system.hpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "particle-system.hpp"
|
||||||
|
|
||||||
|
class FogSystem : public ParticleSystem {
|
||||||
|
public:
|
||||||
|
FogSystem(Renderer &renderer, struct ParticleSystemData data) : ParticleSystem(renderer, data) {}
|
||||||
|
~FogSystem();
|
||||||
|
|
||||||
|
void logic();
|
||||||
|
void spawn_particle();
|
||||||
|
inline void set_speed(float new_speed) {
|
||||||
|
this->speed = new_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
float speed = 1.0f;
|
||||||
|
};
|
|
@ -0,0 +1,56 @@
|
||||||
|
|
||||||
|
#include "particle-system.hpp"
|
||||||
|
|
||||||
|
float randomize() {
|
||||||
|
return (float) rand() / (float) RAND_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleSystem::ParticleSystem(Renderer& renderer, struct ParticleSystemData data) : renderer(renderer) {
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ParticleSystem::setup() {
|
||||||
|
int ret = this->renderer.load_texture(this->data.default_texture, GL_RGBA);
|
||||||
|
if (ret != RET_OK)
|
||||||
|
return RET_ERR;
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::logic() {
|
||||||
|
for (int i = 0; i < this->particles.size(); i++) {
|
||||||
|
Particle &particle = this->particles[i];
|
||||||
|
Sprite &sprite = particle.sprite;
|
||||||
|
|
||||||
|
sprite.origin += particle.force;
|
||||||
|
particle.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < (int) this->data.spawn_rate; i++)
|
||||||
|
this->spawn_particle();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec4 generate_origin(Rectangle rect) {
|
||||||
|
glm::vec4 new_origin = glm::vec4(0.0f);
|
||||||
|
|
||||||
|
new_origin.x = rect.x + (randomize() * rect.width);
|
||||||
|
new_origin.y = rect.y + (randomize() * rect.height);
|
||||||
|
|
||||||
|
return new_origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::spawn_particle() {
|
||||||
|
Particle new_particle(this->renderer, this->data.default_force);
|
||||||
|
|
||||||
|
glm::vec4 new_origin = generate_origin(this->data.spawn_area);
|
||||||
|
|
||||||
|
new_particle.sprite.origin = new_origin;
|
||||||
|
new_particle.sprite.size = this->data.default_size;
|
||||||
|
new_particle.sprite.color = this->data.default_color;
|
||||||
|
|
||||||
|
this->particles.push_back(new_particle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleSystem::~ParticleSystem() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include "../graphics/renderer.hpp"
|
||||||
|
#include "../sprite/sprite.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
|
||||||
|
class Particle {
|
||||||
|
public:
|
||||||
|
Particle(Renderer &renderer, glm::vec4 force);
|
||||||
|
~Particle();
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
Sprite sprite;
|
||||||
|
glm::vec4 force;
|
||||||
|
float time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Rectangle {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParticleSystemData {
|
||||||
|
float spawn_rate; // spawn per call
|
||||||
|
glm::vec4 default_force;
|
||||||
|
glm::vec4 default_color;
|
||||||
|
glm::vec4 default_size;
|
||||||
|
struct Rectangle spawn_area;
|
||||||
|
std::string default_texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ParticleSystem {
|
||||||
|
public:
|
||||||
|
ParticleSystem(Renderer &renderer, struct ParticleSystemData data);
|
||||||
|
~ParticleSystem();
|
||||||
|
|
||||||
|
int setup();
|
||||||
|
virtual void logic();
|
||||||
|
virtual void spawn_particle();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Renderer &renderer;
|
||||||
|
struct ParticleSystemData data;
|
||||||
|
std::vector<Particle> particles;
|
||||||
|
};
|
16
08-particle-system/src/base/particle-system/particle.cpp
Normal file
16
08-particle-system/src/base/particle-system/particle.cpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#include "particle-system.hpp"
|
||||||
|
|
||||||
|
Particle::Particle(Renderer &renderer, glm::vec4 force = glm::vec4(0.0f)) : sprite(renderer) {
|
||||||
|
this->force = force;
|
||||||
|
this->sprite.bake();
|
||||||
|
this->time = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Particle::update() {
|
||||||
|
this->time += 0.0001f;
|
||||||
|
this->sprite.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Particle::~Particle() {
|
||||||
|
|
||||||
|
}
|
55
08-particle-system/src/base/sprite/sprite.cpp
Normal file
55
08-particle-system/src/base/sprite/sprite.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "../graphics/renderer.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
#include "sprite.hpp"
|
||||||
|
|
||||||
|
Sprite::Sprite(Renderer &renderer) : renderer(renderer) {
|
||||||
|
this->vertices = std::vector<glm::vec4>();
|
||||||
|
this->texture_positions = std::vector<glm::vec2>();
|
||||||
|
this->origin = glm::vec4(0.0f);
|
||||||
|
this->size = glm::vec4(1.0f);
|
||||||
|
this->color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
this->ctt = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare data
|
||||||
|
void Sprite::bake() {
|
||||||
|
this->vertices.push_back(glm::vec4(0.5f, 0.5f, 0.0f, 0.0f));
|
||||||
|
this->vertices.push_back(glm::vec4(0.5f, -0.5f, 0.0f, 0.0f));
|
||||||
|
this->vertices.push_back(glm::vec4(-0.5f, -0.5f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
this->vertices.push_back(glm::vec4(-0.5f, 0.5f, 0.0f, 0.0f));
|
||||||
|
this->vertices.push_back(glm::vec4(0.5f, 0.5f, 0.0f, 0.0f));
|
||||||
|
this->vertices.push_back(glm::vec4(-0.5f, -0.5f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
this->texture_positions.push_back(glm::vec2(1.0f, 1.0f));
|
||||||
|
this->texture_positions.push_back(glm::vec2(1.0f, 0.0f));
|
||||||
|
this->texture_positions.push_back(glm::vec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
this->texture_positions.push_back(glm::vec2(0.0f, 1.0f));
|
||||||
|
this->texture_positions.push_back(glm::vec2(1.0f, 1.0f));
|
||||||
|
this->texture_positions.push_back(glm::vec2(0.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::update() {
|
||||||
|
for (int i = 0; i < this->vertices.size(); i++) {
|
||||||
|
struct RendererData data = {
|
||||||
|
.vertex = this->vertices[i],
|
||||||
|
.origin = this->origin,
|
||||||
|
.size = this->size,
|
||||||
|
.color = this->color,
|
||||||
|
.tex = this->texture_positions[i],
|
||||||
|
.ctt_ratio = this->ctt
|
||||||
|
};
|
||||||
|
|
||||||
|
this->renderer.draw(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sprite::~Sprite() {
|
||||||
|
|
||||||
|
}
|
27
08-particle-system/src/base/sprite/sprite.hpp
Normal file
27
08-particle-system/src/base/sprite/sprite.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "../graphics/renderer.hpp"
|
||||||
|
|
||||||
|
class Sprite {
|
||||||
|
public:
|
||||||
|
Sprite(Renderer &renderer);
|
||||||
|
~Sprite();
|
||||||
|
|
||||||
|
void bake();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
glm::vec4 origin;
|
||||||
|
glm::vec4 size;
|
||||||
|
glm::vec4 color;
|
||||||
|
float ctt;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<glm::vec4> vertices;
|
||||||
|
std::vector<glm::vec2> texture_positions;
|
||||||
|
Renderer &renderer;
|
||||||
|
};
|
31
08-particle-system/src/base/window/window.cpp
Normal file
31
08-particle-system/src/base/window/window.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "window.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
|
||||||
|
int Window::init(int width, int height, std::string title) {
|
||||||
|
glfwInit();
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
|
this->window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
|
||||||
|
if (this->window == NULL) {
|
||||||
|
LOG(LOG_ERR, "Failed creating window");
|
||||||
|
glfwTerminate();
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(this->window);
|
||||||
|
|
||||||
|
GLenum err = glewInit();
|
||||||
|
if (err != GLEW_OK) {
|
||||||
|
LOG(LOG_ERR, "FAiled initializing Glew");
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwSetFramebufferSizeCallback(this->window, this->resize_callback);
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
30
08-particle-system/src/base/window/window.hpp
Normal file
30
08-particle-system/src/base/window/window.hpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
class Window {
|
||||||
|
public:
|
||||||
|
int init(int width, int height, std::string title);
|
||||||
|
|
||||||
|
inline static void resize_callback(GLFWwindow *window, int new_width, int new_height) {
|
||||||
|
glViewport(0, 0, new_width, new_height);
|
||||||
|
}
|
||||||
|
inline void set_keyboard_callback(void (*callback)(GLFWwindow *window, int key, int scancode, int action, int mode)) {
|
||||||
|
glfwSetKeyCallback(this->window, callback);
|
||||||
|
}
|
||||||
|
inline void get_size(int *width, int *height) {
|
||||||
|
glfwGetWindowSize(this->window, width, height);
|
||||||
|
}
|
||||||
|
inline bool should_close() {
|
||||||
|
return glfwWindowShouldClose(this->window);
|
||||||
|
}
|
||||||
|
inline void end_frame() {
|
||||||
|
glfwPollEvents();
|
||||||
|
glfwSwapBuffers(this->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pressed_e = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLFWwindow *window;
|
||||||
|
};
|
85
08-particle-system/src/main.cpp
Normal file
85
08-particle-system/src/main.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <stb/stb_image.h>
|
||||||
|
#include "base/window/window.hpp"
|
||||||
|
#include "base/graphics/renderer.hpp"
|
||||||
|
#include "base/particle-system/particle-system.hpp"
|
||||||
|
#include "base/particle-system/fog-system.hpp"
|
||||||
|
#include "base/macros.hpp"
|
||||||
|
|
||||||
|
const int initial_height = 600;
|
||||||
|
const int initial_width = 1000;
|
||||||
|
Window main_window;
|
||||||
|
|
||||||
|
void _keyboard(GLFWwindow *window, int key, int scancode, int action, int mode) {
|
||||||
|
if (action != GLFW_PRESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case GLFW_KEY_E:
|
||||||
|
LOG(LOG_DEBUG, "PRESSING E!");
|
||||||
|
main_window.pressed_e = !main_window.pressed_e;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = main_window.init(initial_width, initial_height, "OpenGL");
|
||||||
|
if (ret != RET_OK) {
|
||||||
|
LOG(LOG_ERR, "Failed initializing GLFW window");
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
main_window.set_keyboard_callback(_keyboard);
|
||||||
|
|
||||||
|
Renderer main_renderer(main_window);
|
||||||
|
ret = main_renderer.setup();
|
||||||
|
if (ret != RET_OK) {
|
||||||
|
LOG(LOG_ERR, "Failed setting up a new renderer");
|
||||||
|
return RET_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParticleSystemData ps_data = {
|
||||||
|
.spawn_rate = 20,
|
||||||
|
.default_force = glm::vec4(0.0f, 0.1f, 0.0f, 0.0f),
|
||||||
|
.default_color = glm::vec4(0.0f, 0.8f, 0.4f, 0.4f),
|
||||||
|
.default_size = glm::vec4(0.3f, 0.3f, 0.1f, 0.1f),
|
||||||
|
.spawn_area = {
|
||||||
|
.x = -120.0f,
|
||||||
|
.y = -240.0f,
|
||||||
|
.width = 220.0f,
|
||||||
|
.height = 220.0f
|
||||||
|
},
|
||||||
|
.default_texture = "assets/particle.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
FogSystem ps(main_renderer, ps_data);
|
||||||
|
ps.setup();
|
||||||
|
|
||||||
|
while (!main_window.should_close()) {
|
||||||
|
Renderer::clear(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
if (main_window.pressed_e)
|
||||||
|
ps.set_speed(10.0f);
|
||||||
|
else
|
||||||
|
ps.set_speed(1.0f);
|
||||||
|
|
||||||
|
ps.logic();
|
||||||
|
|
||||||
|
main_renderer.logic();
|
||||||
|
main_renderer.batch();
|
||||||
|
|
||||||
|
main_window.end_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
return RET_OK;
|
||||||
|
}
|
2
08-particle-system/src/other/stb_image.cpp
Normal file
2
08-particle-system/src/other/stb_image.cpp
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
7987
08-particle-system/src/other/stb_image.h
Normal file
7987
08-particle-system/src/other/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
22
README.md
22
README.md
|
@ -13,6 +13,28 @@
|
||||||
|
|
||||||
My little playground for everything graphics
|
My little playground for everything graphics
|
||||||
|
|
||||||
|
- `01-introduction`: SDL introduction (texture loading, player movement)
|
||||||
|
- `02-jumping`: jumping in SDL (animations, jumping)
|
||||||
|
- `03-network`: connection handling + server side calculations in SDL (client, server)
|
||||||
|
- `04-map`: map generation testing for SDL
|
||||||
|
- `05-opengl`: OpenGL introduction (texture loading)
|
||||||
|
- `06-monogame`: Monogame introduction tests
|
||||||
|
- `07-boilerplate`: Boilerplate OpenGL abstraction (batch rendering)
|
||||||
|
- `08-particle-system`: Expanding OpenGL boilerplate for particle systems + texture loading
|
||||||
|
|
||||||
|
## Goal Experiments
|
||||||
|
|
||||||
|
- [x] OpenGL boilerplate
|
||||||
|
- [x] Particle Systems
|
||||||
|
- [ ] Basic physics
|
||||||
|
- [ ] Effects
|
||||||
|
- [ ] Bloom
|
||||||
|
- [ ] Blur
|
||||||
|
- [ ] Sound
|
||||||
|
- [ ] Multiplayer
|
||||||
|
- [ ] Procedural map generation
|
||||||
|
- [ ] Super Mario movement
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
The code is licensed under the GPL-3.0 license. See the `LICENSE` file for more information
|
The code is licensed under the GPL-3.0 license. See the `LICENSE` file for more information
|
||||||
|
|
Loading…
Reference in New Issue
Block a user