]> git.lizzy.rs Git - dragonblocks3d.git/blob - src/dragonblocks/render_engine.cpp
Initial Commit
[dragonblocks3d.git] / src / dragonblocks / render_engine.cpp
1 #include <stdexcept>
2 #include <glm/gtc/matrix_transform.hpp>
3 #include "camera.hpp"
4 #include "client.hpp"                                           // ugly, only keep until player is implemented
5 #include "core.hpp"                                             // this one too
6 #include "gldebug.hpp"
7 #include "input_handler.hpp"
8 #include "map.hpp"                                              // this one three
9 #include "mesh_gen_thread.hpp"
10 #include "render_engine.hpp"
11 #include "scene.hpp"
12 #include "shader_program.hpp"
13 #include "window.hpp"
14
15 using namespace std;
16 using namespace glm;
17 using namespace dragonblocks;
18
19 RenderEngine *RenderEngine::singleton = nullptr;
20
21 RenderEngine *RenderEngine::create()
22 {
23         if (singleton)
24                 throw runtime_error("RenderEngine already exists");
25         return singleton = new RenderEngine;
26 }
27
28 void RenderEngine::render()
29 {
30         double dtime = glfwGetTime() - last_time;
31         last_time = glfwGetTime();
32         
33         input_handler->processInput(dtime);
34         
35         glEnable(GL_DEPTH_TEST); CHECKERR
36         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); CHECKERR
37
38         updateViewMatrix();     CHECKERR
39         
40         scene->render(dtime, shader_program);
41         
42         window->swapBuffers(); CHECKERR
43         glfwPollEvents(); CHECKERR
44 }
45
46 void RenderEngine::loadChunks()
47 {
48         ivec3 chunkp = Map::getChunkPos(camera->pos);
49         for (int x = chunkp.x - 1; x <= chunkp.x + 1; x++) {
50                 for (int y = chunkp.y - 1; y < chunkp.y + 1; y++) {
51                         for (int z = chunkp.z - 1; z <= chunkp.z + 1; z++) {
52                                 client->map->createChunk(ivec3(x, y, z));
53                         }
54                 }
55         }
56 }
57
58 void RenderEngine::loop()
59 {
60         while (! window->shouldClose()) {
61                 render();
62                 mesh_gen_thread->step();
63                 loadChunks();
64         }
65 }
66
67 void RenderEngine::updateProjectionMatrix()
68 {
69         dvec2 bounds = window->getSize();
70         mat4 projection_matrix = perspective(radians(fov), bounds.x / bounds.y, 0.01, render_distance);
71         shader_program->set("projection", projection_matrix); CHECKERR
72 }
73
74 void RenderEngine::updateViewMatrix()
75 {
76         shader_program->set("view", camera->getViewMatrix()); CHECKERR
77 }
78
79 void RenderEngine::setSky(vec3 sky)
80 {
81         glClearColor(sky.r, sky.g, sky.b, 1.0); CHECKERR
82         shader_program->set("sky", sky); CHECKERR
83 }
84
85 void RenderEngine::setRenderDistance(double d)
86 {
87         render_distance = d;
88         updateProjectionMatrix();
89 }
90
91 void RenderEngine::setFov(double f)
92 {
93         fov = f;
94         updateProjectionMatrix();
95 }
96
97 RenderEngine::~RenderEngine()
98 {
99         delete window;
100         delete camera;
101         delete input_handler;
102         delete mesh_gen_thread;
103         delete scene;
104         delete shader_program;
105 }
106
107 RenderEngine::RenderEngine()
108 {
109         if (! glfwInit())
110                 throw runtime_error("Failed to initialize GLFW");
111         glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
112         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
113         glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
114         
115         window = Window::create(this);
116         camera = new Camera;
117         input_handler = new InputHandler(camera, window);
118         mesh_gen_thread = new MeshGenThread;
119         scene = new Scene;
120         
121         GLenum glew_init_err = glewInit();
122         if (glew_init_err != GLEW_OK)
123                 throw runtime_error("Failed to initialize GLEW");
124
125         shader_program = new ShaderProgram("shaders");
126
127         setSky(vec3(1.0, 1.0, 1.0));
128         setRenderDistance(16);
129         setFov(45);
130         
131         last_time = glfwGetTime();
132 }