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