large spatial / numerics refactor to allow double/integer vector types

This commit is contained in:
Noel Berry 2021-12-12 20:41:23 -08:00
parent 8f9c6aa9ff
commit d91658aa46
53 changed files with 1842 additions and 2056 deletions

View File

@ -32,11 +32,6 @@ add_library(blah
src/numerics/calc.cpp
src/numerics/color.cpp
src/numerics/line.cpp
src/numerics/mat3x2.cpp
src/numerics/mat4x4.cpp
src/numerics/rect.cpp
src/numerics/rectI.cpp
src/streams/bufferstream.cpp
src/streams/filestream.cpp

View File

@ -38,13 +38,13 @@ void render()
{
App::backbuffer->clear(Color::black);
auto center = Vec2(App::backbuffer->width(), App::backbuffer->height()) / 2;
auto center = Vec2f(App::backbuffer->width(), App::backbuffer->height()) / 2;
auto rotation = Time::seconds * Calc::TAU;
auto transform = Mat3x2::create_transform(center, Vec2::zero, Vec2::one, rotation);
auto transform = Mat3x2f::create_transform(center, Vec2::zero, Vec2::one, rotation);
batch.push_matrix(transform);
batch.rect(Rect(-32, -32, 64, 64), Color::red);
batch.tex(tex, Vec2(64, 0), Color::white);
batch.rect(Rectf(-32, -32, 64, 64), Color::red);
batch.tex(tex, Vec2f(64, 0), Color::white);
batch.pop_matrix();
batch.render();

View File

@ -29,19 +29,9 @@
#include "blah/images/packer.h"
#include "blah/numerics/calc.h"
#include "blah/numerics/circle.h"
#include "blah/numerics/spatial.h"
#include "blah/numerics/color.h"
#include "blah/numerics/ease.h"
#include "blah/numerics/line.h"
#include "blah/numerics/mat3x2.h"
#include "blah/numerics/mat4x4.h"
#include "blah/numerics/point.h"
#include "blah/numerics/quad.h"
#include "blah/numerics/rect.h"
#include "blah/numerics/rectI.h"
#include "blah/numerics/vec2.h"
#include "blah/numerics/vec3.h"
#include "blah/numerics/vec4.h"
#include "blah/streams/bufferstream.h"
#include "blah/streams/filestream.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include <blah/common.h>
#include <blah/numerics/point.h>
#include <blah/numerics/spatial.h>
namespace Blah
{

View File

@ -165,7 +165,7 @@ namespace Blah
// clears and disposes the internal string buffer
void dispose();
~Str()
virtual ~Str()
{
if (m_buffer != nullptr && m_buffer != empty_buffer)
delete[] m_buffer;
@ -181,10 +181,10 @@ namespace Blah
}
// returns a pointer to the heap buffer or to our stack allocation
char* data() { return (m_buffer != nullptr ? m_buffer : ((char*)(this) + sizeof(Str))); }
virtual char* data() { return m_buffer; }
// returns a pointer to the heap buffer or to our stack allocation
const char* data() const { return (m_buffer != nullptr ? m_buffer : ((char*)(this) + sizeof(Str))); }
virtual const char* data() const { return m_buffer; }
// assigns the contents of the string
void set(const Str& str) { set(str.cstr(), str.cstr() + str.m_length); }
@ -192,9 +192,10 @@ namespace Blah
// assigns the contents of the string
void set(const char* start, const char* end = nullptr);
char* m_buffer;
private:
static char empty_buffer[1];
char* m_buffer;
int m_length;
int m_capacity;
int m_local_size;
@ -221,6 +222,10 @@ namespace Blah
StrOf& operator=(const Str& rhs) { set(rhs); return *this; }
StrOf& operator=(const StrOf& rhs) { set(rhs); return *this; }
// either return stack or heap buffer depending on which is in-use
char* data() override { return m_buffer != nullptr ? m_buffer : m_local_buffer; }
const char* data() const override { return m_buffer != nullptr ? m_buffer : m_local_buffer; }
// creates a string from the format
static StrOf fmt(const char* str, ...);
};
@ -251,6 +256,33 @@ namespace Blah
return str;
}
struct CaseInsenstiveStringHash
{
std::size_t operator()(const Blah::Str& key) const
{
std::size_t result = 2166136261U;
for (auto& it : key)
{
if (it >= 'A' && it <= 'Z')
result ^= (static_cast<std::size_t>(it) - 'A' + 'a');
else
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
return result;
}
};
struct CaseInsenstiveStringCompare
{
bool operator() (const Str& lhs, const Str& rhs) const
{
return lhs.length() == rhs.length() && lhs.starts_with(rhs, true);
}
};
}
namespace std
@ -264,7 +296,7 @@ namespace std
for (auto& it : key)
{
result ^= static_cast<size_t>(it);
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}
@ -281,7 +313,7 @@ namespace std
for (auto& it : key)
{
result ^= static_cast<size_t>(it);
result ^= static_cast<std::size_t>(it);
result *= 16777619U;
}

View File

@ -104,7 +104,7 @@ namespace Blah
template<typename ... Args>
FilePath join(const FilePath& a, const FilePath& b, const Args&... args)
{
return join(a, join(b, std::forward<Args>(args)...));
return join(a, join(b, args...));
}
}
}

View File

@ -1,9 +1,6 @@
#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/spatial.h>
#include <blah/numerics/color.h>
#include <blah/graphics/subtexture.h>
#include <blah/graphics/spritefont.h>
@ -53,6 +50,10 @@ namespace Blah
const char* sampler_uniform;
const char* matrix_uniform;
// Snaps all drawing coordinates to integer values
// This is useful for drawing Pixel Art stuff
bool integerize = false;
// Default Sampler, set on clear
TextureSampler default_sampler;
@ -63,23 +64,23 @@ namespace Blah
// 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);
void push_matrix(const Mat3x2f& matrix, bool absolute = false);
// Pops the matrix from the stack
Mat3x2 pop_matrix();
Mat3x2f pop_matrix();
// Gets the current matrix from the top of the stackKO
Mat3x2 peek_matrix() const;
Mat3x2f 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);
void push_scissor(const Rectf& scissor);
// Pops a Scissor rectangle from the stack
Rect pop_scissor();
Rectf pop_scissor();
// Gets the current Scissor rectangle from the top of the stack
Rect peek_scissor() const;
Rectf peek_scissor() const;
// Pushes a blend mode
void push_blend(const BlendMode& blend);
@ -130,7 +131,7 @@ namespace Blah
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);
void render(const TargetRef& target, const Mat4x4f& matrix);
// Clears the batch
void clear();
@ -138,60 +139,60 @@ namespace Blah
// 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 line(const Vec2f& from, const Vec2f& to, float t, Color color);
void line(const Vec2f& from, const Vec2f& 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 bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& to, int steps, float t, Color color);
void bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& c, const Vec2f& 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(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color color);
void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color col0, Color col1, Color col2);
void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color color);
void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color col0, Color col1, Color col2);
void tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color color);
void tri_line(const Vec2f& a, const Vec2f& b, const Vec2f& 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 rect(const Rectf& rect, Color color);
void rect_line(const Rectf& rect, float t, Color color);
void rect_rounded(const Rectf& rect, float radius, int steps, Color color);
void rect_rounded(const Rectf& 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 Rectf& rect, float radius, int steps, float t, Color color);
void rect_rounded_line(const Rectf& 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 semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor);
void semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color color);
void semi_circle_line(const Vec2f& 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 circle(const Vec2f& center, float radius, int steps, Color color);
void circle(const Vec2f& center, float radius, int steps, Color center_color, Color outer_color);
void circle_line(const Vec2f& 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 quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color color);
void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color col0, Color col1, Color col2, Color col3);
void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color color);
void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color col0, Color col1, Color col2, Color col3);
void quad_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Vec2f& 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 arrow_head(const Vec2f& point_pos, float radians, float side_len, Color color);
void arrow_head(const Vec2f& point_pos, const Vec2f& 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 TextureRef& texture, const Vec2f& position = Vec2f::zero, Color color = Color::white);
void tex(const TextureRef& texture, const Vec2f& position, const Vec2f& origin, const Vec2f& scale, float rotation, Color color);
void tex(const TextureRef& texture, const Rectf& clip, const Vec2f& position, const Vec2f& origin, const Vec2f& 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 tex(const Subtexture& subtexture, const Vec2f& position = Vec2f::zero, Color color = Color::white);
void tex(const Subtexture& subtexture, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color);
void tex(const Subtexture& subtexture, const Rectf& clip, const Vec2f& pos, const Vec2f& origin, const Vec2f& 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);
void str(const SpriteFont& font, const String& text, const Vec2f& pos, Color color);
void str(const SpriteFont& font, const String& text, const Vec2f& pos, TextAlign align, float size, Color color);
private:
struct Vertex
{
Vec2 pos;
Vec2 tex;
Vec2f pos;
Vec2f tex;
Color col;
u8 mult;
@ -210,7 +211,7 @@ namespace Blah
TextureRef texture;
TextureSampler sampler;
bool flip_vertically;
Rect scissor;
Rectf scissor;
DrawBatch() :
layer(0),
@ -224,15 +225,15 @@ namespace Blah
static ShaderRef m_default_shader;
MaterialRef m_default_material;
MeshRef m_mesh;
Mat3x2 m_matrix;
Mat3x2f 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<Mat3x2f> m_matrix_stack;
Vector<Rectf> m_scissor_stack;
Vector<BlendMode> m_blend_stack;
Vector<MaterialRef> m_material_stack;
Vector<ColorMode> m_color_mode_stack;
@ -240,6 +241,6 @@ namespace Blah
Vector<DrawBatch> m_batches;
int m_batch_insert;
void render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4& matrix);
void render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4f& matrix);
};
}

View File

@ -4,6 +4,7 @@
#include <blah/graphics/shader.h>
#include <blah/graphics/sampler.h>
#include <blah/containers/vector.h>
#include <blah/numerics/spatial.h>
namespace Blah
{
@ -30,6 +31,9 @@ namespace Blah
// If the Shader is invalid, it will return an invalid MaterialRef.
static MaterialRef create(const ShaderRef& shader);
// Clones the material and returns a new one
MaterialRef clone() const;
// Returns the Shader assigned to the Material.
ShaderRef shader() const;
@ -62,6 +66,20 @@ namespace Blah
// can be set.
void set_value(const char* name, const float* value, i64 length);
// Shorthands to more easily assign uniform values
void set_value(const char* name, float value);
void set_value(const char* name, const Vec2f& value);
void set_value(const char* name, const Vec3f& value);
void set_value(const char* name, const Vec4f& value);
void set_value(const char* name, const Mat3x2f& value);
void set_value(const char* name, const Mat4x4f& value);
void set_value(const char* name, const Vector<float>& value);
void set_value(const char* name, const Vector<Vec2f>& value);
void set_value(const char* name, const Vector<Vec3f>& value);
void set_value(const char* name, const Vector<Vec4f>& value);
void set_value(const char* name, const Vector<Mat3x2f>& value);
void set_value(const char* name, const Vector<Mat4x4f>& value);
// Gets a pointer to the values of the given Uniform, or nullptr if it doesn't exist.
const float* get_value(const char* name, i64* length = nullptr) const;

View File

@ -1,6 +1,6 @@
#pragma once
#include <blah/common.h>
#include <blah/numerics/rect.h>
#include <blah/numerics/spatial.h>
#include <blah/containers/str.h>
#include <blah/graphics/texture.h>
#include <blah/graphics/target.h>
@ -57,10 +57,10 @@ namespace Blah
bool has_scissor;
// The viewport (only used if hasViewport is true)
Rect viewport;
Rectf viewport;
// The scissor rectangle (only used if hasScissor is true)
Rect scissor;
Rectf scissor;
// First index in the Mesh to draw from
i64 index_start;

View File

@ -3,7 +3,7 @@
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah/graphics/subtexture.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/spatial.h>
#include <blah/filesystem.h>
#include <unordered_map>
@ -44,7 +44,7 @@ namespace Blah
{
Subtexture subtexture;
float advance = 0;
Vec2 offset;
Vec2f offset;
};
// SpriteFont name

View File

@ -1,6 +1,6 @@
#pragma once
#include <blah/graphics/texture.h>
#include <blah/numerics/rect.h>
#include <blah/numerics/spatial.h>
namespace Blah
{
@ -12,23 +12,23 @@ namespace Blah
TextureRef texture;
// Source rectangle, in pixels
Rect source;
Rectf source;
// Frame rectangle, in pixels. This describes padding around the image.
// This is useful for drawing images that have been trimmed. Ex. if the source
// is 32,32, but the original image was 64,64, the frame could be -16,-16,64,64
Rect frame;
Rectf frame;
// `draw_coords` are automatically assigned through `update` method
Vec2 draw_coords[4];
Vec2f draw_coords[4];
// `tex_coords` are automatically assigned through the `update` method
Vec2 tex_coords[4];
Vec2f tex_coords[4];
Subtexture();
Subtexture(const TextureRef& texture);
Subtexture(const TextureRef& texture, Rect source);
Subtexture(const TextureRef& texture, Rect source, Rect frame);
Subtexture(const TextureRef& texture, Rectf source);
Subtexture(const TextureRef& texture, Rectf source, Rectf frame);
// Returns the width of the image
float width() const { return frame.w; }
@ -40,9 +40,9 @@ namespace Blah
void update();
// returns resulting source and frame rectangles based on the provided clip rectangle
void crop_info(const Rect& clip, Rect* dest_source, Rect* dest_frame) const;
void crop_info(const Rectf& clip, Rectf* dest_source, Rectf* dest_frame) const;
// returns a subtexture cropped to the provided rectangle
Subtexture crop(const Rect& clip) const;
Subtexture crop(const Rectf& clip) const;
};
}

View File

@ -1,7 +1,6 @@
#pragma once
#include <blah/numerics/color.h>
#include <blah/numerics/rectI.h>
#include <blah/numerics/point.h>
#include <blah/numerics/spatial.h>
#include <blah/filesystem.h>
namespace Blah
@ -45,7 +44,7 @@ namespace Blah
// sets the pixels at the provided rectangle to the given data
// data must be at least rect.w * rect.h in size!
void set_pixels(const RectI& rect, Color* data);
void set_pixels(const Recti& rect, Color* data);
// saves the image to a png file
bool save_png(const FilePath& file) const;
@ -60,10 +59,10 @@ namespace Blah
bool save_jpg(Stream& stream, int quality) const;
// gets the pixels from the given source rectangle
void get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, RectI source_rect) const;
void get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, Recti source_rect) const;
// gets a sub image from this image
Image get_sub_image(const RectI& source_rect);
Image get_sub_image(const Recti& source_rect);
private:

View File

@ -1,8 +1,7 @@
#pragma once
#include <blah/images/image.h>
#include <blah/numerics/color.h>
#include <blah/numerics/rectI.h>
#include <blah/numerics/point.h>
#include <blah/numerics/spatial.h>
#include <blah/containers/str.h>
#include <blah/containers/vector.h>
#include <blah/streams/bufferstream.h>
@ -37,13 +36,13 @@ namespace Blah
// Packed frame rectangle.
// This won't be set until after the packer has run.
RectI frame;
Recti frame;
// Packed position and size.
// This won't be set until after the packer has run.
RectI packed;
Recti packed;
Entry(u64 id, const RectI& frame)
Entry(u64 id, const Recti& frame)
: memory_index(0)
, id(id)
, page(0)
@ -83,7 +82,7 @@ namespace Blah
void add(u64 id, const Image& bitmap);
// add a new entry
void add(u64 id, const Image& bitmap, const RectI& source);
void add(u64 id, const Image& bitmap, const Recti& source);
// add a new entry
void add(u64 id, const FilePath& path);
@ -104,13 +103,13 @@ namespace Blah
struct Node
{
bool used;
RectI rect;
Recti rect;
Node* right;
Node* down;
Node();
Node* Find(int w, int h);
Node* Reset(const RectI& rect);
Node* Reset(const Recti& rect);
};
// whether the packer has any changes that require it to run again
@ -123,6 +122,6 @@ namespace Blah
Vector<Entry> m_entries;
// adds a new entry
void add_entry(u64 id, int w, int h, const Color* pixels, const RectI& source);
void add_entry(u64 id, int w, int h, const Color* pixels, const Recti& source);
};
}

View File

@ -1,7 +1,7 @@
#pragma once
#include <blah/common.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/spatial.h>
#include <blah/containers/str.h>
#include <blah/containers/stackvector.h>
@ -392,13 +392,13 @@ namespace Blah
u64 timestamp[Input::max_mouse_buttons];
// mouse position in screen coordinates
Vec2 screen_position;
Vec2f screen_position;
// mouse position in pixel coordinates
Vec2 draw_position;
Vec2f draw_position;
// mouse position on the window
Vec2 position;
Vec2f position;
// mouse wheel value this frame
Point wheel;
@ -407,7 +407,7 @@ namespace Blah
void on_press(MouseButton button);
// invokes a mouse movement
void on_move(const Vec2& position, const Vec2& screen_position);
void on_move(const Vec2f& position, const Vec2f& screen_position);
// invokes a key release
void on_release(MouseButton button);
@ -686,7 +686,7 @@ namespace Blah
{}
// Current Value, -1 to 1
Vec2 value() const;
Vec2f value() const;
// Current value, either -1, 0, or 1
Point sign() const;
@ -735,14 +735,18 @@ namespace Blah
// Input State for the previous frame
extern InputState last_state;
// Key-Repeating intervals
extern float repeat_delay;
extern float repeat_interval;
// Gets the Mouse Position
Vec2 mouse();
Vec2f mouse();
// Gets the Draw Mouse Position (Mouse Position / Window Size * Draw Size)
Vec2 mouse_draw();
Vec2f mouse_draw();
// Gets the Mouse Position in Screen Coordinates
Vec2 mouse_screen();
Vec2f mouse_screen();
// Checks if the given Mouse Button is pressed
bool pressed(MouseButton button);
@ -765,6 +769,9 @@ namespace Blah
// Checks if the keyboard key was released this frame
bool released(Key key);
// Pressed or repeating on-interval
bool repeating(Key key);
// Checks if the Left or Right Ctrl Key is down
bool ctrl();
@ -780,6 +787,12 @@ namespace Blah
// returns a string name of the button
const char* name_of(Button button);
// gets the string contents of the clipboard
const String& get_clipboard();
// sets the string contents of the clipboard
void set_clipboard(const String& text);
// registers a new binding
ButtonBindingRef register_binding(const ButtonBinding& binding);

View File

@ -3,8 +3,6 @@
namespace Blah
{
struct Vec2;
namespace Calc
{
constexpr float PI = 3.141592653f;
@ -14,20 +12,8 @@ namespace Blah
constexpr float UP = PI / -2;
constexpr float DOWN = PI / 2;
float rand_float(float min, float maxExc);
float rand_float(float maxExc);
int rand_int(int min, int maxExc);
int rand_int(int maxExc);
int rand_int();
float approach(float t, float target, float delta);
Vec2 approach(const Vec2& t, const Vec2& target, float delta);
float map(float t, float old_min, float old_max, float new_min, float new_max);
float clamped_map(float t, float old_min, float old_max, float new_min, float new_max);
@ -40,8 +26,8 @@ namespace Blah
float abs(float x);
template<class T>
T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); }
template<class T, class TMin, class TMax>
T clamp(T value, TMin min, TMax max) { return value < min ? static_cast<T>(min) : (value > max ? static_cast<T>(max) : value); }
template<class T>
T min(T a, T b) { return (T)(a < b ? a : b); }

View File

@ -1,26 +0,0 @@
#pragma once
#include <blah/numerics/vec2.h>
namespace Blah
{
struct Circle
{
Vec2 center;
float radius;
constexpr Circle()
: center(), radius(0) {}
constexpr Circle(Vec2 center, float radius)
: center(center), radius(radius) {}
constexpr Circle(float x, float y, float radius)
: center(x, y), radius(radius) {}
constexpr void project(const Vec2& axis, float* min, float* max) const
{
*min = Vec2::dot(center - axis * radius, axis);
*max = Vec2::dot(center + axis * radius, axis);
}
};
}

View File

@ -1,8 +1,7 @@
#pragma once
#include <blah/common.h>
#include <blah/containers/str.h>
#include <blah/numerics/vec3.h>
#include <blah/numerics/vec4.h>
#include <blah/numerics/spatial.h>
#define BLAH_HEX_VALUE(n) ((n >= '0' && n <= '9') ? (n - '0') : ((n >= 'A' && n <= 'F') ? (10 + n - 'A') : ((n >= 'a' && n <= 'f') ? (10 + n - 'a') : 0)))
@ -42,19 +41,19 @@ namespace Blah
, b(b)
, a(a) {}
constexpr Color(const Vec3& vec3)
constexpr Color(const Vec3f& vec3)
: r((int)(vec3.x * 255))
, g((int)(vec3.y * 255))
, b((int)(vec3.z * 255))
, a((int)(255)) {}
constexpr Color(const Vec3& vec3, float alpha)
constexpr Color(const Vec3f& vec3, float alpha)
: r((int)(vec3.x* alpha * 255))
, g((int)(vec3.y* alpha * 255))
, b((int)(vec3.z* alpha * 255))
, a((int)(alpha * 255)) {}
constexpr Color(const Vec4& vec4)
constexpr Color(const Vec4f& vec4)
: r((int)(vec4.x * 255))
, g((int)(vec4.y * 255))
, b((int)(vec4.z * 255))
@ -99,15 +98,15 @@ namespace Blah
String to_hex_rgb() const;
// Converts the Color to a Vec3 (RGB)
constexpr Vec3 to_vec3() const
constexpr Vec3f to_vec3() const
{
return Vec3(r / 255.0f, g / 255.0f, b / 255.0f);
return Vec3f(r / 255.0f, g / 255.0f, b / 255.0f);
}
// Converts the Color to a Vec4 (RGBA)
constexpr Vec4 to_vec4() const
constexpr Vec4f to_vec4() const
{
return Vec4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
return Vec4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
}
// Convers the Color to a u32
@ -120,6 +119,15 @@ namespace Blah
(u32)a;
}
// Convers the Color to a u32
constexpr u32 to_rgb() const
{
return
((u32)r << 16) |
((u32)g << 8) |
(u32)b;
}
// Returns a RGBA Color representation of the integer value
static constexpr Color from_rgba(u32 value)
{
@ -198,16 +206,6 @@ namespace Blah
static const Color purple;
static const Color teal;
};
inline const Color Color::transparent = Color(0, 0, 0, 0);
inline const Color Color::white = Color(255, 255, 255, 255);
inline const Color Color::black = Color(0, 0, 0, 255);
inline const Color Color::red = Color(255, 0, 0, 255);
inline const Color Color::green = Color(0, 255, 0, 255);
inline const Color Color::blue = Color(0, 0, 255, 255);
inline const Color Color::yellow = Color(255, 255, 0, 255);
inline const Color Color::purple = Color(255, 0, 255, 255);
inline const Color Color::teal = Color(0, 255, 255, 255);
}
#undef BLAH_HEX_VALUE

View File

@ -1,50 +0,0 @@
#pragma once
#include <blah/numerics/vec2.h>
namespace Blah
{
struct Rect;
struct Line
{
Vec2 a;
Vec2 b;
constexpr Line()
: a(), b() {}
constexpr Line(const Vec2& a, const Vec2& b)
: a(a), b(b) {}
constexpr Line(float x0, float y0, float x1, float y1)
: a(x0, y0), b(x1, y1) {}
Rect bounds() const;
Vec2 closest_point(const Vec2& pt) const;
bool intersects(const Rect& rect) const;
bool intersects(const Rect& rect, Vec2* out_intersection_point) const;
bool intersects(const Line& line) const;
bool intersects(const Line& line, Vec2* out_intersection_point) const;
constexpr void project(const Vec2& axis, float* min, float* max) const
{
float dot = a.x * axis.x + a.y * axis.y;
*min = dot;
*max = dot;
dot = b.x * axis.x + b.y * axis.y;
*min = dot < *min ? dot : *min;
*max = dot > *max ? dot : *max;
}
constexpr Line operator +(const Vec2& rhs) const
{
return Line(a + rhs, b + rhs);
}
constexpr Line operator -(const Vec2& rhs) const
{
return Line(a - rhs, b - rhs);
}
};
}

View File

@ -1,133 +0,0 @@
#pragma once
namespace Blah
{
struct Vec2;
struct Mat3x2
{
float m11;
float m12;
float m21;
float m22;
float m31;
float m32;
constexpr Mat3x2()
: m11(0), m12(0), m21(0), m22(0), m31(0), m32(0) {}
constexpr Mat3x2(float m11, float m12, float m21, float m22, float m31, float m32)
: m11(m11), m12(m12), m21(m21), m22(m22), m31(m31), m32(m32) {}
static const Mat3x2 identity;
constexpr Mat3x2 invert() const
{
auto det = (m11 * m22) - (m21 * m12);
auto invDet = 1.0f / det;
return Mat3x2
{
m22 * invDet,
-m12 * invDet,
-m21 * invDet,
m11 * invDet,
(m21 * m32 - m31 * m22) * invDet,
(m31 * m12 - m11 * m32) * invDet
};
}
float scaling_factor() const;
static Mat3x2 create_translation(const Vec2& position);
static constexpr Mat3x2 create_translation(float x, float y)
{
return Mat3x2(1, 0, 0, 1, x, y);
}
static constexpr Mat3x2 create_scale(float scale)
{
return Mat3x2(scale, 0, 0, scale, 0, 0);
}
static Mat3x2 create_scale(float x, float y)
{
return Mat3x2(x, 0, 0, y, 0, 0);
}
static Mat3x2 create_scale(const Vec2& scale);
static Mat3x2 create_scale(float scale, const Vec2& center_point);
static Mat3x2 create_scale(const Vec2& scale, const Vec2& center_point);
static Mat3x2 create_scale(float scale_x, float scale_y, const Vec2& center_point);
static Mat3x2 create_rotation(float radians);
static Mat3x2 create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation);
static constexpr Mat3x2 add(const Mat3x2& a, const Mat3x2& b)
{
return Mat3x2(
a.m11 + b.m11,
a.m12 + b.m12,
a.m21 + b.m21,
a.m22 + b.m22,
a.m31 + b.m31,
a.m32 + b.m32);
}
static constexpr Mat3x2 subtract(const Mat3x2& a, const Mat3x2& b)
{
return Mat3x2(
a.m11 - b.m11,
a.m12 - b.m12,
a.m21 - b.m21,
a.m22 - b.m22,
a.m31 - b.m31,
a.m32 - b.m32);
}
static constexpr Mat3x2 multiply(const Mat3x2& a, const Mat3x2& b)
{
return Mat3x2(a.m11 * b.m11 + a.m12 * b.m21,
a.m11 * b.m12 + a.m12 * b.m22,
a.m21 * b.m11 + a.m22 * b.m21,
a.m21 * b.m12 + a.m22 * b.m22,
a.m31 * b.m11 + a.m32 * b.m21 + b.m31,
a.m31 * b.m12 + a.m32 * b.m22 + b.m32);
}
constexpr Mat3x2 operator *(const Mat3x2& rhs) const
{
return multiply(*this, rhs);
}
constexpr Mat3x2 operator +(const Mat3x2& rhs) const
{
return add(*this, rhs);
}
constexpr Mat3x2 operator -(const Mat3x2& rhs) const
{
return subtract(*this, rhs);
}
constexpr Mat3x2& operator *=(const Mat3x2& rhs)
{
*this = multiply(*this, rhs);
return *this;
}
constexpr bool operator==(const Mat3x2& rhs)
{
return m11 == rhs.m11 && m12 == rhs.m12 && m21 == rhs.m21 && m22 == rhs.m22 && m31 == rhs.m31 && m32 == rhs.m32;
}
constexpr bool operator!=(const Mat3x2& rhs)
{
return m11 != rhs.m11 || m12 != rhs.m12 || m21 != rhs.m21 || m22 != rhs.m22 || m31 != rhs.m31 || m32 != rhs.m32;
}
};
inline const Mat3x2 Mat3x2::identity = Mat3x2(1, 0, 0, 1, 0, 0);
}

View File

@ -1,48 +0,0 @@
#pragma once
#include "vec3.h"
namespace Blah
{
struct Mat4x4
{
float m11;
float m12;
float m13;
float m14;
float m21;
float m22;
float m23;
float m24;
float m31;
float m32;
float m33;
float m34;
float m41;
float m42;
float m43;
float m44;
Mat4x4();
Mat4x4(
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44);
static const Mat4x4 identity;
static Mat4x4 create_ortho(float width, float height, float z_near_plane, float z_far_plane);
static Mat4x4 create_ortho_offcenter(float left, float right, float bottom, float top, float z_near_plane, float z_far_plane);
static Mat4x4 create_perspective(float field_of_view, float ratio, float z_near_plane, float z_far_plane);
static Mat4x4 create_translation(float x, float y, float z);
static Mat4x4 create_scale(float x, float y, float z);
static Mat4x4 create_lookat(Vec3 position, Vec3 target, Vec3 up);
Mat4x4 operator* (const Mat4x4& rhs);
};
}

View File

@ -1,117 +0,0 @@
#pragma once
#include <blah/numerics/calc.h>
namespace Blah
{
struct Point
{
int x;
int y;
constexpr Point()
: x(0), y(0) {}
constexpr Point(int x, int y)
: x(x), y(y) {}
constexpr Point operator +(const Point rhs) const
{
return Point(x + rhs.x, y + rhs.y);
}
constexpr Point operator -(const Point rhs) const
{
return Point(x - rhs.x, y - rhs.y);
}
constexpr Point operator /(const int rhs) const
{
return Point(x / rhs, y / rhs);
}
constexpr Point operator *(const int rhs) const
{
return Point(x * rhs, y * rhs);
}
constexpr Point operator -() const
{
return Point(-x, -y);
}
constexpr Point& operator +=(const Point& rhs)
{
x += rhs.x; y += rhs.y;
return *this;
}
constexpr Point& operator -=(const Point& rhs)
{
x -= rhs.x; y -= rhs.y;
return *this;
}
constexpr Point& operator /=(const Point& rhs)
{
x /= rhs.x; y /= rhs.y;
return *this;
}
constexpr Point& operator *=(const Point& rhs)
{
x *= rhs.x; y *= rhs.y;
return *this;
}
constexpr Point& operator /=(int rhs)
{
x /= rhs; y /= rhs;
return *this;
}
constexpr Point& operator *=(int rhs)
{
x *= rhs; y *= rhs;
return *this;
}
constexpr bool operator ==(const Point& rhs) const
{
return x == rhs.x && y == rhs.y;
}
constexpr bool operator !=(const Point& rhs) const
{
return x != rhs.x || y != rhs.y;
}
float length() const
{
return Calc::sqrt((float)(x * x + y * y));
}
constexpr int length_squared() const
{
return x * x + y * y;
}
static const Point unitX;
static const Point unitY;
static const Point right;
static const Point up;
static const Point down;
static const Point left;
static const Point zero;
static const Point one;
};
inline const Point Point::unitX = Point(1, 0);
inline const Point Point::unitY = Point(0, 1);
inline const Point Point::right = Point(1, 0);
inline const Point Point::up = Point(0, -1);
inline const Point Point::down = Point(0, 1);
inline const Point Point::left = Point(-1, 0);
inline const Point Point::zero = Point(0, 0);
inline const Point Point::one = Point(1, 1);
}

View File

@ -1,35 +0,0 @@
#pragma once
#include <blah/numerics/vec2.h>
namespace Blah
{
struct Quad
{
Vec2 a;
Vec2 b;
Vec2 c;
Vec2 d;
constexpr Quad()
: a(), b(), c(), d() {}
constexpr Quad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d)
: a(a), b(b), c(c), d(d) {}
constexpr void project(const Vec2& axis, float* min, float* max) const
{
float dot = Vec2::dot(a, axis);
*min = dot;
*max = dot;
dot = Vec2::dot(b, axis);
*min = dot < *min ? dot : *min;
*max = dot > *max ? dot : *max;
dot = Vec2::dot(c, axis);
*min = dot < *min ? dot : *min;
*max = dot > *max ? dot : *max;
dot = Vec2::dot(d, axis);
*min = dot < *min ? dot : *min;
*max = dot > *max ? dot : *max;
}
};
}

View File

@ -1,173 +0,0 @@
#pragma once
#include <blah/numerics/point.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/rectI.h>
#include <blah/numerics/line.h>
#include <blah/numerics/mat3x2.h>
namespace Blah
{
struct Rect
{
float x;
float y;
float w;
float h;
constexpr Rect()
: x(0), y(0), w(0), h(0) {}
constexpr Rect(float x, float y, float w, float h)
: x(x), y(y), w(w), h(h) {}
constexpr Rect(Vec2 pos, Vec2 size)
: x(pos.x), y(pos.y), w(size.x), h(size.y) {}
constexpr Rect(const RectI& r)
: x(static_cast<float>(r.x)), y(static_cast<float>(r.y)), w(static_cast<float>(r.w)), h(static_cast<float>(r.h)) {}
constexpr float left() const { return x; }
constexpr float right() const { return x + w; }
constexpr float top() const { return y; }
constexpr float bottom() const { return y + h; }
constexpr Vec2 center() const { return Vec2(x + w / 2, y + h / 2); }
constexpr float center_x() const { return x + w / 2; }
constexpr float center_y() const { return y + h / 2; }
constexpr Vec2 top_left() const { return Vec2(x, y); }
constexpr Vec2 top_right() const { return Vec2(x + w, y); }
constexpr Vec2 bottom_right() const { return Vec2(x + w, y + h); }
constexpr Vec2 bottom_left() const { return Vec2(x, y + h); }
constexpr Vec2 center_left() const { return Vec2(x, y + h / 2); }
constexpr Vec2 center_right() const { return Vec2(x + w, y + h / 2); }
constexpr Vec2 middle_top() const { return Vec2(x + w / 2, y); }
constexpr Vec2 middle_bottom() const { return Vec2(x + w / 2, y + h); }
constexpr Line left_line() const { return Line(left(), top(), left(), bottom()); }
constexpr Line right_line() const { return Line(right(), top(), right(), bottom()); }
constexpr Line top_line() const { return Line(left(), top(), right(), top()); }
constexpr Line bottom_line() const { return Line(left(), bottom(), right(), bottom()); }
constexpr bool contains(const Point& pt) const
{
return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h;
}
constexpr bool contains(const Vec2& pt) const
{
return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h;
}
constexpr bool overlaps(const Rect& rect) const
{
return x + w >= rect.x && y + h >= rect.y && x < rect.x + rect.w && y < rect.y + rect.h;
}
Rect overlap_rect(const Rect& other) const;
bool intersects(const Line& line) const;
bool intersects(const Line& line, Vec2* out_intersection_point) const;
bool intersects(const Vec2& line_from, const Vec2& line_to) const;
bool intersects(const Vec2& line_from, const Vec2& line_to, Vec2* out_intersection_point) const;
Vec2 intersection_point(const Line& line) const;
Vec2 intersection_point(const Vec2& line_from, const Vec2& line_to) const;
constexpr Rect scale(float s) const
{
return Rect(x * s, y * s, w * s, h * s);
}
constexpr Rect scale(float sx, float sy) const
{
return Rect(x * sx, y * sy, w * sx, h * sy);
}
constexpr Rect inflate(float amount) const
{
return Rect(x - amount, y - amount, w + amount * 2, h + amount * 2);
}
// Rect Sectors:
// 0101 0100 0110
// 0001 0000 0010
// 1001 1000 1010
// 0000 = inside rectangle, all others refer to sectors relative to the rectangle
constexpr char get_sector(const Vec2& pt) const
{
char h = 0;
if (pt.x < left())
h = 0b0001;
else if (pt.x >= right())
h = 0b0010;
char v = 0;
if (pt.y < top())
v = 0b0100;
else if (pt.y >= bottom())
v = 0b1000;
return h | v;
}
constexpr Rect operator+(const Vec2& rhs) const
{
return Rect(x + rhs.x, y + rhs.y, w, h);
}
constexpr Rect operator-(const Vec2& rhs) const
{
return Rect(x - rhs.x, y - rhs.y, w, h);
}
constexpr Rect& operator+=(const Vec2& rhs)
{
x += rhs.x; y += rhs.y;
return *this;
}
constexpr Rect& operator-=(const Vec2& rhs)
{
x -= rhs.x; y -= rhs.y;
return *this;
}
constexpr bool operator==(const Rect& rhs) const
{
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
}
constexpr bool operator!=(const Rect& rhs) const
{
return x != rhs.x || y != rhs.y || w != rhs.w || h != rhs.h;
}
static constexpr Rect transform(const Rect& rect, const Mat3x2& matrix)
{
return Rect(
(rect.x * matrix.m11) + (rect.y * matrix.m21) + matrix.m31,
(rect.x * matrix.m12) + (rect.y * matrix.m22) + matrix.m32,
(rect.w * matrix.m11) + (rect.h * matrix.m21),
(rect.w * matrix.m12) + (rect.h * matrix.m22));
}
static constexpr Rect transform(float x, float y, float w, float h, const Mat3x2& matrix)
{
return Rect(
(x * matrix.m11) + (y * matrix.m21) + matrix.m31,
(x * matrix.m12) + (y * matrix.m22) + matrix.m32,
(w * matrix.m11) + (h * matrix.m21),
(w * matrix.m12) + (h * matrix.m22));
}
static constexpr Rect from_points(Vec2& from, Vec2& to)
{
auto min = Vec2(from.x < to.x ? from.x : to.x, from.y < to.y ? from.y : to.y);
auto max = Vec2(from.x > to.x ? from.x : to.x, from.y > to.y ? from.y : to.y);
return Rect(min.x, min.y, max.x - min.x, max.y - min.y);
}
};
}

View File

@ -1,59 +0,0 @@
#pragma once
namespace Blah
{
struct Point;
struct Rect;
struct Vec2;
struct RectI
{
int x;
int y;
int w;
int h;
RectI();
RectI(int rx, int ry, int rw, int rh);
RectI(Point pos, Point size);
int left() const;
int right() const;
int top() const;
int bottom() const;
int center_x() const;
int center_y() const;
Point center() const;
Point top_left() const;
Point top_right() const;
Point bottom_left() const;
Point bottom_right() const;
bool overlaps(const RectI& other) const;
RectI overlap_rect(const Rect& against) const;
bool contains(const Point& pt) const;
bool contains(const Vec2& pt) const;
/*
Rect Sectors:
0101 0100 0110
0001 0000 0010
1001 1000 1010
0000 = inside rectangle, all others refer to sectors relative to the rectangle
*/
char get_sector(const Point& pt) const;
char get_sector(const Vec2& pt) const;
bool operator==(const RectI& rhs) const;
bool operator!=(const RectI& rhs) const;
RectI operator+(const Point& rhs) const;
RectI operator-(const Point& rhs) const;
RectI operator*(const int& rhs) const;
RectI operator/(const int& rhs) const;
RectI& operator+=(const Point& rhs);
RectI& operator-=(const Point& rhs);
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,312 +0,0 @@
#pragma once
#include <blah/numerics/point.h>
#include <blah/numerics/calc.h>
#include <blah/numerics/mat3x2.h>
namespace Blah
{
struct Vec2
{
float x;
float y;
constexpr Vec2()
: x(0), y(0) {}
constexpr Vec2(float x, float y)
: x(x), y(y) {}
constexpr Vec2(int x, float y)
: x(static_cast<float>(x)), y(y) {}
constexpr Vec2(float x, int y)
: x(x), y(static_cast<float>(y)) {}
constexpr Vec2(int x, int y)
: x(static_cast<float>(x)), y(static_cast<float>(y)) {}
constexpr Vec2(const Point& p)
: x(static_cast<float>(p.x)), y(static_cast<float>(p.y)) {}
constexpr Vec2 operator +(const Vec2 rhs) const
{
return Vec2(x + rhs.x, y + rhs.y);
}
constexpr Vec2 operator -(const Vec2 rhs) const
{
return Vec2(x - rhs.x, y - rhs.y);
}
constexpr Vec2 operator /(const float rhs) const
{
return Vec2(x / rhs, y / rhs);
}
constexpr Vec2 operator *(const float rhs) const
{
return Vec2(x * rhs, y * rhs);
}
constexpr Vec2 operator -() const
{
return Vec2(-x, -y);
}
constexpr Vec2& operator +=(const Vec2& rhs)
{
x += rhs.x; y += rhs.y;
return *this;
}
constexpr Vec2& operator -=(const Vec2& rhs)
{
x -= rhs.x; y -= rhs.y;
return *this;
}
constexpr Vec2& operator /=(const Vec2& rhs)
{
x /= rhs.x; y /= rhs.y;
return *this;
}
constexpr Vec2& operator *=(const Vec2& rhs)
{
x *= rhs.x; y *= rhs.y;
return *this;
}
constexpr Vec2& operator /=(float rhs)
{
x /= rhs; y /= rhs;
return *this;
}
constexpr Vec2& operator *=(float rhs)
{
x *= rhs; y *= rhs;
return *this;
}
constexpr bool operator ==(const Vec2& rhs) const
{
return x == rhs.x && y == rhs.y;
}
constexpr bool operator !=(const Vec2& rhs) const
{
return x != rhs.x || y != rhs.y;
}
// Returns the absolute value of the Vector
constexpr Vec2 abs() const
{
return Vec2(x < 0 ? -x : x, y < 0 ? -y : 0);
}
// Returns the Normalized Vector
// If the length is 0, the resulting Vector is 0,0
Vec2 normal() const
{
if (x == 0 && y == 0)
return Vec2(0, 0);
const float len = Calc::sqrt((x * x) + (y * y));
return Vec2(x / len, y / len);
}
// Rotates the Vector 90 degrees right (-y, x)
constexpr Vec2 turn_right() const
{
return Vec2(-y, x);
}
// Rotates the Vector 90 degrees left (y, -x)
constexpr Vec2 turn_left() const
{
return Vec2(y, -x);
}
// Returns the length of the Vector
float length() const
{
return Calc::sqrt((x * x) + (y * y));
}
// Returns the squared length of the Vector
constexpr float length_squared() const
{
return (x * x) + (y * y);
}
// Gets the perpendicular Vector (-y, x)
constexpr Vec2 perpendicular() const
{
return Vec2(-y, x);
}
// Gets the angle, in radians, of the Vector
float angle() const
{
return Calc::atan2(y, x);
}
// Calculates the Dot Product between two vectors
static constexpr float dot(Vec2 a, Vec2 b)
{
return (a.x * b.x + a.y * b.y);
}
// Calculates the Dot Product between two vectors
static constexpr float dot(float x, float y, Vec2 b)
{
return (x * b.x + y * b.y);
}
// Calculates the Dot Product between two vectors
static constexpr float dot(float x1, float y1, float x2, float y2)
{
return (x1 * x2 + y1 * y2);
}
// Transforms a Vector by the given Matrix
static constexpr Vec2 transform(const Vec2& vec, const Mat3x2& matrix)
{
return Vec2(
(vec.x * matrix.m11) + (vec.y * matrix.m21) + matrix.m31,
(vec.x * matrix.m12) + (vec.y * matrix.m22) + matrix.m32);
}
// Transforms a Vector by the given Matrix
static constexpr Vec2 transform(float x, float y, const Mat3x2& matrix)
{
return Vec2(
(x * matrix.m11) + (y * matrix.m21) + matrix.m31,
(x * matrix.m12) + (y * matrix.m22) + matrix.m32);
}
// Transforms a Vector Normal by the given Matrix
static constexpr Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix)
{
return Vec2(
vec.x * matrix.m11 + vec.y * matrix.m21,
vec.x * matrix.m12 + vec.y * matrix.m22);
}
// Transforms a Vector Normal by the given Matrix
static constexpr Vec2 transform_normal(float x, float y, const Mat3x2& matrix)
{
return Vec2(
x * matrix.m11 + y * matrix.m21,
x * matrix.m12 + y * matrix.m22);
}
// Calculates a Vector value from the given radians
static Vec2 from_angle(float radians, float length = 1.0f)
{
return Vec2(
Calc::cos(radians) * length,
Calc::sin(radians) * length);
}
// Lerps between two Vectors
static constexpr Vec2 lerp(Vec2 a, Vec2 b, float t)
{
if (t == 0)
return a;
else if (t == 1)
return b;
else
return a + (b - a) * t;
}
// Lerps between two Vectors along a Bezier curve
static constexpr Vec2 lerp_bezier(Vec2 a, Vec2 b, Vec2 end, float t)
{
return lerp(lerp(a, b, t), lerp(b, end, t), t);
}
// Lerps between two Vectors along a Bezier curve
static constexpr Vec2 lerp_bezier(Vec2 a, Vec2 b, Vec2 c, Vec2 end, float t)
{
return lerp_bezier(lerp(a, b, t), lerp(b, c, t), lerp(c, end, t), t);
}
// Reflects a vector along the given Normal
static constexpr Vec2 reflect(const Vec2& vector, const Vec2& normal)
{
const float dot = vector.x * normal.x + vector.y * normal.y;
return Vec2(
vector.x - 2.0f * dot * normal.x,
vector.y - 2.0f * dot * normal.y);
}
// Gets the minimum between two vectors
static constexpr Vec2 min(const Vec2& a, const Vec2& b)
{
return Vec2(
a.x < b.x ? a.x : b.x,
a.y < b.y ? a.y : b.y);
}
// Gets the maximum between two vectors
static constexpr Vec2 max(const Vec2& a, const Vec2& b)
{
return Vec2(
a.x > b.x ? a.x : b.x,
a.y > b.y ? a.y : b.y);
}
// (1, 0)
static const Vec2 unit_x;
// (0, 1)
static const Vec2 unit_y;
// (1, 0)
static const Vec2 right;
// (0, -1)
static const Vec2 up;
// (0, 1)
static const Vec2 down;
// (-1, 0)
static const Vec2 left;
// (0, 0)
static const Vec2 zero;
// (1, 1)
static const Vec2 one;
// (0.707, -0.707)
static const Vec2 up_right;
// (-0.707, -0.707)
static const Vec2 up_left;
// (0.707, 0.707)
static const Vec2 down_right;
// (-0.707, 0.707)
static const Vec2 down_left;
};
inline const Vec2 Vec2::unit_x = Vec2(1, 0);
inline const Vec2 Vec2::unit_y = Vec2(0, 1);
inline const Vec2 Vec2::right = Vec2(1, 0);
inline const Vec2 Vec2::up = Vec2(0, -1);
inline const Vec2 Vec2::down = Vec2(0, 1);
inline const Vec2 Vec2::left = Vec2(-1, 0);
inline const Vec2 Vec2::zero = Vec2(0, 0);
inline const Vec2 Vec2::one = Vec2(1, 1);
inline const Vec2 Vec2::up_right = Vec2(0.70710678118f, -0.70710678118f);
inline const Vec2 Vec2::up_left = Vec2(-0.70710678118f, -0.70710678118f);
inline const Vec2 Vec2::down_right = Vec2(0.70710678118f, 0.70710678118f);
inline const Vec2 Vec2::down_left = Vec2(-0.70710678118f, 0.70710678118f);
}

View File

@ -1,50 +0,0 @@
#pragma once
#include "calc.h"
namespace Blah
{
struct Vec3
{
float x;
float y;
float z;
constexpr Vec3()
: x(0), y(0), z(0) {}
constexpr Vec3(float x, float y, float z)
: x(x), y(y), z(z) {}
constexpr Vec3 operator +(const Vec3 rhs) const
{
return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
}
constexpr Vec3 operator -(const Vec3 rhs) const
{
return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
}
inline Vec3 normal() const
{
float ls = x * x + y * y + z * z;
float length = (float)Calc::sqrt(ls);
return Vec3(x / length, y / length, z / length);
}
static constexpr float dot(Vec3 a, Vec3 b)
{
return a.x * b.x +
a.y * b.y +
a.z * b.z;
}
static constexpr Vec3 cross(Vec3 a, Vec3 b)
{
return Vec3(
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x);
}
};
}

View File

@ -1,18 +0,0 @@
#pragma once
namespace Blah
{
struct Vec4
{
float x;
float y;
float z;
float w;
constexpr Vec4()
: x(0), y(0), z(0), w(0) {}
constexpr Vec4(float x, float y, float z, float w)
: x(x), y(y), z(z), w(w) {}
};
}

View File

@ -9,7 +9,7 @@ namespace Blah
{
public:
MemoryStream();
MemoryStream(char* data, size_t length);
MemoryStream(unsigned char* data, size_t length);
MemoryStream(MemoryStream&& ms) noexcept;
MemoryStream& operator=(MemoryStream&& ms) noexcept;
~MemoryStream() override { m_data = nullptr; m_length = m_position = 0; }
@ -22,15 +22,15 @@ namespace Blah
bool is_writable() const override;
void close() override;
char* data();
const char* data() const;
unsigned char* data();
const unsigned char* data() const;
protected:
size_t read_data(void* ptr, size_t length) override;
size_t write_data(const void* ptr, size_t length) override;
private:
char* m_data;
unsigned char* m_data;
size_t m_length;
size_t m_position;
};

View File

@ -53,8 +53,8 @@ namespace Blah
public:
Stopwatch();
void reset();
u64 microseconds();
u64 milliseconds();
u64 microseconds() const;
u64 milliseconds() const;
private:
u64 start_time;

View File

@ -1,7 +1,6 @@
#include <blah/app.h>
#include <blah/common.h>
#include <blah/time.h>
#include <blah/numerics/point.h>
#include <blah/graphics/target.h>
#include "internal/platform.h"
#include "internal/graphics.h"
@ -142,6 +141,10 @@ bool App::run(const Config* c)
// input
Input::init();
// prepare by updating input & platform once
Input::update_state();
Platform::update(Input::state);
// startup
if (app_config.on_startup != nullptr)
app_config.on_startup();

View File

@ -218,7 +218,7 @@ Str& Str::append_utf16(const u16* start, const u16* end, bool swap_endian)
const u16 surrogate_min = 0xd800u;
const u16 surrogate_max = 0xdbffu;
while (start != end)
while ((end == nullptr && *start != 0) || (end != nullptr && start != end))
{
u16 next = (*start++);
if (swap_endian)

View File

@ -128,25 +128,22 @@ namespace
namespace
{
static Vec2 batch_shape_intersection(const Vec2& p0, const Vec2& p1, const Vec2& q0, const Vec2& q1)
static Vec2f batch_shape_intersection(const Vec2f& p0, const Vec2f& p1, const Vec2f& q0, const Vec2f& q1)
{
const auto aa = p1 - p0;
const auto bb = q0 - q1;
const auto cc = q0 - p0;
const auto t = (bb.x * cc.y - bb.y * cc.x) / (aa.y * bb.x - aa.x * bb.y);
return Vec2(p0.x + t * (p1.x - p0.x), p0.y + t * (p1.y - p0.y));
return Vec2f(p0.x + t * (p1.x - p0.x), p0.y + t * (p1.y - p0.y));
}
}
#define MAKE_VERTEX(vert, mat, px, py, tx, ty, c, m, w, f) \
(vert)->pos.x = ((px) * (mat).m11) + ((py) * (mat).m21) + (mat).m31; \
(vert)->pos.y = ((px) * (mat).m12) + ((py) * (mat).m22) + (mat).m32; \
(vert)->tex.x = tx; \
if (m_batch.flip_vertically) \
(vert)->tex.y = 1.0f - (ty); \
else \
(vert)->tex.y = ty; \
#define MAKE_VERTEX(vert, mat, px, py, tx, ty, c, m, w, f, cast) \
(vert)->pos.x = cast(((px) * (mat).m11) + ((py) * (mat).m21) + (mat).m31); \
(vert)->pos.y = cast(((px) * (mat).m12) + ((py) * (mat).m22) + (mat).m32); \
(vert)->tex.x = (tx); \
(vert)->tex.y = m_batch.flip_vertically ? 1.0f - (ty) : (ty); \
(vert)->col = c; \
(vert)->mult = m; \
(vert)->wash = w; \
@ -163,10 +160,17 @@ namespace
*_i++ = (u32)m_vertices.size() + 2; \
*_i++ = (u32)m_vertices.size() + 3; \
Vertex* _v = m_vertices.expand(4); \
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash); _v++; \
MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash); \
if (integerize) { \
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, std::round); _v++; \
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, std::round); _v++; \
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, std::round); _v++; \
MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash, std::round); \
} else { \
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, float); _v++; \
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, float); _v++; \
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, float); _v++; \
MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash, float); \
} \
}
#define PUSH_TRIANGLE(px0, py0, px1, py1, px2, py2, tx0, ty0, tx1, ty1, tx2, ty2, col0, col1, col2, mult, fill, wash) \
@ -177,9 +181,15 @@ namespace
*_i++ = (u32)m_vertices.size() + 1; \
*_i++ = (u32)m_vertices.size() + 2; \
Vertex* _v = m_vertices.expand(3); \
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash); \
if (integerize) { \
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, std::floor); _v++; \
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, std::floor); _v++; \
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, std::floor); \
} else { \
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, float); _v++; \
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, float); _v++; \
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, float); \
} \
}
#define INSERT_BATCH() \
@ -213,7 +223,7 @@ Batch::~Batch()
dispose();
}
void Batch::push_matrix(const Mat3x2& matrix, bool absolute)
void Batch::push_matrix(const Mat3x2f& matrix, bool absolute)
{
m_matrix_stack.push_back(m_matrix);
if (absolute)
@ -222,33 +232,33 @@ void Batch::push_matrix(const Mat3x2& matrix, bool absolute)
m_matrix = matrix * m_matrix;
}
Mat3x2 Batch::pop_matrix()
Mat3x2f Batch::pop_matrix()
{
auto was = m_matrix;
m_matrix = m_matrix_stack.pop();
return was;
}
Mat3x2 Batch::peek_matrix() const
Mat3x2f Batch::peek_matrix() const
{
return m_matrix;
}
void Batch::push_scissor(const Rect& scissor)
void Batch::push_scissor(const Rectf& scissor)
{
m_scissor_stack.push_back(m_batch.scissor);
SET_BATCH_VAR(scissor);
}
Rect Batch::pop_scissor()
Rectf Batch::pop_scissor()
{
Rect was = m_batch.scissor;
Rect scissor = m_scissor_stack.pop();
Rectf was = m_batch.scissor;
Rectf scissor = m_scissor_stack.pop();
SET_BATCH_VAR(scissor);
return was;
}
Rect Batch::peek_scissor() const
Rectf Batch::peek_scissor() const
{
return m_batch.scissor;
}
@ -388,10 +398,10 @@ void Batch::render(const TargetRef& target)
else
size = Point(target->width(), target->height());
render(target, Mat4x4::create_ortho_offcenter(0, (float)size.x, (float)size.y, 0, 0.01f, 1000.0f));
render(target, Mat4x4f::create_ortho_offcenter(0, (float)size.x, (float)size.y, 0, 0.01f, 1000.0f));
}
void Batch::render(const TargetRef& target, const Mat4x4& matrix)
void Batch::render(const TargetRef& target, const Mat4x4f& matrix)
{
// nothing to draw
if ((m_batches.size() <= 0 && m_batch.elements <= 0) || m_indices.size() <= 0)
@ -422,7 +432,7 @@ void Batch::render(const TargetRef& target, const Mat4x4& matrix)
pass.target = target;
pass.mesh = m_mesh;
pass.has_viewport = false;
pass.viewport = Rect();
pass.viewport = Rectf();
pass.instance_count = 0;
pass.depth = Compare::None;
pass.cull = Cull::None;
@ -443,7 +453,7 @@ void Batch::render(const TargetRef& target, const Mat4x4& matrix)
render_single_batch(pass, m_batch, matrix);
}
void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4& matrix)
void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4f& matrix)
{
// get the material
pass.material = b.material;
@ -462,7 +472,7 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4
pass.material->set_sampler(0, b.sampler);
// assign the matrix uniform
pass.material->set_value(matrix_uniform, &matrix.m11, 16);
pass.material->set_value(matrix_uniform, matrix);
pass.blend = b.blend;
pass.has_scissor = b.scissor.w >= 0 && b.scissor.h >= 0;
@ -475,7 +485,7 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4
void Batch::clear()
{
m_matrix = Mat3x2::identity;
m_matrix = Mat3x2f::identity;
m_color_mode = ColorMode::Normal;
m_tex_mult = 255;
m_tex_wash = 0;
@ -522,22 +532,22 @@ void Batch::dispose()
m_mesh.reset();
}
void Batch::line(const Vec2& from, const Vec2& to, float t, Color color)
void Batch::line(const Vec2f& from, const Vec2f& to, float t, Color color)
{
line(from, to, t, color, color);
}
void Batch::line(const Vec2& from, const Vec2& to, float t, Color fromColor, Color toColor)
void Batch::line(const Vec2f& from, const Vec2f& to, float t, Color fromColor, Color toColor)
{
if (from.x == to.x && from.y == to.y)
return;
Vec2 normal = (to - from).normal();
Vec2 perp = Vec2(normal.y, -normal.x);
Vec2 pos0 = from + perp * t * 0.5f;
Vec2 pos1 = to + perp * t * 0.5f;
Vec2 pos2 = to - perp * t * 0.5f;
Vec2 pos3 = from - perp * t * 0.5f;
Vec2f normal = (to - from).normal();
Vec2f perp = Vec2f(normal.y, -normal.x);
Vec2f pos0 = from + perp * t * 0.5f;
Vec2f pos1 = to + perp * t * 0.5f;
Vec2f pos2 = to - perp * t * 0.5f;
Vec2f pos3 = from - perp * t * 0.5f;
PUSH_QUAD(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y,
@ -546,14 +556,14 @@ void Batch::line(const Vec2& from, const Vec2& to, float t, Color fromColor, Col
0, 0, 255);
}
void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int steps, float t, Color color)
void Batch::bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& to, int steps, float t, Color color)
{
Vec2 prev = from;
Vec2f prev = from;
float add = 1.0f / steps;
for (int i = 1; i < steps; i++)
{
Vec2 at = Vec2::lerp_bezier(from, b, to, add * i);
Vec2f at = Vec2f::lerp_bezier(from, b, to, add * i);
line(prev, at, t, color);
prev = at;
}
@ -561,14 +571,14 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int ste
line(prev, to, t, color);
}
void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Vec2& to, int steps, float t, Color color)
void Batch::bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& c, const Vec2f& to, int steps, float t, Color color)
{
Vec2 prev = from;
Vec2f prev = from;
float add = 1.0f / steps;
for (int i = 1; i < steps; i++)
{
Vec2 at = Vec2::lerp_bezier(from, b, c, to, add * i);
Vec2f at = Vec2f::lerp_bezier(from, b, c, to, add * i);
line(prev, at, t, color);
prev = at;
}
@ -576,7 +586,7 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Ve
line(prev, to, t, color);
}
void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color color)
void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color color)
{
PUSH_TRIANGLE(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y,
@ -585,7 +595,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color colo
0, 0, 255);
}
void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color col0, Color col1, Color col2)
void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color col0, Color col1, Color col2)
{
PUSH_TRIANGLE(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y,
@ -594,7 +604,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color col0
0, 0, 255);
}
void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color color)
void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color color)
{
PUSH_TRIANGLE(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y,
@ -603,7 +613,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2
m_tex_mult, m_tex_wash, 0);
}
void Batch::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 Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color col0, Color col1, Color col2)
{
PUSH_TRIANGLE(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y,
@ -612,7 +622,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2
m_tex_mult, m_tex_wash, 0);
}
void Batch::tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color color)
void Batch::tri_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, float t, Color color)
{
// TODO:
// Detect if the thickness of the line fills the entire shape
@ -635,7 +645,7 @@ void Batch::tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color
quad(cc, c, a, aa, color);
}
void Batch::rect(const Rect& rect, Color color)
void Batch::rect(const Rectf& rect, Color color)
{
PUSH_QUAD(
rect.x, rect.y,
@ -647,7 +657,7 @@ void Batch::rect(const Rect& rect, Color color)
0, 0, 255);
}
void Batch::rect_line(const Rect& rect, float t, Color color)
void Batch::rect_line(const Rectf& rect, float t, Color color)
{
if (t >= rect.w || t >= rect.h)
{
@ -693,12 +703,12 @@ void Batch::rect_line(const Rect& rect, float t, Color color)
}
}
void Batch::rect_rounded(const Rect& rect, float radius, int steps, Color color)
void Batch::rect_rounded(const Rectf& rect, float radius, int steps, Color color)
{
rect_rounded(rect, radius, steps, radius, steps, radius, steps, radius, steps, color);
}
void Batch::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 Batch::rect_rounded(const Rectf& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, Color color)
{
// clamp
rtl = Calc::min(Calc::min(Calc::max(0.0f, rtl), rect.w / 2.0f), rect.h / 2.0f);
@ -713,10 +723,10 @@ void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr,
else
{
// get corners
Rect tl = Rect(rect.top_left(), Vec2(rtl, rtl));
Rect tr = Rect(rect.top_right() + Vec2(-rtr, 0.0f), Vec2(rtr, rtr));
Rect bl = Rect(rect.bottom_left() + Vec2(0.0f, -rbl), Vec2(rbl, rbl));
Rect br = Rect(rect.bottom_right() + Vec2(-rbr, -rbr), Vec2(rbr, rbr));
Rectf tl = Rectf(rect.x, rect.y, rtl, rtl);
Rectf tr = Rectf(rect.x + rect.w - rtr, rect.y, rtr, rtr);
Rectf bl = Rectf(rect.x, rect.y + rect.h - rbl, rbl, rbl);
Rectf br = Rectf(rect.x + rect.w - rbr, rect.y + rect.h - rbr, rbr, rbr);
// rounded corners
semi_circle(tl.bottom_right(), Calc::UP, Calc::LEFT, rtl, rtl_steps, color);
@ -733,12 +743,12 @@ void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr,
}
}
void Batch::rect_rounded_line(const Rect & rect, float radius, int steps, float t, Color color)
void Batch::rect_rounded_line(const Rectf & rect, float radius, int steps, float t, Color color)
{
rect_rounded_line(rect, radius, steps, radius, steps, radius, steps, radius, steps, t, color);
}
void Batch::rect_rounded_line(const Rect& r, 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 Batch::rect_rounded_line(const Rectf& r, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, float t, Color color)
{
// clamp
rtl = Calc::min(Calc::min(Calc::max(0.0f, rtl), r.w / 2.0f), r.h / 2.0f);
@ -753,42 +763,42 @@ void Batch::rect_rounded_line(const Rect& r, float rtl, int rtl_steps, float rtr
else
{
// rounded corners
semi_circle_line(Vec2(r.x + rtl, r.y + rtl), Calc::UP, Calc::LEFT, rtl, rtl_steps, t, color);
semi_circle_line(Vec2(r.x + r.w - rtr, r.y + rtr), Calc::UP, Calc::UP + Calc::TAU * 0.25f, rtr, rtr_steps, t, color);
semi_circle_line(Vec2(r.x + rbl, r.y + r.h - rbl), Calc::DOWN, Calc::LEFT, rbl, rbl_steps, t, color);
semi_circle_line(Vec2(r.x + r.w - rbr, r.y + r.h - rbr), Calc::DOWN, Calc::RIGHT, rbr, rbr_steps, t, color);
semi_circle_line(Vec2f(r.x + rtl, r.y + rtl), Calc::UP, Calc::LEFT, rtl, rtl_steps, t, color);
semi_circle_line(Vec2f(r.x + r.w - rtr, r.y + rtr), Calc::UP, Calc::UP + Calc::TAU * 0.25f, rtr, rtr_steps, t, color);
semi_circle_line(Vec2f(r.x + rbl, r.y + r.h - rbl), Calc::DOWN, Calc::LEFT, rbl, rbl_steps, t, color);
semi_circle_line(Vec2f(r.x + r.w - rbr, r.y + r.h - rbr), Calc::DOWN, Calc::RIGHT, rbr, rbr_steps, t, color);
// connect sides that aren't touching
if (r.h > rtl + rbl)
rect(Rect(r.x, r.y + rtl, t, r.h - rtl - rbl), color);
rect(Rectf(r.x, r.y + rtl, t, r.h - rtl - rbl), color);
if (r.h > rtr + rbr)
rect(Rect(r.x + r.w - t, r.y + rtr, t, r.h - rtr - rbr), color);
rect(Rectf(r.x + r.w - t, r.y + rtr, t, r.h - rtr - rbr), color);
if (r.w > rtl + rtr)
rect(Rect(r.x + rtl, r.y, r.w - rtl - rtr, t), color);
rect(Rectf(r.x + rtl, r.y, r.w - rtl - rtr, t), color);
if (r.w > rbl + rbr)
rect(Rect(r.x + rbl, r.y + r.h - t, r.w - rbl - rbr, t), color);
rect(Rectf(r.x + rbl, r.y + r.h - t, r.w - rbl - rbr, t), color);
}
}
void Batch::semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor)
void Batch::semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor)
{
Vec2 last = Vec2::from_angle(start_radians, radius);
Vec2f last = Vec2f::from_angle(start_radians, radius);
float add = Calc::angle_diff(start_radians, end_radians);
for (int i = 1; i <= steps; i++)
{
Vec2 next = Vec2::from_angle(start_radians + add * (i / (float)steps), radius);
Vec2f next = Vec2f::from_angle(start_radians + add * (i / (float)steps), radius);
tri(center + last, center + next, center, edgeColor, edgeColor, centerColor);
last = next;
}
}
void Batch::semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color color)
void Batch::semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color color)
{
semi_circle(center, start_radians, end_radians, radius, steps, color, color);
}
void Batch::semi_circle_line(const Vec2& center, float start_radians, float end_radians, float radius, int steps, float t, Color color)
void Batch::semi_circle_line(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, float t, Color color)
{
if (t >= radius)
{
@ -798,13 +808,13 @@ void Batch::semi_circle_line(const Vec2& center, float start_radians, float end_
{
const auto add = Calc::angle_diff(start_radians, end_radians);
Vec2 last_inner = Vec2::from_angle(start_radians, radius - t);
Vec2 last_outer = Vec2::from_angle(start_radians, radius);
Vec2f last_inner = Vec2f::from_angle(start_radians, radius - t);
Vec2f last_outer = Vec2f::from_angle(start_radians, radius);
for (int i = 1; i <= steps; i++)
{
const auto next_inner = Vec2::from_angle(start_radians + add * (i / (float)steps), radius - t);
const auto next_outer = Vec2::from_angle(start_radians + add * (i / (float)steps), radius);
const auto next_inner = Vec2f::from_angle(start_radians + add * (i / (float)steps), radius - t);
const auto next_outer = Vec2f::from_angle(start_radians + add * (i / (float)steps), radius);
quad(center + last_inner, center + last_outer, center + next_outer, center + next_inner, color);
@ -814,19 +824,19 @@ void Batch::semi_circle_line(const Vec2& center, float start_radians, float end_
}
}
void Batch::circle(const Vec2& center, float radius, int steps, Color color)
void Batch::circle(const Vec2f& center, float radius, int steps, Color color)
{
circle(center, radius, steps, color, color);
}
void Batch::circle(const Vec2& center, float radius, int steps, Color center_color, Color outer_color)
void Batch::circle(const Vec2f& center, float radius, int steps, Color center_color, Color outer_color)
{
Vec2 last = Vec2(center.x + radius, center.y);
Vec2f last = Vec2f(center.x + radius, center.y);
for (int i = 1; i <= steps; i++)
{
const auto radians = (i / (float)steps) * Calc::TAU;
const auto next = Vec2(center.x + Calc::cos(radians) * radius, center.y + Calc::sin(radians) * radius);
const auto next = Vec2f(center.x + Calc::cos(radians) * radius, center.y + Calc::sin(radians) * radius);
tri(last, next, center, outer_color, outer_color, center_color);
@ -834,7 +844,7 @@ void Batch::circle(const Vec2& center, float radius, int steps, Color center_col
}
}
void Batch::circle_line(const Vec2& center, float radius, float t, int steps, Color color)
void Batch::circle_line(const Vec2f& center, float radius, float t, int steps, Color color)
{
if (t >= radius)
{
@ -842,16 +852,16 @@ void Batch::circle_line(const Vec2& center, float radius, float t, int steps, Co
}
else
{
Vec2 last_inner = Vec2(center.x + radius - t, center.y);
Vec2 last_outer = Vec2(center.x + radius, center.y);
Vec2f last_inner = Vec2f(center.x + radius - t, center.y);
Vec2f last_outer = Vec2f(center.x + radius, center.y);
for (int i = 1; i <= steps; i++)
{
const auto radians = (i / (float)steps) * Calc::TAU;
const auto normal = Vec2(Calc::cos(radians), Calc::sin(radians));
const auto normal = Vec2f(Calc::cos(radians), Calc::sin(radians));
const auto next_inner = Vec2(center.x + normal.x * (radius - t), center.y + normal.y * (radius - t));
const auto next_outer = Vec2(center.x + normal.x * radius, center.y + normal.y * radius);
const auto next_inner = Vec2f(center.x + normal.x * (radius - t), center.y + normal.y * (radius - t));
const auto next_outer = Vec2f(center.x + normal.x * radius, center.y + normal.y * radius);
quad(last_inner, last_outer, next_outer, next_inner, color);
@ -861,7 +871,7 @@ void Batch::circle_line(const Vec2& center, float radius, float t, int steps, Co
}
}
void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color color)
void Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color color)
{
PUSH_QUAD(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y,
@ -870,7 +880,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec
0, 0, 255);
}
void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color col0, Color col1, Color col2, Color col3)
void Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color col0, Color col1, Color col2, Color col3)
{
PUSH_QUAD(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y,
@ -879,7 +889,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec
0, 0, 255);
}
void Batch::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 Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color color)
{
PUSH_QUAD(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y,
@ -888,7 +898,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec
m_tex_mult, m_tex_wash, 0);
}
void Batch::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 Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color col0, Color col1, Color col2, Color col3)
{
PUSH_QUAD(
pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y,
@ -897,7 +907,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec
m_tex_mult, m_tex_wash, 0);
}
void Batch::quad_line(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, float t, Color color)
void Batch::quad_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Vec2f& d, float t, Color color)
{
// TODO:
// Detect if the thickness of the line fills the entire shape
@ -924,22 +934,22 @@ void Batch::quad_line(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d
quad(dd, d, a, aa, color);
}
void Batch::arrow_head(const Vec2& point_pos, float radians, float side_len, Color color)
void Batch::arrow_head(const Vec2f& point_pos, float radians, float side_len, Color color)
{
arrow_head(point_pos, point_pos - Vec2::from_angle(radians), side_len, color);
arrow_head(point_pos, point_pos - Vec2f::from_angle(radians), side_len, color);
}
void Batch::arrow_head(const Vec2& point_pos, const Vec2& from_pos, float side_len, Color color)
void Batch::arrow_head(const Vec2f& point_pos, const Vec2f& from_pos, float side_len, Color color)
{
float height = sqrtf(side_len * side_len - powf(side_len / 2, 2));
Vec2 dir = (point_pos - from_pos).normal();
Vec2 perp = dir.perpendicular();
Vec2 base = point_pos - dir * height;
Vec2f dir = (point_pos - from_pos).normal();
Vec2f perp = dir.turn_right();
Vec2f base = point_pos - dir * height;
tri(point_pos, base + perp * side_len / 2, base - perp * side_len / 2, color);
}
void Batch::tex(const TextureRef& texture, const Vec2& pos, Color color)
void Batch::tex(const TextureRef& texture, const Vec2f& pos, Color color)
{
set_texture(texture);
@ -953,9 +963,9 @@ void Batch::tex(const TextureRef& texture, const Vec2& pos, Color color)
m_tex_mult, m_tex_wash, 0);
}
void Batch::tex(const TextureRef& texture, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color)
void Batch::tex(const TextureRef& texture, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color)
{
push_matrix(Mat3x2::create_transform(pos, origin, scale, rotation));
push_matrix(Mat3x2f::create_transform(pos, origin, scale, rotation));
set_texture(texture);
@ -971,9 +981,9 @@ void Batch::tex(const TextureRef& texture, const Vec2& pos, const Vec2& origin,
pop_matrix();
}
void Batch::tex(const TextureRef& texture, const Rect& clip, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color)
void Batch::tex(const TextureRef& texture, const Rectf& clip, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color)
{
push_matrix(Mat3x2::create_transform(pos, origin, scale, rotation));
push_matrix(Mat3x2f::create_transform(pos, origin, scale, rotation));
set_texture(texture);
@ -993,7 +1003,7 @@ void Batch::tex(const TextureRef& texture, const Rect& clip, const Vec2& pos, co
pop_matrix();
}
void Batch::tex(const Subtexture& sub, const Vec2& pos, Color color)
void Batch::tex(const Subtexture& sub, const Vec2f& pos, Color color)
{
if (!sub.texture)
{
@ -1024,9 +1034,9 @@ void Batch::tex(const Subtexture& sub, const Vec2& pos, Color color)
}
}
void Batch::tex(const Subtexture& sub, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color)
void Batch::tex(const Subtexture& sub, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color)
{
push_matrix(Mat3x2::create_transform(pos, origin, scale, rotation));
push_matrix(Mat3x2f::create_transform(pos, origin, scale, rotation));
if (!sub.texture)
{
@ -1059,24 +1069,24 @@ void Batch::tex(const Subtexture& sub, const Vec2& pos, const Vec2& origin, cons
pop_matrix();
}
void Batch::tex(const Subtexture& sub, const Rect& clip, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color)
void Batch::tex(const Subtexture& sub, const Rectf& clip, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color)
{
tex(sub.crop(clip), pos, origin, scale, rotation, color);
}
void Batch::str(const SpriteFont& font, const String& text, const Vec2& pos, Color color)
void Batch::str(const SpriteFont& font, const String& text, const Vec2f& pos, Color color)
{
str(font, text, pos, TextAlign::TopLeft, font.size, color);
}
void Batch::str(const SpriteFont& font, const String& text, const Vec2& pos, TextAlign align, float size, Color color)
void Batch::str(const SpriteFont& font, const String& text, const Vec2f& pos, TextAlign align, float size, Color color)
{
push_matrix(
Mat3x2::create_scale(size / font.size) *
Mat3x2::create_translation(pos)
Mat3x2f::create_scale(size / font.size) *
Mat3x2f::create_translation(pos)
);
Vec2 offset;
Vec2f offset;
if ((align & TextAlign::Left) == TextAlign::Left)
offset.x = 0;
@ -1119,7 +1129,7 @@ void Batch::str(const SpriteFont& font, const String& text, const Vec2& pos, Tex
// draw it, if the subtexture exists
if (ch.subtexture.texture)
{
Vec2 at = offset + ch.offset;
Vec2f at = offset + ch.offset;
if (i > 0 && text[i - 1] != '\n')
at.x += font.get_kerning(last, next);

View File

@ -6,7 +6,7 @@ using namespace Blah;
namespace
{
int calc_uniform_size(const UniformInfo& uniform)
int blah_calc_uniform_size(const UniformInfo& uniform)
{
int components = 0;
@ -27,16 +27,6 @@ namespace
}
}
MaterialRef Material::create(const ShaderRef& shader)
{
BLAH_ASSERT(shader, "The provided shader is invalid");
if (shader)
return MaterialRef(new Material(shader));
return MaterialRef();
}
Material::Material(const ShaderRef& shader)
{
BLAH_ASSERT(shader, "Material is being created with an invalid shader");
@ -64,12 +54,31 @@ Material::Material(const ShaderRef& shader)
continue;
}
float_size += calc_uniform_size(uniform);
float_size += blah_calc_uniform_size(uniform);
}
m_data.expand(float_size);
}
MaterialRef Material::create(const ShaderRef& shader)
{
BLAH_ASSERT(shader, "The provided shader is invalid");
if (shader)
return MaterialRef(new Material(shader));
return MaterialRef();
}
MaterialRef Material::clone() const
{
auto copy = MaterialRef(new Material(m_shader));
copy->m_textures = m_textures;
copy->m_samplers = m_samplers;
copy->m_data = m_data;
return copy;
}
ShaderRef Material::shader() const
{
return m_shader;
@ -293,7 +302,7 @@ void Material::set_value(const char* name, const float* value, i64 length)
if (strcmp(uniform.name, name) == 0)
{
auto max = calc_uniform_size(uniform);
auto max = blah_calc_uniform_size(uniform);
if (length > max)
{
Log::warn("Exceeding length of Uniform '%s' (%i / %i)", name, length, max);
@ -304,13 +313,73 @@ void Material::set_value(const char* name, const float* value, i64 length)
return;
}
offset += calc_uniform_size(uniform);
offset += blah_calc_uniform_size(uniform);
index++;
}
Log::warn("No Uniform '%s' exists", name);
}
void Material::set_value(const char* name, float value)
{
set_value(name, &value, 1);
}
void Material::set_value(const char* name, const Vec2f& value)
{
set_value(name, &value.x, 2);
}
void Material::set_value(const char* name, const Vec3f& value)
{
set_value(name, &value.x, 3);
}
void Material::set_value(const char* name, const Vec4f& value)
{
set_value(name, &value.x, 4);
}
void Material::set_value(const char* name, const Mat3x2f& value)
{
set_value(name, &value.m11, 6);
}
void Material::set_value(const char* name, const Mat4x4f& value)
{
set_value(name, &value.m11, 16);
}
void Material::set_value(const char* name, const Vector<float>& value)
{
set_value(name, value.data(), value.size());
}
void Material::set_value(const char* name, const Vector<Vec2f>& value)
{
set_value(name, (float*)value.data(), value.size() * 2);
}
void Material::set_value(const char* name, const Vector<Vec3f>& value)
{
set_value(name, (float*)value.data(), value.size() * 3);
}
void Material::set_value(const char* name, const Vector<Vec4f>& value)
{
set_value(name, (float*)value.data(), value.size() * 4);
}
void Material::set_value(const char* name, const Vector<Mat3x2f>& value)
{
set_value(name, (float*)value.data(), value.size() * 6);
}
void Material::set_value(const char* name, const Vector<Mat4x4f>& value)
{
set_value(name, (float*)value.data(), value.size() * 16);
}
const float* Material::get_value(const char* name, i64* length) const
{
BLAH_ASSERT(m_shader, "Material Shader is invalid");
@ -327,12 +396,12 @@ const float* Material::get_value(const char* name, i64* length) const
if (strcmp(uniform.name, name) == 0)
{
if (length != nullptr)
*length = calc_uniform_size(uniform);
*length = blah_calc_uniform_size(uniform);
return m_data.begin() + offset;
}
index++;
offset += calc_uniform_size(uniform);
offset += blah_calc_uniform_size(uniform);
}
Log::warn("No Uniform '%s' exists", name);

View File

@ -12,8 +12,8 @@ RenderPass::RenderPass()
material = MaterialRef();
has_viewport = false;
has_scissor = false;
viewport = Rect();
scissor = Rect();
viewport = Rectf();
scissor = Rectf();
index_start = 0;
index_count = 0;
instance_count = 0;
@ -66,7 +66,7 @@ void RenderPass::perform()
}
// get the total drawable size
auto draw_size = Vec2(pass.target->width(), pass.target->height());
auto draw_size = Vec2f(pass.target->width(), pass.target->height());
// Validate Viewport
if (!pass.has_viewport)
@ -78,12 +78,12 @@ void RenderPass::perform()
}
else
{
pass.viewport = pass.viewport.overlap_rect(Rect(0, 0, draw_size.x, draw_size.y));
pass.viewport = pass.viewport.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y));
}
// Validate Scissor
if (pass.has_scissor)
pass.scissor = pass.scissor.overlap_rect(Rect(0, 0, draw_size.x, draw_size.y));
pass.scissor = pass.scissor.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y));
// perform render
Graphics::render(pass);

View File

@ -213,7 +213,7 @@ void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset)
// add character
auto ch = font.get_character(glyph, scale);
m_characters[i].advance = ch.advance;
m_characters[i].offset = Vec2(ch.offset_x, ch.offset_y);
m_characters[i].offset = Vec2f(ch.offset_x, ch.offset_y);
// pack glyph
if (ch.has_glyph)

View File

@ -6,12 +6,12 @@ using namespace Blah;
Subtexture::Subtexture() {}
Subtexture::Subtexture(const TextureRef& texture)
: Subtexture(texture, Rect(0, 0, (float)texture->width(), (float)texture->height())) {}
: Subtexture(texture, Rectf(0, 0, (float)texture->width(), (float)texture->height())) {}
Subtexture::Subtexture(const TextureRef& texture, Rect source)
: Subtexture(texture, source, Rect(0, 0, source.w, source.h)) {}
Subtexture::Subtexture(const TextureRef& texture, Rectf source)
: Subtexture(texture, source, Rectf(0, 0, source.w, source.h)) {}
Subtexture::Subtexture(const TextureRef& texture, Rect source, Rect frame)
Subtexture::Subtexture(const TextureRef& texture, Rectf source, Rectf frame)
: texture(texture), source(source), frame(frame)
{
update();
@ -44,7 +44,7 @@ void Subtexture::update()
}
}
void Subtexture::crop_info(const Rect& clip, Rect* dest_source, Rect* dest_frame) const
void Subtexture::crop_info(const Rectf& clip, Rectf* dest_source, Rectf* dest_frame) const
{
*dest_source = (clip + source.top_left() + frame.top_left()).overlap_rect(source);
@ -54,7 +54,7 @@ void Subtexture::crop_info(const Rect& clip, Rect* dest_source, Rect* dest_frame
dest_frame->h = clip.h;
}
Subtexture Subtexture::crop(const Rect& clip) const
Subtexture Subtexture::crop(const Rectf& clip) const
{
Subtexture dst;
dst.texture = texture;

View File

@ -193,7 +193,7 @@ void Image::premultiply()
}
}
void Image::set_pixels(const RectI& rect, Color* data)
void Image::set_pixels(const Recti& rect, Color* data)
{
for (int y = 0; y < rect.h; y++)
{
@ -257,7 +257,7 @@ bool Image::save_jpg(Stream& stream, int quality) const
return false;
}
void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, RectI source_rect) const
void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, Recti source_rect) const
{
// can't be outside of the source image
if (source_rect.x < 0) source_rect.x = 0;
@ -279,7 +279,7 @@ void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_siz
}
}
Image Image::get_sub_image(const RectI& source_rect)
Image Image::get_sub_image(const Recti& source_rect)
{
Image img(source_rect.w, source_rect.h);
get_pixels(img.pixels, Point::zero, Point(img.width, img.height), source_rect);

View File

@ -43,15 +43,15 @@ Packer::~Packer()
void Packer::add(u64 id, int width, int height, const Color* pixels)
{
add_entry(id, width, height, pixels, RectI(0, 0, width, height));
add_entry(id, width, height, pixels, Recti(0, 0, width, height));
}
void Packer::add(u64 id, const Image& image)
{
add_entry(id, image.width, image.height, image.pixels, RectI(0, 0, image.width, image.height));
add_entry(id, image.width, image.height, image.pixels, Recti(0, 0, image.width, image.height));
}
void Packer::add(u64 id, const Image& image, const RectI& source)
void Packer::add(u64 id, const Image& image, const Recti& source)
{
add_entry(id, image.width, image.height, image.pixels, source);
}
@ -61,11 +61,11 @@ void Packer::add(u64 id, const FilePath& path)
add(id, Image(path.cstr()));
}
void Packer::add_entry(u64 id, int w, int h, const Color* pixels, const RectI& source)
void Packer::add_entry(u64 id, int w, int h, const Color* pixels, const Recti& source)
{
m_dirty = true;
Entry entry(id, RectI(0, 0, source.w, source.h));
Entry entry(id, Recti(0, 0, source.w, source.h));
// trim
int top = source.y, left = source.x, right = source.x, bottom = source.y;
@ -115,7 +115,6 @@ void Packer::add_entry(u64 id, int w, int h, const Color* pixels, const RectI& s
entry.packed.w = (right - left);
entry.packed.h = (bottom - top);
// create pixel data
entry.memory_index = m_buffer.position();
@ -189,7 +188,7 @@ void Packer::pack()
int from = packed;
int index = 0;
Node* root = nodes[index++].Reset(RectI(0, 0, sources[from]->packed.w + padding * 2 + spacing, sources[from]->packed.h + padding * 2 + spacing));
Node* root = nodes[index++].Reset(Recti(0, 0, sources[from]->packed.w + padding * 2 + spacing, sources[from]->packed.h + padding * 2 + spacing));
while (packed < count)
{
@ -217,18 +216,18 @@ void Packer::pack()
// grow right
if (shouldGrowRight || (!shouldGrowDown && canGrowRight))
{
Node* next = nodes[index++].Reset(RectI(0, 0, root->rect.w + w, root->rect.h));
Node* next = nodes[index++].Reset(Recti(0, 0, root->rect.w + w, root->rect.h));
next->used = true;
next->down = root;
next->right = node = nodes[index++].Reset(RectI(root->rect.w, 0, w, root->rect.h));
next->right = node = nodes[index++].Reset(Recti(root->rect.w, 0, w, root->rect.h));
root = next;
}
// grow down
else
{
Node* next = nodes[index++].Reset(RectI(0, 0, root->rect.w, root->rect.h + h));
Node* next = nodes[index++].Reset(Recti(0, 0, root->rect.w, root->rect.h + h));
next->used = true;
next->down = node = nodes[index++].Reset(RectI(0, root->rect.h, root->rect.w, h));
next->down = node = nodes[index++].Reset(Recti(0, root->rect.h, root->rect.w, h));
next->right = root;
root = next;
}
@ -241,8 +240,8 @@ void Packer::pack()
// add
node->used = true;
node->down = nodes[index++].Reset(RectI(node->rect.x, node->rect.y + h, node->rect.w, node->rect.h - h));
node->right = nodes[index++].Reset(RectI(node->rect.x + w, node->rect.y, node->rect.w - w, h));
node->down = nodes[index++].Reset(Recti(node->rect.x, node->rect.y + h, node->rect.w, node->rect.h - h));
node->right = nodes[index++].Reset(Recti(node->rect.x + w, node->rect.y, node->rect.w - w, h));
sources[packed]->packed.x = node->rect.x + padding;
sources[packed]->packed.y = node->rect.y + padding;
@ -276,21 +275,26 @@ void Packer::pack()
sources[i]->page = page;
if (!sources[i]->empty)
{
RectI dst = sources[i]->packed;
Recti dst = sources[i]->packed;
Color* src = (Color*)(m_buffer.data() + sources[i]->memory_index);
// TODO:
// Optimize this?
if (padding > 0)
{
pages[page].set_pixels(RectI(dst.x - padding, dst.y, dst.w, dst.h), src);
pages[page].set_pixels(RectI(dst.x + padding, dst.y, dst.w, dst.h), src);
pages[page].set_pixels(RectI(dst.x, dst.y - padding, dst.w, dst.h), src);
pages[page].set_pixels(RectI(dst.x, dst.y + padding, dst.w, dst.h), src);
Image& image = pages[page];
for (int x = -padding; x < dst.w + padding * 2; x++)
for (int y = -padding; y < dst.h + padding * 2; y++)
{
int sx = (x < 0 ? 0 : (x > dst.w - 1 ? dst.w - 1 : x));
int sy = (y < 0 ? 0 : (y > dst.h - 1 ? dst.h - 1 : y));
image.pixels[dst.x + x + (dst.y + y) * image.width] = src[sx + sy * dst.w];
}
}
else
{
pages[page].set_pixels(dst, src);
}
pages[page].set_pixels(dst, src);
}
}
}
@ -335,7 +339,7 @@ Packer::Node* Packer::Node::Find(int w, int h)
return nullptr;
}
Packer::Node* Packer::Node::Reset(const RectI& rect)
Packer::Node* Packer::Node::Reset(const Recti& rect)
{
used = false;
this->rect = rect;

View File

@ -2,9 +2,9 @@
#include <blah/app.h>
#include <blah/time.h>
#include <blah/common.h>
#include <blah/numerics/point.h>
#include <blah/numerics/calc.h>
#include "internal/input.h"
#include "internal/platform.h"
#include <cstring>
using namespace Blah;
@ -16,11 +16,15 @@ namespace
Vector<WeakRef<ButtonBinding>> g_buttons;
Vector<WeakRef<AxisBinding>> g_axes;
Vector<WeakRef<StickBinding>> g_sticks;
String g_clipboard;
}
InputState Blah::Input::state;
InputState Blah::Input::last_state;
float Blah::Input::repeat_delay = 0.35f;
float Blah::Input::repeat_interval = 0.025f;
void Input::init()
{
g_empty_controller.name = "Disconnected";
@ -68,6 +72,9 @@ void Input::update_state()
controller.released[j] = false;
}
}
// get clipboard
g_clipboard = Platform::get_clipboard();
}
void Input::update_bindings()
@ -112,7 +119,7 @@ void Input::update_bindings()
}
}
void MouseState::on_move(const Vec2& pos, const Vec2& screen_pos)
void MouseState::on_move(const Vec2f& pos, const Vec2f& screen_pos)
{
position = pos;
screen_position = screen_pos;
@ -223,17 +230,17 @@ bool KeyboardState::alt()
return down[Key::LeftAlt] || down[Key::RightAlt];
}
Vec2 Input::mouse()
Vec2f Input::mouse()
{
return state.mouse.position;
}
Vec2 Input::mouse_draw()
Vec2f Input::mouse_draw()
{
return state.mouse.draw_position;
}
Vec2 Input::mouse_screen()
Vec2f Input::mouse_screen()
{
return state.mouse.screen_position;
}
@ -273,6 +280,26 @@ bool Input::released(Key key)
return state.keyboard.released[key];
}
bool Input::repeating(Key key)
{
if (state.keyboard.pressed[key])
return true;
if (state.keyboard.down[key])
{
double timestamp = state.keyboard.timestamp[key] / (double)Time::ticks_per_second;
double current_time = Time::ticks / (double)Time::ticks_per_second;
if (current_time > timestamp + Input::repeat_delay)
{
if (Time::on_interval(current_time - timestamp, Time::delta, Input::repeat_interval, 0.0f))
return true;
}
}
return false;
}
bool Input::ctrl()
{
return state.keyboard.ctrl();
@ -312,6 +339,17 @@ const char* Input::name_of(Button button)
return "Unknown";
}
const String& Input::get_clipboard()
{
return g_clipboard;
}
void Input::set_clipboard(const String& text)
{
g_clipboard = text;
return Platform::set_clipboard(text);
}
ButtonBindingRef Input::register_binding(const ButtonBinding& binding)
{
auto result = std::make_shared<ButtonBinding>(binding);
@ -730,17 +768,17 @@ void AxisBinding::clear()
positive.clear();
}
Vec2 StickBinding::value() const
Vec2f StickBinding::value() const
{
Vec2 result = Vec2(x.value(), y.value());
Vec2f result = Vec2f(x.value(), y.value());
if (round_threshold > 0 && result.length() < round_threshold)
return Vec2::zero;
return Vec2f::zero;
return result;
}
Point StickBinding::sign() const
{
Vec2 result = value();
Vec2f result = value();
return Point((int)Calc::sign(result.x), (int)Calc::sign(result.y));
}

View File

@ -1420,7 +1420,7 @@ namespace Blah
// Viewport
{
Rect viewport = pass.viewport;
Rectf viewport = pass.viewport;
viewport.y = size.y - viewport.y - viewport.h;
gl.Viewport((GLint)viewport.x, (GLint)viewport.y, (GLint)viewport.w, (GLint)viewport.h);
@ -1434,7 +1434,7 @@ namespace Blah
}
else
{
Rect scissor = pass.scissor;
Rectf scissor = pass.scissor;
scissor.y = size.y - scissor.y - scissor.h;
if (scissor.w < 0)

View File

@ -88,6 +88,12 @@ namespace Blah
// opens a directory in the OS file explorer / finder
void dir_explore(const char* path);
// sets the contents of the clipboard
void set_clipboard(const char* text);
// gets the contents of the clipboard into the given string
const char* get_clipboard();
// OpenGL Methods
void* gl_get_func(const char* name);
void* gl_context_create();

View File

@ -261,8 +261,8 @@ void Platform::update(InputState& state)
SDL_GetGlobalMouseState(&x, &y);
state.mouse.on_move(
Vec2((float)(x - win_x), (float)(y - win_y)),
Vec2((float)x, (float)y));
Vec2f((float)(x - win_x), (float)(y - win_y)),
Vec2f((float)x, (float)y));
}
// poll normal events
@ -722,6 +722,17 @@ void Platform::dir_explore(const char* path)
#endif
// clipboard
void Platform::set_clipboard(const char* text)
{
SDL_SetClipboardText(text);
}
const char* Platform::get_clipboard()
{
return SDL_GetClipboardText();
}
void* Platform::gl_get_func(const char* name)
{
return SDL_GL_GetProcAddress(name);

View File

@ -360,7 +360,7 @@ LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam
return 0;
case WM_MOUSEMOVE:
g_platform.input_state->mouse.on_move(Vec2((float)((u16)lParam), (float)(lParam >> 16)), Vec2::zero);
g_platform.input_state->mouse.on_move(Vec2f((float)((u16)lParam), (float)(lParam >> 16)), Vec2f::zero);
return 0;
case WM_MOUSEWHEEL:
@ -628,6 +628,17 @@ FileRef Platform::file_open(const char* path, FileMode mode)
return FileRef(new Win32File(result));
}
// clipboard
void Platform::set_clipboard(const char* text)
{
BLAH_ASSERT(false, "Not Implemented Yet");
}
const char* Platform::get_clipboard()
{
BLAH_ASSERT(false, "Not Implemented Yet");
}
void* Platform::gl_get_func(const char* name)
{
// this check is taken from https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions

View File

@ -1,49 +1,15 @@
#include <blah/numerics/calc.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/spatial.h>
#include <cmath>
#include <cstdlib>
using namespace Blah;
float Calc::rand_float(float min, float maxExc)
{
return min + rand_float(maxExc - min);
}
float Calc::rand_float(float maxExc)
{
return (rand() / (float)RAND_MAX) * maxExc;
}
int Calc::rand_int(int min, int maxExc)
{
return min + rand_int(maxExc - min);
}
int Calc::rand_int(int maxExc)
{
if (maxExc <= 0)
return 0;
return rand() % maxExc;
}
int Calc::rand_int()
{
return rand();
}
float Calc::approach(float t, float target, float delta)
{
return t < target ? min(t + delta, target) : max(t - delta, target);
}
Vec2 Calc::approach(const Vec2& t, const Vec2& target, float delta)
{
if ((target - t).length() <= delta)
return target;
return t + (target - t).normal() * delta;
}
float Calc::map(float t, float old_min, float old_max, float new_min, float new_max)
{
return new_min + ((t - old_min) / (old_max - old_min)) * (new_max - new_min);

View File

@ -30,4 +30,14 @@ String Color::to_hex_rgb() const
str[4] = hex[(b & 0xF0) >> 4];
str[5] = hex[(b & 0x0F) >> 0];
return str;
}
}
const Color Color::transparent = Color(0, 0, 0, 0);
const Color Color::white = Color(255, 255, 255, 255);
const Color Color::black = Color(0, 0, 0, 255);
const Color Color::red = Color(255, 0, 0, 255);
const Color Color::green = Color(0, 255, 0, 255);
const Color Color::blue = Color(0, 0, 255, 255);
const Color Color::yellow = Color(255, 255, 0, 255);
const Color Color::purple = Color(255, 0, 255, 255);
const Color Color::teal = Color(0, 255, 255, 255);

View File

@ -1,133 +0,0 @@
#include <blah/numerics/line.h>
#include <blah/numerics/rect.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/calc.h>
using namespace Blah;
Rect Line::bounds() const
{
Vec2 pos = Vec2(Calc::min(a.x, b.x), Calc::min(a.y, b.y));
return Rect(
pos,
Vec2(Calc::max(a.x, b.x) - pos.x, Calc::max(a.y, b.y) - pos.y)
);
}
Vec2 Line::closest_point(const Vec2& pt) const
{
Vec2 v = b - a;
Vec2 w = pt - a;
float t = Vec2::dot(w, v) / Vec2::dot(v, v);
t = Calc::clamp(t, 0.0f, 1.0f);
return v * t + a;
}
bool Line::intersects(const Rect& rect) const
{
char ca = rect.get_sector(a);
char cb = rect.get_sector(b);
if (ca == cb || (ca & cb) != 0)
return false;
char both = ca | cb;
// top
if ((both & 0b0100) != 0 && intersects(rect.top_line()))
return true;
// bottom
if ((both & 0b1000) != 0 && intersects(rect.bottom_line()))
return true;
// left
if ((both & 0b0001) != 0 && intersects(rect.left_line()))
return true;
// right
if ((both & 0b0010) != 0 && intersects(rect.right_line()))
return true;
return false;
}
bool Line::intersects(const Rect& rect, Vec2* out_intersection_point) const
{
char ca = rect.get_sector(a);
char cb = rect.get_sector(b);
if (ca == cb || (ca & cb) != 0)
return false;
char both = ca | cb;
// top
if ((both & 0b0100) != 0 && intersects(rect.top_line(), out_intersection_point))
return true;
// bottom
if ((both & 0b1000) != 0 && intersects(rect.bottom_line(), out_intersection_point))
return true;
// left
if ((both & 0b0001) != 0 && intersects(rect.left_line(), out_intersection_point))
return true;
// right
if ((both & 0b0010) != 0 && intersects(rect.right_line(), out_intersection_point))
return true;
return false;
}
bool Line::intersects(const Line& line) const
{
Vec2 e = b - a;
Vec2 d = line.b - line.a;
float e_dot_d_perp = e.x * d.y - e.y * d.x;
// if e dot d == 0, it means the lines are parallel
// so have infinite intersection points
if (e_dot_d_perp < 0.0001 && e_dot_d_perp > -0.0001)
return false;
Vec2 c = line.a - a;
float t = (c.x * d.y - c.y * d.x) / e_dot_d_perp;
if (t < 0 || t > 1)
return false;
float u = (c.x * e.y - c.y * e.x) / e_dot_d_perp;
if (u < 0 || u > 1)
return false;
return true;
}
bool Line::intersects(const Line& line, Vec2* intersection_point) const
{
Vec2 e = b - a;
Vec2 d = line.b - line.a;
float e_dot_d_perp = e.x * d.y - e.y * d.x;
// if e dot d == 0, it means the lines are parallel
// so have infinite intersection points
if (e_dot_d_perp < 0.0001 && e_dot_d_perp > -0.0001)
return false;
Vec2 c = line.a - a;
float t = (c.x * d.y - c.y * d.x) / e_dot_d_perp;
if (t < 0 || t > 1)
return false;
float u = (c.x * e.y - c.y * e.x) / e_dot_d_perp;
if (u < 0 || u > 1)
return false;
Vec2 i = (e * t) + a;
intersection_point->x = i.x;
intersection_point->y = i.y;
return true;
}

View File

@ -1,95 +0,0 @@
#include <blah/numerics/mat3x2.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/calc.h>
using namespace Blah;
float Mat3x2::scaling_factor() const
{
return Calc::sqrt(m11 * m11 + m12 * m12);
}
Mat3x2 Mat3x2::create_translation(const Vec2& position)
{
return create_translation(position.x, position.y);
}
Mat3x2 Mat3x2::create_scale(const Vec2& scale)
{
return create_scale(scale.x, scale.y);
}
Mat3x2 Mat3x2::create_scale(float scale, const Vec2& center_point)
{
Mat3x2 result;
float tx = center_point.x * (1 - scale);
float ty = center_point.y * (1 - scale);
result.m11 = scale;
result.m12 = 0.0f;
result.m21 = 0.0f;
result.m22 = scale;
result.m31 = tx;
result.m32 = ty;
return result;
}
Mat3x2 Mat3x2::create_scale(const Vec2& scale, const Vec2& center_point)
{
Mat3x2 result;
float tx = center_point.x * (1 - scale.x);
float ty = center_point.y * (1 - scale.y);
result.m11 = scale.x;
result.m12 = 0.0f;
result.m21 = 0.0f;
result.m22 = scale.y;
result.m31 = tx;
result.m32 = ty;
return result;
}
Mat3x2 Mat3x2::create_scale(float scale_x, float scale_y, const Vec2& center_point)
{
Mat3x2 result;
float tx = center_point.x * (1 - scale_x);
float ty = center_point.y * (1 - scale_y);
result.m11 = scale_x;
result.m12 = 0.0f;
result.m21 = 0.0f;
result.m22 = scale_y;
result.m31 = tx;
result.m32 = ty;
return result;
}
Mat3x2 Mat3x2::create_rotation(float radians)
{
float c = Calc::cos(radians);
float s = Calc::sin(radians);
return Mat3x2(c, s, -s, c, 0, 0);
}
Mat3x2 Mat3x2::create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation)
{
Mat3x2 matrix = identity;
if (origin.x != 0 || origin.y != 0)
matrix = create_translation(-origin.x, -origin.y);
if (scale.x != 1 || scale.y != 1)
matrix = matrix * create_scale(scale);
if (rotation != 0)
matrix = matrix * create_rotation(rotation);
if (position.x != 0 || position.y != 0)
matrix = matrix * create_translation(position);
return matrix;
}

View File

@ -1,161 +0,0 @@
#include <blah/numerics/mat4x4.h>
#include <blah/common.h>
using namespace Blah;
Mat4x4::Mat4x4() :
m11(0.0f), m12(0.0f), m13(0.0f), m14(0.0f),
m21(0.0f), m22(0.0f), m23(0.0f), m24(0.0f),
m31(0.0f), m32(0.0f), m33(0.0f), m34(0.0f),
m41(0.0f), m42(0.0f), m43(0.0f), m44(0.0f) {}
Mat4x4::Mat4x4(
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44) :
m11(m11), m12(m12), m13(m13), m14(m14),
m21(m21), m22(m22), m23(m23), m24(m24),
m31(m31), m32(m32), m33(m33), m34(m34),
m41(m41), m42(m42), m43(m43), m44(m44) {}
const Mat4x4 Mat4x4::identity = Mat4x4(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
Mat4x4 Mat4x4::create_ortho(float width, float height, float z_near_plane, float z_far_plane)
{
Mat4x4 result = identity;
result.m11 = 2.0f / width;
result.m12 = result.m13 = result.m14 = 0.0f;
result.m22 = -2.0f / height;
result.m21 = result.m23 = result.m24 = 0.0f;
result.m33 = 1.0f / (z_near_plane - z_far_plane);
result.m31 = result.m32 = result.m34 = 0.0f;
result.m41 = result.m42 = 0.0f;
result.m43 = z_near_plane / (z_near_plane - z_far_plane);
result.m44 = 1.0f;
return result;
}
Mat4x4 Mat4x4::create_ortho_offcenter(float left, float right, float bottom, float top, float z_near_plane, float z_far_plane)
{
Mat4x4 result = identity;
result.m11 = 2.0f / (right - left);
result.m12 = result.m13 = result.m14 = 0.0f;
result.m22 = 2.0f / (top - bottom);
result.m21 = result.m23 = result.m24 = 0.0f;
result.m33 = 1.0f / (z_near_plane - z_far_plane);
result.m31 = result.m32 = result.m34 = 0.0f;
result.m41 = (left + right) / (left - right);
result.m42 = (top + bottom) / (bottom - top);
result.m43 = z_near_plane / (z_near_plane - z_far_plane);
result.m44 = 1.0f;
return result;
}
Mat4x4 Mat4x4::create_perspective(float field_of_view, float ratio, float z_near_plane, float z_far_plane)
{
float yScale = 1.0f / (float)Calc::tan(field_of_view * 0.5f);
float xScale = yScale / ratio;
Mat4x4 result;
result.m11 = xScale;
result.m12 = result.m13 = result.m14 = 0.0f;
result.m22 = yScale;
result.m21 = result.m23 = result.m24 = 0.0f;
result.m31 = result.m32 = 0.0f;
result.m33 = z_far_plane / (z_near_plane - z_far_plane);
result.m34 = -1.0f;
result.m41 = result.m42 = result.m44 = 0.0f;
result.m43 = z_near_plane * z_far_plane / (z_near_plane - z_far_plane);
return result;
}
Mat4x4 Mat4x4::create_translation(float x, float y, float z)
{
Mat4x4 result = identity;
result.m41 = x;
result.m42 = y;
result.m43 = z;
return result;
}
Mat4x4 Mat4x4::create_scale(float x, float y, float z)
{
Mat4x4 result = identity;
result.m11 = x;
result.m22 = y;
result.m33 = z;
return result;
}
Mat4x4 Mat4x4::create_lookat(Vec3 position, Vec3 target, Vec3 up)
{
Vec3 zaxis = (position - target).normal();
Vec3 xaxis = Vec3::cross(up, zaxis).normal();
Vec3 yaxis = Vec3::cross(zaxis, xaxis);
Mat4x4 result;
result.m11 = xaxis.x;
result.m12 = yaxis.x;
result.m13 = zaxis.x;
result.m14 = 0.0f;
result.m21 = xaxis.y;
result.m22 = yaxis.y;
result.m23 = zaxis.y;
result.m24 = 0.0f;
result.m31 = xaxis.z;
result.m32 = yaxis.z;
result.m33 = zaxis.z;
result.m34 = 0.0f;
result.m41 = -Vec3::dot(xaxis, position);
result.m42 = -Vec3::dot(yaxis, position);
result.m43 = -Vec3::dot(zaxis, position);
result.m44 = 1.0f;
return result;
}
Mat4x4 Mat4x4::operator*(const Mat4x4& rhs)
{
Mat4x4 m;
m.m11 = m11 * rhs.m11 + m12 * rhs.m21 + m13 * rhs.m31 + m14 * rhs.m41;
m.m12 = m11 * rhs.m12 + m12 * rhs.m22 + m13 * rhs.m32 + m14 * rhs.m42;
m.m13 = m11 * rhs.m13 + m12 * rhs.m23 + m13 * rhs.m33 + m14 * rhs.m43;
m.m14 = m11 * rhs.m14 + m12 * rhs.m24 + m13 * rhs.m34 + m14 * rhs.m44;
m.m21 = m21 * rhs.m11 + m22 * rhs.m21 + m23 * rhs.m31 + m24 * rhs.m41;
m.m22 = m21 * rhs.m12 + m22 * rhs.m22 + m23 * rhs.m32 + m24 * rhs.m42;
m.m23 = m21 * rhs.m13 + m22 * rhs.m23 + m23 * rhs.m33 + m24 * rhs.m43;
m.m24 = m21 * rhs.m14 + m22 * rhs.m24 + m23 * rhs.m34 + m24 * rhs.m44;
m.m31 = m31 * rhs.m11 + m32 * rhs.m21 + m33 * rhs.m31 + m34 * rhs.m41;
m.m32 = m31 * rhs.m12 + m32 * rhs.m22 + m33 * rhs.m32 + m34 * rhs.m42;
m.m33 = m31 * rhs.m13 + m32 * rhs.m23 + m33 * rhs.m33 + m34 * rhs.m43;
m.m34 = m31 * rhs.m14 + m32 * rhs.m24 + m33 * rhs.m34 + m34 * rhs.m44;
m.m41 = m41 * rhs.m11 + m42 * rhs.m21 + m43 * rhs.m31 + m44 * rhs.m41;
m.m42 = m41 * rhs.m12 + m42 * rhs.m22 + m43 * rhs.m32 + m44 * rhs.m42;
m.m43 = m41 * rhs.m13 + m42 * rhs.m23 + m43 * rhs.m33 + m44 * rhs.m43;
m.m44 = m41 * rhs.m14 + m42 * rhs.m24 + m43 * rhs.m34 + m44 * rhs.m44;
return m;
}

View File

@ -1,61 +0,0 @@
#include <blah/numerics/rect.h>
#include <blah/numerics/calc.h>
using namespace Blah;
Rect Rect::overlap_rect(const Rect& against) const
{
Rect result(0, 0, 0, 0);
if (x + w >= against.x && x < against.x + against.w)
{
result.x = Calc::max(x, against.x);
result.w = Calc::min(x + w, against.x + against.w) - result.x;
}
if (y + h >= against.y && y < against.y + against.h)
{
result.y = Calc::max(y, against.y);
result.h = Calc::min(y + h, against.y + against.h) - result.y;
}
return result;
}
bool Rect::intersects(const Line& line) const
{
return line.intersects(*this);
}
bool Rect::intersects(const Line& line, Vec2* out_intersection_point) const
{
return line.intersects(*this, out_intersection_point);
}
bool Rect::intersects(const Vec2& line_from, const Vec2& line_to) const
{
return intersects(Line(line_from, line_to));
}
bool Rect::intersects(const Vec2& line_from, const Vec2& line_to, Vec2* out_intersection_point) const
{
return intersects(Line(line_from, line_to), out_intersection_point);
}
Vec2 Rect::intersection_point(const Line& line) const
{
Vec2 ret;
if (line.intersects(*this, &ret))
return ret;
else
return Vec2::zero;
}
Vec2 Rect::intersection_point(const Vec2& line_from, const Vec2& line_to) const
{
Vec2 ret;
if (Line(line_from, line_to).intersects(*this, &ret))
return ret;
else
return Vec2::zero;
}

View File

@ -1,202 +0,0 @@
#include <blah/numerics/rectI.h>
#include <blah/numerics/rect.h>
#include <blah/numerics/point.h>
#include <blah/numerics/vec2.h>
#include <blah/numerics/calc.h>
using namespace Blah;
RectI::RectI()
{
x = y = w = h = 0;
}
RectI::RectI(int rx, int ry, int rw, int rh)
{
x = rx;
y = ry;
w = rw;
h = rh;
}
RectI::RectI(Point pos, Point size)
{
x = pos.x;
y = pos.y;
w = size.x;
h = size.y;
}
int RectI::left() const
{
return x;
}
int RectI::right() const
{
return x + w;
}
int RectI::top() const
{
return y;
}
int RectI::bottom() const
{
return y + h;
}
int RectI::center_x() const
{
return x + w / 2;
}
int RectI::center_y() const
{
return y + h / 2;
}
Point RectI::center() const
{
return Point(x + w / 2, y + h / 2);
}
Point RectI::top_left() const
{
return Point(x, y);
}
Point RectI::top_right() const
{
return Point(x + w, y);
}
Point RectI::bottom_left() const
{
return Point(x, y + h);
}
Point RectI::bottom_right() const
{
return Point(x + w, y + h);
}
bool RectI::overlaps(const RectI& other) const
{
return x < other.x + other.w
&& other.x < x + w
&& y < other.y + other.h
&& other.y < y + h;
}
RectI RectI::overlap_rect(const Rect& against) const
{
RectI result = *this;
if (x + w >= against.x && x < against.x + against.w)
{
result.x = Calc::max(x, (int)against.x);
result.w = Calc::min(x + w, (int)(against.x + against.w)) - result.x;
}
if (y + h >= against.y && y < against.y + against.h)
{
result.y = Calc::max(y, (int)against.y);
result.h = Calc::min(y + h, (int)(against.y + against.h)) - result.y;
}
return result;
}
bool RectI::contains(const Point& point) const
{
return point.x >= x && point.x < x + w && point.y >= y && point.y < y + h;
}
bool RectI::contains(const Vec2& point) const
{
return point.x >= x && point.x < x + w && point.y >= y && point.y < y + h;
}
char RectI::get_sector(const Point& pt) const
{
char h;
if (pt.x < left())
h = 0b0001;
else if (pt.x >= right())
h = 0b0010;
else
h = 0;
char v;
if (pt.y < top())
v = 0b0100;
else if (pt.y >= bottom())
v = 0b1000;
else
v = 0;
return h | v;
}
char RectI::get_sector(const Vec2& pt) const
{
char h;
if (pt.x < left())
h = 0b0001;
else if (pt.x >= right())
h = 0b0010;
else
h = 0;
char v;
if (pt.y < top())
v = 0b0100;
else if (pt.y >= bottom())
v = 0b1000;
else
v = 0;
return h | v;
}
bool RectI::operator==(const RectI& rhs) const
{
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
}
bool RectI::operator!=(const RectI& rhs) const
{
return !(*this == rhs);
}
RectI RectI::operator+(const Point& rhs) const
{
return RectI(x + rhs.x, y + rhs.y, w, h);
}
RectI RectI::operator-(const Point& rhs) const
{
return RectI(x - rhs.x, y - rhs.y, w, h);
}
RectI RectI::operator*(const int& rhs) const
{
return RectI(x * rhs, y * rhs, w * rhs, h * rhs);
}
RectI RectI::operator/(const int& rhs) const
{
return RectI(x / rhs, y / rhs, w / rhs, h / rhs);
}
RectI& RectI::operator+=(const Point& rhs)
{
x += rhs.x; y += rhs.y; return *this;
}
RectI& RectI::operator-=(const Point& rhs)
{
x -= rhs.x; y -= rhs.y; return *this;
}

View File

@ -6,7 +6,7 @@ using namespace Blah;
MemoryStream::MemoryStream()
: m_data(nullptr), m_length(0), m_position(0) {}
MemoryStream::MemoryStream(char* data, size_t length)
MemoryStream::MemoryStream(unsigned char* data, size_t length)
: m_data(data), m_length(length), m_position(0) {}
MemoryStream::MemoryStream(MemoryStream&& src) noexcept
@ -89,12 +89,12 @@ void MemoryStream::close()
m_data = nullptr; m_length = m_position = 0;
}
char* MemoryStream::data()
unsigned char* MemoryStream::data()
{
return m_data;
}
const char* MemoryStream::data() const
const unsigned char* MemoryStream::data() const
{
return m_data;
}

View File

@ -65,12 +65,12 @@ void Stopwatch::reset()
start_time = std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count();
}
u64 Stopwatch::milliseconds()
u64 Stopwatch::milliseconds() const
{
return microseconds() / 1000;
}
u64 Stopwatch::microseconds()
u64 Stopwatch::microseconds() const
{
return std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count() - start_time;
}