933bd6247b24529ca682471d52ac121ec3e9e9dc
[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 = 4;
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         camera->set_orbit_params(phi, theta, dist);
123
124         // scene_ground = new Scene;
125         // if(!scene_ground->load("data/ground.obj")) {
126         //      fprintf(stderr, "Failed to load scene: ground.obj.\n");
127         //      return false;
128         // }
129
130         // rground = new Renderer;
131         // rground->camera = camera;
132         // rground->scene = scene_ground;
133
134         // if(!rground->create()) {
135         //      fprintf(stderr, "Failed to create default renderer.\n");
136         //      return false;
137         // }
138
139         // gskybox = gfx_create_texture();
140         // gskybox->load("data/cubemap/cubemap.hdr");
141         // rground->set_sky_tex(gskybox);
142
143         scene_cow = new Scene;
144         if(!scene_cow->load("data/spot/spot.obj")) {
145                 fprintf(stderr, "Failed to load scene: spot.obj.\n");
146                 return false;
147         }
148
149         rcow = new Renderer;
150         rcow->camera = camera;
151         rcow->scene = scene_cow;
152
153         if(!rcow->create()) {
154                 fprintf(stderr, "Failed to create renderer for cows.\n");
155                 return false;
156         }
157
158         TerrainParams p;
159         p.xsz = 50;
160         p.ysz = 50;
161         p.max_height = 1;
162         p.xtiles = 1; //40;
163         p.ytiles = 1; // 40;
164         p.tile_usub = 8;
165         p.tile_vsub = 8;
166         p.num_octaves = 3;
167         p.noise_freq = 10;
168         p.coarse_heightmap = 0;
169
170         t.init();
171         t.generate(p);
172
173         tmat.diffuse = Vec3(1, 0, 0);
174         tmat.specular = Vec3(0.5, 0, 0);
175         tmat.shininess = 40;
176         tmat.dtex = 0;
177         tmat.name = "tt";
178
179         t.material = tmat;
180
181         tr = new Renderer;
182         tr->camera = camera;
183         tr->scene = t.get_visible(camera);
184         if(!tr->create()) {
185                 fprintf(stderr, "terrain fail\n");
186                 return false;
187         }
188
189
190 // TODO delete: debugging
191         // for(size_t i=0; i<scene_ground->objects.size(); ++i) {
192         //      printf("object: %d\n", (int)i);
193         //      printf("mesh: %s\n", scene_ground->objects[i]->mesh->name.c_str());
194         //      printf("material: %s\n", scene_ground->objects[i]->material->name.c_str());
195         //      printf("transform:\n");
196         //      scene_ground->objects[i]->transform.print();
197         // }
198         return true;
199 }
200
201 static void cleanup()
202 {
203         delete sdr_man;
204         delete camera;
205
206         delete scene_cow;
207         delete rcow;
208
209         // delete scene_ground;
210         // delete rground;
211
212 //TODO
213         delete tr;
214         gfx_cleanup();
215 }
216
217 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods)
218 {
219         if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
220                 glfwSetWindowShouldClose(win, GLFW_TRUE);
221         }
222 }
223
224 static double prev_x, prev_y;
225 static bool button[8];
226
227 static void clbk_motion(GLFWwindow *win, double x, double y)
228 {
229         double dx = x - prev_x;
230         double dy = y - prev_y;
231
232         prev_x = x;
233         prev_y = y;
234
235         if(button[0]) {
236                 theta += dx;
237                 phi += dy;
238
239                 if(phi < -90)
240                         phi = -90;
241                 if(phi > 90)
242                         phi = 90;
243         }
244
245         if(button[1]) {
246                 dist += dy * 0.1;
247                 if(dist < 0.0) {
248                         dist = 0.0;
249                 }
250         }
251 }
252
253 static void clbk_mouse(GLFWwindow *win, int bn, int action, int mods)
254 {
255         button[bn] = action == GLFW_PRESS;
256         glfwGetCursorPos(win, &prev_x, &prev_y);
257 }
258
259 static void clbk_reshape(GLFWwindow *win, int width, int height)
260 {
261         gfx_viewport(0, 0, width, height);
262         aspect = (float)width / (float)height;
263         mprojection = calc_projection_matrix(45, aspect, 0.5, 1000.0);
264
265         win_h = height;
266         win_w = width;
267 }
268
269 static void display()
270 {
271         camera->set_orbit_params(phi, theta, dist);
272
273         // gfx_clear(0.76, 0.3, 0.43);
274         gfx_clear(0.1, 0.1, 0.1);
275
276         tr->draw();
277 //      rground->draw();
278         // rcow->draw();
279 }