fixed terrain tiles generation
[demo] / src / main.cc
1 #include <GL/glew.h>
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <vector>
7
8 #include <gmath/gmath.h>
9
10 #include "gfxapi.h"
11 #include "global.h"
12
13 /* TODO: fix those */
14 #include "camera.h"
15 #include "mesh.h"
16 #include "object.h"
17 #include "renderer.h"
18 #include "scene.h"
19 #include "terrain.h"
20 #include "texture.h"
21
22 #include "opengl/opengl.h"
23 #include "vulkan/vk.h"
24
25 /* static functions */
26
27 static bool init(Gfx_API api);
28 static void cleanup();
29 static void display();
30
31 /* glfw callbacks */
32
33 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods);
34 static void clbk_motion(GLFWwindow *win, double x, double y);
35 static void clbk_mouse(GLFWwindow *win, int button, int action, int mods);
36 static void clbk_reshape(GLFWwindow *win, int width, int height);
37
38 /* global variables */
39
40 Mat4 mprojection;
41
42 GLFWwindow *win;
43 int win_w = 800;
44 int win_h = 600;
45
46 float phi = 25;
47 float theta = 0;
48 float dist = 16;
49
50 ShaderManager *sdr_man;
51
52 /* variables */
53
54 static float aspect;
55 static OrbitCamera *camera;
56
57 static Scene *scene_cow;
58 static Renderer *rcow;
59
60 static Scene *scene_ground;
61 static Renderer *rground; // default renderer
62 static Texture *gskybox;
63
64 static Renderer *tr;
65 static Material tmat;
66 static Terrain t;
67
68 /* *** */
69
70 int main(int argc, char **argv)
71 {
72         Gfx_API api;
73
74         for(int i=0; i<argc; ++i) {
75                 if(strcmp(argv[i], "-opengl") == 0) {
76                         api = GFX_GL;
77                         printf("Backend: OpenGL.\n");
78                 }
79                 else if(strcmp(argv[i], "-vulkan") == 0) {
80                         api = GFX_VK;
81                         printf("Backend: Vulkan.\n");
82                 }
83                 else {
84                         api = GFX_GL;
85                         printf("No backend specified. Using OpenGL.\n");
86                 }
87         }
88
89         if(!init(api)) {
90                 fprintf(stderr, "Failed to initialize program.\n");
91                 return 1;
92         }
93
94         glfwSetKeyCallback(win, clbk_key);
95         glfwSetCursorPosCallback(win, clbk_motion);
96         glfwSetMouseButtonCallback(win, clbk_mouse);
97         glfwSetWindowSizeCallback(win, clbk_reshape);
98
99         glfwGetWindowSize(win, &win_w, &win_h);
100         clbk_reshape(win, win_w, win_h);
101
102         while(!glfwWindowShouldClose(win)) {
103                 display();
104
105                 glfwSwapBuffers(win);
106                 glfwPollEvents();
107         }
108
109         cleanup();
110         // atexit(cleanup);
111         return 0;
112 }
113
114 static bool init(Gfx_API api)
115 {
116         if(!gfx_init(api))
117                 return false;
118
119         sdr_man = new ShaderManager;
120
121         camera = new OrbitCamera;
122
123         // scene_ground = new Scene;
124         // if(!scene_ground->load("data/ground.obj")) {
125         //      fprintf(stderr, "Failed to load scene: ground.obj.\n");
126         //      return false;
127         // }
128
129         // rground = new Renderer;
130         // rground->camera = camera;
131         // rground->scene = scene_ground;
132
133         // if(!rground->create()) {
134         //      fprintf(stderr, "Failed to create default renderer.\n");
135         //      return false;
136         // }
137
138         // gskybox = gfx_create_texture();
139         // gskybox->load("data/cubemap/cubemap.hdr");
140         // rground->set_sky_tex(gskybox);
141
142         scene_cow = new Scene;
143         if(!scene_cow->load("data/spot/spot.obj")) {
144                 fprintf(stderr, "Failed to load scene: spot.obj.\n");
145                 return false;
146         }
147
148         rcow = new Renderer;
149         rcow->camera = camera;
150         rcow->scene = scene_cow;
151
152         if(!rcow->create()) {
153                 fprintf(stderr, "Failed to create renderer for cows.\n");
154                 return false;
155         }
156
157         TerrainParams p;
158         p.xsz = 50;
159         p.ysz = 50;
160         p.max_height = 2;
161         p.xtiles = 20;
162         p.ytiles = 20;
163         p.tile_usub = 10;
164         p.tile_vsub = 10;
165         p.num_octaves = 3;
166         p.noise_freq = 10;
167         p.coarse_heightmap = 0;
168
169         t.init();
170         t.generate(p);
171
172         tmat.diffuse = Vec3(1, 0, 0);
173         tmat.specular = Vec3(0.5, 0, 0);
174         tmat.shininess = 40;
175         tmat.dtex = 0;
176         tmat.name = "tt";
177
178         t.material = tmat;
179
180         tr = new Renderer;
181         tr->camera = camera;
182         tr->scene = t.get_visible(camera);
183         if(!tr->create()) {
184                 fprintf(stderr, "terrain fail\n");
185                 return false;
186         }
187
188
189 // TODO delete: debugging
190         // for(size_t i=0; i<scene_ground->objects.size(); ++i) {
191         //      printf("object: %d\n", (int)i);
192         //      printf("mesh: %s\n", scene_ground->objects[i]->mesh->name.c_str());
193         //      printf("material: %s\n", scene_ground->objects[i]->material->name.c_str());
194         //      printf("transform:\n");
195         //      scene_ground->objects[i]->transform.print();
196         // }
197         return true;
198 }
199
200 static void cleanup()
201 {
202         delete sdr_man;
203         delete camera;
204
205         delete scene_cow;
206         delete rcow;
207
208         // delete scene_ground;
209         // delete rground;
210
211 //TODO
212         delete tr;
213         gfx_cleanup();
214 }
215
216 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods)
217 {
218         if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
219                 glfwSetWindowShouldClose(win, GLFW_TRUE);
220         }
221 }
222
223 static double prev_x, prev_y;
224 static bool button[8];
225
226 static void clbk_motion(GLFWwindow *win, double x, double y)
227 {
228         double dx = x - prev_x;
229         double dy = y - prev_y;
230
231         prev_x = x;
232         prev_y = y;
233
234         if(button[0]) {
235                 theta += dx * 0.5;
236                 phi += dy * 0.5;
237
238                 if(phi < 0)
239                         phi = 0;
240                 if(phi > 90)
241                         phi = 90;
242         }
243
244         if(button[1]) {
245                 dist += dy * 0.1;
246                 if(dist < 0.0) {
247                         dist = 0.0;
248                 }
249         }
250 }
251
252 static void clbk_mouse(GLFWwindow *win, int bn, int action, int mods)
253 {
254         button[bn] = action == GLFW_PRESS;
255         glfwGetCursorPos(win, &prev_x, &prev_y);
256 }
257
258 static void clbk_reshape(GLFWwindow *win, int width, int height)
259 {
260         gfx_viewport(0, 0, width, height);
261         aspect = (float)width / (float)height;
262         mprojection = calc_projection_matrix(45, aspect, 0.5, 1000.0);
263
264         win_h = height;
265         win_w = width;
266 }
267
268 static void display()
269 {
270         camera->set_orbit_params(theta, phi, dist);
271
272         // gfx_clear(0.76, 0.3, 0.43);
273         gfx_clear(0.1, 0.1, 0.1);
274
275         tr->draw();
276 //      rground->draw();
277         // rcow->draw();
278 }