]> git.localhorst.tv Git - blank.git/blob - src/graphics/viewport.cpp
reorganize basic rendering functionality
[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 , center(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         center = glm::translate(glm::vec3(fw * 0.5f, fh * 0.5f, 0.0f));
132
133         chunk_prog.SetProjection(Perspective());
134         if (active_prog == HUD) {
135                 entity_prog.SetProjection(Ortho());
136         } else {
137                 entity_prog.SetProjection(Perspective());
138         }
139         sprite_prog.SetProjection(Ortho());
140 }
141
142 void Viewport::Clear() noexcept {
143         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
144 }
145
146 void Viewport::ClearDepth() noexcept {
147         glClear(GL_DEPTH_BUFFER_BIT);
148 }
149
150
151 BlockLighting &Viewport::ChunkProgram() noexcept {
152         if (active_prog != CHUNK) {
153                 chunk_prog.Activate();
154                 EnableDepthTest();
155                 EnableBackfaceCulling();
156                 DisableBlending();
157                 active_prog = CHUNK;
158         }
159         return chunk_prog;
160 }
161
162 DirectionalLighting &Viewport::EntityProgram() noexcept {
163         if (active_prog != ENTITY) {
164                 entity_prog.Activate();
165                 EnableDepthTest();
166                 EnableBackfaceCulling();
167                 DisableBlending();
168                 entity_prog.SetVP(cam.View(), cam.Projection());
169                 active_prog = ENTITY;
170         }
171         return entity_prog;
172 }
173
174 DirectionalLighting &Viewport::HUDProgram() noexcept {
175         if (active_prog != HUD) {
176                 entity_prog.Activate();
177                 EnableDepthTest();
178                 EnableBackfaceCulling();
179                 entity_prog.SetVP(canv.View(), canv.Projection());
180                 active_prog = HUD;
181         }
182         return entity_prog;
183 }
184
185 BlendedSprite &Viewport::SpriteProgram() noexcept {
186         if (active_prog != SPRITE) {
187                 sprite_prog.Activate();
188                 EnableAlphaBlending();
189                 active_prog = SPRITE;
190         }
191         return sprite_prog;
192 }
193
194
195 void Viewport::WorldPosition(const glm::mat4 &t) noexcept {
196         cam.View(glm::inverse(t));
197         chunk_prog.SetView(cam.View());
198 }
199
200 }