3D City v-1.0
Computer Graphics Project
application.cpp
Go to the documentation of this file.
1#define _USE_MATH_DEFINES
2#include <iostream>
3#include <vector>
4#include <chrono>
5#include <thread>
6
7#include "core.h"
8#include "transformations.h"
9#include "camera.h"
10#include "engine.h"
11#include "model.h"
12
16uint32_t deltatime;
17
18const std::vector<vec4> cube = {{0, 0, 0, 1}, {0, 0, 50, 1}, {0, 50, 50, 1}, {0, 50, 0, 1}, {50, 0, 0, 1}, {50, 0, 50, 1}, {50, 50, 50, 1}, {50, 50, 0, 1}};
19const std::vector<Vertex> square = {Vertex(vec3(0, 0, 0), vec3(0, 0, 1)), Vertex(vec3(5, 0, 0), vec3(0, 0, 1)), Vertex(vec3(5, 5, 0), vec3(0, 0, 1)), Vertex(vec3(0, 5, 0), vec3(0, 0, 1))};
20const std::vector<uint32_t> square_indices = {0, 1, 2, 0, 2, 3};
21
22const std::vector<uint32_t> cube_indices = {0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7};
23const std::vector<uint32_t> cube_indices_triangles = {0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4};
24
25const std::vector<vec4> axes_endpoints = {
26 {-100, 0, 0, 1},
27 {100, 0, 0, 1},
28 {0, 100, 0, 1},
29 {0, -100, 0, 1},
30 {0, 0, 100, 1},
31 {0, 0, -100, 1}};
32
33float zvp = 50, zprp = 200;
34
35static void error_callback(int error, const char *description) {
36 fprintf(stderr, "GLFW Error: %s\n", description);
37}
38
39static bool captured = false;
40static double mx, my;
42
43void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
44 // auto dir = cam1.center - cam1.eye;
45 // const float cameraSpeed = 2.5 * s.deltatime;
46 // vec3 left = vec3::cross(cam1.getUp(), cam1.getViewDir());
47 switch (action) {
48 case GLFW_PRESS:
49 switch (key) {
50 case GLFW_KEY_ESCAPE:
51 glfwSetWindowShouldClose(window, true);
52 break;
53 case GLFW_KEY_1:
54 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
55 captured = false;
56 break;
57 case GLFW_KEY_2:
58 glfwGetCursorPos(window, &mx, &my);
59 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
60 captured = true;
61 break;
62 case GLFW_KEY_6:
63 //graphicsEngine->executesubimage2d();
64 break;
65 default:
66 break;
67 }
68 break;
69 }
70}
71
72void processHoldEvent(GLFWwindow *window) {
73 // auto dir = cam1.center - cam1.eye;
74
75 const float cameraSpeed = cam1.speed * deltatime;
77
78 if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
79 cam1.eye += (cam1.getViewDir() * cameraSpeed);
80 }
81 if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
82 cam1.eye += (left * cameraSpeed);
83 }
84 if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
85 cam1.eye -= (cam1.getViewDir() * cameraSpeed);
86 }
87 if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
88 cam1.eye -= (left * cameraSpeed);
89 }
90 if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) {
91 cam1.eye += (cam1.getUp() * cameraSpeed);
92 }
93 if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {
94 cam1.eye -= (cam1.getUp() * cameraSpeed);
95 }
96
97 float factor = 1;
98 auto light_speed = 0.3f;
99
100 if (glfwGetKey(window, GLFW_KEY_KP_8) == GLFW_PRESS) {
101 graphicsEngine->pointLights.back().delpos(cam1.getViewDir() * light_speed);
102 }
103
104 if (glfwGetKey(window, GLFW_KEY_KP_2) == GLFW_PRESS) {
105 graphicsEngine->pointLights.back().delpos(-cam1.getViewDir() * light_speed);
106 }
107
108 if (glfwGetKey(window, GLFW_KEY_KP_4) == GLFW_PRESS) {
109 graphicsEngine->pointLights.back().delpos(left * light_speed);
110 }
111
112 if (glfwGetKey(window, GLFW_KEY_KP_6) == GLFW_PRESS) {
113 graphicsEngine->pointLights.back().delpos(-left * light_speed);
114 }
115
116 if (glfwGetKey(window, GLFW_KEY_KP_ADD) == GLFW_PRESS) {
117 graphicsEngine->pointLights.back().delpos(-cam1.getUp() * light_speed);
118 }
119
120 if (glfwGetKey(window, GLFW_KEY_KP_SUBTRACT) == GLFW_PRESS) {
121 graphicsEngine->pointLights.back().delpos(cam1.getUp() * light_speed);
122 }
123
124 //if (glfwGetKey(window, GLFW_KEY_KP_1) == GLFW_PRESS) {
125 // graphicsEngine->pointLights.back().delpos(cam1.getUp() * light_speed);
126 //}
127
128 //if (glfwGetKey(window, GLFW_KEY_KP_0) == GLFW_PRESS) {
129 // graphicsEngine->pointLights.back().delpos(-cam1.getUp() * light_speed);
130 //}
131
132 if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
134 }
135 if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
137 }
138 if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
140 }
141 if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
143 }
144 if (glfwGetKey(window, GLFW_KEY_KP_0) == GLFW_PRESS) {
146 if (graphicsEngine->nearPlane < 0.01)
148 // graphicsEngine->lightRenderDistance -= 0.1;
149 // if (graphicsEngine->lightRenderDistance < 0.01)
150 // graphicsEngine->lightRenderDistance = 0.01;
151 }
152
153 if (glfwGetKey(window, GLFW_KEY_KP_1) == GLFW_PRESS) {
155 // graphicsEngine->lightRenderDistance += 0.1;
156 }
157}
158
159static void cursor_position_callback(GLFWwindow *window, double x, double y) {
160 float factor = 100;
161 if (captured) {
162 float xoffset = mx - x;
163 float yoffset = my - y;
164 mx = x;
165 my = y;
166
167 xoffset *= cam1.sensitivity * deltatime;
168 yoffset *= cam1.sensitivity * deltatime;
169 const float bias = 1.f - fabs(vec3::dot(cam1.getViewDir(), vec3(0, 1, 0)));
170 cam1.newDelYaw(-xoffset * bias);
171 cam1.DelPitch(-yoffset);
172 }
173}
174
176
177static void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
178
179 window_height = height;
180 window_width = width;
181
182 delete graphicsEngine->fboCPU;
183 graphicsEngine->fboCPU = new framebuffer(width, height);
184
185 glViewport(0, 0, window_width, window_height);
186
187 GLcall(glGenTextures(1, &graphicsEngine->tex));
188 GLcall(glActiveTexture(GL_TEXTURE0));
189 GLcall(glBindTexture(GL_TEXTURE_2D, graphicsEngine->tex));
190 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
192 GLcall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, graphicsEngine->fboCPU->x_size, graphicsEngine->fboCPU->y_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
193 GLcall(glBindTexture(GL_TEXTURE_2D, 0));
194}
195
196void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) {
197 if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
198 auto eng = (engine *)glfwGetWindowUserPointer(window);
199 glfwGetCursorPos(window, &mx, &my);
200 const size_t index = (eng->fboCPU->y_size - my) * eng->fboCPU->x_size + mx;
201 color col = eng->fboCPU->colorlayer[index];
202 printf("clicked color: (%d,%d,%d)\n", col.r(), col.g(), col.b());
203 }
204}
205float gameTime = 12.f;
206
207void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
208 auto eng = (engine *)glfwGetWindowUserPointer(window);
209 gameTime += yoffset;
210 eng->setTime(gameTime >= 24 || gameTime <= 0 ? 0 : gameTime);
211}
212
213vec3 getCenterOfMass(const Vertex *vertices, const unsigned int size) {
214 vec3 center(0);
215 for (unsigned int i = 0; i < size; i++) {
216 center += vertices[i].position;
217 }
218 return center / size;
219}
220
221int main(int argc, char **argv) {
222
223 auto threads = std::thread::hardware_concurrency();
224
225 GLFWwindow *window;
226
227 if (!glfwInit())
228 return -1;
229 glfwSetErrorCallback(error_callback);
230
231 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
232 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
233 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
234 window = glfwCreateWindow(640, 480, "main", NULL, NULL);
235 if (!(window)) {
236 glfwTerminate();
237 return -1;
238 }
239
240 glfwSetKeyCallback(window, key_callback);
241 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
242 glfwSetCursorPosCallback(window, cursor_position_callback);
243 glfwSetMouseButtonCallback(window, mouse_button_callback);
244 glfwSetScrollCallback(window, scroll_callback);
245
246 glfwMakeContextCurrent(window);
247
248 GLenum err = glewInit();
249 if (GLEW_OK != err) {
250 fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
251 }
252
253 glfwSwapInterval(1);
254
255 glfwGetFramebufferSize(window, &window_width, &window_height);
257 glfwSetWindowUserPointer(window, graphicsEngine);
258
259 auto path = searchRes();
260
261 node rootNode;
262
263 // auto lightmodel = Model::loadModel_obj(path + "/sphere.obj", "light");
264
265 // auto colorCube = Model::loadModel_obj(path + "/color/testColored.obj", "color");
266 // auto textureBox = Model::loadModel_obj(path + "/Crate/Crate1.obj", "texturebox");
267 // auto football_real = Model::loadModel_obj(path + "/Football/Football_LowPoly.obj", "football");
268 // auto stupa = Model::loadModel_obj(path + "/swayambhunath/swayambhunath.obj", "city");
269 auto city = Model::loadModel_obj(path + "/city/citymodified.obj", "city");
270 // auto texturedSquare = Model::loadModel_obj(path + "/texturedSquare.obj", "city");
271 // rootNode.children["city"] = city;
272
273 cam1.eye = vec3(-12.8432, 31.9937, -68.8763);
274 cam1.changeDir(vec3(0.141717, -0.510119, 0.848348));
275 // graphicsEngine->nearPlane = 1;
276 Material m;
277 m.diffuseColor = color(255, 0, 0);
280 graphicsEngine->dirlight = dirLight(-vec3(std::sin(60), std::cos(60), 0).normalize(), 1, color(255));
282 // graphicsEngine->wireframe = true;
284
285 int lightNumber = 0;
286 for (auto &mesh : city->meshes) {
287 if (mesh->name.find("lightCube") != std::string::npos) {
288 const vec3 center = getCenterOfMass(mesh->m_vertices.data(), mesh->m_vertices.size());
289 for (auto &vertex : mesh->m_vertices) {
290 auto debugTranslate = trans::translate(-center);
291 vertex.position = debugTranslate * vertex.position;
292 }
293 graphicsEngine->pointLights.emplace_back(center, 1.5, mesh, color(rand() % 255u, rand() % 255u, rand() % 255u, 255));
294 }
295 lightNumber++;
296 }
297
298 // graphicsEngine->pointLights.emplace_back(vec3(0.670566, 1.62085, 0.872629), 3, lightmodel->meshes.back());
299 // graphicsEngine->pointLights.back().setScale(vec3(0.5));
300
301 auto lastframe = std::chrono::high_resolution_clock::now();
302 std::string fpsString = "FPS: ";
303 const auto place = fpsString.find_first_of(" ") + 1;
304
305 while (!glfwWindowShouldClose(window)) {
306 deltatime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - lastframe).count();
307 lastframe = std::chrono::high_resolution_clock::now();
308
309 // graphicsEngine->pointLights.back().setpos(graphicsEngine->cam->eye);
310
311 glfwPollEvents();
312 processHoldEvent(window);
313
314 translate3d = trans::translate(vec3(5, 0, -5));
315 scale3d = trans::scaling3d(vec3(0.5));
316
317 fpsString.replace(fpsString.begin() + place, fpsString.end(), std::to_string(1e6 / deltatime));
318 glfwSetWindowTitle(window, fpsString.c_str());
319
320 // std::cout << "camera Eye: " << cam1.eye << std::endl;
321 // std::cout << "camera viewdir: " << cam1.getViewDir() << std::endl;
322
323 // printf("\033[F");
324 // printf("\033[F");
326
327 //for (auto &mesh : lightmodel->meshes) {
328 // graphicsEngine->currentMesh = mesh;
329 // if (mesh->doLightCalculations && mesh->draw) {
330 // // graphicsEngine->makeRequiredTriangles(mesh->m_vertices, mesh->m_indices, mat4f());
331 // }
332 //}
333
334 for (auto &mesh : city->meshes) {
336 if (mesh->doLightCalculations && mesh->draw) {
337 // if (mesh->name.find("Plane.1552") != std::string::npos)
338 graphicsEngine->makeRequiredTriangles(mesh->m_vertices, mesh->m_indices, mesh->matModel);
339 }
340 }
341
342 // graphicsEngine->currentMesh = texturedSquare->meshes[0];
343 // if (texturedSquare->meshes[0]->doLightCalculations && texturedSquare->meshes[0]->draw) {
344 // graphicsEngine->makeRequiredTriangles(texturedSquare->meshes[0]->m_vertices, texturedSquare->meshes[0]->m_indices, mat4f());
345 // }
346
347 // graphicsEngine->currentMesh = textureBox->meshes[0];
348 // if (textureBox->meshes[0]->doLightCalculations && textureBox->meshes[0]->draw) {
349 // graphicsEngine->makeRequiredTriangles(textureBox->meshes[0]->m_vertices, textureBox->meshes[0]->m_indices, trans::scaling3d(vec3(2)));
350 // }
351
352 for (auto &light : graphicsEngine->pointLights) {
353 light.draw(*graphicsEngine);
354 }
355
357 glfwSwapBuffers(window);
358 }
359 delete graphicsEngine;
360 glfwDestroyWindow(window);
361 glfwTerminate();
362 return 0;
363}
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
int window_width
const std::vector< vec4 > axes_endpoints
Definition: application.cpp:25
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: application.cpp:43
const std::vector< Vertex > square
Definition: application.cpp:19
engine * graphicsEngine
Definition: application.cpp:41
int main(int argc, char **argv)
mat4f translate3d
Definition: application.cpp:13
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
camera cam1
Definition: application.cpp:15
float zprp
Definition: application.cpp:33
const std::vector< vec4 > cube
Definition: application.cpp:18
mat4f scale3d
Definition: application.cpp:14
void processHoldEvent(GLFWwindow *window)
Definition: application.cpp:72
vec3 getCenterOfMass(const Vertex *vertices, const unsigned int size)
const std::vector< uint32_t > square_indices
Definition: application.cpp:20
int window_height
uint32_t deltatime
Definition: application.cpp:16
const std::vector< uint32_t > cube_indices
Definition: application.cpp:22
const std::vector< uint32_t > cube_indices_triangles
Definition: application.cpp:23
float gameTime
float zvp
Definition: application.cpp:33
camera class implementing simple camera movement
Definition: camera.h:6
vec3 getViewDir() const
Definition: camera.h:68
void DelPitch(float angle_in_deg)
Definition: camera.h:51
vec3 eye
Definition: camera.h:12
void newDelYaw(float angle_in_deg)
Definition: camera.h:32
void changeDir(vec3 dir)
Definition: camera.h:26
float speed
Definition: camera.h:16
float sensitivity
Definition: camera.h:15
vec3 getUp() const
Definition: camera.h:67
#define GLcall(x)
Definition: core.h:43
vec3_T< float > vec3
Definition: maths.h:305
node * loadModel_obj(std::string const &path, const std::string &name, bool flipUV=false)
loads model with given path and register it with given name.
Definition: model.h:241
class to store information about material read from .mtl file along with obj
Definition: material.h:20
color diffuseColor
Definition: material.h:27
Definition: core.h:108
vec4 position
Definition: core.h:109
class that holds color with 8 bits per channel with 4 channels rgba.
Definition: core.h:165
Definition: core.h:341
backend for all rendering purposes
Definition: engine.h:94
void makeRequiredTriangles(const std::vector< Vertex > &vertices, const std::vector< uint32_t > &indices, const mat4f &modelmat)
fill triangles array by doing required clipping and culling
Definition: engine.h:361
camera * cam
camera
Definition: engine.h:305
void clear()
clear all drawing surface
Definition: engine.h:242
void setTime(float time)
Definition: engine.h:382
Mesh * currentMesh
which material to use for further render calls
Definition: engine.h:292
bool cullBackface
switch for backface culling
Definition: engine.h:287
void draw()
send framebuffer from cpu to gpu as texture to be able to render using opengl
Definition: engine.h:251
framebuffer * fboCPU
Definition: engine.h:96
uint32_t tex
Definition: engine.h:98
std::vector< pointLight > pointLights
Definition: engine.h:300
float ambientLightIntensity
lights.
Definition: engine.h:297
dirLight dirlight
Definition: engine.h:299
float nearPlane
nearplane of camera for clipping and culling
Definition: engine.h:282
Framebuffer implementation for cpu.
Definition: engine.h:25
size_t x_size
Definition: engine.h:32
size_t y_size
Definition: engine.h:32
anything that can be transformed( has modelmatrix )
Definition: node.h:14
static float dot(const vec3_T< float > &a, const vec3_T< float > &b)
Definition: maths.h:301
static vec3_T< float > cross(const vec3_T< float > &a, const vec3_T< float > &b)
Definition: maths.h:293
vec3_T< float > normalize()
Definition: maths.h:278