]> git.localhorst.tv Git - blobs.git/blob - src/graphics/viewport.cpp
remote outdated TODO
[blobs.git] / src / graphics / viewport.cpp
1 #include "Camera.hpp"
2 #include "Viewport.hpp"
3
4 #include "../const.hpp"
5 #include "../world/Body.hpp"
6
7 #include <cmath>
8 #include <GL/glew.h>
9 #include <glm/gtx/transform.hpp>
10
11
12 namespace blobs {
13 namespace graphics {
14
15 Camera::Camera(const world::Body &r) noexcept
16 : fov(PI_0p25)
17 , aspect(1.0f)
18 , near(0.1f)
19 , far(12560.0f)
20 , projection(glm::perspective(fov, aspect, near, far))
21 , view(1.0f)
22 , ref(&r)
23 , track_orient(false) {
24
25 }
26
27 Camera::~Camera() noexcept {
28 }
29
30 Camera &Camera::FOV(float f) noexcept {
31         fov = f;
32         UpdateProjection();
33         return *this;
34 }
35
36 Camera &Camera::Aspect(float r) noexcept {
37         aspect = r;
38         UpdateProjection();
39         return *this;
40 }
41
42 Camera &Camera::Aspect(float w, float h) noexcept {
43         Aspect(w / h);
44         return *this;
45 }
46
47 Camera &Camera::Clip(float n, float f) noexcept {
48         near = n;
49         far = f;
50         UpdateProjection();
51         return *this;
52 }
53
54 Camera &Camera::Reference(const world::Body &r) noexcept {
55         ref = &r;
56         return *this;
57 }
58
59 Camera &Camera::FirstPerson(int srf, const glm::vec3 &pos, const glm::vec3 &at) noexcept {
60         track_orient = true;
61
62         float dir = srf < 3 ? 1.0f : -1.0f;
63
64         glm::vec3 position;
65         position[(srf + 0) % 3] = pos.x;
66         position[(srf + 1) % 3] = pos.y;
67         position[(srf + 2) % 3] = dir * (pos.z + Reference().Radius());
68
69         glm::vec3 up(0.0f);
70         up[(srf + 2) % 3] = dir;
71
72         glm::vec3 target;
73         target[(srf + 0) % 3] = at.x;
74         target[(srf + 1) % 3] = at.y;
75         target[(srf + 2) % 3] = dir * (at.z + Reference().Radius());
76
77         view = glm::lookAt(position, target, up);
78
79         return *this;
80 }
81
82 Camera &Camera::MapView(int srf, const glm::vec3 &pos, float roll) noexcept {
83         track_orient = true;
84
85         float dir = srf < 3 ? 1.0f : -1.0f;
86
87         glm::vec3 position;
88         position[(srf + 0) % 3] = pos.x;
89         position[(srf + 1) % 3] = pos.y;
90         position[(srf + 2) % 3] = dir * (pos.z + Reference().Radius());
91
92         glm::vec3 up(0.0f);
93         up[(srf + 0) % 3] = std::cos(roll);
94         up[(srf + 1) % 3] = std::sin(roll);
95         up[(srf + 2) % 3] = 0.0f;
96
97         glm::vec3 target = position;
98         target[(srf + 2) % 3] -= dir;
99
100         view = glm::lookAt(position, target, up);
101
102         return *this;
103 }
104
105 Camera &Camera::Orbital(const glm::vec3 &pos) noexcept {
106         track_orient = false;
107         view = glm::lookAt(pos, glm::vec3(0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
108         return *this;
109 }
110
111 glm::mat4 Camera::Model(const world::Body &b) const noexcept {
112         if (&b == ref) {
113                 return track_orient ? glm::mat4(1.0f) : glm::mat4(ref->LocalTransform());
114         } else if (b.HasParent() && &b.Parent() == ref) {
115                 return track_orient
116                         ? ref->InverseTransform() * b.FromParent() * b.LocalTransform()
117                         : b.FromParent() * b.LocalTransform();
118         } else if (ref->HasParent() && &ref->Parent() == &b) {
119                 return track_orient
120                         ? ref->InverseTransform() * ref->ToParent() * b.LocalTransform()
121                         : ref->ToParent() * b.LocalTransform();
122         } else {
123                 return track_orient
124                         ? ref->InverseTransform() * ref->ToUniverse() * b.FromUniverse() * b.LocalTransform()
125                         : ref->ToUniverse() * b.FromUniverse() * b.LocalTransform();
126         }
127 }
128
129 void Camera::UpdateProjection() noexcept {
130         projection = glm::perspective(fov, aspect, near, far);
131 }
132
133
134 Viewport::Viewport(int w, int h)
135 : width(w)
136 , height(h) {
137         Resize(w, h);
138         glClearColor(0.0, 0.0, 0.0, 1.0);
139 }
140
141 Viewport::~Viewport() {
142 }
143
144
145 void Viewport::Resize(int w, int h) {
146         width = w;
147         height = h;
148         glViewport(0, 0, w, h);
149 }
150
151 void Viewport::Clear() {
152         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
153 }
154
155 void Viewport::ClearDepth() {
156         glClear(GL_DEPTH_BUFFER_BIT);
157 }
158
159 }
160 }