]> git.localhorst.tv Git - blank.git/blob - src/graphics/viewport.cpp
sky box model & shader
[blank.git] / src / graphics / viewport.cpp
1 #include "Camera.hpp"
2 #include "Canvas.hpp"
3 #include "Viewport.hpp"
4
5 #include "../app/init.hpp"
6 #include "../model/geometry.hpp"
7
8 #include <GL/glew.h>
9 #include <glm/gtc/matrix_transform.hpp>
10 #include <glm/gtx/transform.hpp>
11 #include <SDL.h>
12
13
14 namespace blank {
15
16 Camera::Camera() noexcept
17 : fov(PI_0p25)
18 , aspect(1.0f)
19 , near(0.1f)
20 , far(256.0f)
21 , projection(glm::perspective(fov, aspect, near, far))
22 , view(1.0f) {
23
24 }
25
26
27 void Camera::FOV(float f) noexcept {
28         fov = f;
29         UpdateProjection();
30 }
31
32 void Camera::Aspect(float r) noexcept {
33         aspect = r;
34         UpdateProjection();
35 }
36
37 void Camera::Aspect(float w, float h) noexcept {
38         Aspect(w / h);
39 }
40
41 void Camera::Clip(float n, float f) noexcept {
42         near = n;
43         far = f;
44         UpdateProjection();
45 }
46
47
48 void Camera::UpdateProjection() noexcept {
49         projection = glm::perspective(fov, aspect, near, far);
50 }
51
52
53 Canvas::Canvas() noexcept
54 : offset(0.0f, 0.0f)
55 , size(1.0f, 1.0f)
56 , near(100.0f)
57 , far(-100.0f)
58 , projection(glm::ortho(offset.x, size.x, size.y, offset.y, near, far))
59 , view(1.0f) {
60
61 }
62
63
64 void Canvas::Resize(float w, float h) noexcept {
65         size.x = w;
66         size.y = h;
67         UpdateProjection();
68 }
69
70
71 void Canvas::UpdateProjection() noexcept {
72         projection = glm::ortho(offset.x, size.x, size.y, offset.y, near, far);
73 }
74
75
76 Viewport::Viewport()
77 : cam()
78 , canv()
79 , cursor(1.0f)
80 , chunk_prog()
81 , entity_prog()
82 , sky_prog()
83 , sprite_prog()
84 , active_prog(NONE) {
85         glClearColor(0.0, 0.0, 0.0, 1.0);
86 }
87
88 void Viewport::VSync(bool b) noexcept {
89         if (SDL_GL_SetSwapInterval(b) != 0) {
90                 throw SDLError("SDL_GL_SetSwapInterval");
91         }
92 }
93
94 void Viewport::EnableDepthTest() noexcept {
95         glEnable(GL_DEPTH_TEST);
96         glDepthFunc(GL_LESS);
97 }
98
99 void Viewport::EqualDepthTest() noexcept {
100         glEnable(GL_DEPTH_TEST);
101         glDepthFunc(GL_LEQUAL);
102 }
103
104 void Viewport::DisableDepthTest() noexcept {
105         glDisable(GL_DEPTH_TEST);
106 }
107
108 void Viewport::EnableBackfaceCulling() noexcept {
109         glEnable(GL_CULL_FACE);
110 }
111
112 void Viewport::DisableBackfaceCulling() noexcept {
113         glDisable(GL_CULL_FACE);
114 }
115
116 void Viewport::EnableAlphaBlending() noexcept {
117         glEnable(GL_BLEND);
118         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
119 }
120
121 void Viewport::EnableInvertBlending() noexcept {
122         glEnable(GL_BLEND);
123         glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
124 }
125
126 void Viewport::DisableBlending() noexcept {
127         glDisable(GL_BLEND);
128 }
129
130 void Viewport::Resize(int w, int h) noexcept {
131         glViewport(0, 0, w, h);
132         float fw = w;
133         float fh = h;
134         cam.Aspect(fw, fh);
135         canv.Resize(fw, fh);
136
137         chunk_prog.SetProjection(Perspective());
138         if (active_prog == HUD) {
139                 entity_prog.SetProjection(Ortho());
140         } else {
141                 entity_prog.SetProjection(Perspective());
142         }
143         sprite_prog.SetProjection(Ortho());
144 }
145
146 void Viewport::Clear() noexcept {
147         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
148 }
149
150 void Viewport::ClearDepth() noexcept {
151         glClear(GL_DEPTH_BUFFER_BIT);
152 }
153
154
155 void Viewport::SetCursor(const glm::vec3 &pos) {
156         cursor[3].x = pos.x;
157         cursor[3].y = pos.y;
158         cursor[3].z = pos.z;
159 }
160
161 void Viewport::SetCursor(const glm::vec3 &pos, Gravity grav) {
162         glm::vec2 p(align(grav, canv.Size(), glm::vec2(pos) + canv.Offset()));
163         cursor[3].x = p.x;
164         cursor[3].y = p.y;
165         cursor[3].z = pos.z;
166 }
167
168 void Viewport::MoveCursor(const glm::vec3 &d) {
169         cursor[3].x += d.x;
170         cursor[3].y += d.y;
171         cursor[3].z += d.z;
172 }
173
174
175 BlockLighting &Viewport::ChunkProgram() noexcept {
176         if (active_prog != CHUNK) {
177                 chunk_prog.Activate();
178                 EnableDepthTest();
179                 EnableBackfaceCulling();
180                 DisableBlending();
181                 active_prog = CHUNK;
182         }
183         return chunk_prog;
184 }
185
186 DirectionalLighting &Viewport::EntityProgram() noexcept {
187         if (active_prog != ENTITY) {
188                 entity_prog.Activate();
189                 EnableDepthTest();
190                 EnableBackfaceCulling();
191                 DisableBlending();
192                 entity_prog.SetVP(cam.View(), cam.Projection());
193                 active_prog = ENTITY;
194         }
195         return entity_prog;
196 }
197
198 DirectionalLighting &Viewport::HUDProgram() noexcept {
199         if (active_prog != HUD) {
200                 entity_prog.Activate();
201                 EnableDepthTest();
202                 EnableBackfaceCulling();
203                 entity_prog.SetVP(canv.View(), canv.Projection());
204                 active_prog = HUD;
205         }
206         return entity_prog;
207 }
208
209 PlainColor &Viewport::WorldOutlineProgram() noexcept {
210         if (active_prog != OUTLINE_WORLD) {
211                 outline_prog.Activate();
212                 outline_prog.SetVP(cam.View(), cam.Projection());
213                 active_prog = OUTLINE_WORLD;
214         }
215         return outline_prog;
216 }
217
218 PlainColor &Viewport::HUDOutlineProgram() noexcept {
219         if (active_prog != OUTLINE_HUD) {
220                 outline_prog.Activate();
221                 outline_prog.SetVP(canv.View(), canv.Projection());
222                 active_prog = OUTLINE_HUD;
223         }
224         return outline_prog;
225 }
226
227 SkyBoxShader &Viewport::SkyBoxProgram() noexcept {
228         if (active_prog != SKY_BOX) {
229                 sky_prog.Activate();
230                 DisableBlending();
231                 EqualDepthTest();
232                 active_prog = SKY_BOX;
233         }
234         return sky_prog;
235 }
236
237 BlendedSprite &Viewport::SpriteProgram() noexcept {
238         if (active_prog != SPRITE) {
239                 sprite_prog.Activate();
240                 EnableAlphaBlending();
241                 active_prog = SPRITE;
242         }
243         return sprite_prog;
244 }
245
246
247 void Viewport::WorldPosition(const glm::mat4 &t) noexcept {
248         cam.View(glm::inverse(t));
249         chunk_prog.SetView(cam.View());
250 }
251
252 }