X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Ftacos.cpp;h=fe1c7aa68c73bc1b5b5f3d39e39677c93b59d537;hb=refs%2Fheads%2Fmaster;hp=7e0976f6dab2a54d4d247802ace1d1019896b578;hpb=88073614253d3a9c678848a6e905c3794aa831ca;p=tacos.git diff --git a/src/tacos.cpp b/src/tacos.cpp index 7e0976f..fe1c7aa 100644 --- a/src/tacos.cpp +++ b/src/tacos.cpp @@ -1,10 +1,263 @@ +#include "app/assets.hpp" +#include "app/config.hpp" #include "app/init.hpp" -#include "app/window.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; int main(int argc, char *argv[]) { - Init init; - Window window; + Config config; + config.ReadArgs(argc, argv); + + Init init(config); + AssetLoader asset_loader(config); + 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; + + // === test === + Shader floor_vert(asset_loader.LoadVertexShader("floor")); + Shader floor_frag(asset_loader.LoadFragmentShader("floor")); + Program floor_program; + floor_program.Attach(floor_vert); + floor_program.Attach(floor_frag); + floor_program.Link(); + 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) { + for (int x = 0; x < floor.Width(); ++x) { + floor.SetElevation(x, z, noise(glm::vec3(x * noise_scale, 0.0f, z * noise_scale)) * height_scale); + } + } + floor.GenerateVertices(); + + 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; + + // 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; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + viewport.Resize(event.window.data1, event.window.data2); + } + break; + default: + 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)); + MV = camera.View() * M; + MVP = viewport.Perspective() * MV; + floor_program.Uniform(mv_location, MV); + floor_program.Uniform(mvp_location, MVP); + floor.DrawVAO(x, z); + } + } + if (cursor.Visible()) { + cursor_program.Use(); + cursor_program.Uniform(vp_location, VP); + cursor.Draw(); + } + window.Flip(); + + last = now; + } + return 0; }