skybox working
[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 "texture.h"
20
21 #include "opengl/opengl.h"
22 #include "vulkan/vk.h"
23
24 /* static functions */
25
26 static bool init(Gfx_API api);
27 static void cleanup();
28 static void display();
29
30 /* glfw callbacks */
31
32 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods);
33 static void clbk_motion(GLFWwindow *win, double x, double y);
34 static void clbk_mouse(GLFWwindow *win, int button, int action, int mods);
35 static void clbk_reshape(GLFWwindow *win, int width, int height);
36
37 /* global variables */
38
39 Mat4 mprojection;
40
41 GLFWwindow *win;
42 int win_w = 800;
43 int win_h = 600;
44
45 float phi = 25;
46 float theta = 0;
47 float dist = 4;
48
49 ShaderManager *sdr_man;
50
51 /* variables */
52
53 static float aspect;
54 static OrbitCamera *camera;
55
56 static Scene *scene_cow;
57 static Renderer *rcow;
58
59 static Scene *scene_ground;
60 static Renderer *rground; // default renderer
61 static Texture *gskybox;
62
63 /* *** */
64
65 int main(int argc, char **argv)
66 {
67         Gfx_API api;
68
69         for(int i=0; i<argc; ++i) {
70                 if(strcmp(argv[i], "-opengl") == 0) {
71                         api = GFX_GL;
72                         printf("Backend: OpenGL.\n");
73                 }
74                 else if(strcmp(argv[i], "-vulkan") == 0) {
75                         api = GFX_VK;
76                         printf("Backend: Vulkan.\n");
77                 }
78                 else {
79                         api = GFX_GL;
80                         printf("No backend specified. Using OpenGL.\n");
81                 }
82         }
83
84         if(!init(api)) {
85                 fprintf(stderr, "Failed to initialize program.\n");
86                 return 1;
87         }
88
89         glfwSetKeyCallback(win, clbk_key);
90         glfwSetCursorPosCallback(win, clbk_motion);
91         glfwSetMouseButtonCallback(win, clbk_mouse);
92         glfwSetWindowSizeCallback(win, clbk_reshape);
93
94         glfwGetWindowSize(win, &win_w, &win_h);
95         clbk_reshape(win, win_w, win_h);
96
97         while(!glfwWindowShouldClose(win)) {
98                 display();
99
100                 glfwSwapBuffers(win);
101                 glfwPollEvents();
102         }
103
104         cleanup();
105         // atexit(cleanup);
106         return 0;
107 }
108
109 static bool init(Gfx_API api)
110 {
111         if(!gfx_init(api))
112                 return false;
113
114         sdr_man = new ShaderManager;
115
116         camera = new OrbitCamera;
117         camera->set_orbit_params(phi, theta, dist);
118
119         scene_ground = new Scene;
120         if(!scene_ground->load("data/ground.obj")) {
121                 fprintf(stderr, "Failed to load scene: ground.obj.\n");
122                 return false;
123         }
124
125         scene_cow = new Scene;
126         if(!scene_cow->load("data/spot/spot.obj")) {
127                 fprintf(stderr, "Failed to load scene: spot.obj.\n");
128                 return false;
129         }
130
131         rground = new Renderer;
132         rground->camera = camera;
133         rground->scene = scene_ground;
134
135         if(!rground->create()) {
136                 fprintf(stderr, "Failed to create default renderer.\n");
137                 return false;
138         }
139
140         gskybox = gfx_create_texture();
141         gskybox->load("data/cubemap/cubemap.jpg");
142         rground->set_sky_tex(gskybox);
143
144         rcow = new Renderer;
145         rcow->camera = camera;
146         rcow->scene = scene_cow;
147
148         if(!rcow->create()) {
149                 fprintf(stderr, "Failed to create renderer for cows.\n");
150                 return false;
151         }
152
153 // TODO delete: debugging
154         for(size_t i=0; i<scene_ground->objects.size(); ++i) {
155                 printf("object: %d\n", (int)i);
156                 printf("mesh: %s\n", scene_ground->objects[i]->mesh->name.c_str());
157                 printf("material: %s\n", scene_ground->objects[i]->material->name.c_str());
158                 printf("transform:\n");
159                 scene_ground->objects[i]->transform.print();
160         }
161         return true;
162 }
163
164 static void cleanup()
165 {
166         delete sdr_man;
167         delete camera;
168
169         delete scene_cow;
170         delete rcow;
171
172         delete scene_ground;
173         delete rground;
174
175         gfx_cleanup();
176 }
177
178 static void clbk_key(GLFWwindow *win, int key, int scancode, int action, int mods)
179 {
180         if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
181                 glfwSetWindowShouldClose(win, GLFW_TRUE);
182         }
183 }
184
185 static double prev_x, prev_y;
186 static bool button[8];
187
188 static void clbk_motion(GLFWwindow *win, double x, double y)
189 {
190         double dx = x - prev_x;
191         double dy = y - prev_y;
192
193         prev_x = x;
194         prev_y = y;
195
196         if(button[0]) {
197                 theta += dx;
198                 phi += dy;
199
200                 if(phi < -90)
201                         phi = -90;
202                 if(phi > 90)
203                         phi = 90;
204         }
205
206         if(button[1]) {
207                 dist += dy * 0.1;
208                 if(dist < 0.0) {
209                         dist = 0.0;
210                 }
211         }
212 }
213
214 static void clbk_mouse(GLFWwindow *win, int bn, int action, int mods)
215 {
216         button[bn] = action == GLFW_PRESS;
217         glfwGetCursorPos(win, &prev_x, &prev_y);
218 }
219
220 static void clbk_reshape(GLFWwindow *win, int width, int height)
221 {
222         gfx_viewport(0, 0, width, height);
223         aspect = (float)width / (float)height;
224         mprojection = calc_projection_matrix(45, aspect, 0.5, 1000.0);
225
226         win_h = height;
227         win_w = width;
228 }
229
230 static void display()
231 {
232         camera->set_orbit_params(phi, theta, dist);
233
234         gfx_clear(0.76, 0.3, 0.43);
235
236         rground->draw();
237         rcow->draw();
238 }