]> git.localhorst.tv Git - blank.git/blob - src/app.cpp
3de246c8bff2b84b56eb33ad8fb59a7d3148f00f
[blank.git] / src / app.cpp
1 #include "app.hpp"
2
3 #include <iostream>
4 #include <stdexcept>
5
6
7 namespace {
8
9 constexpr GLfloat vtx_coords[] = {
10         -1.0f, -1.0f, 0.0f,
11          1.0f, -1.0f, 0.0f,
12          0.0f,  1.0f, 0.0f,
13 };
14
15 }
16
17 namespace blank {
18
19 Application::Application()
20 : init_sdl()
21 , init_img()
22 , init_gl()
23 , window()
24 , ctx(window.CreateContext())
25 , init_glew()
26 , program()
27 , move_velocity(0.001f)
28 , pitch_sensitivity(-0.0025f)
29 , yaw_sensitivity(-0.001f)
30 , cam()
31 , model()
32 , vtx_buf(0)
33 , mvp_handle(0)
34 , running(false)
35 , front(false)
36 , back(false)
37 , left(false)
38 , right(false)
39 , up(false)
40 , down(false) {
41         GLContext::EnableVSync();
42         GLContext::EnableBackfaceCulling();
43         program.LoadShader(
44                 GL_VERTEX_SHADER,
45                 "#version 330 core\n"
46                 "layout(location = 0) in vec3 vertexPosition_modelspace;\n"
47                 "uniform mat4 MVP;\n"
48                 "void main() {\n"
49                         "vec4 v = vec4(vertexPosition_modelspace, 1);\n"
50                         "gl_Position = MVP * v;\n"
51                 "}\n"
52         );
53         program.LoadShader(
54                 GL_FRAGMENT_SHADER,
55                 "#version 330 core\n"
56                 "out vec3 color;\n"
57                 "void main() {\n"
58                         "color = vec3(1, 1, 1);\n"
59                 "}\n"
60         );
61         program.Link();
62         if (!program.Linked()) {
63                 program.Log(std::cerr);
64                 throw std::runtime_error("link program");
65         }
66
67         GLuint VertexArrayID;
68         glGenVertexArrays(1, &VertexArrayID);
69         glBindVertexArray(VertexArrayID);
70
71         glGenBuffers(1, &vtx_buf);
72         glBindBuffer(GL_ARRAY_BUFFER, vtx_buf);
73         glBufferData(GL_ARRAY_BUFFER, sizeof(vtx_coords), vtx_coords, GL_STATIC_DRAW);
74
75         model.Position(glm::vec3(0, 0, -4));
76         cam.Position(glm::vec3(0, 0, 4));
77
78         mvp_handle = program.UniformLocation("MVP");
79
80         glClearColor(0.0, 0.0, 0.0, 1.0);
81 }
82
83 Application::~Application() {
84
85 }
86
87
88 void Application::Run() {
89         running = true;
90         Uint32 last = SDL_GetTicks();
91         window.GrabMouse();
92         while (running) {
93                 Uint32 now = SDL_GetTicks();
94                 int delta = now - last;
95                 Loop(delta);
96                 last = now;
97         }
98 }
99
100 void Application::Loop(int dt) {
101         HandleEvents();
102         Update(dt);
103         Render();
104 }
105
106
107 void Application::HandleEvents() {
108         SDL_Event event;
109         while (SDL_PollEvent(&event)) {
110                 switch (event.type) {
111                         case SDL_KEYDOWN:
112                         case SDL_KEYUP:
113                                 switch (event.key.keysym.sym) {
114                                         case SDLK_w:
115                                                 front = event.key.state == SDL_PRESSED;
116                                                 break;
117                                         case SDLK_s:
118                                                 back = event.key.state == SDL_PRESSED;
119                                                 break;
120                                         case SDLK_a:
121                                                 left = event.key.state == SDL_PRESSED;
122                                                 break;
123                                         case SDLK_d:
124                                                 right = event.key.state == SDL_PRESSED;
125                                                 break;
126                                         case SDLK_q:
127                                                 up = event.key.state == SDL_PRESSED;
128                                                 break;
129                                         case SDLK_e:
130                                                 down = event.key.state == SDL_PRESSED;
131                                                 break;
132                                 }
133                                 break;
134                         case SDL_MOUSEMOTION:
135                                 cam.RotateYaw(event.motion.xrel * yaw_sensitivity);
136                                 cam.RotatePitch(event.motion.yrel * pitch_sensitivity);
137                                 break;
138                         case SDL_QUIT:
139                                 running = false;
140                                 break;
141                         case SDL_WINDOWEVENT:
142                                 switch (event.window.event) {
143                                         case SDL_WINDOWEVENT_RESIZED:
144                                                 cam.Viewport(event.window.data1, event.window.data2);
145                                                 break;
146                                         default:
147                                                 break;
148                                 }
149                                 break;
150                         default:
151                                 break;
152                 }
153         }
154 }
155
156 void Application::Update(int dt) {
157         glm::vec3 vel;
158         if (right && !left) {
159                 vel.x = move_velocity;
160         } else if (left && !right) {
161                 vel.x = -move_velocity;
162         }
163         if (up && !down) {
164                 vel.y = move_velocity;
165         } else if (down && !up) {
166                 vel.y = -move_velocity;
167         }
168         if (back && !front) {
169                 vel.z = move_velocity;
170         } else if (front && !back) {
171                 vel.z = -move_velocity;
172         }
173         cam.Velocity(vel);
174
175         cam.Update(dt);
176         model.Update(dt);
177 }
178
179 void Application::Render() {
180         glClear(GL_COLOR_BUFFER_BIT);
181
182         program.Use();
183
184         glm::mat4 mvp(cam.MakeMVP(model.Transform()));
185         glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]);
186
187         glEnableVertexAttribArray(0);
188         glBindBuffer(GL_ARRAY_BUFFER, vtx_buf);
189         glVertexAttribPointer(
190                 0,        // attribute 0 (for shader)
191                 3,        // size
192                 GL_FLOAT, // type
193                 GL_FALSE, // normalized
194                 0,        // stride
195                 nullptr   // offset
196         );
197         glDrawArrays(
198                 GL_TRIANGLES, // how
199                 0,            // start
200                 3             // len
201         );
202         glDisableVertexAttribArray(0);
203
204         window.Flip();
205 }
206
207 }