gbuffer.cpp 6.93 KB
Newer Older
unknown's avatar
unknown committed
1
2
3
4
#include "GBuffer.h" 
#include <core/state.h>
#include <core/numeric/flags.h>
#include <util/files.h>
5
#include <core/objects/light.h>
6
#include <core/message_tags.h>
7
#include <core/rendering/batch_render_list.h>
unknown's avatar
unknown committed
8

9
namespace glare::core
unknown's avatar
unknown committed
10
{
11
12
	GBuffer::GBuffer()
		: m_width(0), m_height(0), m_skybox(std::make_shared<core::Skybox>())
13
	{
14
	}
15

16
17
18
19
20
	GBuffer::GBuffer(unsigned int width, unsigned int height, unsigned samples)
		: GBuffer()
	{
		initialize(width, height, samples);
	}
21

22
23
24
25
26
27
28
29
30
	void GBuffer::initialize(unsigned width, unsigned height, unsigned samples)
	{
		m_width = width;
		m_height = height;

		m_texture_renderer = DefaultTextureRenderers::makeRenderer(files::shader("screenshader/gbuffer/gbuffer.frag"));

		const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor());

Johannes Braun's avatar
Johannes Braun committed
31
		m_gbuffer_framebuffer = std::make_shared<Framebuffer>(static_cast<unsigned>(mode->width), static_cast<unsigned>(mode->height), samples);
32
33
34
35
36
		m_gbuffer_framebuffer->attach(gl::Attachment::eColor0);
		m_gbuffer_framebuffer->attach(gl::Attachment::eColor1);
		m_gbuffer_framebuffer->attach(gl::Attachment::eColor2);
		m_gbuffer_framebuffer->attach(gl::Attachment::eColor3);
		m_gbuffer_framebuffer->attach(gl::Attachment::eColor4);
37
		m_gbuffer_framebuffer->attach(gl::Attachment::eColor5);
38
39
		m_gbuffer_framebuffer->attach(gl::Attachment::eDepth);

Johannes Braun's avatar
Johannes Braun committed
40
		m_temporary_framebuffer_01 = std::make_shared<Framebuffer>(static_cast<unsigned>(mode->width), static_cast<unsigned>(mode->height));
41
		m_temporary_framebuffer_01->attach(gl::Attachment::eColor0);
Johannes Braun's avatar
Johannes Braun committed
42
		m_temporary_framebuffer_02 = std::make_shared<Framebuffer>(static_cast<unsigned>(mode->width), static_cast<unsigned>(mode->height));
43
44
		m_temporary_framebuffer_02->attach(gl::Attachment::eColor0);

45
		m_lights_buffer = std::make_unique<Buffer>();
46
47

		//Update all uniforms that won't change anymore...
48
49
50
51
52
53
		m_texture_renderer->shader().uniform("u_gbuffer.base_ior", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor0).textureAddress());
		m_texture_renderer->shader().uniform("u_gbuffer.rough_metallic_transmit_emit", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor1).textureAddress());
		m_texture_renderer->shader().uniform("u_gbuffer.normal", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor2).textureAddress());
		m_texture_renderer->shader().uniform("u_gbuffer.modelview_position", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor3).textureAddress());
		m_texture_renderer->shader().uniform("u_gbuffer.world_position", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor4).textureAddress());
		m_texture_renderer->shader().uniform("u_gbuffer.depth", m_gbuffer_framebuffer->attachment(gl::Attachment::eDepth).textureAddress());
54
55
56
57
58
59
60
61
62
63
64
65

		// Those will only be later updated at will when resizing.
		m_texture_renderer->shader().uniform("screen.width", m_width);
		m_texture_renderer->shader().uniform("screen.height", m_height);
		m_texture_renderer->shader().uniform("u_samples", m_gbuffer_framebuffer->samples());

		m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[0]", "samplePoint");
		m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[1]", "sampleSpot");
		m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[2]", "sampleDirectional");
		m_texture_renderer->shader().bindSubroutine(gl::ShaderType::eFragment, "u_light_sample[3]", "sampleAmbient");

	}
unknown's avatar
unknown committed
66

67
68
69
70
71
72
	void GBuffer::record(std::function<void()> render_function) const
	{
		activate();
		render_function();
		deactivate();
	}
unknown's avatar
unknown committed
73

74
75
76
77
78
	void GBuffer::activate() const
	{
		m_gbuffer_framebuffer->activate();
		gl::clear(gl::ClearBufferBits::eColor | gl::ClearBufferBits::eDepth);
	}
unknown's avatar
unknown committed
79

80
81
82
83
	void GBuffer::deactivate() const
	{
		m_gbuffer_framebuffer->deactivate();
	}
unknown's avatar
unknown committed
84

85
	void GBuffer::draw() const
86
	{
87
		m_lights_buffer->upload<LightShadow>(core::Context::current().lights().get(), gl::BufferUsage::eDynamicDraw);
88
89
90

		m_temporary_framebuffer_01->activate();
		static auto ssao_renderer = DefaultTextureRenderers::makeRenderer(files::shader("screenshader/ssao/ssao.frag"));
91
		ssao_renderer->shader().uniform("projection_matrix", core::Context::current().camera()->projectionMatrix());
92
93
94
		ssao_renderer->shader().uniform("screen_space_positions", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor3).textureAddress());
		ssao_renderer->shader().uniform("screen_space_normals", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor5).textureAddress());
		ssao_renderer->shader().uniform("u_gbuffer.depth", m_gbuffer_framebuffer->attachment(gl::Attachment::eDepth).textureAddress());
95
96
97
98
99
100
		ssao_renderer->shader().uniform("screen_size", glm::vec2(m_width, m_height));
		ssao_renderer->draw();
		m_temporary_framebuffer_01->deactivate();

		m_temporary_framebuffer_02->activate();
		static auto blur_1d = DefaultTextureRenderers::makeRenderer(files::shader("screenshader/blur/blur_1d.frag"));
101
		blur_1d->shader().uniform("rgb_color_texture", m_temporary_framebuffer_01->attachment(gl::Attachment::eColor0).textureAddress());
102
103
104
105
106
		blur_1d->shader().uniform("axis", 0u);
		blur_1d->draw();
		m_temporary_framebuffer_02->deactivate();

		m_temporary_framebuffer_01->activate();
107
		blur_1d->shader().uniform("rgb_color_texture", m_temporary_framebuffer_02->attachment(gl::Attachment::eColor0).textureAddress());
108
109
110
111
		blur_1d->shader().uniform("axis", 1u);
		blur_1d->draw();
		m_temporary_framebuffer_01->deactivate();

112
113
114
		deactivate();
		gl::setEnabled(gl::EnableParameter::eDepthTest, false);
		m_texture_renderer->shader().use();
unknown's avatar
unknown committed
115

116
		m_texture_renderer->shader().storageBuffer("lightsBuffer", *m_lights_buffer);
unknown's avatar
unknown committed
117

118
		if (m_skybox->isInitialized())
Johannes Braun's avatar
Johannes Braun committed
119
			m_texture_renderer->shader().uniform("environment", m_skybox->texture().textureAddress());
120

121
		m_texture_renderer->shader().uniform("u_ssao_texture", m_temporary_framebuffer_01->attachment(gl::Attachment::eColor0).textureAddress());
122
123
124
		m_texture_renderer->shader().uniform("u_view", core::Context::current().camera()->viewMatrix());
		m_texture_renderer->shader().uniform("u_projection", core::Context::current().camera()->projectionMatrix());
		m_texture_renderer->shader().uniform("camera_position", glm::vec3(core::Context::current().camera()->owner()->worldTransform().position));
125
126
127
		m_texture_renderer->draw();
		gl::setEnabled(gl::EnableParameter::eDepthTest, true);
	}
128

129
130
131
132
	std::shared_ptr<Skybox> GBuffer::getSkybox() const
	{
		return m_skybox;
	}
unknown's avatar
unknown committed
133

134
135
136
137
	void GBuffer::setSkybox(std::shared_ptr<Skybox> skybox)
	{
		m_skybox = skybox;
	}
unknown's avatar
unknown committed
138

Johannes Braun's avatar
Johannes Braun committed
139
	const Framebuffer& GBuffer::framebuffer() const
140
141
142
	{
		return *m_gbuffer_framebuffer;
	}
unknown's avatar
unknown committed
143

144
145
146
147
	void GBuffer::updateSize(unsigned width, unsigned height)
	{
		updateSize(width, height, m_gbuffer_framebuffer->samples());
	}
148

149
150
151
152
153
154
155
156
	void GBuffer::updateSize(unsigned width, unsigned height, unsigned samples)
	{
		m_width = width;// width;
		m_height = height;// height;
		m_gbuffer_framebuffer->resize(width, height, samples);
		m_texture_renderer->shader().uniform("screen.width", m_width);
		m_texture_renderer->shader().uniform("screen.height", m_height);
		m_texture_renderer->shader().uniform("u_samples", samples);
unknown's avatar
unknown committed
157
	}
158
}