/* std */ #include #include #include #include #include #include /* OpenGL */ #include "glad/glad.h" #include /* 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=1500, .map_height=1200, .population=5000000, .increase=10.0f, .decay=0.5f, .diffusion=5.0f, .speed=60.0f, .steering=180.0f * deg_to_rad, .sensing_distance=3.0f, .sensing_angle=45.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.create_window(); /* Load and compile particles update shader */ cs_particles_update.load("./shaders/particles_update.glsl"); cs_particles_update.compile(); /* Load and compile map update shader */ cs_map_update.load("./shaders/map_update.glsl"); cs_map_update.compile(); /* Load and compile map reset shader */ cs_map_reset.load("./shaders/map_reset.glsl"); cs_map_reset.compile(); /* Load and compile draw shader */ cs_draw.load("./shaders/draw.glsl"); cs_draw.compile(); /* Particles init */ std::vector 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); } /* Create and fill particles buffer */ particles_buffer.create(); particles_buffer.set(particles.data(), particles.size(), sizeof(particles[0])); /* Map init */ std::vector 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(); int key_previous_status; int key_current_status = GLFW_RELEASE; while(app.running()){ pervious_time = current_time; current_time = app.time(); float dt = current_time - pervious_time; /* Update uniforms */ particle_uniform(config, cs_particles_update); map_update_uniform(config, cs_map_update); map_reset_uniform(config, cs_map_reset); cs_draw.set_uniform("map_width", config.map_width); cs_draw.set_uniform("map_height", config.map_height); cs_draw.set_uniform("display_population_value", average_population); cs_draw.set_uniform("display_pheromone_value", average_pheromone); /* 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(); canvas.draw(); /* Reset map */ cs_map_reset.execute(config.map_width * config.map_height, 256); ComputeShader::wait(); /* Display, move on */ app.update(); key_previous_status = key_current_status; key_current_status = app.key_status(GLFW_KEY_R); if(key_current_status != key_previous_status && key_current_status == GLFW_RELEASE){ printf("Reloading draw Shader\n"); cs_draw.load("./shaders/draw.glsl"); cs_draw.compile(); particles_buffer.bind_base(cs_draw.get_program(), "particles_buffer", 1); map_buffer.bind_base(cs_draw.get_program(), "map_buffer", 2); } } cs_particles_update.release(); particles_buffer.release(); return 0; }