]> git.localhorst.tv Git - tacos.git/blob - src/tacos.cpp
mouse cursor mockup
[tacos.git] / src / tacos.cpp
1 #include "app/assets.hpp"
2 #include "app/config.hpp"
3 #include "app/init.hpp"
4 #include "app/keymap.hpp"
5 #include "graphics/camera.hpp"
6 #include "graphics/shader.hpp"
7 #include "graphics/viewport.hpp"
8 #include "graphics/window.hpp"
9 #include "physics/ray.hpp"
10 #include "rand/SimplexNoise.hpp"
11 #include "world/Cursor.hpp"
12 #include "world/Floor.hpp"
13
14 #include <iostream>
15 #include <GL/glew.h>
16 #include <glm/glm.hpp>
17 #include <glm/gtc/matrix_transform.hpp>
18 #include <glm/gtx/io.hpp>
19
20 using namespace tacos;
21
22 int main(int argc, char *argv[]) {
23         Config config;
24         config.ReadArgs(argc, argv);
25
26         Init init(config);
27         AssetLoader asset_loader(config);
28         Window window(1440, 900);
29         Viewport viewport(1440, 900);
30
31         Keymap keymap;
32         keymap.LoadDefault();
33
34         constexpr float noise_scale = 1.0f/64.0f;
35         constexpr float height_scale = 5.0f;
36
37         // === test ===
38         Shader floor_vert(asset_loader.LoadVertexShader("floor"));
39         Shader floor_frag(asset_loader.LoadFragmentShader("floor"));
40         Program floor_program;
41         floor_program.Attach(floor_vert);
42         floor_program.Attach(floor_frag);
43         floor_program.Link();
44         GLint mv_location = floor_program.UniformLocation("MV");
45         GLint mvp_location = floor_program.UniformLocation("MVP");
46
47         Shader cursor_vert(asset_loader.LoadVertexShader("cursor"));
48         Shader cursor_frag(asset_loader.LoadFragmentShader("cursor"));
49         Program cursor_program;
50         cursor_program.Attach(cursor_vert);
51         cursor_program.Attach(cursor_frag);
52         cursor_program.Link();
53         GLint vp_location = cursor_program.UniformLocation("VP");
54
55         Floor floor(64, 50);
56         SimplexNoise noise(0);
57         for (int z = 0; z < floor.Depth(); ++z) {
58                 for (int x = 0; x < floor.Width(); ++x) {
59                         floor.SetElevation(x, z, noise(glm::vec3(x * noise_scale, 0.0f, z * noise_scale)) * height_scale);
60                 }
61         }
62         floor.GenerateVertices();
63
64         Cursor cursor;
65
66         Camera camera;
67         camera.Warp(glm::vec3(20.0f, 0.0f, 20.0f));
68
69         glm::mat4 M;
70         glm::mat4 V;
71         glm::mat4 VP;
72         glm::mat4 MV;
73         glm::mat4 MVP;
74
75         // cursor stuff
76         glm::mat4 inverse_VP;
77         glm::vec2 screen_mouse;
78         {
79                 int x, y;
80                 SDL_GetMouseState(&x, &y);
81                 screen_mouse.x = x;
82                 screen_mouse.y = y;
83         }
84         Ray world_mouse;
85         glm::vec3 pointer;
86
87         constexpr float cam_speed = 15.0f; // units per second
88         constexpr float cam_rot_speed = 2.0f; // radians per second
89
90         glm::vec3 cam_fwd(0.0f);
91         glm::vec3 cam_rev(0.0f);
92         float cam_near = 0.0f;
93         float cam_far = 0.0f;
94         glm::vec2 cam_rot_ccw(0.0f);
95         glm::vec2 cam_rot_cw(0.0f);
96
97         bool running = true;
98         Uint32 last = SDL_GetTicks();
99         SDL_Event event;
100         while (running) {
101                 Uint32 now = SDL_GetTicks();
102                 // handle
103                 while (SDL_PollEvent(&event)) {
104                         switch (event.type) {
105                                 case SDL_KEYDOWN:
106                                         switch (keymap.Lookup(event.key)) {
107                                                 case Keymap::CAMERA_RIGHT:
108                                                         cam_fwd.x = 1.0f;
109                                                         break;
110                                                 case Keymap::CAMERA_LEFT:
111                                                         cam_rev.x = 1.0f;
112                                                         break;
113                                                 case Keymap::CAMERA_UP:
114                                                         cam_fwd.y = 1.0f;
115                                                         break;
116                                                 case Keymap::CAMERA_DOWN:
117                                                         cam_rev.y = 1.0f;
118                                                         break;
119                                                 case Keymap::CAMERA_BACK:
120                                                         cam_fwd.z = 1.0f;
121                                                         break;
122                                                 case Keymap::CAMERA_FORWARD:
123                                                         cam_rev.z = 1.0f;
124                                                         break;
125                                                 case Keymap::CAMERA_NEARER:
126                                                         cam_near = 1.0f;
127                                                         break;
128                                                 case Keymap::CAMERA_FARTHER:
129                                                         cam_far = 1.0f;
130                                                         break;
131                                                 case Keymap::CAMERA_PITCH_CCW:
132                                                         cam_rot_ccw.x = 1.0f;
133                                                         break;
134                                                 case Keymap::CAMERA_PITCH_CW:
135                                                         cam_rot_cw.x = 1.0f;
136                                                         break;
137                                                 case Keymap::CAMERA_YAW_CCW:
138                                                         cam_rot_ccw.y = 1.0f;
139                                                         break;
140                                                 case Keymap::CAMERA_YAW_CW:
141                                                         cam_rot_cw.y = 1.0f;
142                                                         break;
143                                                 case Keymap::EXIT:
144                                                         running = false;
145                                                         break;
146                                                 default:
147                                                 case Keymap::NONE:
148                                                         break;
149                                         }
150                                         break;
151                                 case SDL_KEYUP:
152                                         switch (keymap.Lookup(event.key)) {
153                                                 case Keymap::CAMERA_RIGHT:
154                                                         cam_fwd.x = 0.0f;
155                                                         break;
156                                                 case Keymap::CAMERA_LEFT:
157                                                         cam_rev.x = 0.0f;
158                                                         break;
159                                                 case Keymap::CAMERA_UP:
160                                                         cam_fwd.y = 0.0f;
161                                                         break;
162                                                 case Keymap::CAMERA_DOWN:
163                                                         cam_rev.y = 0.0f;
164                                                         break;
165                                                 case Keymap::CAMERA_BACK:
166                                                         cam_fwd.z = 0.0f;
167                                                         break;
168                                                 case Keymap::CAMERA_FORWARD:
169                                                         cam_rev.z = 0.0f;
170                                                         break;
171                                                 case Keymap::CAMERA_NEARER:
172                                                         cam_near = 0.0f;
173                                                         break;
174                                                 case Keymap::CAMERA_FARTHER:
175                                                         cam_far = 0.0f;
176                                                         break;
177                                                 case Keymap::CAMERA_PITCH_CCW:
178                                                         cam_rot_ccw.x = 0.0f;
179                                                         break;
180                                                 case Keymap::CAMERA_PITCH_CW:
181                                                         cam_rot_cw.x = 0.0f;
182                                                         break;
183                                                 case Keymap::CAMERA_YAW_CCW:
184                                                         cam_rot_ccw.y = 0.0f;
185                                                         break;
186                                                 case Keymap::CAMERA_YAW_CW:
187                                                         cam_rot_cw.y = 0.0f;
188                                                         break;
189                                                 default:
190                                                 case Keymap::NONE:
191                                                         break;
192                                         }
193                                         break;
194                                 case SDL_MOUSEMOTION:
195                                         screen_mouse.x = event.motion.x;
196                                         screen_mouse.y = event.motion.y;
197                                         break;
198                                 case SDL_QUIT:
199                                         running = false;
200                                         break;
201                                 case SDL_WINDOWEVENT:
202                                         if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
203                                                 viewport.Resize(event.window.data1, event.window.data2);
204                                         }
205                                         break;
206                                 default:
207                                         break;
208                         }
209                 }
210
211                 // update
212                 float dt = (now - last) * 0.001f;
213                 camera.Move((cam_fwd - cam_rev) * cam_speed * dt);
214                 camera.BackOff((cam_far - cam_near) * cam_speed * dt);
215                 camera.Rotate((cam_rot_ccw - cam_rot_cw) * cam_rot_speed * dt);
216
217                 V = camera.View();
218                 VP = viewport.Perspective() * V;
219                 { // mouse
220                         inverse_VP = glm::inverse(VP);
221                         glm::vec2 clip_mouse((screen_mouse / glm::vec2(viewport.Width(), viewport.Height()) - 0.5f) * 2.0f);
222                         // viewport space has origin in lower left, but sdl gives coordinates with orgin in upper left,
223                         // so Y is inverted here (since it maps from -1 to 1 simply by negating)
224                         glm::vec4 ray_begin(inverse_VP * glm::vec4(clip_mouse.x, -clip_mouse.y, -1.0f, 1.0f));
225                         glm::vec4 ray_end(inverse_VP * glm::vec4(clip_mouse.x, -clip_mouse.y, 0.0f, 1.0f));
226                         world_mouse.origin = glm::vec3(ray_begin) / ray_begin.w;
227                         world_mouse.direction = glm::normalize((glm::vec3(ray_end) / ray_end.w) - world_mouse.origin);
228                 }
229
230                 if (floor.Intersection(world_mouse, pointer)) {
231                         cursor.FloorTile(floor, int(pointer.x), int(pointer.z));
232                 } else {
233                         cursor.Hide();
234                 }
235
236                 // render
237                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
238                 floor_program.Use();
239                 for (int z = 0; z < floor.VAODepth(); ++z) {
240                         for (int x = 0; x < floor.VAOWidth(); ++x) {
241                                 M = glm::translate(glm::mat4(1.0f), floor.VAOPosition(x, z));
242                                 MV = camera.View() * M;
243                                 MVP = viewport.Perspective() * MV;
244                                 floor_program.Uniform(mv_location, MV);
245                                 floor_program.Uniform(mvp_location, MVP);
246                                 floor.DrawVAO(x, z);
247                         }
248                 }
249                 if (cursor.Visible()) {
250                         cursor_program.Use();
251                         cursor_program.Uniform(vp_location, VP);
252                         cursor.Draw();
253                 }
254                 window.Flip();
255
256                 last = now;
257         }
258
259         return 0;
260 }