X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fgraphics%2Fviewport.cpp;h=0fe24085739db91a49385b635028497f2c358e6f;hb=f4729fcfcf6f4802dd2439aa23dc3a4faf39827d;hp=060738016233d00e197190106d907fe1db750eeb;hpb=5d2da8a07411ad6417d6ed8d1be997189cf5ce89;p=blank.git diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp index 0607380..0fe2408 100644 --- a/src/graphics/viewport.cpp +++ b/src/graphics/viewport.cpp @@ -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 #include @@ -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,20 +77,40 @@ 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() -, center(1.0f) +, 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"); + if (b) { + throw SDLError("SDL_GL_SetSwapInterval(1)"); + } else { + // allow failure, because this usually means there's no vsync + // support at all, i.e. "it's off" + } } } @@ -95,6 +119,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,15 +157,9 @@ void Viewport::Resize(int w, int h) noexcept { cam.Aspect(fw, fh); canv.Resize(fw, fh); - center = glm::translate(glm::vec3(fw * 0.5f, fh * 0.5f, 0.0f)); - - 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 { @@ -148,6 +171,30 @@ void Viewport::ClearDepth() noexcept { } +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) 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) noexcept { + cursor[3].x += d.x; + cursor[3].y += d.y; + cursor[3].z += d.z; +} + + BlockLighting &Viewport::ChunkProgram() noexcept { if (active_prog != CHUNK) { chunk_prog.Activate(); @@ -182,6 +229,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(); @@ -193,8 +269,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()); } }