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
Orthographic 2D camera.
Definition Camera.hpp:28
Data & get_data()
Get camera view and proj.
Definition Camera.cpp:130
glm::vec4 & vec4()
Get vec4.
Definition Colour.cpp:160
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
void clear()
Clears data from buffer.
void buffer(const unsigned int offset, 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 destroy()
Destroys shader program.
Definition Shader.cpp:219
bool parse(const std::string &src)
Loads a combined raw shader.
Definition Shader.cpp:100
void compile()
Compiles shader into GPU mem.
Definition Shader.cpp:130
void bind() const
Make active shader.
Definition Shader.cpp:227
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
Standard opengl texture.
Definition Texture2D.hpp:21
OpenGL 2D Texture.
Definition Texture.hpp:26
unsigned int id() const
Gets opengl handle.
Definition Texture.cpp:167
virtual void bind()=0
Activate context.
Defines the 2D transformation of an entity.
Definition Transform.hpp:21
glm::mat4 & get_transform()
Retrieve internal transformation matrix.
Abstraction for OpenGL vertex array objects.
int count() const
Get the index count.
void * offset()
Gets index offset.
int instances() const
Number of instances to render.
void bind()
Bind this vertex array.
unsigned int id() const
Get vertex array handle.
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.