Ember
A C++ 20 'game engine' built with SDL3 with wide platform support.
ember_core.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include "core/text_parser.h"
5 
6 #pragma region OPENGL/ES
7 #include "core/renderer/mesh.h"
9 #pragma endregion
10 
11 #pragma region METAL
12 #pragma endregion
13 
14 #include "core/audio/ember_audio.h"
15 #include "core/ember_utils.h"
16 #include "core/system_info.h"
17 #include "core/http/http_client.h"
18 
24 
28 enum class DrawCommandType {
29  NONE,
30  TEXTURE,
31  TEXT,
32  LINE,
33  RECT,
34  TRIANGLE,
35  CIRCLE,
36  POLYGON
37 };
38 
42 struct DrawCommand {
44  std::vector<Vertex> vertices;
45  std::vector<uint32_t> indices;
46  Uint32 texture_id = 0;
47  float line_width = 1.0f;
48  int circle_segments = 32;
49  int z_index = 0;
50 
56  explicit DrawCommand(DrawCommandType t, int z = 0) : type(t), z_index(z) {
57  }
58 };
59 
63 struct BatchKey {
64  Uint32 texture_id;
65  int z_index;
68 
72  bool operator==(const BatchKey& other) const {
73  return texture_id == other.texture_id && z_index == other.z_index && type == other.type;
74  }
75 };
76 
80 template <>
81 struct std::hash<BatchKey> {
82  std::size_t operator()(const BatchKey& k) const {
83  std::size_t h1 = std::hash<Uint32>()(k.texture_id);
84  std::size_t h2 = std::hash<int>()(k.z_index);
85  std::size_t h3 = std::hash<int>()(static_cast<int>(k.type));
86  std::size_t combined = h1 ^ (h2 << 1);
87  return (combined >> 1) ^ h3;
88  }
89 };
90 
94 struct Batch {
95  std::vector<Vertex> vertices;
96  std::vector<uint32_t> indices;
97  Uint32 texture_id = 0;
99  int z_index = 0;
102  float thickness = 1.0f;
103 };
104 
105 
109 class Renderer {
110 public:
111  virtual ~Renderer() = default;
112 
113  int Viewport[2] = {800, 600};
114  SDL_Window* Window = nullptr;
116 
118  virtual void initialize() = 0;
119 
127  virtual bool load_font(const std::string& font_path, const std::string& font_alias, int font_size = 48) = 0;
128 
129 
135  virtual std::shared_ptr<Texture> load_texture(const std::string& path) = 0;
136 
142  virtual std::shared_ptr<Texture> get_texture(const std::string& path) = 0;
143 
147  virtual void draw_texture(const Texture* texture, const Rect2& dest_rect, float rotation, const glm::vec4& color,
148  const Rect2& src_rect, int z_index,
149  bool flip_h = false, bool flip_v = false, const UberShader& uber_shader = {}) = 0;
150 
154  virtual void draw_rect(Rect2 rect, float rotation, const glm::vec4& color, bool filled = true, int z_index = 0) = 0;
155 
159  virtual void draw_text(const std::string& text, float x, float y, float rotation, float scale, const glm::vec4& color,
160  const std::string& font_alias = "", int z_index = 0,
161  const UberShader& uber_shader = UberShader::none(),int ft_size = 0) = 0;
162 
166  virtual void draw_line(float x1, float y1, float x2, float y2, float thickness, float rotation, const glm::vec4& color,
167  int z_index = 0) = 0;
168 
172  virtual void draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, float rotation, const glm::vec4& color,
173  bool filled = true, int z_index = 0) = 0;
174 
178  virtual void draw_circle(float center_x, float center_y, float rotation, float radius, const glm::vec4& color, bool filled = true,
179  int segments = 32, int z_index = 0) = 0;
180 
184  virtual void draw_polygon(const std::vector<glm::vec2>& points, float rotation, const glm::vec4& color, bool filled = true,
185  int z_index = 0) = 0;
186 
187 
191  virtual void flush() = 0;
192 
199  virtual void present() = 0;
200 
205  virtual void clear(glm::vec4 color = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)) = 0;
206 
212  virtual void resize_viewport(int view_width, int view_height) = 0;
213 
217  virtual void set_context(const void* ctx) = 0;
218 
222  virtual void* get_context() = 0;
223 
227  virtual void destroy() = 0;
228 
232  virtual void unload_font(const Font& font) = 0;
233 
237  virtual void unload_texture(Uint32 id) = 0;
238 
239  void set_view_matrix(const glm::mat4& view_matrix = glm::mat4(1.f));
240 
241  [[nodiscard]] glm::mat4 get_view_matrix() const;
242 
243  virtual Uint32 get_framebuffer_texture() const {
244  return 0;
245  }
246 
248  return _textures;
249  }
250 
251  virtual std::vector<std::string>& get_loaded_fonts_name() {
252  static std::vector<std::string> font_names;
253  font_names.clear();
254 
255  for (const auto& [name, font] : fonts) {
256  font_names.push_back(name);
257  }
258 
259  return font_names;
260  }
261 
262 
263 protected:
265 
266  FT_Library _ft = {};
267 
269  std::string current_font_name;
270 
271  glm::mat4 _projection = glm::mat4(1.f);
272  glm::mat4 _view = glm::mat4(1.f);
273 
275 
277 
282  virtual void set_default_font(const std::string& font_name) = 0;
283 
287  glm::vec2 rotate_point(const glm::vec2& point, const glm::vec2& center, float radians);
288 
297 
301  virtual void render_fbo() = 0;
302 
306  void submit(const BatchKey& key, float x, float y, float w, float h, float u0, float v0, float u1, float v1,
307  const glm::vec4& color, float rotation = 0.0f, bool is_filled = true);
308 
309  virtual void set_effect_uniforms(const UberShader& uber_shader, const glm::vec2& texture_size = glm::vec2(1, 1)) = 0;
310 
311  [[nodiscard]] virtual glm::vec2 get_texture_size(Uint32 texture_id) const = 0;
312 };
Base class for all renderers.
Definition: ember_core.h:109
virtual void draw_circle(float center_x, float center_y, float rotation, float radius, const glm::vec4 &color, bool filled=true, int segments=32, int z_index=0)=0
Draw a circle.
virtual void unload_texture(Uint32 id)=0
Unload a texture by its ID.
virtual void draw_polygon(const std::vector< glm::vec2 > &points, float rotation, const glm::vec4 &color, bool filled=true, int z_index=0)=0
Draw a polygon.
virtual void set_default_font(const std::string &font_name)=0
Set the current font to use for rendering.
glm::vec2 rotate_point(const glm::vec2 &point, const glm::vec2 &center, float radians)
Rotate a point around a center point.
Definition: ember_core.cpp:12
virtual void set_effect_uniforms(const UberShader &uber_shader, const glm::vec2 &texture_size=glm::vec2(1, 1))=0
HashMap< Uint32, glm::vec2 > _texture_sizes
HACK_FIX: Cached texture sizes by ID.
Definition: ember_core.h:276
virtual void initialize()=0
Initialize the renderer and its resources.
virtual void present()=0
Swap buffers to present the rendered frame.
glm::mat4 get_view_matrix() const
Definition: ember_core.cpp:8
virtual void draw_rect(Rect2 rect, float rotation, const glm::vec4 &color, bool filled=true, int z_index=0)=0
Draw a rectangle (filled or outlined).
virtual void flush()=0
Submit all batched draw calls.
virtual void resize_viewport(int view_width, int view_height)=0
Resize the rendering context.
virtual void draw_texture(const Texture *texture, const Rect2 &dest_rect, float rotation, const glm::vec4 &color, const Rect2 &src_rect, int z_index, bool flip_h=false, bool flip_v=false, const UberShader &uber_shader={})=0
Draw a textured quad.
virtual std::shared_ptr< Texture > get_texture(const std::string &path)=0
Get a previously loaded texture.
Backend Type
Default Type of renderer.
Definition: ember_core.h:115
glm::mat4 _view
View matrix.
Definition: ember_core.h:272
glm::mat4 _projection
Projection matrix.
Definition: ember_core.h:271
virtual glm::vec2 get_texture_size(Uint32 texture_id) const =0
virtual void clear(glm::vec4 color=glm::vec4(0.0f, 0.0f, 0.0f, 0.0f))=0
Clear the screen to the given color.
virtual void draw_text(const std::string &text, float x, float y, float rotation, float scale, const glm::vec4 &color, const std::string &font_alias="", int z_index=0, const UberShader &uber_shader=UberShader::none(), int ft_size=0)=0
Draw text to screen.
virtual void draw_triangle(float x1, float y1, float x2, float y2, float x3, float y3, float rotation, const glm::vec4 &color, bool filled=true, int z_index=0)=0
Draw a triangle.
FT_Library _ft
FreeType library instance.
Definition: ember_core.h:266
void submit(const BatchKey &key, float x, float y, float w, float h, float u0, float v0, float u1, float v1, const glm::vec4 &color, float rotation=0.0f, bool is_filled=true)
Add a quad (textured or untextured) to the appropriate batch.
Definition: ember_core.cpp:42
virtual void * get_context()=0
Get the platform-specific rendering context.
virtual HashMap< std::string, std::shared_ptr< Texture > > & get_loaded_textures()
Definition: ember_core.h:247
virtual void set_context(const void *ctx)=0
Set the platform-specific rendering context.
void set_view_matrix(const glm::mat4 &view_matrix=glm::mat4(1.f))
Definition: ember_core.cpp:4
Recti calc_display()
Calculate the display rectangle for rendering based on the viewport and window size.
Definition: ember_core.cpp:19
std::string current_font_name
Currently selected font alias.
Definition: ember_core.h:269
virtual void destroy()=0
Destroy rendering resources.
HashMap< std::string, std::shared_ptr< Texture > > _textures
Cached textures.
Definition: ember_core.h:274
HashMap< BatchKey, Batch > _batches
All batches by key.
Definition: ember_core.h:264
virtual void render_fbo()=0
Render the current frame buffer.
virtual void draw_line(float x1, float y1, float x2, float y2, float thickness, float rotation, const glm::vec4 &color, int z_index=0)=0
Draw a line.
virtual ~Renderer()=default
virtual bool load_font(const std::string &font_path, const std::string &font_alias, int font_size=48)=0
Load a font.
virtual std::vector< std::string > & get_loaded_fonts_name()
Definition: ember_core.h:251
virtual std::shared_ptr< Texture > load_texture(const std::string &path)=0
Load a texture from disk.
virtual Uint32 get_framebuffer_texture() const
Definition: ember_core.h:243
HashMap< std::string, Font > fonts
Loaded fonts.
Definition: ember_core.h:268
virtual void unload_font(const Font &font)=0
Unload a loaded font.
DrawCommandType
Types of draw commands supported by the renderer.
Definition: ember_core.h:28
@ LINE
Draw line.
@ RECT
Draw rectangle.
@ TEXTURE
Draw textured quad.
@ TEXT
Draw text.
@ TRIANGLE
Draw triangle.
@ NONE
No command.
DrawCommandMode
Mode of drawing commands.
Definition: ember_core.h:23
Backend
Supported rendering backends for the engine.
Definition: engine_config.h:11
@ GL_COMPATIBILITY
OpenGL-based compatibility profile.
std::unordered_map< K, V > HashMap
Definition: imports.h:12
Used to batch draw commands by shared properties.
Definition: ember_core.h:63
bool operator==(const BatchKey &other) const
Equality operator.
Definition: ember_core.h:72
int z_index
Z-index.
Definition: ember_core.h:65
UberShader uber_shader
Shader used for this batch.
Definition: ember_core.h:67
Uint32 texture_id
Texture used.
Definition: ember_core.h:64
DrawCommandType type
Type of draw command.
Definition: ember_core.h:66
A group of vertices and indices that can be rendered together.
Definition: ember_core.h:94
DrawCommandMode mode
Definition: ember_core.h:101
Uint32 texture_id
Texture used in this batch.
Definition: ember_core.h:97
std::vector< uint32_t > indices
Batched index data.
Definition: ember_core.h:96
std::vector< Vertex > vertices
Batched vertex data.
Definition: ember_core.h:95
UberShader uber_shader
Shader effects applied.
Definition: ember_core.h:100
DrawCommandType type
Type of draw command.
Definition: ember_core.h:98
float thickness
Line thickness for lines.
Definition: ember_core.h:102
int z_index
Render order.
Definition: ember_core.h:99
Represents a single rendering command.
Definition: ember_core.h:42
int z_index
Z-index (render order).
Definition: ember_core.h:49
int circle_segments
Number of segments for circles.
Definition: ember_core.h:48
Uint32 texture_id
Texture used (if any).
Definition: ember_core.h:46
std::vector< Vertex > vertices
Vertex data.
Definition: ember_core.h:44
DrawCommandType type
Type of draw command.
Definition: ember_core.h:43
DrawCommand(DrawCommandType t, int z=0)
Constructs a DrawCommand with type and optional z-index.
Definition: ember_core.h:56
float line_width
Line thickness (if applicable).
Definition: ember_core.h:47
std::vector< uint32_t > indices
Index buffer.
Definition: ember_core.h:45
Font struct.
Definition: engine_structs.h:137
Float rectangle struct.
Definition: engine_structs.h:33
Integer rectangle struct.
Definition: engine_structs.h:53
Texture base class.
Definition: engine_structs.h:14
UberShader shader effects for rendering texts and sprites.
Definition: shader.h:8
static UberShader none()
Definition: shader.h:16
Definition: engine_config.h:73
Definition: engine_config.h:128
std::size_t operator()(const BatchKey &k) const
Definition: ember_core.h:82