]> git.localhorst.tv Git - blank.git/blobdiff - src/graphics/viewport.cpp
move common exceptions to app/error
[blank.git] / src / graphics / viewport.cpp
index e6ac76810b1c39a33c0008e9a2434621a3f93c0d..a475f3e796f1d4c8d2b2af82987db711d368beb5 100644 (file)
@@ -1,9 +1,10 @@
 #include "Camera.hpp"
 #include "Canvas.hpp"
+#include "SkyBox.hpp"
 #include "Viewport.hpp"
 
-#include "../app/init.hpp"
-#include "../model/geometry.hpp"
+#include "../app/error.hpp"
+#include "../geometry/const.hpp"
 
 #include <GL/glew.h>
 #include <glm/gtc/matrix_transform.hpp>
@@ -44,6 +45,9 @@ void Camera::Clip(float n, float f) noexcept {
        UpdateProjection();
 }
 
+void Camera::View(const glm::mat4 &v) noexcept {
+       view = v;
+}
 
 void Camera::UpdateProjection() noexcept {
        projection = glm::perspective(fov, aspect, near, far);
@@ -73,18 +77,33 @@ void Canvas::UpdateProjection() noexcept {
 }
 
 
+SkyBox::SkyBox(CubeMap &&tex)
+: texture(std::move(tex))
+, mesh() {
+       mesh.LoadUnitBox();
+}
+
+void SkyBox::Render(Viewport &viewport) noexcept {
+       SkyBoxShader &prog = viewport.SkyBoxProgram();
+       prog.SetTexture(texture);
+       mesh.Draw();
+}
+
+
 Viewport::Viewport()
 : cam()
 , canv()
 , cursor(1.0f)
+, cam_offset(0.0f)
 , chunk_prog()
 , entity_prog()
+, sky_prog()
 , sprite_prog()
 , active_prog(NONE) {
        glClearColor(0.0, 0.0, 0.0, 1.0);
 }
 
-void Viewport::VSync(bool b) noexcept {
+void Viewport::VSync(bool b) {
        if (SDL_GL_SetSwapInterval(b) != 0) {
                throw SDLError("SDL_GL_SetSwapInterval");
        }
@@ -95,6 +114,11 @@ void Viewport::EnableDepthTest() noexcept {
        glDepthFunc(GL_LESS);
 }
 
+void Viewport::EqualDepthTest() noexcept {
+       glEnable(GL_DEPTH_TEST);
+       glDepthFunc(GL_LEQUAL);
+}
+
 void Viewport::DisableDepthTest() noexcept {
        glDisable(GL_DEPTH_TEST);
 }
@@ -128,13 +152,9 @@ void Viewport::Resize(int w, int h) noexcept {
        cam.Aspect(fw, fh);
        canv.Resize(fw, fh);
 
-       chunk_prog.SetProjection(Perspective());
-       if (active_prog == HUD) {
-               entity_prog.SetProjection(Ortho());
-       } else {
-               entity_prog.SetProjection(Perspective());
-       }
-       sprite_prog.SetProjection(Ortho());
+       ChunkProgram().SetProjection(Perspective());
+       SkyBoxProgram().SetProjection(Perspective());
+       SpriteProgram().SetProjection(Ortho());
 }
 
 void Viewport::Clear() noexcept {
@@ -146,20 +166,24 @@ void Viewport::ClearDepth() noexcept {
 }
 
 
-void Viewport::SetCursor(const glm::vec3 &pos) {
+glm::vec2 Viewport::GetPosition(const glm::vec2 &off, Gravity grav) const noexcept {
+       return align(grav, canv.Size(), off + canv.Offset());
+}
+
+void Viewport::SetCursor(const glm::vec3 &pos) noexcept {
        cursor[3].x = pos.x;
        cursor[3].y = pos.y;
        cursor[3].z = pos.z;
 }
 
-void Viewport::SetCursor(const glm::vec3 &pos, Gravity grav) {
-       glm::vec2 p(align(grav, canv.Size(), glm::vec2(pos) + canv.Offset()));
+void Viewport::SetCursor(const glm::vec3 &pos, Gravity grav) noexcept {
+       glm::vec2 p(GetPosition(glm::vec2(pos), grav));
        cursor[3].x = p.x;
        cursor[3].y = p.y;
        cursor[3].z = pos.z;
 }
 
-void Viewport::MoveCursor(const glm::vec3 &d) {
+void Viewport::MoveCursor(const glm::vec3 &d) noexcept {
        cursor[3].x += d.x;
        cursor[3].y += d.y;
        cursor[3].z += d.z;
@@ -200,6 +224,35 @@ DirectionalLighting &Viewport::HUDProgram() noexcept {
        return entity_prog;
 }
 
+PlainColor &Viewport::WorldColorProgram() noexcept {
+       if (active_prog != COLOR_WORLD) {
+               color_prog.Activate();
+               color_prog.SetVP(cam.View(), cam.Projection());
+               active_prog = COLOR_WORLD;
+       }
+       return color_prog;
+}
+
+PlainColor &Viewport::HUDColorProgram() noexcept {
+       if (active_prog != COLOR_HUD) {
+               color_prog.Activate();
+               color_prog.SetVP(canv.View(), canv.Projection());
+               active_prog = COLOR_HUD;
+       }
+       return color_prog;
+}
+
+SkyBoxShader &Viewport::SkyBoxProgram() noexcept {
+       if (active_prog != SKY_BOX) {
+               sky_prog.Activate();
+               DisableBlending();
+               DisableBackfaceCulling();
+               EqualDepthTest();
+               active_prog = SKY_BOX;
+       }
+       return sky_prog;
+}
+
 BlendedSprite &Viewport::SpriteProgram() noexcept {
        if (active_prog != SPRITE) {
                sprite_prog.Activate();
@@ -211,8 +264,10 @@ BlendedSprite &Viewport::SpriteProgram() noexcept {
 
 
 void Viewport::WorldPosition(const glm::mat4 &t) noexcept {
-       cam.View(glm::inverse(t));
-       chunk_prog.SetView(cam.View());
+       cam.View(glm::translate(glm::inverse(t), glm::vec3(t * glm::vec4(cam_offset, 0.0f))));
+       ChunkProgram().SetView(cam.View());
+       sky_prog.Activate();
+       SkyBoxProgram().SetView(cam.View());
 }
 
 }