From 8ab4ea13545cccbacbd1ed610968d3f481c1b3c8 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 23 Sep 2015 17:07:05 +0200 Subject: [PATCH] sky box model & shader --- src/graphics/SkyBoxShader.hpp | 44 +++++++++++++++++ src/graphics/Viewport.hpp | 5 ++ src/graphics/shader.cpp | 92 +++++++++++++++++++++++++++++++++++ src/graphics/viewport.cpp | 16 ++++++ src/model/Shape.hpp | 4 ++ src/model/SkyBoxModel.hpp | 59 ++++++++++++++++++++++ src/model/model.cpp | 21 ++++++++ src/model/shape.cpp | 11 +++++ 8 files changed, 252 insertions(+) create mode 100644 src/graphics/SkyBoxShader.hpp create mode 100644 src/model/SkyBoxModel.hpp diff --git a/src/graphics/SkyBoxShader.hpp b/src/graphics/SkyBoxShader.hpp new file mode 100644 index 0000000..752298e --- /dev/null +++ b/src/graphics/SkyBoxShader.hpp @@ -0,0 +1,44 @@ +#ifndef BLANK_GRAPHICS_SKYBOXSHADER_HPP_ +#define BLANK_GRAPHICS_SKYBOXSHADER_HPP_ + +#include "CubeMap.hpp" + + +namespace blank { + +class SkyBoxShader { + +public: + SkyBoxShader(); + + void Activate() noexcept; + + void SetTexture(CubeMap &) 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 m_handle; + GLuint mv_handle; + GLuint mvp_handle; + GLuint sampler_handle; + +}; + +} + +#endif diff --git a/src/graphics/Viewport.hpp b/src/graphics/Viewport.hpp index 4d55d88..03e0e0d 100644 --- a/src/graphics/Viewport.hpp +++ b/src/graphics/Viewport.hpp @@ -8,6 +8,7 @@ #include "Canvas.hpp" #include "DirectionalLighting.hpp" #include "PlainColor.hpp" +#include "SkyBoxShader.hpp" #include @@ -25,6 +26,7 @@ public: void VSync(bool b) noexcept; void EnableDepthTest() noexcept; + void EqualDepthTest() noexcept; void DisableDepthTest() noexcept; void EnableBackfaceCulling() noexcept; @@ -52,6 +54,7 @@ public: DirectionalLighting &HUDProgram() noexcept; PlainColor &WorldOutlineProgram() noexcept; PlainColor &HUDOutlineProgram() noexcept; + SkyBoxShader &SkyBoxProgram() noexcept; BlendedSprite &SpriteProgram() noexcept; void WorldPosition(const glm::mat4 &) noexcept; @@ -68,6 +71,7 @@ private: BlockLighting chunk_prog; DirectionalLighting entity_prog; PlainColor outline_prog; + SkyBoxShader sky_prog; BlendedSprite sprite_prog; enum { @@ -77,6 +81,7 @@ private: HUD, OUTLINE_WORLD, OUTLINE_HUD, + SKY_BOX, SPRITE, } active_prog; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index f04b46f..62a9c63 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -4,8 +4,10 @@ #include "PlainColor.hpp" #include "Program.hpp" #include "Shader.hpp" +#include "SkyBoxShader.hpp" #include "ArrayTexture.hpp" +#include "CubeMap.hpp" #include "Texture.hpp" #include "../app/init.hpp" @@ -494,6 +496,96 @@ void BlendedSprite::SetBG(const glm::vec4 &v) noexcept { } +SkyBoxShader::SkyBoxShader() +: program() +, vp(1.0f) +, m_handle(0) +, mv_handle(0) +, mvp_handle(0) +, sampler_handle(0) { + program.LoadShader( + GL_VERTEX_SHADER, + "#version 330 core\n" + "layout(location = 0) in vec3 vtx_position;\n" + "uniform mat4 M;\n" + "uniform mat4 MV;\n" + "uniform mat4 MVP;\n" + "out vec3 vtx_viewspace;\n" + "void main() {\n" + "gl_Position = MVP * vec4(vtx_position, 1);\n" + "gl_Position.z = gl_Position.w;\n" + "vtx_viewspace = (MV * vec4(vtx_position, 1)).xyz;\n" + "}\n" + ); + program.LoadShader( + GL_FRAGMENT_SHADER, + "#version 330 core\n" + "in vec3 vtx_viewspace;\n" + "uniform samplerCube tex_sampler;\n" + "out vec3 color;\n" + "void main() {\n" + "color = texture(tex_sampler, vtx_viewspace).rgb;\n" + "}\n" + ); + program.Link(); + if (!program.Linked()) { + program.Log(std::cerr); + throw std::runtime_error("link program"); + } + + m_handle = program.UniformLocation("M"); + mv_handle = program.UniformLocation("MV"); + mvp_handle = program.UniformLocation("MVP"); + sampler_handle = program.UniformLocation("tex_sampler"); +} + + +void SkyBoxShader::Activate() noexcept { + program.Use(); +} + +void SkyBoxShader::SetM(const glm::mat4 &M) noexcept { + glm::mat4 m(M); + m[0].w = 0.0f; + m[1].w = 0.0f; + m[2].w = 0.0f; + m[3] = { 0.0f, 0.0f, 0.0f, 1.0f }; + program.Uniform(m_handle, m); + program.Uniform(mv_handle, view * m); + program.Uniform(mvp_handle, vp * m); +} + +void SkyBoxShader::SetTexture(CubeMap &tex) noexcept { + glActiveTexture(GL_TEXTURE0); + tex.Bind(); + program.Uniform(sampler_handle, GLint(0)); +} + +void SkyBoxShader::SetProjection(const glm::mat4 &p) noexcept { + projection = p; + vp = p * view; +} + +void SkyBoxShader::SetView(const glm::mat4 &v) noexcept { + view = v; + view[0].w = 0.0f; + view[1].w = 0.0f; + view[2].w = 0.0f; + view[3] = { 0.0f, 0.0f, 0.0f, 1.0f }; + vp = projection * v; +} + +void SkyBoxShader::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept { + projection = p; + SetView(v); +} + +void SkyBoxShader::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept { + SetVP(v, p); + SetM(m); +} + + PlainColor::PlainColor() : program() , vp(1.0f) diff --git a/src/graphics/viewport.cpp b/src/graphics/viewport.cpp index 48bd5ee..875da78 100644 --- a/src/graphics/viewport.cpp +++ b/src/graphics/viewport.cpp @@ -79,6 +79,7 @@ Viewport::Viewport() , cursor(1.0f) , chunk_prog() , entity_prog() +, sky_prog() , sprite_prog() , active_prog(NONE) { glClearColor(0.0, 0.0, 0.0, 1.0); @@ -95,6 +96,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); } @@ -218,6 +224,16 @@ PlainColor &Viewport::HUDOutlineProgram() noexcept { return outline_prog; } +SkyBoxShader &Viewport::SkyBoxProgram() noexcept { + if (active_prog != SKY_BOX) { + sky_prog.Activate(); + DisableBlending(); + EqualDepthTest(); + active_prog = SKY_BOX; + } + return sky_prog; +} + BlendedSprite &Viewport::SpriteProgram() noexcept { if (active_prog != SPRITE) { sprite_prog.Activate(); diff --git a/src/model/Shape.hpp b/src/model/Shape.hpp index 28a36ab..312b1aa 100644 --- a/src/model/Shape.hpp +++ b/src/model/Shape.hpp @@ -4,6 +4,7 @@ #include "BlockModel.hpp" #include "EntityModel.hpp" #include "OutlineModel.hpp" +#include "SkyBoxModel.hpp" #include @@ -45,6 +46,9 @@ struct Shape { float tex_offset = 0.0f, BlockModel::Index idx_offset = 0 ) const; + void Vertices( + SkyBoxModel::Buffer &out + ) const; /// the number of vertices this shape's outline has size_t OutlineCount() const { return out_pos.size(); } diff --git a/src/model/SkyBoxModel.hpp b/src/model/SkyBoxModel.hpp new file mode 100644 index 0000000..84555ee --- /dev/null +++ b/src/model/SkyBoxModel.hpp @@ -0,0 +1,59 @@ +#ifndef BLANK_MODEL_SKYBOXMODEL_HPP_ +#define BLANK_MODEL_SKYBOXMODEL_HPP_ + +#include "../graphics/VertexArray.hpp" + +#include +#include + + +namespace blank { + +class SkyBoxModel { + +public: + using Position = glm::vec3; + using Index = unsigned int; + + using Positions = std::vector; + using Indices = std::vector; + + enum Attribute { + ATTRIB_VERTEX, + ATTRIB_INDEX, + ATTRIB_COUNT, + }; + + struct Buffer { + + Positions vertices; + Indices indices; + + void Clear() noexcept { + vertices.clear(); + indices.clear(); + } + + void Reserve(size_t p, size_t i) { + vertices.reserve(p); + indices.reserve(i); + } + + }; + + using VAO = VertexArray; + +public: + void LoadUnitBox(); + void Update(const Buffer &) noexcept; + + void Draw() const noexcept; + +private: + VAO vao; + +}; + +} + +#endif diff --git a/src/model/model.cpp b/src/model/model.cpp index 72de1da..7aaf8f6 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -1,8 +1,11 @@ #include "BlockModel.hpp" #include "EntityModel.hpp" #include "OutlineModel.hpp" +#include "SkyBoxModel.hpp" #include "SpriteModel.hpp" +#include "shapes.hpp" + #include #include @@ -84,6 +87,24 @@ void OutlineModel::Draw() noexcept { } +void SkyBoxModel::LoadUnitBox() { + Buffer buffer; + CuboidShape shape({{ -1, -1, -1 }, { 1, 1, 1 }}); + shape.Vertices(buffer); + Update(buffer); +} + +void SkyBoxModel::Update(const Buffer &buf) noexcept { + vao.Bind(); + vao.PushAttribute(ATTRIB_VERTEX, buf.vertices); + vao.PushIndices(ATTRIB_INDEX, buf.indices); +} + +void SkyBoxModel::Draw() const noexcept { + vao.DrawTriangleElements(); +} + + void SpriteModel::Buffer::LoadRect( float w, float h, const glm::vec2 &pivot, diff --git a/src/model/shape.cpp b/src/model/shape.cpp index 4ee5b8f..7422f89 100644 --- a/src/model/shape.cpp +++ b/src/model/shape.cpp @@ -59,6 +59,17 @@ void Shape::Vertices( } } +void Shape::Vertices( + SkyBoxModel::Buffer &out +) const { + for (const auto &pos : vtx_pos) { + out.vertices.emplace_back(pos); + } + for (auto idx : vtx_idx) { + out.indices.emplace_back(idx); + } +} + void Shape::Outline(OutlineModel::Buffer &out) const { out.vertices.insert(out.vertices.end(), out_pos.begin(), out_pos.end()); out.indices.insert(out.indices.end(), out_idx.begin(), out_idx.end()); -- 2.39.2