From a32b120a2c06d3c7ad6a217bc46bba9e76d75d93 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 13 Aug 2015 18:08:22 +0200 Subject: [PATCH] dedicated shader for outlines --- TODO | 4 --- src/graphics/PlainColor.hpp | 42 +++++++++++++++++++++++ src/graphics/Viewport.hpp | 6 ++++ src/graphics/shader.cpp | 66 +++++++++++++++++++++++++++++++++++++ src/graphics/viewport.cpp | 18 ++++++++++ src/ui/ui.cpp | 21 ++++++------ 6 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 src/graphics/PlainColor.hpp diff --git a/TODO b/TODO index fffc6de..9bd2aaa 100644 --- a/TODO +++ b/TODO @@ -8,10 +8,6 @@ composite entity animations complex entities are made up of part which have their own local transform that can be animated (like e.g. an arm or head) -textures - - okay, now I need a better solution for the crosshair ^^ - font rendering with background now being a thing, a padding might be nice diff --git a/src/graphics/PlainColor.hpp b/src/graphics/PlainColor.hpp new file mode 100644 index 0000000..cfaaebe --- /dev/null +++ b/src/graphics/PlainColor.hpp @@ -0,0 +1,42 @@ +#ifndef BLANK_GRAPHICS_PLAINCOLOR_HPP_ +#define BLANK_GRAPHICS_PLAINCOLOR_HPP_ + +#include "Program.hpp" + +#include +#include + + +namespace blank { + +class PlainColor { + +public: + PlainColor(); + + void Activate() noexcept; + + void SetM(const glm::mat4 &m) noexcept; + void SetProjection(const glm::mat4 &p) noexcept; + void SetView(const glm::mat4 &v) noexcept; + void SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept; + void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept; + + const glm::mat4 &Projection() const noexcept { return projection; } + const glm::mat4 &View() const noexcept { return view; } + const glm::mat4 &GetVP() const noexcept { return vp; } + +private: + Program program; + + glm::mat4 projection; + glm::mat4 view; + glm::mat4 vp; + + GLuint mvp_handle; + +}; + +} + +#endif diff --git a/src/graphics/Viewport.hpp b/src/graphics/Viewport.hpp index 1995ce6..4d55d88 100644 --- a/src/graphics/Viewport.hpp +++ b/src/graphics/Viewport.hpp @@ -7,6 +7,7 @@ #include "Camera.hpp" #include "Canvas.hpp" #include "DirectionalLighting.hpp" +#include "PlainColor.hpp" #include @@ -49,6 +50,8 @@ public: BlockLighting &ChunkProgram() noexcept; DirectionalLighting &EntityProgram() noexcept; DirectionalLighting &HUDProgram() noexcept; + PlainColor &WorldOutlineProgram() noexcept; + PlainColor &HUDOutlineProgram() noexcept; BlendedSprite &SpriteProgram() noexcept; void WorldPosition(const glm::mat4 &) noexcept; @@ -64,6 +67,7 @@ private: BlockLighting chunk_prog; DirectionalLighting entity_prog; + PlainColor outline_prog; BlendedSprite sprite_prog; enum { @@ -71,6 +75,8 @@ private: CHUNK, ENTITY, HUD, + OUTLINE_WORLD, + OUTLINE_HUD, SPRITE, } active_prog; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 938dc97..f04b46f 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -1,6 +1,7 @@ #include "BlendedSprite.hpp" #include "BlockLighting.hpp" #include "DirectionalLighting.hpp" +#include "PlainColor.hpp" #include "Program.hpp" #include "Shader.hpp" @@ -492,4 +493,69 @@ void BlendedSprite::SetBG(const glm::vec4 &v) noexcept { program.Uniform(bg_handle, v); } + +PlainColor::PlainColor() +: program() +, vp(1.0f) +, mvp_handle(0) { + program.LoadShader( + GL_VERTEX_SHADER, + "#version 330 core\n" + "layout(location = 0) in vec3 vtx_position;\n" + "layout(location = 1) in vec3 vtx_color;\n" + "uniform mat4 MVP;\n" + "out vec3 frag_color;\n" + "void main() {\n" + "gl_Position = MVP * vec4(vtx_position, 1);\n" + "frag_color = vtx_color;\n" + "}\n" + ); + program.LoadShader( + GL_FRAGMENT_SHADER, + "#version 330 core\n" + "in vec3 frag_color;\n" + "out vec3 color;\n" + "void main() {\n" + "color = frag_color;\n" + "}\n" + ); + program.Link(); + if (!program.Linked()) { + program.Log(std::cerr); + throw std::runtime_error("link program"); + } + + mvp_handle = program.UniformLocation("MVP"); +} + + +void PlainColor::Activate() noexcept { + program.Use(); +} + +void PlainColor::SetM(const glm::mat4 &m) noexcept { + program.Uniform(mvp_handle, vp * m); +} + +void PlainColor::SetProjection(const glm::mat4 &p) noexcept { + projection = p; + vp = p * view; +} + +void PlainColor::SetView(const glm::mat4 &v) noexcept { + view = v; + vp = projection * v; +} + +void PlainColor::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept { + projection = p; + view = v; + vp = p * v; +} + +void PlainColor::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept { + SetVP(v, p); + SetM(m); +} + } diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp index e6ac768..48bd5ee 100644 --- a/src/graphics/viewport.cpp +++ b/src/graphics/viewport.cpp @@ -200,6 +200,24 @@ DirectionalLighting &Viewport::HUDProgram() noexcept { return entity_prog; } +PlainColor &Viewport::WorldOutlineProgram() noexcept { + if (active_prog != OUTLINE_WORLD) { + outline_prog.Activate(); + outline_prog.SetVP(cam.View(), cam.Projection()); + active_prog = OUTLINE_WORLD; + } + return outline_prog; +} + +PlainColor &Viewport::HUDOutlineProgram() noexcept { + if (active_prog != OUTLINE_HUD) { + outline_prog.Activate(); + outline_prog.SetVP(canv.View(), canv.Projection()); + active_prog = OUTLINE_HUD; + } + return outline_prog; +} + BlendedSprite &Viewport::SpriteProgram() noexcept { if (active_prog != SPRITE) { sprite_prog.Activate(); diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index be03c7e..f9836ba 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -72,17 +72,18 @@ void HUD::Display(const Block &b) { 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); - + PlainColor &outline_prog = viewport.HUDOutlineProgram(); viewport.EnableInvertBlending(); viewport.SetCursor(glm::vec3(0.0f), Gravity::CENTER); - world_prog.SetM(viewport.Cursor()); + outline_prog.SetM(viewport.Cursor()); crosshair.Draw(); if (block_visible) { + DirectionalLighting &world_prog = viewport.HUDProgram(); + world_prog.SetLightDirection({ 1.0f, 3.0f, 5.0f }); + // disable distance fog + world_prog.SetFogDensity(0.0f); + viewport.DisableBlending(); world_prog.SetM(block_transform); block.Draw(); @@ -511,9 +512,9 @@ void Interface::CheckAim() { outl_buf.Clear(); aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outl_buf); outline.Update(outl_buf); - outline_transform = glm::scale(glm::vec3(1.0002f)); - outline_transform *= aim_chunk->Transform(world.Player().ChunkCoords()); + outline_transform = aim_chunk->Transform(world.Player().ChunkCoords()); outline_transform *= aim_chunk->ToTransform(Chunk::ToPos(aim_block), aim_block); + outline_transform *= glm::scale(glm::vec3(1.005f)); } else { aim_chunk = nullptr; } @@ -524,8 +525,8 @@ void Interface::Render(Viewport &viewport) noexcept { if (config.visual_disabled) return; if (aim_chunk) { - DirectionalLighting &world_prog = viewport.EntityProgram(); - world_prog.SetM(outline_transform); + PlainColor &outline_prog = viewport.WorldOutlineProgram(); + outline_prog.SetM(outline_transform); outline.Draw(); } -- 2.39.2