]> git.localhorst.tv Git - blank.git/blob - src/graphics/viewport.cpp
combine text handling stuff into a class
[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 , sprite_prog()
83 , active_prog(NONE) {
84         glClearColor(0.0, 0.0, 0.0, 1.0);
85 }
86
87 void Viewport::VSync(bool b) noexcept {
88         if (SDL_GL_SetSwapInterval(b) != 0) {
89                 throw SDLError("SDL_GL_SetSwapInterval");
90         }
91 }
92
93 void Viewport::EnableDepthTest() noexcept {
94         glEnable(GL_DEPTH_TEST);
95         glDepthFunc(GL_LESS);
96 }
97
98 void Viewport::DisableDepthTest() noexcept {
99         glDisable(GL_DEPTH_TEST);
100 }
101
102 void Viewport::EnableBackfaceCulling() noexcept {
103         glEnable(GL_CULL_FACE);
104 }
105
106 void Viewport::DisableBackfaceCulling() noexcept {
107         glDisable(GL_CULL_FACE);
108 }
109
110 void Viewport::EnableAlphaBlending() noexcept {
111         glEnable(GL_BLEND);
112         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
113 }
114
115 void Viewport::EnableInvertBlending() noexcept {
116         glEnable(GL_BLEND);
117         glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
118 }
119
120 void Viewport::DisableBlending() noexcept {
121         glDisable(GL_BLEND);
122 }
123
124 void Viewport::Resize(int w, int h) noexcept {
125         glViewport(0, 0, w, h);
126         float fw = w;
127         float fh = h;
128         cam.Aspect(fw, fh);
129         canv.Resize(fw, fh);
130
131         chunk_prog.SetProjection(Perspective());
132         if (active_prog == HUD) {
133                 entity_prog.SetProjection(Ortho());
134         } else {
135                 entity_prog.SetProjection(Perspective());
136         }
137         sprite_prog.SetProjection(Ortho());
138 }
139
140 void Viewport::Clear() noexcept {
141         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
142 }
143
144 void Viewport::ClearDepth() noexcept {
145         glClear(GL_DEPTH_BUFFER_BIT);
146 }
147
148
149 void Viewport::SetCursor(const glm::vec3 &pos) {
150         cursor[3].x = pos.x;
151         cursor[3].y = pos.y;
152         cursor[3].z = pos.z;
153 }
154
155 void Viewport::SetCursor(const glm::vec3 &pos, Gravity grav) {
156         glm::vec2 p(align(grav, canv.Size(), glm::vec2(pos) + canv.Offset()));
157         cursor[3].x = p.x;
158         cursor[3].y = p.y;
159         cursor[3].z = pos.z;
160 }
161
162 void Viewport::MoveCursor(const glm::vec3 &d) {
163         cursor[3].x += d.x;
164         cursor[3].y += d.y;
165         cursor[3].z += d.z;
166 }
167
168
169 BlockLighting &Viewport::ChunkProgram() noexcept {
170         if (active_prog != CHUNK) {
171                 chunk_prog.Activate();
172                 EnableDepthTest();
173                 EnableBackfaceCulling();
174                 DisableBlending();
175                 active_prog = CHUNK;
176         }
177         return chunk_prog;
178 }
179
180 DirectionalLighting &Viewport::EntityProgram() noexcept {
181         if (active_prog != ENTITY) {
182                 entity_prog.Activate();
183                 EnableDepthTest();
184                 EnableBackfaceCulling();
185                 DisableBlending();
186                 entity_prog.SetVP(cam.View(), cam.Projection());
187                 active_prog = ENTITY;
188         }
189         return entity_prog;
190 }
191
192 DirectionalLighting &Viewport::HUDProgram() noexcept {
193         if (active_prog != HUD) {
194                 entity_prog.Activate();
195                 EnableDepthTest();
196                 EnableBackfaceCulling();
197                 entity_prog.SetVP(canv.View(), canv.Projection());
198                 active_prog = HUD;
199         }
200         return entity_prog;
201 }
202
203 BlendedSprite &Viewport::SpriteProgram() noexcept {
204         if (active_prog != SPRITE) {
205                 sprite_prog.Activate();
206                 EnableAlphaBlending();
207                 active_prog = SPRITE;
208         }
209         return sprite_prog;
210 }
211
212
213 void Viewport::WorldPosition(const glm::mat4 &t) noexcept {
214         cam.View(glm::inverse(t));
215         chunk_prog.SetView(cam.View());
216 }
217
218 }