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
#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"
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;
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) {
void Application::Run() {
running = true;
Uint32 last = SDL_GetTicks();
- window.GrabMouse();
+ init.window.GrabMouse();
while (running) {
Uint32 now = SDL_GetTicks();
int delta = now - last;
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;
}
}
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();
}
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
-#include <stdexcept>
-#include <string>
#include <GL/glew.h>
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)");
}
}
InitIMG::InitIMG() {
if (IMG_Init(IMG_INIT_PNG) == 0) {
- sdl_error("IMG_Init(IMG_INIT_PNG)");
+ throw SDLError("IMG_Init(IMG_INIT_PNG)");
}
}
InitTTF::InitTTF() {
if (TTF_Init() != 0) {
- sdl_error("TTF_Init()");
+ throw SDLError("TTF_Init()");
}
}
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)");
}
}
}
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
)) {
if (!handle) {
- sdl_error("SDL_CreateWindow");
+ throw SDLError("SDL_CreateWindow");
}
}
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);
}
}
}
+
+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() {
+
+}
+
}
#define BLANK_APP_INIT_HPP_
#include <SDL.h>
+#include <stdexcept>
+#include <string>
namespace blank {
-class GLContext;
+class SDLError
+: public std::runtime_error {
+
+public:
+ SDLError();
+ explicit SDLError(const std::string &);
+
+};
class InitSDL {
void GrabMouse();
void ReleaseMouse();
- GLContext CreateContext();
+ SDL_Window *Handle() { return handle; }
void Flip();
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;
};
};
+
+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
+++ /dev/null
-#include "Camera.hpp"
-
-#include "../model/geometry.hpp"
-
-#include <GL/glew.h>
-#include <glm/gtc/matrix_transform.hpp>
-
-
-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);
-}
-
-}
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;
private:
float fov;
float aspect;
- float near_clip;
- float far_clip;
+ float near;
+ float far;
glm::mat4 projection;
+ glm::mat4 view;
};
--- /dev/null
+#ifndef BLANK_GRAPHICS_CANVAS_HPP_
+#define BLANK_GRAPHICS_CANVAS_HPP_
+
+#include <glm/glm.hpp>
+
+
+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
--- /dev/null
+#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 <glm/glm.hpp>
+#include <SDL.h>
+
+
+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
void DirectionalLighting::Activate() noexcept {
- GLContext::EnableDepthTest();
- GLContext::EnableBackfaceCulling();
program.Use();
glUniform3f(light_direction_handle, light_direction.x, light_direction.y, light_direction.z);
void BlockLighting::Activate() noexcept {
- GLContext::EnableDepthTest();
- GLContext::EnableBackfaceCulling();
- GLContext::DisableBlending();
program.Use();
}
void BlendedSprite::Activate() noexcept {
- GLContext::EnableAlphaBlending();
program.Use();
}
--- /dev/null
+#include "Camera.hpp"
+#include "Canvas.hpp"
+#include "Viewport.hpp"
+
+#include "../app/init.hpp"
+#include "../model/geometry.hpp"
+
+#include <GL/glew.h>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtx/transform.hpp>
+#include <SDL.h>
+
+
+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());
+}
+
+}
namespace blank {
-class BlendedSprite;
class Block;
class BlockTypeRegistry;
-class DirectionalLighting;
class Font;
+class Viewport;
class HUD {
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;
bool block_visible;
OutlineModel crosshair;
- glm::mat4 crosshair_transform;
-
- float near, far;
- glm::mat4 projection;
- glm::mat4 view;
};
class Assets;
class Chunk;
-class BlendedSprite;
-class DirectionalLighting;
class FrameCounter;
+class Viewport;
class World;
class Interface {
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();
void Update(int dt);
- void Render(DirectionalLighting &, BlendedSprite &) noexcept;
+ void Render(Viewport &) noexcept;
private:
void CheckAim();
Texture counter_tex;
SpriteModel counter_sprite;
glm::mat4 counter_transform;
+ float counter_x;
SDL_Color counter_color;
Config config;
#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"
, 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));
}
-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);
}
-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();
}
, counter_tex()
, counter_sprite()
, counter_transform(1.0f)
+, counter_x(935.0f)
, counter_color{0xFF, 0xFF, 0xFF, 0xFF}
, config(config)
, place_timer(256)
, selection(1)
, fwd(0)
, rev(0) {
- hud.Viewport(960, 600);
hud.Display(selection);
}
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
));
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;
}
}
-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);
}
}
#include "World.hpp"
#include "WorldCollision.hpp"
-#include "../graphics/BlockLighting.hpp"
-#include "../graphics/DirectionalLighting.hpp"
+#include "../graphics/Viewport.hpp"
#include <iostream>
#include <limits>
}
-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()));
}
}
- 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()) {
namespace blank {
-class BlockLighting;
-class DirectionalLighting;
+class Viewport;
class WorldCollision;
class World {
void Update(int dt);
- void Render(BlockLighting &, DirectionalLighting &);
+ void Render(Viewport &);
private:
BlockTypeRegistry blockType;
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();