1e45c4bee3f2f348dcd685d68df675e66e807cef
[demo] / src / main.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <vector>
5
6 #include <gmath/gmath.h>
7
8 #include "global.h"
9
10 /* TODO: fix those */
11 #include "camera.h"
12 #include "mesh.h"
13 #include "object.h"
14 #include "scene.h"
15 #include "shader_manager.h"
16
17 #include "opengl/opengl.h"
18 #include "vulkan/vk.h"
19
20 /* static functions */
21
22 static bool init();
23 static void cleanup();
24 static void display();
25
26 /* glfw callbacks */
27
28 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods);
29 static void clbk_motion(GLFWwindow *win, double x, double y);
30 static void clbk_mouse(GLFWwindow *win, int button, int action, int mods);
31 static void clbk_reshape(GLFWwindow *win, int width, int height);
32
33 /* global variables */
34
35 bool use_vulkan;
36 Mat4 mprojection;
37
38 GLFWwindow *win;
39 int win_w = 800;
40 int win_h = 600;
41
42 OrbitCamera *camera;
43 float phi = 25;
44 float theta = 0;
45 float dist = 4;
46
47 ShaderManager *sdr_man;
48
49 /* variables */
50 static float aspect;
51
52 // TODO: remove just for test:
53 static Scene scene;
54
55 int main(int argc, char **argv)
56 {
57         for(int i=0; i<argc; ++i) {
58                 if(strcmp(argv[i], "-opengl") == 0) {
59                         use_vulkan = false;
60                         printf("Backend: OpenGL.\n");
61                 }
62                 else if(strcmp(argv[i], "-vulkan") == 0) {
63                         use_vulkan = true;
64                         printf("Backend: Vulkan.\n");
65                 }
66                 else {
67                         printf("No backend specified. Using OpenGL.\n");
68                 }
69         }
70
71         if(!init()) {
72                 fprintf(stderr, "Failed to initialize program.\n");
73                 return 1;
74         }
75
76         glfwSetKeyCallback(win, clbk_key);
77         glfwSetCursorPosCallback(win, clbk_motion);
78         glfwSetMouseButtonCallback(win, clbk_mouse);
79         glfwSetWindowSizeCallback(win, clbk_reshape);
80
81         while(!glfwWindowShouldClose(win)) {
82                 display();
83
84                 glfwSwapBuffers(win);
85                 glfwPollEvents();
86         }
87
88         atexit(cleanup);
89         return 0;
90 }
91
92 static bool init()
93 {
94         if(use_vulkan) {
95                 if(!init_vulkan())
96                         return false;
97         }
98         else {
99                 if(!init_opengl())
100                         return false;
101         }
102
103         sdr_man = new ShaderManager;
104
105         camera = new OrbitCamera;
106         camera->set_orbit_params(phi, theta, dist);
107
108         if(!scene.load("data/spot/spot_control_mesh.obj")) {
109                 fprintf(stderr, "Failed to load scene.\n");
110                 return false;
111         }
112
113 // TODO delete: debugging
114         for(size_t i=0; i<scene.objects.size(); ++i) {
115                 printf("object: %d\n", (int)i);
116                 printf("mesh: %s\n", scene.objects[i]->mesh->name.c_str());
117                 printf("material: %s\n", scene.objects[i]->material->name.c_str());
118                 printf("transform:\n");
119                 scene.objects[i]->transform.print();
120         }
121         return true;
122 }
123
124 static void cleanup()
125 {
126         delete sdr_man;
127         delete camera;
128
129         if(use_vulkan) {
130                 cleanup_vulkan();
131         }
132         else {
133                 cleanup_opengl();
134         }
135 }
136
137 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods)
138 {
139         if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
140                 glfwSetWindowShouldClose(win, GLFW_TRUE);
141         }
142 }
143
144 static double prev_x, prev_y;
145 static int button;
146
147 static void clbk_motion(GLFWwindow *win, double x, double y)
148 {
149         switch(button) {
150         case GLFW_MOUSE_BUTTON_LEFT:
151                 theta += x - prev_x;
152                 phi += y - prev_y;
153
154                 if(phi < -90)
155                         phi = -90;
156                 if(phi > 90)
157                         phi = 90;
158
159                 break;
160
161         case GLFW_MOUSE_BUTTON_RIGHT:
162                 dist *= (y - prev_y) * 0.01 + 1;
163                 if(dist < 0.0) {
164                         dist = 0.0;
165                 }
166                 break;
167         }
168
169         prev_x = x;
170         prev_y = y;
171 }
172
173 static void clbk_mouse(GLFWwindow *win, int bn, int action, int mods)
174 {
175         button = bn;
176         glfwGetCursorPos(win, &prev_x, &prev_y);
177 }
178
179 static void clbk_reshape(GLFWwindow *win, int width, int height)
180 {
181         if(use_vulkan) {
182                 //TODO
183                 return;
184         }
185         else {
186                 glViewport(0, 0, width, height);
187                 aspect = (float)width / (float)height;
188                 mprojection = calc_projection_matrix(1000, 0.5, aspect, 45);
189         }
190 }
191
192 static void display()
193 {
194         if(use_vulkan) {
195                 display_vulkan();
196         }
197         else {
198                 display_opengl();
199                 scene.objects[0]->mesh->draw();
200         }
201 }