]> git.localhorst.tv Git - tacos.git/blobdiff - src/tacos.cpp
mouse cursor mockup
[tacos.git] / src / tacos.cpp
index 0e47e6e27af2baa545bbd961d1d0aab3f0887fcf..e477ab4a97e00a17da46bcbd151cea7eb0608480 100644 (file)
@@ -6,13 +6,16 @@
 #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 <iostream>
 #include <GL/glew.h>
 #include <glm/glm.hpp>
 #include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtx/io.hpp>
 
 using namespace tacos;
 
@@ -41,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) {
@@ -50,14 +61,29 @@ int main(int argc, char *argv[]) {
        }
        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
 
@@ -68,8 +94,6 @@ int main(int argc, char *argv[]) {
        glm::vec2 cam_rot_ccw(0.0f);
        glm::vec2 cam_rot_cw(0.0f);
 
-       floor_program.Use();
-
        bool running = true;
        Uint32 last = SDL_GetTicks();
        SDL_Event event;
@@ -167,6 +191,10 @@ int main(int argc, char *argv[]) {
                                                        break;
                                        }
                                        break;
+                               case SDL_MOUSEMOTION:
+                                       screen_mouse.x = event.motion.x;
+                                       screen_mouse.y = event.motion.y;
+                                       break;
                                case SDL_QUIT:
                                        running = false;
                                        break;
@@ -186,9 +214,28 @@ int main(int argc, char *argv[]) {
                camera.BackOff((cam_far - cam_near) * cam_speed * dt);
                camera.Rotate((cam_rot_ccw - cam_rot_cw) * cam_rot_speed * dt);
 
-               // render
                V = camera.View();
+               VP = viewport.Perspective() * V;
+               { // mouse
+                       inverse_VP = glm::inverse(VP);
+                       glm::vec2 clip_mouse((screen_mouse / glm::vec2(viewport.Width(), viewport.Height()) - 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);
+               }
+
+               if (floor.Intersection(world_mouse, pointer)) {
+                       cursor.FloorTile(floor, int(pointer.x), int(pointer.z));
+               } else {
+                       cursor.Hide();
+               }
+
+               // 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));
@@ -199,6 +246,11 @@ 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;