|
|
@@ -0,0 +1,182 @@
|
|
|
+/* std */
|
|
|
+#include <iostream>
|
|
|
+#include <vector>
|
|
|
+#include <string>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <cmath>
|
|
|
+
|
|
|
+/* OpenGL */
|
|
|
+#include "glad/glad.h"
|
|
|
+#include <GLFW/glfw3.h>
|
|
|
+
|
|
|
+/* Project classes */
|
|
|
+#include "Helper.hpp"
|
|
|
+#include "Config.hpp"
|
|
|
+#include "Cell.hpp"
|
|
|
+#include "Particle.hpp"
|
|
|
+#include "ComputeShader.hpp"
|
|
|
+#include "Application.hpp"
|
|
|
+#include "Buffer.hpp"
|
|
|
+#include "Canvas.hpp"
|
|
|
+
|
|
|
+constexpr float deg_to_rad = (float) (3.141592653589793 / 180.0);
|
|
|
+
|
|
|
+int main(int argc, char *argv[]){
|
|
|
+ srand(0);
|
|
|
+ std::string filename;
|
|
|
+ Application app;
|
|
|
+ Config config;
|
|
|
+ ComputeShader cs_particles_update;
|
|
|
+ ComputeShader cs_map_update;
|
|
|
+ ComputeShader cs_map_reset;
|
|
|
+ ComputeShader cs_draw;
|
|
|
+ Buffer particles_buffer;
|
|
|
+ Buffer map_buffer;
|
|
|
+ Canvas canvas;
|
|
|
+
|
|
|
+ config = {
|
|
|
+ .map_width=800,
|
|
|
+ .map_height=600,
|
|
|
+
|
|
|
+ .population=100,
|
|
|
+
|
|
|
+ .increase=10.0f,
|
|
|
+ .decay=5.0f,
|
|
|
+ .diffusion=2.0f,
|
|
|
+
|
|
|
+ .speed=0.5f,
|
|
|
+ .steering=90.0f * deg_to_rad,
|
|
|
+ .sensing_distance=1.0f,
|
|
|
+ .sensing_angle=60.0f * deg_to_rad,
|
|
|
+ };
|
|
|
+ float average_population = (float)config.population / (float)(config.map_width * config.map_height);
|
|
|
+ float average_pheromone = (float)config.increase * average_population;
|
|
|
+
|
|
|
+ printf("Avg pop %08f - Avg phe %08f\n", average_population, average_pheromone);
|
|
|
+
|
|
|
+ app = Application(config.map_width, config.map_height);
|
|
|
+ app.init();
|
|
|
+ app.createWindow();
|
|
|
+
|
|
|
+ /* Load and compile particles update shader */
|
|
|
+ cs_particles_update.load("./shaders/particles_update.glsl");
|
|
|
+ cs_particles_update.compile();
|
|
|
+ particle_uniform(config, cs_particles_update);
|
|
|
+
|
|
|
+ /* Load and compile map update shader */
|
|
|
+ cs_map_update.load("./shaders/map_update.glsl");
|
|
|
+ cs_map_update.compile();
|
|
|
+ map_update_uniform(config, cs_map_update);
|
|
|
+
|
|
|
+ /* Load and compile map reset shader */
|
|
|
+ cs_map_reset.load("./shaders/map_reset.glsl");
|
|
|
+ cs_map_reset.compile();
|
|
|
+ map_reset_uniform(config, cs_map_reset);
|
|
|
+
|
|
|
+ /* Load and compile draw shader */
|
|
|
+ cs_draw.load("./shaders/draw.glsl");
|
|
|
+ cs_draw.compile();
|
|
|
+ cs_draw.set_uniform("map_width", config.map_width);
|
|
|
+ cs_draw.set_uniform("map_height", config.map_height);
|
|
|
+
|
|
|
+ /* Particles init */
|
|
|
+ std::vector<Particle> particles(config.population);
|
|
|
+ for(auto &particle : particles){
|
|
|
+ particle.pos_x = random_float(0.0f, config.map_width);
|
|
|
+ particle.pos_y = random_float(0.0f, config.map_height);
|
|
|
+
|
|
|
+ float angle = random_float(0, 360) * deg_to_rad;
|
|
|
+ particle.dir_x = cosf(angle);
|
|
|
+ particle.dir_y = sinf(angle);
|
|
|
+ }
|
|
|
+ particles[0].pos_x = 0.5;
|
|
|
+ particles[0].pos_y = 0.5;
|
|
|
+ particles[0].dir_x = 1;
|
|
|
+ particles[0].dir_y = 0;
|
|
|
+ printf("Bob %f, %f\n", particles[0].pos_x, particles[0].pos_y);
|
|
|
+
|
|
|
+ /* Create and fill particles buffer */
|
|
|
+ particles_buffer.create();
|
|
|
+ particles_buffer.set(particles.data(), particles.size(), sizeof(particles[0]));
|
|
|
+
|
|
|
+ /* Map init */
|
|
|
+ std::vector<Cell> map(config.map_width * config.map_height);
|
|
|
+ for(auto &cell : map){
|
|
|
+ cell = {
|
|
|
+ .pheromone = 0,
|
|
|
+ .result = 0,
|
|
|
+ .population = 0,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Create and fill map buffer */
|
|
|
+ map_buffer.create();
|
|
|
+ map_buffer.set(map.data(), map.size(), sizeof(map[0]));
|
|
|
+
|
|
|
+ /* Create Canvas */
|
|
|
+ canvas = Canvas(config.map_width, config.map_width);
|
|
|
+ canvas.create();
|
|
|
+
|
|
|
+ /* Bind buffers to compute shaders */
|
|
|
+ particles_buffer.bind_base(cs_particles_update.get_program(), "particles_buffer", 1);
|
|
|
+ map_buffer.bind_base(cs_particles_update.get_program(), "map_buffer", 2);
|
|
|
+
|
|
|
+ map_buffer.bind_base(cs_map_update.get_program(), "map_buffer", 2);
|
|
|
+
|
|
|
+ particles_buffer.bind_base(cs_draw.get_program(), "particles_buffer", 1);
|
|
|
+ map_buffer.bind_base(cs_draw.get_program(), "map_buffer", 2);
|
|
|
+
|
|
|
+ map_buffer.bind_base(cs_map_reset.get_program(), "map_buffer", 2);
|
|
|
+
|
|
|
+ /* Main loop */
|
|
|
+ float pervious_time;
|
|
|
+ float current_time = app.time();
|
|
|
+ while(app.running()){
|
|
|
+ pervious_time = current_time;
|
|
|
+ current_time = app.time();
|
|
|
+
|
|
|
+ float dt = current_time - pervious_time;
|
|
|
+ // printf("[% 6f]\n", dt * 1000);
|
|
|
+
|
|
|
+ /* Update particles */
|
|
|
+ cs_particles_update.set_uniform("dt", dt);
|
|
|
+ cs_particles_update.execute(config.population, 256);
|
|
|
+ ComputeShader::wait();
|
|
|
+
|
|
|
+ /* Update map */
|
|
|
+ cs_map_update.set_uniform("dt", dt);
|
|
|
+ cs_map_update.execute(config.map_width, config.map_height, 16, 16);
|
|
|
+ ComputeShader::wait();
|
|
|
+ // Particle bob;
|
|
|
+ // particles_buffer.get(&bob, 1, sizeof(bob));
|
|
|
+ // size_t i = floor(bob.pos_y) * config.map_width + floor(bob.pos_x);
|
|
|
+ // map_buffer.get(map.data(), i+1, sizeof(map[0]));
|
|
|
+ // ComputeShader::wait();
|
|
|
+ // printf("Bob[%6f,%6f], Map[%ld] = {.pop=%d,.phe=%f}\n",
|
|
|
+ // bob.pos_x, bob.pos_y, i, map[i].population, map[i].pheromone);
|
|
|
+
|
|
|
+
|
|
|
+ /* Draw map */
|
|
|
+ cs_draw.activate();
|
|
|
+ canvas.bind();
|
|
|
+ cs_draw.execute(config.map_width, config.map_height, 16, 16);
|
|
|
+ ComputeShader::wait();
|
|
|
+ cs_draw.set_uniform("display_population_value", 10*average_population);
|
|
|
+ cs_draw.set_uniform("display_pheromone_value", 1000*average_pheromone);
|
|
|
+ canvas.draw();
|
|
|
+
|
|
|
+ app.update();
|
|
|
+
|
|
|
+ /* Reset map */
|
|
|
+ cs_map_reset.execute(config.population, 256);
|
|
|
+ ComputeShader::wait();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ cs_particles_update.release();
|
|
|
+ particles_buffer.release();
|
|
|
+
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|