--- /dev/null
+#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
#include "Canvas.hpp"
#include "DirectionalLighting.hpp"
#include "PlainColor.hpp"
+#include "SkyBoxShader.hpp"
#include <glm/glm.hpp>
void VSync(bool b) noexcept;
void EnableDepthTest() noexcept;
+ void EqualDepthTest() noexcept;
void DisableDepthTest() noexcept;
void EnableBackfaceCulling() noexcept;
DirectionalLighting &HUDProgram() noexcept;
PlainColor &WorldOutlineProgram() noexcept;
PlainColor &HUDOutlineProgram() noexcept;
+ SkyBoxShader &SkyBoxProgram() noexcept;
BlendedSprite &SpriteProgram() noexcept;
void WorldPosition(const glm::mat4 &) noexcept;
BlockLighting chunk_prog;
DirectionalLighting entity_prog;
PlainColor outline_prog;
+ SkyBoxShader sky_prog;
BlendedSprite sprite_prog;
enum {
HUD,
OUTLINE_WORLD,
OUTLINE_HUD,
+ SKY_BOX,
SPRITE,
} active_prog;
#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"
}
+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)
, cursor(1.0f)
, chunk_prog()
, entity_prog()
+, sky_prog()
, sprite_prog()
, active_prog(NONE) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glDepthFunc(GL_LESS);
}
+void Viewport::EqualDepthTest() noexcept {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+}
+
void Viewport::DisableDepthTest() noexcept {
glDisable(GL_DEPTH_TEST);
}
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();
#include "BlockModel.hpp"
#include "EntityModel.hpp"
#include "OutlineModel.hpp"
+#include "SkyBoxModel.hpp"
#include <glm/glm.hpp>
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(); }
--- /dev/null
+#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
#include "BlockModel.hpp"
#include "EntityModel.hpp"
#include "OutlineModel.hpp"
+#include "SkyBoxModel.hpp"
#include "SpriteModel.hpp"
+#include "shapes.hpp"
+
#include <algorithm>
#include <iostream>
}
+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,
}
}
+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());