X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Ftacos.cpp;h=fe1c7aa68c73bc1b5b5f3d39e39677c93b59d537;hb=0146c7b7f02ef5d74116546489aee85383bb4969;hp=580becb9caa0e391a5b779de2010976a9609ad22;hpb=dfe661278fe5fd69e821d530d50b78082d19ce54;p=tacos.git diff --git a/src/tacos.cpp b/src/tacos.cpp index 580becb..fe1c7aa 100644 --- a/src/tacos.cpp +++ b/src/tacos.cpp @@ -1,17 +1,21 @@ #include "app/assets.hpp" #include "app/config.hpp" #include "app/init.hpp" +#include "app/keymap.hpp" #include "graphics/camera.hpp" #include "graphics/shader.hpp" #include "graphics/viewport.hpp" #include "graphics/window.hpp" +#include "physics/ray.hpp" #include "rand/SimplexNoise.hpp" +#include "world/Cursor.hpp" #include "world/Floor.hpp" #include #include #include #include +#include using namespace tacos; @@ -24,6 +28,9 @@ int main(int argc, char *argv[]) { Window window(1440, 900); Viewport viewport(1440, 900); + Keymap keymap; + keymap.LoadDefault(); + constexpr float noise_scale = 1.0f/64.0f; constexpr float height_scale = 5.0f; @@ -37,6 +44,14 @@ int main(int argc, char *argv[]) { GLint mv_location = floor_program.UniformLocation("MV"); GLint mvp_location = floor_program.UniformLocation("MVP"); + Shader cursor_vert(asset_loader.LoadVertexShader("cursor")); + Shader cursor_frag(asset_loader.LoadFragmentShader("cursor")); + Program cursor_program; + cursor_program.Attach(cursor_vert); + cursor_program.Attach(cursor_frag); + cursor_program.Link(); + GLint vp_location = cursor_program.UniformLocation("VP"); + Floor floor(64, 50); SimplexNoise noise(0); for (int z = 0; z < floor.Depth(); ++z) { @@ -46,21 +61,140 @@ int main(int argc, char *argv[]) { } floor.GenerateVertices(); - glm::vec3 focus(20.0f, 0.0f, 20.0f); - Camera camera(focus); + Cursor cursor; + + Camera camera; + camera.Warp(glm::vec3(20.0f, 0.0f, 20.0f)); glm::mat4 M; glm::mat4 V; + glm::mat4 VP; glm::mat4 MV; glm::mat4 MVP; - floor_program.Use(); + // cursor stuff + glm::mat4 inverse_VP; + glm::vec2 screen_mouse; + { + int x, y; + SDL_GetMouseState(&x, &y); + screen_mouse.x = x; + screen_mouse.y = y; + } + Ray world_mouse; + glm::vec3 pointer; + + constexpr float cam_speed = 15.0f; // units per second + constexpr float cam_rot_speed = 2.0f; // radians per second + + glm::vec3 cam_fwd(0.0f); + glm::vec3 cam_rev(0.0f); + float cam_near = 0.0f; + float cam_far = 0.0f; + glm::vec2 cam_rot_ccw(0.0f); + glm::vec2 cam_rot_cw(0.0f); bool running = true; + Uint32 last = SDL_GetTicks(); SDL_Event event; while (running) { + Uint32 now = SDL_GetTicks(); + // handle while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_KEYDOWN: + switch (keymap.Lookup(event.key)) { + case Keymap::CAMERA_RIGHT: + cam_fwd.x = 1.0f; + break; + case Keymap::CAMERA_LEFT: + cam_rev.x = 1.0f; + break; + case Keymap::CAMERA_UP: + cam_fwd.y = 1.0f; + break; + case Keymap::CAMERA_DOWN: + cam_rev.y = 1.0f; + break; + case Keymap::CAMERA_BACK: + cam_fwd.z = 1.0f; + break; + case Keymap::CAMERA_FORWARD: + cam_rev.z = 1.0f; + break; + case Keymap::CAMERA_NEARER: + cam_near = 1.0f; + break; + case Keymap::CAMERA_FARTHER: + cam_far = 1.0f; + break; + case Keymap::CAMERA_PITCH_CCW: + cam_rot_ccw.x = 1.0f; + break; + case Keymap::CAMERA_PITCH_CW: + cam_rot_cw.x = 1.0f; + break; + case Keymap::CAMERA_YAW_CCW: + cam_rot_ccw.y = 1.0f; + break; + case Keymap::CAMERA_YAW_CW: + cam_rot_cw.y = 1.0f; + break; + case Keymap::EXIT: + running = false; + break; + default: + case Keymap::NONE: + break; + } + break; + case SDL_KEYUP: + switch (keymap.Lookup(event.key)) { + case Keymap::CAMERA_RIGHT: + cam_fwd.x = 0.0f; + break; + case Keymap::CAMERA_LEFT: + cam_rev.x = 0.0f; + break; + case Keymap::CAMERA_UP: + cam_fwd.y = 0.0f; + break; + case Keymap::CAMERA_DOWN: + cam_rev.y = 0.0f; + break; + case Keymap::CAMERA_BACK: + cam_fwd.z = 0.0f; + break; + case Keymap::CAMERA_FORWARD: + cam_rev.z = 0.0f; + break; + case Keymap::CAMERA_NEARER: + cam_near = 0.0f; + break; + case Keymap::CAMERA_FARTHER: + cam_far = 0.0f; + break; + case Keymap::CAMERA_PITCH_CCW: + cam_rot_ccw.x = 0.0f; + break; + case Keymap::CAMERA_PITCH_CW: + cam_rot_cw.x = 0.0f; + break; + case Keymap::CAMERA_YAW_CCW: + cam_rot_ccw.y = 0.0f; + break; + case Keymap::CAMERA_YAW_CW: + cam_rot_cw.y = 0.0f; + break; + default: + case Keymap::NONE: + break; + } + break; + case SDL_MOUSEMOTION: + screen_mouse.x = event.motion.x; + screen_mouse.y = event.motion.y; + break; case SDL_QUIT: running = false; break; @@ -73,8 +207,38 @@ int main(int argc, char *argv[]) { break; } } + + // update + float dt = (now - last) * 0.001f; + camera.Move((cam_fwd - cam_rev) * cam_speed * dt); + camera.BackOff((cam_far - cam_near) * cam_speed * dt); + camera.Rotate((cam_rot_ccw - cam_rot_cw) * cam_rot_speed * dt); + V = camera.View(); + VP = viewport.Perspective() * V; + { // mouse + inverse_VP = glm::inverse(VP); + glm::vec2 clip_mouse((screen_mouse * viewport.InverseSize() - 0.5f) * 2.0f); + // viewport space has origin in lower left, but sdl gives coordinates with orgin in upper left, + // so Y is inverted here (since it maps from -1 to 1 simply by negating) + glm::vec4 ray_begin(inverse_VP * glm::vec4(clip_mouse.x, -clip_mouse.y, -1.0f, 1.0f)); + glm::vec4 ray_end(inverse_VP * glm::vec4(clip_mouse.x, -clip_mouse.y, 0.0f, 1.0f)); + world_mouse.origin = glm::vec3(ray_begin) / ray_begin.w; + world_mouse.direction = glm::normalize((glm::vec3(ray_end) / ray_end.w) - world_mouse.origin); + } + + //std::cout << "ray " << world_mouse.origin << ", " << world_mouse.direction << std::endl; + if (floor.Intersection(world_mouse, pointer)) { + cursor.FloorTile(floor, int(pointer.x), int(pointer.z)); + //std::cout << " +++ intersecting at " << pointer << std::endl; + } else { + cursor.Hide(); + //std::cout << " --- not intersecting" << std::endl; + } + + // render glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + floor_program.Use(); for (int z = 0; z < floor.VAODepth(); ++z) { for (int x = 0; x < floor.VAOWidth(); ++x) { M = glm::translate(glm::mat4(1.0f), floor.VAOPosition(x, z)); @@ -85,7 +249,14 @@ int main(int argc, char *argv[]) { floor.DrawVAO(x, z); } } + if (cursor.Visible()) { + cursor_program.Use(); + cursor_program.Uniform(vp_location, VP); + cursor.Draw(); + } window.Flip(); + + last = now; } return 0;