quick backup - everything is going to be changed on vulkan side.
[demo] / src / main.cc
index d4d4226..6b1050b 100644 (file)
@@ -1,4 +1,5 @@
 #include <GL/glew.h>
+#include <GLFW/glfw3.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -13,8 +14,8 @@
 /* TODO: fix those */
 #include "camera.h"
 #include "mesh.h"
+#include "morph_renderer.h"
 #include "object.h"
-#include "renderer.h"
 #include "scene.h"
 #include "terrain.h"
 #include "texture.h"
@@ -27,6 +28,7 @@
 static bool init(Gfx_API api);
 static void cleanup();
 static void display();
+static bool gen_poisson(std::vector<Vec2> &points, float min_dist, float radius);
 
 /* glfw callbacks */
 
@@ -43,9 +45,10 @@ GLFWwindow *win;
 int win_w = 800;
 int win_h = 600;
 
-
 ShaderManager *sdr_man;
 
+double time_sec;
+
 /* variables */
 static bool move_camera;
 
@@ -57,12 +60,17 @@ static Vec3 cam_pos;
 static float aspect;
 static OrbitCamera *camera;
 
+static float fog_density;
+
+static int num_cows = 400;
+static float cow_gap = 4;
 static Scene *cow_scene;
-static Object *cow_object;
-static Renderer *cow_rend;
+static MorphRenderer *cow_rend;
 
 static Terrain terrain;
+static TerrainParams p;
 static Texture *skybox_tex;
+static Texture *irradiance_tex;
 static Texture *terrain_tex;
 static Material terrain_mat;
 static Renderer *terrain_rend;
@@ -73,7 +81,7 @@ int main(int argc, char **argv)
 {
        Gfx_API api;
 
-       for(int i=0; i<argc; ++i) {
+       for(int i=1; i<argc; i++) {
                if(strcmp(argv[i], "-opengl") == 0) {
                        api = GFX_GL;
                        printf("Backend: OpenGL.\n");
@@ -93,6 +101,9 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       //TODO
+       return 0;
+
        glfwSetKeyCallback(win, clbk_key);
        glfwSetCursorPosCallback(win, clbk_motion);
        glfwSetMouseButtonCallback(win, clbk_mouse);
@@ -109,7 +120,6 @@ int main(int argc, char **argv)
        }
 
        cleanup();
-       // atexit(cleanup);
        return 0;
 }
 
@@ -118,27 +128,12 @@ static bool init(Gfx_API api)
        if(!gfx_init(api))
                return false;
 
+       fog_density = 0.0037;
+
        sdr_man = new ShaderManager;
 
        camera = new OrbitCamera;
 
-       cow_scene = new Scene;
-       if(!cow_scene->load("data/spot/spot.obj")) {
-               fprintf(stderr, "Failed to load scene: spot.obj.\n");
-               return false;
-       }
-
-       cow_rend = new Renderer;
-       cow_rend->camera = camera;
-       cow_rend->scene = cow_scene;
-
-       if(!cow_rend->create()) {
-               fprintf(stderr, "Failed to create renderer for cows.\n");
-               return false;
-       }
-
-       cow_object = cow_scene->objects[0];
-
        terrain_tex = gfx_create_texture();
        if(!terrain_tex->load("data/grass.jpeg")) {
                fprintf(stderr, "Failed to load ground texture.\n");
@@ -151,7 +146,6 @@ static bool init(Gfx_API api)
                return false;
        }
 
-       TerrainParams p;
        p.xsz = 200;
        p.ysz = 200;
        p.max_height = 30;
@@ -182,11 +176,56 @@ static bool init(Gfx_API api)
        skybox_tex->load("data/cubemap/cubemap.hdr");
        terrain_rend->set_sky_tex(skybox_tex);
 
+       irradiance_tex = gfx_create_texture();
+       irradiance_tex->load("data/cubemap/irradiance.hdr");
+       terrain_rend->set_diffuse_sky_tex(irradiance_tex);
+
        if(!terrain_rend->create()) {
                fprintf(stderr, "terrain fail\n");
                return false;
        }
+       terrain_rend->fog_density = fog_density;
 
+       cow_scene = new Scene;
+       if(!cow_scene->load("data/spot/spot.obj")) {
+               fprintf(stderr, "Failed to load scene: spot.obj.\n");
+               return false;
+       }
+
+       cow_rend = new MorphRenderer;
+       cow_rend->camera = camera;
+       cow_rend->scene = cow_scene;
+       cow_rend->fog_density = fog_density;
+
+       if(!cow_rend->create()) {
+               fprintf(stderr, "Failed to create renderer for cows.\n");
+               return false;
+       }
+
+       /* create cow objects */
+       Object *cow0 = cow_scene->objects[0];
+       cow0->transform.rotation_y(M_PI);
+       cow_scene->objects.clear();
+
+       float disk_radius = std::min(p.xsz, p.ysz) / 2.0 * 0.65;
+       std::vector<Vec2> cow_pos;
+
+       for(int i=0; i<num_cows; i++) {
+               Object *cow = new Object;
+               *cow = *cow0;
+
+               if(!gen_poisson(cow_pos, cow_gap, disk_radius))
+                       goto cowgen_end;
+               Vec2 pos = cow_pos.back();
+               float y = terrain.get_height(Vec3(pos.x, 1, pos.y));
+
+               cow->transform.translate(pos.x, y, pos.y);
+               cow_scene->objects.push_back(cow);
+       }
+
+cowgen_end:
+       printf("generated: %d cows from %d\n", (int)cow_pos.size(), num_cows);
+       delete cow0;
        return true;
 }
 
@@ -198,9 +237,11 @@ static void cleanup()
        delete cow_scene;
        delete cow_rend;
 
-//TODO
+       delete skybox_tex;
+       delete irradiance_tex;
        delete terrain_tex;
        delete terrain_rend;
+
        gfx_cleanup();
 }
 
@@ -222,6 +263,14 @@ static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mod
                        move_camera = !move_camera;
                        break;
 
+               // case 'F':
+               //      fog_density = fog_density < 1 - 0.0009 ? fog_density + 0.0001 : 1;
+               //      break;
+
+               // case 'U':
+               //      fog_density = fog_density > 0.0001 ? fog_density - 0.0001 : 0;
+               //      break;
+
                default:
                        break;
                }
@@ -259,7 +308,7 @@ static void clbk_motion(GLFWwindow *win, double x, double y)
                        cam_dist = 0.0;
                }
        }
- }
+}
 
 static void clbk_mouse(GLFWwindow *win, int bn, int action, int mods)
 {
@@ -299,9 +348,9 @@ static void update(float dt)
 static void display()
 {
        static float prev_tsec;
-       float tsec = glfwGetTime();
-       float dt = tsec - prev_tsec;
-       prev_tsec = tsec;
+       time_sec = glfwGetTime();
+       float dt = time_sec - prev_tsec;
+       prev_tsec = time_sec;
 
        update(dt);
 
@@ -312,8 +361,31 @@ static void display()
        gfx_clear(0.1, 0.1, 0.1);
 
        terrain_rend->draw();
-
-       cow_pos.y = terrain.get_height(cow_pos);
-       cow_object->transform.translation(cow_pos);
        cow_rend->draw();
+}
+
+static bool gen_poisson(std::vector<Vec2> &points, float min_dist, float radius)
+{
+       /* poisson radius */
+       for(int i = 0; i < 1000; i++) {
+               float angle = (float)rand() / (float)RAND_MAX * 2 * M_PI;
+               float r = sqrt((float)rand() / (float)RAND_MAX) * radius;
+
+               Vec2 p;
+               p.x = cos(angle) * r;
+               p.y = sin(angle) * r;
+
+               bool valid = true;
+               for(size_t j=0; j<points.size(); j++) {
+                       if(length_sq(points[j] - p) < min_dist * min_dist) {
+                               valid = false;
+                               break;
+                       }
+               }
+               if(valid) {
+                       points.push_back(p);
+                       return true;
+               }
+       }
+       return false;
 }
\ No newline at end of file