X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fmain.cc;h=aeb57a64e2b572cf667323e822792361d1747b9e;hb=HEAD;hp=4d77441ffdb89e5a103a4a4259dffb519a3f32b9;hpb=369d75c73bf926a6dbcf4d740c8664bbb401602a;p=demo diff --git a/src/main.cc b/src/main.cc index 4d77441..aeb57a6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,177 +1,411 @@ +#include +#include + #include #include #include #include +#include + +#include "gfxapi.h" +#include "global.h" + /* TODO: fix those */ #include "camera.h" #include "mesh.h" +#include "morph_renderer.h" #include "object.h" #include "scene.h" +#include "terrain.h" +#include "texture.h" #include "opengl/opengl.h" #include "vulkan/vk.h" /* static functions */ -static bool init(); +static bool init(Gfx_API api); static void cleanup(); static void display(); +static bool gen_poisson(std::vector &points, float min_dist, float radius); /* glfw callbacks */ -static void key_clbk(GLFWwindow *win, int key, int scancode, int action, int mods); -static void motion_clbk(GLFWwindow *win, double x, double y); -static void mouse_clbk(GLFWwindow *win, int button, int action, int mods); + +static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods); +static void clbk_motion(GLFWwindow *win, double x, double y); +static void clbk_mouse(GLFWwindow *win, int button, int action, int mods); +static void clbk_reshape(GLFWwindow *win, int width, int height); /* global variables */ -bool use_vulkan; + +Mat4 mprojection; GLFWwindow *win; int win_w = 800; int win_h = 600; -OrbitCamera *camera; +ShaderManager *sdr_man; + +double time_sec; /* variables */ -static float phi = 25; -static float theta = 0; -static float dist = 4; +static bool move_camera; -// TODO: remove just for test: -static Scene scene; +static float cam_phi = 25; +static float cam_theta = 0; +static float cam_dist = 16; +static Vec3 cam_pos; + +static float aspect; +static OrbitCamera *camera; + +static float fog_density; + +static int num_cows = 1; +static float cow_gap = 4; +static Scene *cow_scene; +static MorphRenderer *cow_rend; + +static Terrain terrain; +static TerrainParams p; +static Texture *skybox_tex; +static Texture *irradiance_tex; +static Texture *terrain_tex; +static Texture *dirt_tex; +static Material terrain_mat; +static Renderer *terrain_rend; + +/* *** */ int main(int argc, char **argv) { - for(int i=0; iload("data/grass.jpeg")) { + fprintf(stderr, "Failed to load ground grass texture.\n"); + return false; } - else { - if(!init_opengl()) - return false; + + dirt_tex = gfx_create_texture(); + if(!dirt_tex->load("data/dirt.jpg")) { + fprintf(stderr, "Failed to load ground dirt texture.\n"); + return false; } - camera = new OrbitCamera; - camera->set_orbit_params(phi, theta, dist); + Image ter_hmap; + if(!ter_hmap.load("data/terhmap.png")) { + fprintf(stderr, "Failed to load terrain heightmap.\n"); + return false; + } + + p.xsz = 20;//200; + p.ysz = 20; //200; + p.max_height = 3;//30; + p.xtiles = 4;//40; + p.ytiles = 4;//40; + p.tile_usub = 10; + p.tile_vsub = 10; + p.num_octaves = 3; + p.noise_freq = 5; + p.coarse_heightmap = ter_hmap; + + terrain.init(); + terrain.generate(p); + + terrain_mat.diffuse = Vec3(1, 1, 1); + terrain_mat.specular = Vec3(0, 0, 0); + terrain_mat.shininess = 40; + terrain_mat.dtex = terrain_tex; + terrain_mat.name = "tt"; + + terrain.material = terrain_mat; - if(!scene.load("data/spot/spot_control_mesh.obj")) { - fprintf(stderr, "Failed to load scene.\n"); + terrain_rend = new Renderer; + terrain_rend->camera = camera; + terrain_rend->scene = terrain.get_visible(camera); + + skybox_tex = gfx_create_texture(); + 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; - for(size_t i=0; imesh->name.c_str()); - printf("material: %s\n", scene.objects[i]->material->name.c_str()); - printf("transform:\n"); - scene.objects[i]->transform.print(); + 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 cow_pos; + + for(int i=0; itransform.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; } static void cleanup() { - if(use_vulkan) { - cleanup_vulkan(); - } - else { - cleanup_opengl(); - } - + delete sdr_man; delete camera; + + delete cow_scene; + delete cow_rend; + + delete skybox_tex; + delete irradiance_tex; + delete terrain_tex; + delete terrain_rend; + + gfx_cleanup(); } -static void key_clbk(GLFWwindow *win, int key, int scancode, int action, int mods) +static float cow_speed = 10; +static Vec3 cow_pos; +static bool keystate[256]; + +static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods) { - if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - glfwSetWindowShouldClose(win, GLFW_TRUE); + if(action == GLFW_REPEAT) return; + + if(action == GLFW_PRESS) { + switch(key) { + case GLFW_KEY_ESCAPE: + glfwSetWindowShouldClose(win, GLFW_TRUE); + return; + + case ' ': + 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; + + case 'P': + gfx_wireframe(true); + break; + + case 'F': + gfx_wireframe(false); + break; + + default: + break; + } + } + + if(key < 256) { + keystate[key] = action == GLFW_PRESS; } } static double prev_x, prev_y; -static int button; +static bool button[8]; -static void motion_clbk(GLFWwindow *win, double x, double y) +static void clbk_motion(GLFWwindow *win, double x, double y) { - switch(button) { - case GLFW_MOUSE_BUTTON_LEFT: - theta += x - prev_x; - phi += y - prev_y; - - if(phi < -90) - phi = -90; - if(phi > 90) - phi = 90; - - break; - - case GLFW_MOUSE_BUTTON_RIGHT: - dist *= (y - prev_y) * 0.01 + 1; - if(dist < 0.0) { - dist = 0.0; - } - break; - } + double dx = x - prev_x; + double dy = y - prev_y; prev_x = x; prev_y = y; + + if(button[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + + if(cam_phi < 0) + cam_phi = 0; + if(cam_phi > 90) + cam_phi = 90; + } + + if(button[1]) { + cam_dist += dy * 0.1; + if(cam_dist < 0.0) { + cam_dist = 0.0; + } + } } -static void mouse_clbk(GLFWwindow *win, int bn, int action, int mods) +static void clbk_mouse(GLFWwindow *win, int bn, int action, int mods) { - button = bn; + button[bn] = action == GLFW_PRESS; glfwGetCursorPos(win, &prev_x, &prev_y); } +static void clbk_reshape(GLFWwindow *win, int width, int height) +{ + gfx_reshape(width, height); + gfx_viewport(0, 0, width, height); + aspect = (float)width / (float)height; + mprojection = calc_projection_matrix(45, aspect, 0.5, 1000.0); + + win_h = height; + win_w = width; +} + +static void update(float dt) +{ + Vec3 dir; + + if(keystate['D']) + dir.x += cow_speed * dt; + if(keystate['A']) + dir.x -= cow_speed * dt; + if(keystate['W']) + dir.z -= cow_speed * dt; + if(keystate['S']) + dir.z += cow_speed * dt; + + Vec3 *pos = move_camera ? &cam_pos : &cow_pos; + float theta = cam_theta / 180.0 * M_PI; + pos->x += dir.x * cos(theta) - dir.z * sin(theta); + pos->z += dir.x * sin(theta) + dir.z * cos(theta); +} + static void display() { - if(use_vulkan) { - display_vulkan(); - } - else { - display_opengl(); + static float prev_tsec; + time_sec = glfwGetTime(); + float dt = time_sec - prev_tsec; + prev_tsec = time_sec; + + update(dt); + + cam_pos.y = terrain.get_height(cam_pos) + 0.5; + camera->set_orbit_params(cam_theta, cam_phi, cam_dist); + camera->set_position(cam_pos.x, cam_pos.y, cam_pos.z); + + gfx_begin_drawing(); + + gfx_clear(0.1, 0.1, 0.1); + + terrain_rend->draw(); + cow_rend->draw(); + + gfx_end_drawing(); +} + +static bool gen_poisson(std::vector &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