Charles Croz 1 an în urmă
părinte
comite
e2bfbea48c

+ 1 - 1
CppGPU/Makefile

@@ -1,6 +1,6 @@
 
 APP=particle
-OBJ=./src/main.o ./src/ComputeShader.o ./src/Application.o ./src/Buffer.o ./src/Canvas.o
+OBJ=./src/main.o ./src/ComputeShader.o ./src/Config.o ./src/Application.o ./src/Buffer.o ./src/Canvas.o
 OBJ_OPEN_GL=./src/glad.o
 HEADERS=./include/Config.hpp ./include/Helper.hpp ./include/Particle.hpp ./include/Cell.hpp
 

+ 8 - 0
CppGPU/configs/config0.cfg

@@ -0,0 +1,8 @@
+increase=10.0f
+decay=0.5f
+diffusion=5.0f
+
+speed=60.0f
+steering=360.0f
+sensing_distance=3.0f
+sensing_angle=45.0f

+ 8 - 0
CppGPU/configs/config1.cfg

@@ -0,0 +1,8 @@
+increase=10.0f
+decay=0.1f
+diffusion=6.0f
+
+speed=50.0f
+steering=320.0f
+sensing_distance=3.0f
+sensing_angle=45.0f

+ 8 - 0
CppGPU/configs/config2.cfg

@@ -0,0 +1,8 @@
+increase=10.0f
+decay=0.03f
+diffusion=8.0f
+
+speed=40.0f
+steering=280.0f
+sensing_distance=3.0f
+sensing_angle=45.0f

+ 8 - 0
CppGPU/configs/config3.cfg

@@ -0,0 +1,8 @@
+increase=10.0f
+decay=0.03f
+diffusion=10.0f
+
+speed=20.0f
+steering=240.0f
+sensing_distance=3.0f
+sensing_angle=45.0f

+ 8 - 0
CppGPU/configs/config9.cfg

@@ -0,0 +1,8 @@
+increase=1.0f
+decay=1.0f
+diffusion=10.0f
+
+speed=40.0f
+steering=0.0f
+sensing_distance=3.0f
+sensing_angle=45.0f

+ 2 - 1
CppGPU/include/Application.hpp

@@ -16,7 +16,7 @@ private:
     int m_window_width{};
     int m_window_heigth{};
     std::string m_appName = "Lyfe";
-    GLFWwindow* window{};
+    GLFWwindow* m_window{};
 
 public:
     Application() = default;
@@ -26,6 +26,7 @@ public:
     void init();
     void terminate();
     bool create_window();
+    void register_callback(GLFWkeyfun);
     bool running();
     void update();
     int key_status(int code);

+ 7 - 1
CppGPU/include/Config.hpp

@@ -2,8 +2,12 @@
 #define PARTICLE_CONFIG
 
 #include <stddef.h>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sstream>
 
-struct  Config
+struct Config
 {
     int map_width{};
     int map_height{};
@@ -20,5 +24,7 @@ struct  Config
     float sensing_angle{};
 };
 
+bool load_config(std::string filename, Config *config);
+
 
 #endif // PARTICLE_CONFIG

+ 3 - 3
CppGPU/shaders/draw.glsl → CppGPU/shaders/draw0.glsl

@@ -39,13 +39,13 @@ void main(){
     uint cell_id = y * map_width + x;
     cell_t cell = map[cell_id]; 
 
-    float pop_value = cell.population / display_population_value;
+    float pop_value = cell.population / display_population_value / 2.5;
     float phe_value = cell.pheromone / display_pheromone_value;
 
     imageStore(canvas, ivec2(gl_GlobalInvocationID.xy), 
         vec4(pop_value + phe_value,
-             pop_value,
-             phe_value,
+             pop_value / 2,
+             pop_value / 3,
              1));
     // Particules rouges, phero bleues
     // imageStore(canvas, ivec2(gl_GlobalInvocationID.xy), 

+ 50 - 0
CppGPU/shaders/draw1.glsl

@@ -0,0 +1,50 @@
+#version 430 core
+
+struct particle_t {
+    vec2 pos;
+    vec2 dir;
+};
+
+struct cell_t {
+    float pheromone;
+    float result;
+    int population;
+};
+
+layout(binding = 0, rgba8) writeonly uniform image2D canvas;
+
+uniform int map_width;
+uniform int map_height;
+
+uniform float display_population_value;
+uniform float display_pheromone_value;
+
+layout(std430, binding = 1) coherent buffer particles_buffer
+{
+    particle_t particles[];
+};
+
+layout(std430, binding = 2) coherent buffer map_buffer
+{
+    cell_t map[];
+};
+
+layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
+void main(){
+    uint x = gl_GlobalInvocationID.x;
+    uint y = gl_GlobalInvocationID.y;
+    if(x >= map_width || y >= map_height){
+        return;
+    }
+    uint cell_id = y * map_width + x;
+    cell_t cell = map[cell_id]; 
+
+    float pop_value = cell.population / display_population_value / 2.5;
+    float phe_value = cell.pheromone / display_pheromone_value;
+
+    imageStore(canvas, ivec2(gl_GlobalInvocationID.xy), 
+        vec4(phe_value / 3,
+             phe_value / 5,
+             pop_value / 2,
+             1));
+}

+ 11 - 6
CppGPU/src/Application.cpp

@@ -24,13 +24,13 @@ void Application::terminate()
 
 bool Application::create_window()
 {
-    window = glfwCreateWindow(m_window_width, m_window_heigth, m_appName.c_str(), nullptr, nullptr);
-    if(window == nullptr){
+    m_window = glfwCreateWindow(m_window_width, m_window_heigth, m_appName.c_str(), nullptr, nullptr);
+    if(m_window == nullptr){
         std::cout << "glfwCreateWindow failed" << std::endl;
         terminate();
         return false;
     }
-    glfwMakeContextCurrent(window);
+    glfwMakeContextCurrent(m_window);
     
     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
     {
@@ -44,20 +44,25 @@ bool Application::create_window()
     return true;
 }
 
+void Application::register_callback(GLFWkeyfun fct)
+{
+    glfwSetKeyCallback(m_window, fct);
+}
+
 bool Application::running()
 {
-    return !glfwWindowShouldClose(window);
+    return !glfwWindowShouldClose(m_window);
 }
 
 void Application::update()
 {
-    glfwSwapBuffers(window);
+    glfwSwapBuffers(m_window);
     glfwPollEvents();
 }
 
 int Application::key_status(int code)
 {
-    return glfwGetKey(window, code);
+    return glfwGetKey(m_window, code);
 }
 
 float Application::time()

+ 38 - 0
CppGPU/src/Config.cpp

@@ -0,0 +1,38 @@
+#include "Config.hpp"
+
+constexpr float deg_to_rad = (float) (3.141592653589793 / 180.0);
+
+bool load_config(std::string filename, Config *config){
+    std::ifstream input_file(filename);
+    
+    if(!input_file){
+        std::cout << "Can't open " << filename << std::endl;
+        return false;
+    }
+
+    for(std::string line; getline(input_file, line); ){
+        size_t index = line.find("=");
+        if(index == std::string::npos)
+            continue;
+        std::string name = line.substr(0, index);
+        std::string value = line.substr(index + 1, std::string::npos);
+
+        if(name == "increase"){
+            config->increase = std::stof(value);
+        }else if(name == "decay"){
+            config->decay = std::stof(value);
+        }else if(name == "diffusion"){
+            config->diffusion = std::stof(value);
+        }else if(name == "speed"){
+            config->speed = std::stof(value);
+        }else if(name == "steering"){
+            config->steering = std::stof(value) * deg_to_rad;
+        }else if(name == "sensing_distance"){
+            config->sensing_distance = std::stof(value);
+        }else if(name == "sensing_angle"){
+            config->sensing_angle = std::stof(value) * deg_to_rad;
+        }
+    }
+
+    return true;
+}

+ 60 - 27
CppGPU/src/main.cpp

@@ -22,34 +22,81 @@
 
 constexpr float deg_to_rad = (float) (3.141592653589793 / 180.0);
 
+/* Keys callbacks */
+Config config;
+ComputeShader cs_draw;
+Buffer particles_buffer;
+Buffer map_buffer;
+
+void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
+    Config new_conf = config;
+    if(action != GLFW_PRESS)
+        return;
+    char filename[100];
+    if(glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE
+       && (key >= GLFW_KEY_0 && key <= GLFW_KEY_9)){
+        char pattern[] = "./configs/config%d.cfg";
+        sprintf(filename, pattern, key - GLFW_KEY_0);
+        if(load_config(std::string(filename), &new_conf)){
+            config = new_conf;
+            std::cout << "Loaded '" << filename << "'" << std::endl;
+        }else{
+            std::cout << "Failed to load '" << filename << "'" << std::endl;
+        }
+    }else if(glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS
+             && (key >= GLFW_KEY_0 && key <= GLFW_KEY_9)){
+        char pattern[] = "./shaders/draw%d.glsl";
+        sprintf(filename, pattern, key - GLFW_KEY_0);
+        cs_draw.load(filename);
+        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);
+    }
+}
+
 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,
+    int map_width =  1500;
+    int map_height = 1200;
+    size_t population = 5000000;
+    if(argc > 2){
+        map_width  = strtol(argv[1], nullptr, 0);
+        map_height = strtol(argv[2], nullptr, 0);
+    }
+    if(argc > 3){
+        population = strtol(argv[3], nullptr, 0);
+    }
 
-        .population=5000000,
+    // Default value
+    config = {
+        .map_width=map_width,
+        .map_height=map_height,
 
+        .population=population,
+ 
         .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,
     };
+
+    Config new_conf = config;
+    if(load_config("./configs/config0.cfg", &new_conf)){
+        config = new_conf;
+    }
+
+
     float average_population = (float)config.population / (float)(config.map_width * config.map_height);
     float average_pheromone = (float)config.increase * average_population;
 
@@ -72,7 +119,7 @@ int main(int argc, char *argv[]){
     cs_map_reset.compile();
 
     /* Load and compile draw shader */
-    cs_draw.load("./shaders/draw.glsl");
+    cs_draw.load("./shaders/draw0.glsl");
     cs_draw.compile();
 
     /* Particles init */
@@ -119,6 +166,9 @@ int main(int argc, char *argv[]){
     
     map_buffer.bind_base(cs_map_reset.get_program(), "map_buffer", 2);
 
+    /* Register key callbacks */
+    app.register_callback(key_callback);
+
     /* Main loop */
     float pervious_time;
     float current_time = app.time();
@@ -148,14 +198,6 @@ int main(int argc, char *argv[]){
         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();
@@ -175,17 +217,8 @@ int main(int argc, char *argv[]){
         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;
 }