mirror of
https://github.com/NoelFB/blah.git
synced 2025-04-11 01:26:05 +08:00
243 lines
8.9 KiB
C++
243 lines
8.9 KiB
C++
#pragma once
|
|
#include <blah/containers/str.h>
|
|
#include <blah/numerics/vec2.h>
|
|
#include <blah/numerics/rect.h>
|
|
#include <blah/numerics/mat3x2.h>
|
|
#include <blah/numerics/mat4x4.h>
|
|
#include <blah/numerics/color.h>
|
|
#include <blah/graphics/subtexture.h>
|
|
#include <blah/graphics/spritefont.h>
|
|
#include <blah/containers/vector.h>
|
|
#include <blah/graphics/blend.h>
|
|
#include <blah/graphics/sampler.h>
|
|
#include <blah/graphics/renderpass.h>
|
|
#include <blah/app.h>
|
|
|
|
namespace Blah
|
|
{
|
|
// Spritebatcher Color Mode
|
|
enum class ColorMode
|
|
{
|
|
// Draws textures and shapes normally
|
|
Normal,
|
|
|
|
// Ignores the texture color but still uses transparency, essentially
|
|
// drawing the "shape" of the texture a solid color
|
|
Wash
|
|
};
|
|
|
|
enum class TextAlign : char
|
|
{
|
|
Center = 0,
|
|
Left = 1 << 1,
|
|
Right = 1 << 2,
|
|
Top = 1 << 3,
|
|
Bottom = 1 << 4,
|
|
|
|
TopLeft = Top | Left,
|
|
TopRight = Top | Right,
|
|
BottomLeft = Bottom | Left,
|
|
BottomRight = Bottom | Right
|
|
};
|
|
|
|
inline TextAlign operator|(TextAlign lhs, TextAlign rhs) { return static_cast<TextAlign>(static_cast<char>(lhs) | static_cast<char>(rhs)); }
|
|
inline TextAlign operator&(TextAlign lhs, TextAlign rhs) { return static_cast<TextAlign>(static_cast<char>(lhs) & static_cast<char>(rhs)); }
|
|
|
|
// A 2D sprite batcher, used for drawing shapes and textures
|
|
class Batch
|
|
{
|
|
public:
|
|
|
|
// The name of the Matrix Uniform in the Shader
|
|
const char* matrix_uniform;
|
|
|
|
// Default Sampler, set on clear
|
|
TextureSampler default_sampler;
|
|
|
|
Batch();
|
|
Batch(const Batch& other) = delete;
|
|
Batch& operator=(const Batch& other) = delete;
|
|
~Batch();
|
|
|
|
// Pushes a new matrix onto the stack, and uses it for transforming all drawing.
|
|
// `absolute` means the matrix provided will not be transformed by the current stack.
|
|
void push_matrix(const Mat3x2& matrix, bool absolute = false);
|
|
|
|
// Pops the matrix from the stack
|
|
Mat3x2 pop_matrix();
|
|
|
|
// Gets the current matrix from the top of the stackKO
|
|
Mat3x2 peek_matrix() const;
|
|
|
|
// Pushes a Scissor rectangle. Note this is not transformed by the matrix stack
|
|
// or other scissors. Each push is screen-space.
|
|
void push_scissor(const Rect& scissor);
|
|
|
|
// Pops a Scissor rectangle from the stack
|
|
Rect pop_scissor();
|
|
|
|
// Gets the current Scissor rectangle from the top of the stack
|
|
Rect peek_scissor() const;
|
|
|
|
// Pushes a blend mode
|
|
void push_blend(const BlendMode& blend);
|
|
|
|
// Pops a blend mode
|
|
BlendMode pop_blend();
|
|
|
|
// Gets the current BlendMode from the top of the stack
|
|
BlendMode peek_blend() const;
|
|
|
|
// Pushes a Material to use for all drawing. Note that the state of the Material
|
|
// is not copied - it will be drawn with the values of the Material at render.
|
|
void push_material(const MaterialRef& material);
|
|
|
|
// Pops a Material
|
|
MaterialRef pop_material();
|
|
|
|
// Gets the current Material from the top of the stack
|
|
MaterialRef peek_material() const;
|
|
|
|
// Pushes a render layer. Lower values are rendered first. This is not super optimized
|
|
// and should generally be avoided.
|
|
void push_layer(int layer);
|
|
|
|
// Pops a Layer
|
|
int pop_layer();
|
|
|
|
// Gets the current Layer from the top of the stack
|
|
int peek_layer() const;
|
|
|
|
// Pushes a Color Mode for drawing Textures
|
|
void push_color_mode(ColorMode mode);
|
|
|
|
// Pops a Color MOde
|
|
ColorMode pop_color_mode();
|
|
|
|
// Gets the current ColorMode from the top of the stack
|
|
ColorMode peek_color_mode() const;
|
|
|
|
// Sets the current texture used for drawing. Note that certain functions will override
|
|
// this (ex the `str` and `tex` methods)
|
|
void set_texture(const TextureRef& texture);
|
|
|
|
// Sets the current texture sampler for drawing.
|
|
void set_sampler(const TextureSampler& sampler);
|
|
|
|
// Draws the batch to the given target
|
|
void render(const TargetRef& target = App::backbuffer);
|
|
|
|
// Draws the batch to the given target, with the provided matrix
|
|
void render(const TargetRef& target, const Mat4x4& matrix);
|
|
|
|
// Clears the batch
|
|
void clear();
|
|
|
|
// Clears and disposes all resources that the batch is using
|
|
void dispose();
|
|
|
|
void line(const Vec2& from, const Vec2& to, float t, Color color);
|
|
void line(const Vec2& from, const Vec2& to, float t, Color fromColor, Color toColor);
|
|
|
|
void bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int steps, float t, Color color);
|
|
void bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Vec2& to, int steps, float t, Color color);
|
|
|
|
void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color color);
|
|
void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color col0, Color col1, Color col2);
|
|
void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color color);
|
|
void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color col0, Color col1, Color col2);
|
|
|
|
void tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color color);
|
|
|
|
void rect(const Rect& rect, Color color);
|
|
void rect_line(const Rect& rect, float t, Color color);
|
|
void rect_rounded(const Rect& rect, float radius, int steps, Color color);
|
|
void rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, Color color);
|
|
void rect_rounded_line(const Rect& rect, float radius, int steps, float t, Color color);
|
|
void rect_rounded_line(const Rect& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, float t, Color color);
|
|
|
|
void semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor);
|
|
void semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color color);
|
|
void semi_circle_line(const Vec2& center, float start_radians, float end_radians, float radius, int steps, float t, Color color);
|
|
|
|
void circle(const Vec2& center, float radius, int steps, Color color);
|
|
void circle(const Vec2& center, float radius, int steps, Color center_color, Color outer_color);
|
|
void circle_line(const Vec2& center, float radius, float t, int steps, Color color);
|
|
|
|
void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color color);
|
|
void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color col0, Color col1, Color col2, Color col3);
|
|
void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, const Vec2& tex3, Color color);
|
|
void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, const Vec2& tex3, Color col0, Color col1, Color col2, Color col3);
|
|
void quad_line(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, float t, Color color);
|
|
|
|
void arrow_head(const Vec2& point_pos, float radians, float side_len, Color color);
|
|
void arrow_head(const Vec2& point_pos, const Vec2& from_pos, float side_len, Color color);
|
|
|
|
void tex(const TextureRef& texture, const Vec2& position = Vec2::zero, Color color = Color::white);
|
|
void tex(const TextureRef& texture, const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation, Color color);
|
|
void tex(const TextureRef& texture, const Rect& clip, const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation, Color color);
|
|
|
|
void tex(const Subtexture& subtexture, const Vec2& position = Vec2::zero, Color color = Color::white);
|
|
void tex(const Subtexture& subtexture, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color);
|
|
void tex(const Subtexture& subtexture, const Rect& clip, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color);
|
|
|
|
void str(const SpriteFont& font, const String& text, const Vec2& pos, Color color);
|
|
void str(const SpriteFont& font, const String& text, const Vec2& pos, TextAlign align, float size, Color color);
|
|
|
|
private:
|
|
|
|
struct Vertex
|
|
{
|
|
Vec2 pos;
|
|
Vec2 tex;
|
|
Color col;
|
|
|
|
u8 mult;
|
|
u8 wash;
|
|
u8 fill;
|
|
u8 pad;
|
|
};
|
|
|
|
struct DrawBatch
|
|
{
|
|
int layer;
|
|
int offset;
|
|
int elements;
|
|
MaterialRef material;
|
|
BlendMode blend;
|
|
TextureRef texture;
|
|
TextureSampler sampler;
|
|
bool flip_vertically;
|
|
Rect scissor;
|
|
|
|
DrawBatch() :
|
|
layer(0),
|
|
offset(0),
|
|
elements(0),
|
|
blend(BlendMode::Normal),
|
|
flip_vertically(false),
|
|
scissor(0, 0, -1, -1) {}
|
|
};
|
|
|
|
static ShaderRef m_default_shader;
|
|
MaterialRef m_default_material;
|
|
MeshRef m_mesh;
|
|
Mat3x2 m_matrix;
|
|
ColorMode m_color_mode;
|
|
u8 m_tex_mult;
|
|
u8 m_tex_wash;
|
|
DrawBatch m_batch;
|
|
Vector<Vertex> m_vertices;
|
|
Vector<u32> m_indices;
|
|
Vector<Mat3x2> m_matrix_stack;
|
|
Vector<Rect> m_scissor_stack;
|
|
Vector<BlendMode> m_blend_stack;
|
|
Vector<MaterialRef> m_material_stack;
|
|
Vector<ColorMode> m_color_mode_stack;
|
|
Vector<int> m_layer_stack;
|
|
Vector<DrawBatch> m_batches;
|
|
int m_batch_insert;
|
|
|
|
void render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4& matrix);
|
|
};
|
|
} |