galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
Renderer.cpp
Go to the documentation of this file.
1
7
8#include "galaxy/core/ServiceLocator.hpp"
12
13#include "Renderer.hpp"
14
15namespace galaxy
16{
17 namespace graphics
18 {
20 {
21 static Renderer renderer;
22 return renderer;
23 }
24
26 : m_camera {GAlAXY_BUFFER_CAMERA_INDEX}
27 , m_renderdata {GAlAXY_BUFFER_RENDERDATA_INDEX}
28 {
29 }
30
32 {
33 // Reserve some upfront memory to ease initial allocations.
34 if (m_cmds.capacity() < GALAXY_RENDERCOMMAND_INITIAL_ALLOCS)
35 {
36 m_cmds.reserve(GALAXY_RENDERCOMMAND_INITIAL_ALLOCS);
37 }
38
40 {
42 }
43
44 m_camera.buffer<Camera::Data>(0, 1, nullptr);
45 m_renderdata.buffer<RenderData>(0, 1, nullptr);
46
47 auto& w = core::ServiceLocator<core::Window>::ref();
48 const auto width = w.frame_width();
49 const auto height = w.frame_height();
50
51 m_post.init(width, width);
53 m_post.add<graphics::FilmicGrain>(width, width);
55 m_post.add<graphics::GaussianBlur>(width, width);
56 m_post.add<graphics::Sharpen>(width, width);
57 m_post.add<graphics::SMAA>(width, width);
58
59 calc_viewport(width, height);
60 }
61
63 {
64 m_cmds.clear();
69 }
70
71 void Renderer::on_window_resized(const events::WindowResized& e)
72 {
73 calc_viewport(e.width, e.height);
74 }
75
77 {
78 m_camera.sub_buffer<Camera::Data>(0, 1, &camera.get_data());
79 }
80
82 {
83 m_cmds.emplace_back(std::move(command));
84 }
85
86 void Renderer::submit_texture(const Texture2D& texture, VertexArray& va, Transform& tf, const int layer, const float opacity)
87 {
88 auto& cmd = m_cmds.emplace_back(RenderCommand {});
89
90 cmd.count = va.count();
91 cmd.instances = va.instances();
92 cmd.layer = layer;
93 cmd.mode = GL_TRIANGLES;
94 cmd.offset = va.offset();
95 cmd.vao = va.id();
96 cmd.texture = texture.id();
97 cmd.uniforms.colour = {1.0f, 1.0f, 1.0f, opacity};
98 cmd.uniforms.entity = -1;
99 cmd.uniforms.point = false;
100 cmd.uniforms.textured = true;
101 cmd.uniforms.transform = tf.get_transform();
102
103 submit_cmd(cmd);
104 }
105
106 void Renderer::submit_text(Text& text, Transform& tf, const int layer)
107 {
108 auto& cmd = m_cmds.emplace_back(RenderCommand {});
109
110 cmd.count = text.vao().count();
111 cmd.instances = text.vao().instances();
112 cmd.layer = layer;
113 cmd.mode = GL_TRIANGLES;
114 cmd.offset = text.vao().offset();
115 cmd.vao = text.vao().id();
116 cmd.texture = text.render_texture().texture();
117 cmd.uniforms.colour = text.m_colour.vec4();
118 cmd.uniforms.entity = -1;
119 cmd.uniforms.point = false;
120 cmd.uniforms.textured = true;
121 cmd.uniforms.transform = tf.get_transform();
122
123 submit_cmd(cmd);
124 }
125
126 void Renderer::submit_shape(Shape* shape, Transform& tf, const int layer)
127 {
128 auto& cmd = m_cmds.emplace_back(RenderCommand {});
129
130 cmd.count = shape->vao().count();
131 cmd.instances = shape->vao().instances();
132 cmd.layer = layer;
133 cmd.mode = shape->mode();
134 cmd.offset = shape->vao().offset();
135 cmd.vao = shape->vao().id();
136 cmd.texture = 0;
137 cmd.uniforms.colour = shape->m_colour.vec4();
138 cmd.uniforms.entity = -1;
139 cmd.uniforms.point = shape->mode() == GL_POINTS ? true : false;
140 cmd.uniforms.textured = false;
141 cmd.uniforms.transform = tf.get_transform();
142
143 submit_cmd(cmd);
144 }
145
147 {
148 glActiveTexture(GL_TEXTURE0);
149
150 target.bind();
151 va.bind();
152 texture->bind();
153
154 auto rtt = core::ServiceLocator<resource::Shaders>::ref().get("render_to_texture");
155 rtt->bind();
156 rtt->set_uniform("u_projection", target.get_proj());
157 rtt->set_uniform("u_transform", tf.get_transform());
158
159 glDrawElements(GL_TRIANGLES, va.count(), GL_UNSIGNED_INT, va.offset());
160
161 glBindVertexArray(0);
162 glBindTexture(GL_TEXTURE_2D, 0);
163 glUseProgram(0);
164 }
165
167 {
168 // I don't think we would ever sort the amount of renderable data required to do this in parallel faster.
169 std::sort(m_cmds.begin(), m_cmds.end(), [](auto left, auto right) -> bool {
170 return left.layer < right.layer;
171 });
172
174 m_camera.bind();
176
177 glActiveTexture(GL_TEXTURE0);
178
179 for (auto& cmd : m_cmds)
180 {
181 m_renderdata.sub_buffer<RenderData>(0, 1, &cmd.uniforms);
182
183 glBindTexture(GL_TEXTURE_2D, cmd.texture);
184 glBindVertexArray(cmd.vao);
185 glDrawElementsInstanced(cmd.mode, cmd.count, GL_UNSIGNED_INT, cmd.offset, cmd.instances);
186 }
187 }
188
190 {
191 m_cmds.clear();
192 }
193
195 {
196 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
197 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
198 }
199
201 {
202 m_post.bind();
203 clear_active();
204 }
205
207 {
209 m_post.unbind();
210 }
211
213 {
215 }
216
218 {
219#ifdef GALAXY_WIN_PLATFORM
220#pragma warning(push)
221#pragma warning(disable : 4244)
222#endif
223 glBindFramebuffer(GL_FRAMEBUFFER, 0);
224 glViewport(m_viewport.x, m_viewport.y, m_viewport.z, m_viewport.w);
225 clear_active();
226
227 // model view i.e. camera.
228 // glOrtho(0, screen_width, screen_height, 0, -1, 1);
229 // float scale_x = (float)((float)(screen_width)) / (float)virtual_width);
230 // float scale_y = (float)((float)(screen_height) / (float)virtual_height);
231 // glScalef(scale_x, scale_y, 1.0f);
232
233#ifdef GALAXY_WIN_PLATFORM
234#pragma warning(pop)
235#endif
236 }
237
239 {
240 glfwSwapBuffers(core::ServiceLocator<core::Window>::ref().handle());
241 }
242
243 void Renderer::calc_viewport(int window_width, int window_height)
244 {
245 auto& w = core::ServiceLocator<core::Window>::ref();
246
247 int width = window_width;
248 int height = static_cast<int>(width / w.aspect_ratio() + 0.5f);
249
250 if (height > window_height)
251 {
252 // It doesn't fit our height, we must switch to pillarbox then.
253 height = window_height;
254 width = static_cast<int>(height * w.aspect_ratio() + 0.5f);
255 }
256
257 // Set up the new viewport centered in the backbuffer.
258 m_viewport.x = static_cast<float>((window_width / 2) - (width / 2));
259 m_viewport.y = static_cast<float>((window_height / 2) - (height / 2));
260 m_viewport.z = static_cast<float>(width);
261 m_viewport.w = static_cast<float>(height);
262 }
263 } // namespace graphics
264} // namespace galaxy
void bind() const
Bind buffer.
void clear() const
Clears data from buffer.
void buffer(const unsigned int count, Object *data)
Buffer data.
void sub_buffer(const unsigned int offset, const unsigned int count, Object *data)
Sub buffer data.
void compile()
Compiles shader into GPU mem.
Definition Shader.cpp:113
bool parse(const std::string &src) noexcept
Loads a combined raw shader.
Definition Shader.cpp:83
void bind() const
Make active shader.
Definition Shader.cpp:211
void destroy()
Destroys shader program.
Definition Shader.cpp:202
Bindless OpenGL 2D Texture.
Definition Texture.hpp:22
void bind() const noexcept
Bind to sampler.
Definition Texture.cpp:157
Abstraction for OpenGL vertex array objects.
void bind() const
Bind this vertex array.
int count() const noexcept
Get the index count.
unsigned int id() const noexcept
Get vertex array handle.
void * offset() noexcept
Gets index offset.
Orthographic 2D camera.
Definition Camera.hpp:28
Data & get_data()
Get camera view and proj.
Definition Camera.cpp:130
void bind()
Bind to draw to post processor framebuffer.
void destroy()
Cleanup used memory.
Effect * add(Args &&... args)
Add an effect to process.
void render_effects()
Draw post effects to stored framebuffer.
void render_output()
Draw finished post effects to default framebuffer (screen).
void unbind()
Unbind to draw to post processor framebuffer.
void init(const int width, const int height)
Initialize post processor and GL buffers.
Draw to an opengl texture instead of the screen.
const glm::mat4 & get_proj()
Get render texture projection.
unsigned int texture() const
Gets framebuffer texture.
void bind(bool clear=true)
Activate context.
2D OpenGL renderer.
Definition Renderer.hpp:33
void submit_text(Text &text, Transform &tf, const int layer)
Submit standalone text to be rendered.
Definition Renderer.cpp:106
meta::vector< RenderCommand > m_cmds
List of renderables to draw.
Definition Renderer.hpp:179
glm::vec4 m_viewport
Default framebuffer viewport.
Definition Renderer.hpp:204
void end_default()
Swaps buffers.
Definition Renderer.cpp:238
void submit_texture(const Texture2D &texture, VertexArray &va, Transform &tf, const int layer, const float opacity)
Submit a standalone texture to be rendered.
Definition Renderer.cpp:86
void begin_post()
Begin rendering to post process framebuffer.
Definition Renderer.cpp:200
void render_post()
Renders final post processing output to active framebuffer.
Definition Renderer.cpp:212
ShaderStorageBuffer m_renderdata
Uniform buffer storage.
Definition Renderer.hpp:194
void end_post()
Renders effects to post processing framebuffer and rebinds to default framebuffer.
Definition Renderer.cpp:206
void clear_active()
Clears currently active framebuffer.
Definition Renderer.cpp:194
PostProcess m_post
Post processor.
Definition Renderer.hpp:199
void flush()
Deletes all submitted render commands.
Definition Renderer.cpp:189
void submit_cmd(RenderCommand &command)
Add an entity rendering command.
Definition Renderer.cpp:81
void submit_camera(Camera &camera)
Set the camera to use when calling draw().
Definition Renderer.cpp:76
void init()
Initialize renderer.
Definition Renderer.cpp:31
void draw()
Draw all submitted render commands to screen.
Definition Renderer.cpp:166
static Renderer & ref()
Get reference to renderer singleton.
Definition Renderer.cpp:19
Shader m_r2d_shader
Mono render shader.
Definition Renderer.hpp:184
void submit_shape(Shape *shape, Transform &tf, const int layer)
Submit a standalone shape to be rendered.
Definition Renderer.cpp:126
void destroy()
Cleanup renderer data.
Definition Renderer.cpp:62
void draw_texture_to_target(RenderTexture &target, Texture *texture, VertexArray &va, Transform &tf)
Draw a texture to a render texture.
Definition Renderer.cpp:146
void calc_viewport(int window_width, int window_height)
Need to recalculate default framebuffer viewport.
Definition Renderer.cpp:243
void begin_default()
Start rendering to default framebuffer.
Definition Renderer.cpp:217
ShaderStorageBuffer m_camera
Camera buffer storage.
Definition Renderer.hpp:189
void on_window_resized(const events::WindowResized &e)
Event processing method for window size change.
Definition Renderer.cpp:71
Submorphological Anti Aliasing.
Definition SMAA.hpp:24
A generic 2D shape.
Definition Shape.hpp:22
Colour m_colour
Used by all primitives.
Definition Shape.hpp:84
VertexArray & vao()
Get vertex array object.
Definition Shape.cpp:65
unsigned int mode() const
Get OpenGL rendering mode.
Definition Shape.cpp:50
Sharpening effect.
Definition Sharpen.hpp:25
String of glyphs rendered with a font.
Definition Text.hpp:23
graphics::Colour m_colour
Text colour.
Definition Text.hpp:184
graphics::RenderTexture & render_texture()
Get render texture.
Definition Text.cpp:215
graphics::VertexArray & vao()
Get vertex array.
Definition Text.cpp:210
Defines the 2D transformation of an entity.
Definition Transform.hpp:21
glm::mat4 & get_transform()
Retrieve internal transformation matrix.
constexpr const auto r2d_frag_shader
Fragment shader for the 2d renderer.
Definition R2DShader.hpp:60
constexpr const auto r2d_vert_shader
Vertex shader for the 2d renderer.
Definition R2DShader.hpp:18
Animated.cpp galaxy.
Definition Animated.cpp:16
Data to be passed to the renderer.
Uniform data passed to shader from entity.