From 5d2da8a07411ad6417d6ed8d1be997189cf5ce89 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 27 Jul 2015 13:53:58 +0200 Subject: [PATCH] reorganize basic rendering functionality --- TODO | 4 + src/app/Application.hpp | 19 +--- src/app/app.cpp | 42 +++----- src/app/init.cpp | 115 ++++++++-------------- src/app/init.hpp | 43 +++++--- src/graphics/Camera.cpp | 55 ----------- src/graphics/Camera.hpp | 12 +-- src/graphics/Canvas.hpp | 38 ++++++++ src/graphics/Viewport.hpp | 78 +++++++++++++++ src/graphics/shader.cpp | 6 -- src/graphics/viewport.cpp | 200 ++++++++++++++++++++++++++++++++++++++ src/ui/HUD.hpp | 13 +-- src/ui/Interface.hpp | 9 +- src/ui/ui.cpp | 56 ++++------- src/world/World.cpp | 13 ++- src/world/World.hpp | 5 +- tst/test.cpp | 6 +- 17 files changed, 445 insertions(+), 269 deletions(-) delete mode 100644 src/graphics/Camera.cpp create mode 100644 src/graphics/Canvas.hpp create mode 100644 src/graphics/Viewport.hpp create mode 100644 src/graphics/viewport.cpp diff --git a/TODO b/TODO index 5fc2e9e..8c52ca1 100644 --- a/TODO +++ b/TODO @@ -17,6 +17,10 @@ font colours set font fg and bg colour as either uniform or vertex attribute and lerp between them based on the texture's alpha component + it may also be feasible to get rid of SDL_ttf and use freetype + directly to eliminate the unneccessary surface creation + ftgl might also be worth looking at + command line usefull for development and later on world administration diff --git a/src/app/Application.hpp b/src/app/Application.hpp index 97cac73..a8e0f2d 100644 --- a/src/app/Application.hpp +++ b/src/app/Application.hpp @@ -5,10 +5,7 @@ #include "FrameCounter.hpp" #include "init.hpp" #include "RandomWalk.hpp" -#include "../graphics/BlendedSprite.hpp" -#include "../graphics/BlockLighting.hpp" -#include "../graphics/Camera.hpp" -#include "../graphics/DirectionalLighting.hpp" +#include "../graphics/Viewport.hpp" #include "../ui/Interface.hpp" #include "../world/World.hpp" @@ -57,21 +54,11 @@ public: static Entity &MakeTestEntity(World &); private: - InitSDL init_sdl; - InitIMG init_img; - InitTTF init_ttf; - InitGL init_gl; - Window window; - GLContext ctx; - InitGLEW init_glew; + Init init; + Viewport viewport; Assets assets; FrameCounter counter; - BlockLighting chunk_prog; - DirectionalLighting entity_prog; - BlendedSprite sprite_prog; - - Camera cam; World world; Interface interface; diff --git a/src/app/app.cpp b/src/app/app.cpp index 52a5905..8577e45 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -27,28 +27,15 @@ string get_asset_path() { namespace blank { Application::Application(const Config &config) -: init_sdl() -, init_img() -, init_ttf() -, init_gl(config.doublebuf, config.multisampling) -, window() -, ctx(window.CreateContext()) -, init_glew() +: init(config.doublebuf, config.multisampling) +, viewport() , assets(get_asset_path()) , counter() -, chunk_prog() -, entity_prog() -, sprite_prog() -, cam() , world(config.world) , interface(config.interface, assets, counter, world) , test_controller(MakeTestEntity(world)) , running(false) { - if (config.vsync) { - GLContext::EnableVSync(); - } - - glClearColor(0.0, 0.0, 0.0, 1.0); + viewport.VSync(config.vsync); } Entity &Application::MakeTestEntity(World &world) { @@ -94,7 +81,7 @@ void Application::RunS(size_t n, size_t t) { void Application::Run() { running = true; Uint32 last = SDL_GetTicks(); - window.GrabMouse(); + init.window.GrabMouse(); while (running) { Uint32 now = SDL_GetTicks(); int delta = now - last; @@ -151,17 +138,16 @@ void Application::HandleEvents() { void Application::Handle(const SDL_WindowEvent &event) { switch (event.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: - window.GrabMouse(); + init.window.GrabMouse(); break; case SDL_WINDOWEVENT_FOCUS_LOST: - window.ReleaseMouse(); + init.window.ReleaseMouse(); break; case SDL_WINDOWEVENT_RESIZED: - cam.Viewport(event.data1, event.data2); - interface.Handle(event); + viewport.Resize(event.data1, event.data2); + interface.Resize(viewport); break; default: - interface.Handle(event); break; } } @@ -177,18 +163,14 @@ void Application::Update(int dt) { void Application::Render() { // gl implementation may (and will probably) delay vsync blocking until // the first write after flipping, which is this clear call - GLContext::Clear(); + viewport.Clear(); counter.EnterRender(); - chunk_prog.SetProjection(cam.Projection()); - entity_prog.SetProjection(cam.Projection()); - - world.Render(chunk_prog, entity_prog); - - interface.Render(entity_prog, sprite_prog); + world.Render(viewport); + interface.Render(viewport); counter.ExitRender(); - window.Flip(); + init.window.Flip(); } diff --git a/src/app/init.cpp b/src/app/init.cpp index 9c97c9f..1cc0c24 100644 --- a/src/app/init.cpp +++ b/src/app/init.cpp @@ -4,30 +4,39 @@ #include #include #include -#include -#include #include namespace { -void sdl_error(std::string msg) { +std::string sdl_error_append(std::string msg) { const char *error = SDL_GetError(); if (*error != '\0') { msg += ": "; msg += error; SDL_ClearError(); } - throw std::runtime_error(msg); + return msg; } } namespace blank { +SDLError::SDLError() +: std::runtime_error(SDL_GetError()) { + +} + +SDLError::SDLError(const std::string &msg) +: std::runtime_error(sdl_error_append(msg)) { + +} + + InitSDL::InitSDL() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { - sdl_error("SDL_Init(SDL_INIT_VIDEO)"); + throw SDLError("SDL_Init(SDL_INIT_VIDEO)"); } } @@ -38,7 +47,7 @@ InitSDL::~InitSDL() { InitIMG::InitIMG() { if (IMG_Init(IMG_INIT_PNG) == 0) { - sdl_error("IMG_Init(IMG_INIT_PNG)"); + throw SDLError("IMG_Init(IMG_INIT_PNG)"); } } @@ -49,7 +58,7 @@ InitIMG::~InitIMG() { InitTTF::InitTTF() { if (TTF_Init() != 0) { - sdl_error("TTF_Init()"); + throw SDLError("TTF_Init()"); } } @@ -60,27 +69,27 @@ InitTTF::~InitTTF() { InitGL::InitGL(bool double_buffer, int sample_size) { if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)"); + throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)"); } if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)"); + throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)"); } if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)"); + throw SDLError("SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)"); } if (double_buffer) { if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)"); + throw SDLError("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)"); } } if (sample_size > 1) { if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS)"); + throw SDLError("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS)"); } if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, sample_size) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES)"); + throw SDLError("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES)"); } } } @@ -94,7 +103,7 @@ Window::Window() SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE )) { if (!handle) { - sdl_error("SDL_CreateWindow"); + throw SDLError("SDL_CreateWindow"); } } @@ -112,84 +121,30 @@ void Window::ReleaseInput() { void Window::GrabMouse() { if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) { - sdl_error("SDL_SetRelativeMouseMode"); + throw SDLError("SDL_SetRelativeMouseMode"); } } void Window::ReleaseMouse() { if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) { - sdl_error("SDL_SetRelativeMouseMode"); + throw SDLError("SDL_SetRelativeMouseMode"); } } -GLContext Window::CreateContext() { - return GLContext(handle); -} - void Window::Flip() { SDL_GL_SwapWindow(handle); } GLContext::GLContext(SDL_Window *win) -: handle(SDL_GL_CreateContext(win)) { - if (!handle) { - sdl_error("SDL_GL_CreateContext"); +: ctx(SDL_GL_CreateContext(win)) { + if (!ctx) { + throw SDLError("SDL_GL_CreateContext"); } } GLContext::~GLContext() { - if (handle) { - SDL_GL_DeleteContext(handle); - } -} - - -GLContext::GLContext(GLContext &&other) -: handle(other.handle) { - other.handle = nullptr; -} - -GLContext &GLContext::operator =(GLContext &&other) { - std::swap(handle, other.handle); - return *this; -} - -void GLContext::EnableVSync() { - if (SDL_GL_SetSwapInterval(1) != 0) { - sdl_error("SDL_GL_SetSwapInterval"); - } -} - -void GLContext::EnableDepthTest() noexcept { - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); -} - -void GLContext::EnableBackfaceCulling() noexcept { - glEnable(GL_CULL_FACE); -} - -void GLContext::EnableAlphaBlending() noexcept { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -void GLContext::EnableInvertBlending() noexcept { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); -} - -void GLContext::DisableBlending() noexcept { - glDisable(GL_BLEND); -} - -void GLContext::Clear() noexcept { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void GLContext::ClearDepthBuffer() noexcept { - glClear(GL_DEPTH_BUFFER_BIT); + SDL_GL_DeleteContext(ctx); } @@ -208,4 +163,16 @@ InitGLEW::InitGLEW() { } } + +Init::Init(bool double_buffer, int sample_size) +: init_sdl() +, init_img() +, init_ttf() +, init_gl(double_buffer, sample_size) +, window() +, ctx(window.Handle()) +, init_glew() { + +} + } diff --git a/src/app/init.hpp b/src/app/init.hpp index f0777c8..122210d 100644 --- a/src/app/init.hpp +++ b/src/app/init.hpp @@ -2,11 +2,20 @@ #define BLANK_APP_INIT_HPP_ #include +#include +#include namespace blank { -class GLContext; +class SDLError +: public std::runtime_error { + +public: + SDLError(); + explicit SDLError(const std::string &); + +}; class InitSDL { @@ -71,7 +80,7 @@ public: void GrabMouse(); void ReleaseMouse(); - GLContext CreateContext(); + SDL_Window *Handle() { return handle; } void Flip(); @@ -87,24 +96,11 @@ public: explicit GLContext(SDL_Window *); ~GLContext(); - GLContext(GLContext &&); - GLContext &operator =(GLContext &&); - GLContext(const GLContext &) = delete; GLContext &operator =(const GLContext &) = delete; - static void EnableVSync(); - static void EnableDepthTest() noexcept; - static void EnableBackfaceCulling() noexcept; - static void EnableAlphaBlending() noexcept; - static void EnableInvertBlending() noexcept; - static void DisableBlending() noexcept; - - static void Clear() noexcept; - static void ClearDepthBuffer() noexcept; - private: - SDL_GLContext handle; + SDL_GLContext ctx; }; @@ -119,6 +115,21 @@ public: }; + +struct Init { + + Init(bool double_buffer = true, int sample_size = 1); + + InitSDL init_sdl; + InitIMG init_img; + InitTTF init_ttf; + InitGL init_gl; + Window window; + GLContext ctx; + InitGLEW init_glew; + +}; + } #endif diff --git a/src/graphics/Camera.cpp b/src/graphics/Camera.cpp deleted file mode 100644 index 5f61d26..0000000 --- a/src/graphics/Camera.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "Camera.hpp" - -#include "../model/geometry.hpp" - -#include -#include - - -namespace blank { - -Camera::Camera() noexcept -: fov(PI_0p25) -, aspect(1.0f) -, near_clip(0.1f) -, far_clip(256.0f) -, projection(glm::perspective(fov, aspect, near_clip, far_clip)) { - -} - - -void Camera::Viewport(int width, int height) noexcept { - Viewport(0, 0, width, height); -} - -void Camera::Viewport(int x, int y, int width, int height) noexcept { - glViewport(x, y, width, height); - Aspect(width, height); -} - -void Camera::FOV(float f) noexcept { - fov = f; - UpdateProjection(); -} - -void Camera::Aspect(float r) noexcept { - aspect = r; - UpdateProjection(); -} - -void Camera::Aspect(float w, float h) noexcept { - Aspect(w / h); -} - -void Camera::Clip(float near, float far) noexcept { - near_clip = near; - far_clip = far; - UpdateProjection(); -} - - -void Camera::UpdateProjection() noexcept { - projection = glm::perspective(fov, aspect, near_clip, far_clip); -} - -} diff --git a/src/graphics/Camera.hpp b/src/graphics/Camera.hpp index 2fabfc6..924b5b4 100644 --- a/src/graphics/Camera.hpp +++ b/src/graphics/Camera.hpp @@ -11,16 +11,15 @@ class Camera { public: Camera() noexcept; - void Viewport(int width, int height) noexcept; - void Viewport(int x, int y, int width, int height) noexcept; - /// FOV in radians void FOV(float f) noexcept; void Aspect(float r) noexcept; void Aspect(float w, float h) noexcept; void Clip(float near, float far) noexcept; - const glm::mat4 &Projection() noexcept { return projection; } + const glm::mat4 &Projection() const noexcept { return projection; } + const glm::mat4 &View() const noexcept { return view; } + void View(const glm::mat4 &v) noexcept { view = v; } private: void UpdateProjection() noexcept; @@ -28,10 +27,11 @@ private: private: float fov; float aspect; - float near_clip; - float far_clip; + float near; + float far; glm::mat4 projection; + glm::mat4 view; }; diff --git a/src/graphics/Canvas.hpp b/src/graphics/Canvas.hpp new file mode 100644 index 0000000..a9ce7f5 --- /dev/null +++ b/src/graphics/Canvas.hpp @@ -0,0 +1,38 @@ +#ifndef BLANK_GRAPHICS_CANVAS_HPP_ +#define BLANK_GRAPHICS_CANVAS_HPP_ + +#include + + +namespace blank { + +class Canvas { + +public: + Canvas() noexcept; + + void Resize(float w, float h) noexcept; + + const glm::vec2 &Offset() const noexcept { return offset; } + const glm::vec2 &Size() const noexcept { return size; } + + const glm::mat4 &Projection() const noexcept { return projection; } + const glm::mat4 &View() const noexcept { return view; } + +private: + void UpdateProjection() noexcept; + +private: + glm::vec2 offset; + glm::vec2 size; + float near; + float far; + + glm::mat4 projection; + glm::mat4 view; + +}; + +} + +#endif diff --git a/src/graphics/Viewport.hpp b/src/graphics/Viewport.hpp new file mode 100644 index 0000000..d64e580 --- /dev/null +++ b/src/graphics/Viewport.hpp @@ -0,0 +1,78 @@ +#ifndef BLANK_GRAPHICS_VIEWPORT_HPP_ +#define BLANK_GRAPHICS_VIEWPORT_HPP_ + +#include "BlendedSprite.hpp" +#include "BlockLighting.hpp" +#include "Camera.hpp" +#include "Canvas.hpp" +#include "DirectionalLighting.hpp" + +#include +#include + + +namespace blank { + +class Viewport { + +public: + Viewport(); + + Viewport(const Viewport &) = delete; + Viewport &operator =(const Viewport &) = delete; + + void VSync(bool b) noexcept; + + void EnableDepthTest() noexcept; + void DisableDepthTest() noexcept; + + void EnableBackfaceCulling() noexcept; + void DisableBackfaceCulling() noexcept; + + void EnableAlphaBlending() noexcept; + void EnableInvertBlending() noexcept; + void DisableBlending() noexcept; + + void Resize(int w, int h) noexcept; + + float Width() const noexcept { return canv.Size().x; } + float Height() const noexcept { return canv.Size().y; } + + void Clear() noexcept; + void ClearDepth() noexcept; + + BlockLighting &ChunkProgram() noexcept; + DirectionalLighting &EntityProgram() noexcept; + DirectionalLighting &HUDProgram() noexcept; + BlendedSprite &SpriteProgram() noexcept; + + void WorldPosition(const glm::mat4 &) noexcept; + + const glm::mat4 &Perspective() const noexcept { return cam.Projection(); } + const glm::mat4 &Ortho() const noexcept { return canv.Projection(); } + const glm::mat4 &CenterTransform() const noexcept { return center; } + +private: + SDL_GLContext ctx; + Camera cam; + Canvas canv; + + glm::mat4 center; + + BlockLighting chunk_prog; + DirectionalLighting entity_prog; + BlendedSprite sprite_prog; + + enum { + NONE, + CHUNK, + ENTITY, + HUD, + SPRITE, + } active_prog; + +}; + +} + +#endif diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index c38f9af..de994ce 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -215,8 +215,6 @@ DirectionalLighting::DirectionalLighting() void DirectionalLighting::Activate() noexcept { - GLContext::EnableDepthTest(); - GLContext::EnableBackfaceCulling(); program.Use(); glUniform3f(light_direction_handle, light_direction.x, light_direction.y, light_direction.z); @@ -319,9 +317,6 @@ BlockLighting::BlockLighting() void BlockLighting::Activate() noexcept { - GLContext::EnableDepthTest(); - GLContext::EnableBackfaceCulling(); - GLContext::DisableBlending(); program.Use(); } @@ -398,7 +393,6 @@ BlendedSprite::BlendedSprite() void BlendedSprite::Activate() noexcept { - GLContext::EnableAlphaBlending(); program.Use(); } diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp new file mode 100644 index 0000000..0607380 --- /dev/null +++ b/src/graphics/viewport.cpp @@ -0,0 +1,200 @@ +#include "Camera.hpp" +#include "Canvas.hpp" +#include "Viewport.hpp" + +#include "../app/init.hpp" +#include "../model/geometry.hpp" + +#include +#include +#include +#include + + +namespace blank { + +Camera::Camera() noexcept +: fov(PI_0p25) +, aspect(1.0f) +, near(0.1f) +, far(256.0f) +, projection(glm::perspective(fov, aspect, near, far)) +, view(1.0f) { + +} + + +void Camera::FOV(float f) noexcept { + fov = f; + UpdateProjection(); +} + +void Camera::Aspect(float r) noexcept { + aspect = r; + UpdateProjection(); +} + +void Camera::Aspect(float w, float h) noexcept { + Aspect(w / h); +} + +void Camera::Clip(float n, float f) noexcept { + near = n; + far = f; + UpdateProjection(); +} + + +void Camera::UpdateProjection() noexcept { + projection = glm::perspective(fov, aspect, near, far); +} + + +Canvas::Canvas() noexcept +: offset(0.0f, 0.0f) +, size(1.0f, 1.0f) +, near(100.0f) +, far(-100.0f) +, projection(glm::ortho(offset.x, size.x, size.y, offset.y, near, far)) +, view(1.0f) { + +} + + +void Canvas::Resize(float w, float h) noexcept { + size.x = w; + size.y = h; + UpdateProjection(); +} + + +void Canvas::UpdateProjection() noexcept { + projection = glm::ortho(offset.x, size.x, size.y, offset.y, near, far); +} + + +Viewport::Viewport() +: cam() +, canv() +, center(1.0f) +, chunk_prog() +, entity_prog() +, sprite_prog() +, active_prog(NONE) { + glClearColor(0.0, 0.0, 0.0, 1.0); +} + +void Viewport::VSync(bool b) noexcept { + if (SDL_GL_SetSwapInterval(b) != 0) { + throw SDLError("SDL_GL_SetSwapInterval"); + } +} + +void Viewport::EnableDepthTest() noexcept { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); +} + +void Viewport::DisableDepthTest() noexcept { + glDisable(GL_DEPTH_TEST); +} + +void Viewport::EnableBackfaceCulling() noexcept { + glEnable(GL_CULL_FACE); +} + +void Viewport::DisableBackfaceCulling() noexcept { + glDisable(GL_CULL_FACE); +} + +void Viewport::EnableAlphaBlending() noexcept { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void Viewport::EnableInvertBlending() noexcept { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); +} + +void Viewport::DisableBlending() noexcept { + glDisable(GL_BLEND); +} + +void Viewport::Resize(int w, int h) noexcept { + glViewport(0, 0, w, h); + float fw = w; + float fh = h; + 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()); +} + +void Viewport::Clear() noexcept { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void Viewport::ClearDepth() noexcept { + glClear(GL_DEPTH_BUFFER_BIT); +} + + +BlockLighting &Viewport::ChunkProgram() noexcept { + if (active_prog != CHUNK) { + chunk_prog.Activate(); + EnableDepthTest(); + EnableBackfaceCulling(); + DisableBlending(); + active_prog = CHUNK; + } + return chunk_prog; +} + +DirectionalLighting &Viewport::EntityProgram() noexcept { + if (active_prog != ENTITY) { + entity_prog.Activate(); + EnableDepthTest(); + EnableBackfaceCulling(); + DisableBlending(); + entity_prog.SetVP(cam.View(), cam.Projection()); + active_prog = ENTITY; + } + return entity_prog; +} + +DirectionalLighting &Viewport::HUDProgram() noexcept { + if (active_prog != HUD) { + entity_prog.Activate(); + EnableDepthTest(); + EnableBackfaceCulling(); + entity_prog.SetVP(canv.View(), canv.Projection()); + active_prog = HUD; + } + return entity_prog; +} + +BlendedSprite &Viewport::SpriteProgram() noexcept { + if (active_prog != SPRITE) { + sprite_prog.Activate(); + EnableAlphaBlending(); + active_prog = SPRITE; + } + return sprite_prog; +} + + +void Viewport::WorldPosition(const glm::mat4 &t) noexcept { + cam.View(glm::inverse(t)); + chunk_prog.SetView(cam.View()); +} + +} diff --git a/src/ui/HUD.hpp b/src/ui/HUD.hpp index 245d886..4b60127 100644 --- a/src/ui/HUD.hpp +++ b/src/ui/HUD.hpp @@ -11,11 +11,10 @@ namespace blank { -class BlendedSprite; class Block; class BlockTypeRegistry; -class DirectionalLighting; class Font; +class Viewport; class HUD { @@ -25,12 +24,9 @@ public: HUD(const HUD &) = delete; HUD &operator =(const HUD &) = delete; - void Viewport(float width, float height) noexcept; - void Viewport(float x, float y, float width, float height) noexcept; - void Display(const Block &); - void Render(DirectionalLighting &, BlendedSprite &) noexcept; + void Render(Viewport &) noexcept; private: const BlockTypeRegistry &types; @@ -48,11 +44,6 @@ private: bool block_visible; OutlineModel crosshair; - glm::mat4 crosshair_transform; - - float near, far; - glm::mat4 projection; - glm::mat4 view; }; diff --git a/src/ui/Interface.hpp b/src/ui/Interface.hpp index d01fe25..f3b1252 100644 --- a/src/ui/Interface.hpp +++ b/src/ui/Interface.hpp @@ -17,9 +17,8 @@ namespace blank { class Assets; class Chunk; -class BlendedSprite; -class DirectionalLighting; class FrameCounter; +class Viewport; class World; class Interface { @@ -43,7 +42,8 @@ public: void HandlePress(const SDL_MouseButtonEvent &); void HandleRelease(const SDL_MouseButtonEvent &); void Handle(const SDL_MouseWheelEvent &); - void Handle(const SDL_WindowEvent &) noexcept; + + void Resize(const Viewport &); void FaceBlock(); void TurnBlock(); @@ -68,7 +68,7 @@ public: void Update(int dt); - void Render(DirectionalLighting &, BlendedSprite &) noexcept; + void Render(Viewport &) noexcept; private: void CheckAim(); @@ -92,6 +92,7 @@ private: Texture counter_tex; SpriteModel counter_sprite; glm::mat4 counter_transform; + float counter_x; SDL_Color counter_color; Config config; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index 88190e6..80fbbcd 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -4,9 +4,8 @@ #include "../app/Assets.hpp" #include "../app/FrameCounter.hpp" #include "../app/init.hpp" -#include "../graphics/BlendedSprite.hpp" -#include "../graphics/DirectionalLighting.hpp" #include "../graphics/Font.hpp" +#include "../graphics/Viewport.hpp" #include "../model/shapes.hpp" #include "../world/World.hpp" @@ -31,12 +30,7 @@ HUD::HUD(const BlockTypeRegistry &types, const Font &font) , label_transform(1.0f) , label_color{0xFF, 0xFF, 0xFF, 0xFF} , block_visible(false) -, crosshair() -, crosshair_transform(1.0f) -, near(100.0f) -, far(-100.0f) -, projection(glm::ortho(0.0f, 1.0f, 1.0f, 0.0f, near, far)) -, view(1.0f) { +, crosshair() { block_transform = glm::translate(block_transform, glm::vec3(50.0f, 50.0f, 0.0f)); block_transform = glm::scale(block_transform, glm::vec3(50.0f)); block_transform = glm::rotate(block_transform, 3.5f, glm::vec3(1.0f, 0.0f, 0.0f)); @@ -54,16 +48,6 @@ HUD::HUD(const BlockTypeRegistry &types, const Font &font) } -void HUD::Viewport(float width, float height) noexcept { - Viewport(0, 0, width, height); -} - -void HUD::Viewport(float x, float y, float width, float height) noexcept { - projection = glm::ortho(x, width, height, y, near, far); - crosshair_transform = glm::translate(glm::vec3(width * 0.5f, height * 0.5f, 0.0f)); -} - - void HUD::Display(const Block &b) { const BlockType &type = types.Get(b.type); @@ -84,24 +68,25 @@ void HUD::Display(const Block &b) { } -void HUD::Render(DirectionalLighting &world_prog, BlendedSprite &sprite_prog) noexcept { - world_prog.Activate(); +void HUD::Render(Viewport &viewport) noexcept { + viewport.ClearDepth(); + + DirectionalLighting &world_prog = viewport.HUDProgram(); world_prog.SetLightDirection({ 1.0f, 3.0f, 5.0f }); // disable distance fog world_prog.SetFogDensity(0.0f); - GLContext::ClearDepthBuffer(); - GLContext::EnableInvertBlending(); - world_prog.SetMVP(crosshair_transform, view, projection); + viewport.EnableInvertBlending(); + world_prog.SetM(viewport.CenterTransform()); crosshair.Draw(); if (block_visible) { - GLContext::DisableBlending(); + viewport.DisableBlending(); world_prog.SetM(block_transform); block.Draw(); - sprite_prog.Activate(); - sprite_prog.SetMVP(label_transform, view, projection); + BlendedSprite &sprite_prog = viewport.SpriteProgram(); + sprite_prog.SetM(label_transform); sprite_prog.SetTexture(block_label); label_sprite.Draw(); } @@ -128,6 +113,7 @@ Interface::Interface( , counter_tex() , counter_sprite() , counter_transform(1.0f) +, counter_x(935.0f) , counter_color{0xFF, 0xFF, 0xFF, 0xFF} , config(config) , place_timer(256) @@ -136,7 +122,6 @@ Interface::Interface( , selection(1) , fwd(0) , rev(0) { - hud.Viewport(960, 600); hud.Display(selection); } @@ -314,7 +299,7 @@ void Interface::UpdateCounter() { glm::vec2 size(font.TextSize(text.c_str())); counter_sprite.LoadRect(size.x, size.y); counter_transform = glm::translate(glm::vec3( - 400.0f - size.x, + counter_x - size.x, 25.0f, 0.75f )); @@ -402,10 +387,9 @@ void Interface::SelectPrevious() { hud.Display(selection); } -void Interface::Handle(const SDL_WindowEvent &event) noexcept { - if (event.event == SDL_WINDOWEVENT_RESIZED) { - hud.Viewport(event.data1, event.data2); - } + +void Interface::Resize(const Viewport &viewport) { + counter_x = viewport.Width() - 25.0f; } @@ -448,23 +432,23 @@ void Interface::CheckAim() { } -void Interface::Render(DirectionalLighting &world_prog, BlendedSprite &sprite_prog) noexcept { +void Interface::Render(Viewport &viewport) noexcept { if (config.visual_disabled) return; if (aim_chunk) { - world_prog.Activate(); + DirectionalLighting &world_prog = viewport.EntityProgram(); world_prog.SetM(outline_transform); outline.Draw(); } if (show_counter) { - sprite_prog.Activate(); + BlendedSprite &sprite_prog = viewport.SpriteProgram(); sprite_prog.SetM(counter_transform); sprite_prog.SetTexture(counter_tex); counter_sprite.Draw(); } - hud.Render(world_prog, sprite_prog); + hud.Render(viewport); } } diff --git a/src/world/World.cpp b/src/world/World.cpp index 94cd092..97dcc08 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -1,8 +1,7 @@ #include "World.hpp" #include "WorldCollision.hpp" -#include "../graphics/BlockLighting.hpp" -#include "../graphics/DirectionalLighting.hpp" +#include "../graphics/Viewport.hpp" #include #include @@ -295,10 +294,11 @@ void World::Resolve(Entity &e, std::vector &col) { } -void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) { - chunk_prog.Activate(); +void World::Render(Viewport &viewport) { + viewport.WorldPosition(player->Transform(player->ChunkCoords())); + + BlockLighting &chunk_prog = viewport.ChunkProgram(); chunk_prog.SetFogDensity(fog_density); - chunk_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); for (Chunk &chunk : chunks.Loaded()) { glm::mat4 m(chunk.Transform(player->ChunkCoords())); @@ -309,10 +309,9 @@ void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) } } - entity_prog.Activate(); + DirectionalLighting &entity_prog = viewport.EntityProgram(); entity_prog.SetLightDirection(light_direction); entity_prog.SetFogDensity(fog_density); - entity_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); for (Entity &entity : entities) { if (entity.HasShape()) { diff --git a/src/world/World.hpp b/src/world/World.hpp index 9ec4cb2..10710fb 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -14,8 +14,7 @@ namespace blank { -class BlockLighting; -class DirectionalLighting; +class Viewport; class WorldCollision; class World { @@ -59,7 +58,7 @@ public: void Update(int dt); - void Render(BlockLighting &, DirectionalLighting &); + void Render(Viewport &); private: BlockTypeRegistry blockType; diff --git a/tst/test.cpp b/tst/test.cpp index 180b0ed..b12d04b 100644 --- a/tst/test.cpp +++ b/tst/test.cpp @@ -8,11 +8,7 @@ using CppUnit::TextUi::TestRunner; int main(int, char **) { - blank::InitSDL sdl; - blank::InitGL gl; - blank::Window win; - blank::GLContext ctx(win.CreateContext()); - blank::InitGLEW glew; + blank::Init init; TestRunner runner; TestFactoryRegistry ®istry = TestFactoryRegistry::getRegistry(); -- 2.39.2