]> git.localhorst.tv Git - blank.git/blob - src/app.cpp
block type colors
[blank.git] / src / app.cpp
1 #include "app.hpp"
2
3 #include <iostream>
4 #include <stdexcept>
5
6
7 namespace blank {
8
9 Application::Application()
10 : init_sdl()
11 , init_img()
12 , init_gl()
13 , window()
14 , ctx(window.CreateContext())
15 , init_glew()
16 , program()
17 , move_velocity(0.003f)
18 , pitch_sensitivity(-0.0025f)
19 , yaw_sensitivity(-0.001f)
20 , blockType()
21 , cam()
22 , chunk()
23 , light_position(17.0f, 17.0f, 17.0f)
24 , light_color(1.0f, 1.0f, 1.0f)
25 , light_power(250.0f)
26 , m_handle(0)
27 , v_handle(0)
28 , mv_handle(0)
29 , mvp_handle(0)
30 , light_position_handle(0)
31 , light_color_handle(0)
32 , light_power_handle(0)
33 , running(false)
34 , front(false)
35 , back(false)
36 , left(false)
37 , right(false)
38 , up(false)
39 , down(false) {
40         GLContext::EnableVSync();
41         GLContext::EnableDepthTest();
42         GLContext::EnableBackfaceCulling();
43         program.LoadShader(
44                 GL_VERTEX_SHADER,
45                 "#version 330 core\n"
46                 "layout(location = 0) in vec3 vtx_position;\n"
47                 "layout(location = 1) in vec3 vtx_color;\n"
48                 "layout(location = 2) in vec3 vtx_normal;\n"
49                 "uniform mat4 M;\n"
50                 "uniform mat4 V;\n"
51                 "uniform mat4 MVP;\n"
52                 "uniform vec3 light_position;\n"
53                 "out vec3 frag_color;\n"
54                 "out vec3 vtx_world;\n"
55                 "out vec3 normal;\n"
56                 "out vec3 eye;\n"
57                 "out vec3 light_direction;\n"
58                 "void main() {\n"
59                         "vec4 v = vec4(vtx_position, 1);\n"
60                         "gl_Position = MVP * v;\n"
61                         "vtx_world = (M * v).xyz;\n"
62                         "vec3 vtx_camera = (V * M * v).xyz;\n"
63                         "eye = vec3(0, 0, 0) - vtx_camera;\n"
64                         "vec3 light_camera = (V * v).xyz;\n"
65                         "light_direction = light_position + eye;\n"
66                         "normal = (V * M * vec4(vtx_normal, 0)).xyz;\n"
67                         "frag_color = vtx_color;\n"
68                 "}\n"
69         );
70         program.LoadShader(
71                 GL_FRAGMENT_SHADER,
72                 "#version 330 core\n"
73                 "in vec3 frag_color;\n"
74                 "in vec3 vtx_world;\n"
75                 "in vec3 normal;\n"
76                 "in vec3 eye;\n"
77                 "in vec3 light_direction;\n"
78                 "uniform mat4 MV;\n"
79                 "uniform vec3 light_position;\n"
80                 "uniform vec3 light_color;\n"
81                 "uniform float light_power;\n"
82                 "out vec3 color;\n"
83                 "void main() {\n"
84                         "vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n"
85                         "vec3 specular = vec3(0.3, 0.3, 0.3);\n"
86                         "float distance = length(light_position - vtx_world);\n"
87                         "vec3 n = normalize(normal);\n"
88                         "vec3 l = normalize(light_direction);\n"
89                         "float cos_theta = clamp(dot(n, l), 0, 1);\n"
90                         "vec3 E = normalize(eye);\n"
91                         "vec3 R = reflect(-l, n);\n"
92                         "float cos_alpha = clamp(dot(E, R), 0, 1);\n"
93                         "color = ambient"
94                                 " + frag_color * light_color * light_power * cos_theta / (distance * distance)"
95                                 " + specular * light_color * light_power * pow(cos_alpha, 5) / (distance * distance);\n"
96                 "}\n"
97         );
98         program.Link();
99         if (!program.Linked()) {
100                 program.Log(std::cerr);
101                 throw std::runtime_error("link program");
102         }
103
104         GLuint VertexArrayID;
105         glGenVertexArrays(1, &VertexArrayID);
106         glBindVertexArray(VertexArrayID);
107
108         cam.Position(glm::vec3(0, 4, 4));
109
110         blockType.Add(BlockType(true, glm::vec3(1, 1, 1)));
111         blockType.Add(BlockType(true, glm::vec3(1, 0, 0)));
112         blockType.Add(BlockType(true, glm::vec3(0, 1, 0)));
113         blockType.Add(BlockType(true, glm::vec3(0, 0, 1)));
114
115         chunk.BlockAt(glm::vec3(0, 0, 0)) = Block(blockType[4]);
116         chunk.BlockAt(glm::vec3(0, 0, 1)) = Block(blockType[1]);
117         chunk.BlockAt(glm::vec3(1, 0, 0)) = Block(blockType[2]);
118         chunk.BlockAt(glm::vec3(1, 0, 1)) = Block(blockType[3]);
119         chunk.BlockAt(glm::vec3(2, 0, 0)) = Block(blockType[4]);
120         chunk.BlockAt(glm::vec3(2, 0, 1)) = Block(blockType[1]);
121         chunk.BlockAt(glm::vec3(3, 0, 0)) = Block(blockType[2]);
122         chunk.BlockAt(glm::vec3(3, 0, 1)) = Block(blockType[3]);
123         chunk.BlockAt(glm::vec3(2, 0, 2)) = Block(blockType[4]);
124         chunk.BlockAt(glm::vec3(2, 0, 3)) = Block(blockType[1]);
125         chunk.BlockAt(glm::vec3(3, 0, 2)) = Block(blockType[2]);
126         chunk.BlockAt(glm::vec3(3, 0, 3)) = Block(blockType[3]);
127         chunk.BlockAt(glm::vec3(1, 1, 0)) = Block(blockType[1]);
128         chunk.BlockAt(glm::vec3(1, 1, 1)) = Block(blockType[4]);
129         chunk.BlockAt(glm::vec3(2, 1, 1)) = Block(blockType[3]);
130         chunk.BlockAt(glm::vec3(2, 2, 1)) = Block(blockType[2]);
131         chunk.Invalidate();
132
133         m_handle = program.UniformLocation("M");
134         v_handle = program.UniformLocation("V");
135         mv_handle = program.UniformLocation("MV");
136         mvp_handle = program.UniformLocation("MVP");
137         light_position_handle = program.UniformLocation("light_position");
138         light_color_handle = program.UniformLocation("light_color");
139         light_power_handle = program.UniformLocation("light_power");
140
141         glClearColor(0.0, 0.0, 0.0, 1.0);
142 }
143
144 Application::~Application() {
145
146 }
147
148
149 void Application::Run() {
150         running = true;
151         Uint32 last = SDL_GetTicks();
152         window.GrabMouse();
153         while (running) {
154                 Uint32 now = SDL_GetTicks();
155                 int delta = now - last;
156                 Loop(delta);
157                 last = now;
158         }
159 }
160
161 void Application::Loop(int dt) {
162         HandleEvents();
163         Update(dt);
164         Render();
165 }
166
167
168 void Application::HandleEvents() {
169         SDL_Event event;
170         while (SDL_PollEvent(&event)) {
171                 switch (event.type) {
172                         case SDL_KEYDOWN:
173                         case SDL_KEYUP:
174                                 switch (event.key.keysym.sym) {
175                                         case SDLK_w:
176                                                 front = event.key.state == SDL_PRESSED;
177                                                 break;
178                                         case SDLK_s:
179                                                 back = event.key.state == SDL_PRESSED;
180                                                 break;
181                                         case SDLK_a:
182                                                 left = event.key.state == SDL_PRESSED;
183                                                 break;
184                                         case SDLK_d:
185                                                 right = event.key.state == SDL_PRESSED;
186                                                 break;
187                                         case SDLK_q:
188                                                 up = event.key.state == SDL_PRESSED;
189                                                 break;
190                                         case SDLK_e:
191                                                 down = event.key.state == SDL_PRESSED;
192                                                 break;
193                                 }
194                                 break;
195                         case SDL_MOUSEMOTION:
196                                 cam.RotateYaw(event.motion.xrel * yaw_sensitivity);
197                                 cam.RotatePitch(event.motion.yrel * pitch_sensitivity);
198                                 break;
199                         case SDL_QUIT:
200                                 running = false;
201                                 break;
202                         case SDL_WINDOWEVENT:
203                                 switch (event.window.event) {
204                                         case SDL_WINDOWEVENT_RESIZED:
205                                                 cam.Viewport(event.window.data1, event.window.data2);
206                                                 break;
207                                         default:
208                                                 break;
209                                 }
210                                 break;
211                         default:
212                                 break;
213                 }
214         }
215 }
216
217 void Application::Update(int dt) {
218         glm::vec3 vel;
219         if (right && !left) {
220                 vel.x = move_velocity;
221         } else if (left && !right) {
222                 vel.x = -move_velocity;
223         }
224         if (up && !down) {
225                 vel.y = move_velocity;
226         } else if (down && !up) {
227                 vel.y = -move_velocity;
228         }
229         if (back && !front) {
230                 vel.z = move_velocity;
231         } else if (front && !back) {
232                 vel.z = -move_velocity;
233         }
234         cam.OrientationVelocity(vel);
235
236         cam.Update(dt);
237 }
238
239 void Application::Render() {
240         GLContext::Clear();
241
242         program.Use();
243
244         glm::mat4 m(1.0f);
245         glm::mat4 mv(cam.View() * m);
246         glm::mat4 mvp(cam.MakeMVP(m));
247         glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]);
248         glUniformMatrix4fv(v_handle, 1, GL_FALSE, &cam.View()[0][0]);
249         glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]);
250         glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]);
251         glUniform3f(light_position_handle, light_position.x, light_position.y, light_position.z);
252         glUniform3f(light_color_handle, light_color.x, light_color.y, light_color.z);
253         glUniform1f(light_power_handle, light_power);
254
255         chunk.Draw();
256
257         window.Flip();
258 }
259
260 }