skybox.cpp 3.93 KB
Newer Older
1
#include "skybox.h" 
unknown's avatar
unknown committed
2
3
4
5

#include <util/log.h>
#include <util/files.h>
#include <util/images.h>
's avatar
committed
6

7
8
#include <core/state.h>

's avatar
committed
9
10
11
12
namespace glare
{
	namespace core
	{
13
14

		Skybox::Skybox()
unknown's avatar
unknown committed
15
			: m_handle(std::move(gl::TextureTarget::eCubeMap))
's avatar
committed
16
17
		{

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
		}

		Skybox::Skybox(std::vector<fs::path> faces)
			: Skybox()
		{
			reset(faces);
		}

		bool Skybox::isInitialized() const
		{
			return m_initialized;
		}

		void Skybox::reset(const std::vector<fs::path>& faces)
		{
			m_initialized = true;
's avatar
committed
34
			int width; int height;
unknown's avatar
unknown committed
35
36
			gl::textureParameter(m_handle, gl::TextureParameter::eBaseLevel, 0);
			gl::textureParameter(m_handle, gl::TextureParameter::eMaxLevel, 8);
's avatar
committed
37
38
39
40

			for (GLuint face = 0; face < faces.size(); face++)
			{
				Log_Debug << "Face No " << face;
unknown's avatar
unknown committed
41
42
				auto vec = images::load<unsigned char>(faces[face], width, height, 3);
				images::flip(width, height, 3, vec.data());
43
				gl::textureImage2D(m_handle, gl::TextureImageTarget2D(static_cast<int>(gl::TextureImageTarget2D::eCubeMapPosX) + face), 0, gl::TextureInternalFormat::eRGB, width, height, 0, gl::TextureFormat::eRGB, gl::Type::eUByte, vec.data());
's avatar
committed
44
45
			}

unknown's avatar
unknown committed
46
47
48
49
50
51
			gl::textureParameter(m_handle, gl::TextureParameter::eMagFilter, gl::TextureFilterMag::eLinear);
			gl::textureParameter(m_handle, gl::TextureParameter::eMinFilter, gl::TextureFilterMin::eLinearMipmapLinear);
			gl::textureParameter(m_handle, gl::TextureParameter::eWrapS, gl::TextureWrapMode::eClampToEdge);
			gl::textureParameter(m_handle, gl::TextureParameter::eWrapT, gl::TextureWrapMode::eClampToEdge);
			gl::textureParameter(m_handle, gl::TextureParameter::eWrapR, gl::TextureWrapMode::eClampToEdge);
			gl::generateTextureMipmap(m_handle);
's avatar
committed
52
53
54
55
56
57
58
59
60
61
62
63

			std::vector<math::Vertex> triangle_vertices
			{
				math::Vertex{ glm::vec4(-1, -1, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(0, 0) },
				math::Vertex{ glm::vec4(3, -1, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(2, 0) },
				math::Vertex{ glm::vec4(-1, 3, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(0, 2) },
			};

			std::vector<unsigned> indices { 0, 2, 1 };

			m_triangle_mesh = std::make_shared<Mesh>(triangle_vertices, indices);

64
65
			const auto vert = std::make_shared<Shader>(gl::ShaderType::eVertex, files::shader("/cubemap/triangle_skybox.vert"));
			const auto frag = std::make_shared<Shader>(gl::ShaderType::eFragment, files::shader("/cubemap/triangle_skybox.frag"));
Johannes Braun's avatar
Johannes Braun committed
66
			m_cubemap_shader = std::make_shared<Program>(std::vector<std::shared_ptr<Shader>>{ frag, vert });
unknown's avatar
unknown committed
67

's avatar
committed
68
69
70
71
72
73
74
75
76
77
78
79
		}

		std::vector<fs::path> Skybox::collectFilesFrom(const fs::path &directory)
		{
			return { directory / "/posx.jpg",
				directory / "/negx.jpg",
				directory / "/posy.jpg",
				directory / "/negy.jpg",
				directory / "/posz.jpg",
				directory / "/negz.jpg" };
		}

80
		void Skybox::draw(DrawMode mode)
's avatar
committed
81
		{
82
83
84
85
86
			if (mode == DrawMode::eShaded)
			{
				gl::depthMask(false);
				gl::cullFace(gl::Face::eFront);
				m_cubemap_shader->use();
unknown's avatar
unknown committed
87

88
89
				m_cubemap_shader->uniform("u_cube_map", makeResident());
				m_cubemap_shader->uniform("u_inv_view_projection", glm::inverse(state::camera->getViewProjection()));
90
				m_cubemap_shader->uniform("cam_position", state::camera->owner()->worldTransform().position);
91
				m_triangle_mesh->draw();
's avatar
committed
92

93
94
95
				gl::cullFace(gl::Face::eBack);
				gl::depthMask(true);
			}
's avatar
committed
96
97
		}

98
		unsigned Skybox::id() const
's avatar
committed
99
		{
100
			return m_handle;
's avatar
committed
101
102
		}

103
		uint64_t Skybox::residentAddress() const
's avatar
committed
104
		{
105
			return m_resident_address;
's avatar
committed
106
107
		}

108
		bool Skybox::resident() const
's avatar
committed
109
		{
110
			return m_resident_address != 0 && gl::isTextureHandleResident(m_resident_address);
's avatar
committed
111
112
		}

unknown's avatar
unknown committed
113
		uint64_t Skybox::makeResident() const
's avatar
committed
114
		{
115
116
117
118
119
120
121
122
			if (!resident())
			{
				m_resident_address = gl::getTextureHandle(m_handle);
				gl::makeTextureHandleResident(m_resident_address);
			}
			assert(resident());
			return m_resident_address;
		}
's avatar
committed
123

124
125
126
127
128
129
		void Skybox::makeNonResident() const
		{
			if (resident())
			{
				gl::makeTextureHandleNonResident(m_handle);
			}
's avatar
committed
130
131
132
		}
	}
}