]> git.localhorst.tv Git - blank.git/commitdiff
sky box model & shader
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 23 Sep 2015 15:07:05 +0000 (17:07 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 23 Sep 2015 15:32:19 +0000 (17:32 +0200)
src/graphics/SkyBoxShader.hpp [new file with mode: 0644]
src/graphics/Viewport.hpp
src/graphics/shader.cpp
src/graphics/viewport.cpp
src/model/Shape.hpp
src/model/SkyBoxModel.hpp [new file with mode: 0644]
src/model/model.cpp
src/model/shape.cpp

diff --git a/src/graphics/SkyBoxShader.hpp b/src/graphics/SkyBoxShader.hpp
new file mode 100644 (file)
index 0000000..752298e
--- /dev/null
@@ -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
index 4d55d8893dadbe289bd3a9c835170c1709ba4906..03e0e0d05c247420387bdc5fc1c851a71b3f992b 100644 (file)
@@ -8,6 +8,7 @@
 #include "Canvas.hpp"
 #include "DirectionalLighting.hpp"
 #include "PlainColor.hpp"
+#include "SkyBoxShader.hpp"
 
 #include <glm/glm.hpp>
 
@@ -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;
 
index f04b46f5f1eba30ca828d3fc6c92d4dbe5a73d94..62a9c631a1057991899c9f511d78ddd6eb341c28 100644 (file)
@@ -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)
index 48bd5ee32ce017751f436a25a8228a51f5703059..875da78d83c6ecb1913f5cfa61a45ebcc0cabbcb 100644 (file)
@@ -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();
index 28a36ab6445afd585328a2999ad3ea8967011bb0..312b1aafd1cf212951ffeee433ed2a22b99da5bf 100644 (file)
@@ -4,6 +4,7 @@
 #include "BlockModel.hpp"
 #include "EntityModel.hpp"
 #include "OutlineModel.hpp"
+#include "SkyBoxModel.hpp"
 
 #include <glm/glm.hpp>
 
@@ -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 (file)
index 0000000..84555ee
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef BLANK_MODEL_SKYBOXMODEL_HPP_
+#define BLANK_MODEL_SKYBOXMODEL_HPP_
+
+#include "../graphics/VertexArray.hpp"
+
+#include <vector>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+class SkyBoxModel {
+
+public:
+       using Position = glm::vec3;
+       using Index = unsigned int;
+
+       using Positions = std::vector<Position>;
+       using Indices = std::vector<Index>;
+
+       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<ATTRIB_COUNT>;
+
+public:
+       void LoadUnitBox();
+       void Update(const Buffer &) noexcept;
+
+       void Draw() const noexcept;
+
+private:
+       VAO vao;
+
+};
+
+}
+
+#endif
index 72de1dadfa304f9d0026e30411def46cc022a839..7aaf8f613b931a595e16a89800197260dd6fd044 100644 (file)
@@ -1,8 +1,11 @@
 #include "BlockModel.hpp"
 #include "EntityModel.hpp"
 #include "OutlineModel.hpp"
+#include "SkyBoxModel.hpp"
 #include "SpriteModel.hpp"
 
+#include "shapes.hpp"
+
 #include <algorithm>
 #include <iostream>
 
@@ -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,
index 4ee5b8f24299c74163c48d5bc3c5c7b46d5ae773..7422f899e856297f7ccb2f49bbbf53c2c2fa991a 100644 (file)
@@ -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());