Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Brad Svercl 2021-03-14 19:42:57 -05:00
commit 1978a64f79
22 changed files with 607 additions and 141 deletions

View File

@ -45,6 +45,7 @@
#include "blah/math/rectI.h"
#include "blah/math/stopwatch.h"
#include "blah/math/vec2.h"
#include "blah/math/vec3.h"
#include "blah/math/vec4.h"
#include "blah/streams/bufferstream.h"

View File

@ -1,8 +1,13 @@
#pragma once
#include <memory>
#include <functional>
#include <blah/core/log.h>
namespace Blah
{
using AppEventFn = std::function<void()>;
using AppLogFn = std::function<void(const char* message, Log::Category category)>;
struct Config
{
const char* name;
@ -11,15 +16,12 @@ namespace Blah
int max_updates;
int target_framerate;
void (*on_startup)();
void (*on_shutdown)();
void (*on_update)();
void (*on_render)();
void (*on_exit_request)();
void (*on_info)(const char* text);
void (*on_warn)(const char* text);
void (*on_error)(const char* text);
AppEventFn on_startup;
AppEventFn on_shutdown;
AppEventFn on_update;
AppEventFn on_render;
AppEventFn on_exit_request;
AppLogFn on_log;
Config();
};

View File

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

View File

@ -1,7 +1,7 @@
#pragma once
// error / abort
#ifdef DEBUG
#if defined(DEBUG) || defined(_DEBUG)
#include <stdlib.h>
#define BLAH_ERROR(message) \
@ -23,6 +23,9 @@
#define BLAH_ASSERT(condition, message) \
do { if (!(condition)) { BLAH_ERROR(message); } } while(0)
#define BLAH_ASSERT_FMT(condition, message, ...) \
do { if (!(condition)) { BLAH_ERROR_FMT(message, __VA_ARGS__); } } while(0)
// maximum length of a print/warn/error message
#ifndef BLAH_MESSAGE
#define BLAH_MESSAGE 1024
@ -32,6 +35,13 @@ namespace Blah
{
namespace Log
{
enum class Category
{
Info,
Warning,
Error
};
void print(const char* info, ...);
void warn(const char* info, ...);
void error(const char* info, ...);

View File

@ -14,6 +14,15 @@ namespace Blah
class FrameBuffer;
typedef std::shared_ptr<FrameBuffer> FrameBufferRef;
enum class ClearMask
{
None = 0,
Color = 1,
Depth = 2,
Stencil = 4,
All = (int)Color | (int)Depth | (int)Stencil
};
class FrameBuffer
{
protected:
@ -56,7 +65,7 @@ namespace Blah
virtual int height() const = 0;
// Clears the FrameBuffer
virtual void clear(Color color) = 0;
virtual void clear(Color color = Color::black, float depth = 1.0f, uint8_t stencil = 0, ClearMask mask = ClearMask::All) = 0;
};
}

View File

@ -61,6 +61,8 @@ namespace Blah
float cos(float x);
float tan(float x);
float atan2(float y, float x);
float pow(float x, float n);

View File

@ -1,4 +1,5 @@
#pragma once
#include "vec3.h"
namespace Blah
{
@ -36,8 +37,11 @@ namespace Blah
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

@ -17,12 +17,12 @@ namespace Blah
RectI(int rx, int ry, int rw, int rh);
RectI(Point pos, Point size);
int left() const { return x; }
int right() const { return x + w; }
int top() const { return y; }
int bottom() const { return y + h; }
int centerX() const { return x + w / 2; }
int centerY() const { return y + h / 2; }
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;
@ -30,14 +30,7 @@ namespace Blah
Point bottom_left() const;
Point bottom_right() const;
bool overlaps(const RectI& other) const
{
return x < other.x + other.w
&& other.x < x + w
&& y < other.y + other.h
&& other.y < y + h;
}
bool overlaps(const RectI& other) const;
bool contains(const Point& pt) const;
bool contains(const Vec2& pt) const;
@ -51,14 +44,14 @@ namespace Blah
char get_sector(const Point& pt) const;
char get_sector(const Vec2& pt) const;
bool operator==(const RectI& rhs) const { return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; }
bool operator!=(const RectI& rhs) const { return !(*this == rhs); }
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);
RectI operator*(const int& rhs) const { return RectI(x * rhs, y * rhs, w * rhs, h * rhs); }
};
}

View File

@ -33,39 +33,108 @@ namespace Blah
bool operator ==(const Vec2& rhs) const;
bool operator !=(const Vec2& rhs) const;
// Returns the absolute value of the Vector
Vec2 abs() const;
// Returns the Normalized Vector
// If the length is 0, the resulting Vector is 0,0
Vec2 normal() const;
// Rotates the Vector 90 degrees right (y, -x)
Vec2 turn_right() const;
// Rotates the Vector 90 degrees left (-y, x)
Vec2 turn_left() const;
// Returns the length of the Vector
float length() const;
// Returns the squared length of the Vector
float length_squared() const;
// Gets the perpendicular Vector (-y, x)
Vec2 perpendicular() const;
// Gets the angle, in radians, of the Vector
float angle() const;
// Calculates the Dot Product between two vectors
static float dot(Vec2 a, Vec2 b);
// Calculates the Dot Product between two vectors
static float dot(float x, float y, Vec2 b);
// Calculates the Dot Product between two vectors
static float dot(float x1, float y1, float x2, float y2);
// Transforms a Vector by the given Matrix
static Vec2 transform(const Vec2& vec, const Mat3x2& matrix);
// Transforms a Vector by the given Matrix
static Vec2 transform(float x, float y, const Mat3x2& matrix);
static Vec2 from_angle(float radians, float length);
static Vec2 from_angle(float radians);
// Transforms a Vector Normal by the given Matrix
static Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix);
// Transforms a Vector Normal by the given Matrix
static Vec2 transform_normal(float x, float y, const Mat3x2& matrix);
// Calculates a Vector value from the given radians
static Vec2 from_angle(float radians, float length = 1.0f);
// Lerps between two Vectors
static Vec2 lerp(Vec2 start, Vec2 end, float t);
static Vec2 bezier_lerp(Vec2 start, Vec2 b, Vec2 end, float t);
static Vec2 bezier_lerp(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t);
// Lerps between two Vectors along a Bezier curve
static Vec2 lerp_bezier(Vec2 start, Vec2 b, Vec2 end, float t);
// Lerps between two Vectors along a Bezier curve
static Vec2 lerp_bezier(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t);
// Reflects a vector along the given Normal
static Vec2 reflect(const Vec2& vector, const Vec2& normal);
// Gets the minimum between two vectors
static Vec2 min(const Vec2& a, const Vec2& b);
// Gets the maximum between two vectors
static Vec2 max(const Vec2& a, const Vec2& b);
// (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;
};

56
include/blah/math/vec3.h Normal file
View File

@ -0,0 +1,56 @@
#pragma once
#include "calc.h"
namespace Blah
{
struct Vec3
{
float x;
float y;
float z;
Vec3()
: x(0)
, y(0)
, z(0)
{}
Vec3(float x, float y, float z)
: x(x)
, y(y)
, z(z)
{}
inline Vec3 operator +(const Vec3 rhs) const
{
return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
}
inline 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 inline float dot(Vec3 a, Vec3 b)
{
return a.x * b.x +
a.y * b.y +
a.z * b.z;
}
static inline 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

@ -27,9 +27,7 @@ Config::Config()
on_update = nullptr;
on_render = nullptr;
on_exit_request = App::exit;
on_info = nullptr;
on_warn = nullptr;
on_error = nullptr;
on_log = nullptr;
}
namespace
@ -302,9 +300,9 @@ namespace
return App::draw_height();
}
virtual void clear(Color color) override
virtual void clear(Color color, float depth, uint8_t stencil, ClearMask mask) override
{
GraphicsBackend::clear_backbuffer(color);
GraphicsBackend::clear_backbuffer(color, depth, stencil, mask);
}
};

View File

@ -13,9 +13,9 @@ void Log::print(const char* format, ...)
vsnprintf(msg, sizeof(char) * BLAH_MESSAGE, format, ap);
va_end(ap);
if (App::is_running() && App::config()->on_info != nullptr)
if (App::is_running() && App::config()->on_log)
{
App::config()->on_info(msg);
App::config()->on_log(msg, Category::Info);
}
else
{
@ -31,13 +31,13 @@ void Log::warn(const char* format, ...)
vsnprintf(msg, sizeof(char) * BLAH_MESSAGE, format, ap);
va_end(ap);
if (App::is_running() && App::config()->on_warn != nullptr)
if (App::is_running() && App::config()->on_log)
{
App::config()->on_warn(msg);
App::config()->on_log(msg, Category::Warning);
}
else
{
printf("\033[01;33mWARN:\033[0m\t%s\n", msg);
printf("WARN: %s\n", msg);
}
}
@ -49,12 +49,12 @@ void Log::error(const char* format, ...)
vsnprintf(msg, sizeof(char) * BLAH_MESSAGE, format, ap);
va_end(ap);
if (App::is_running() && App::config()->on_error != nullptr)
if (App::is_running() && App::config()->on_log)
{
App::config()->on_error(msg);
App::config()->on_log(msg, Category::Error);
}
else
{
printf("\033[1;31mERROR:\033[0m\t%s\n", msg);
printf("ERROR: %s\n", msg);
}
}

View File

@ -1,5 +1,4 @@
#include <blah/core/time.h>
#include <math.h>
using namespace Blah;
@ -26,7 +25,9 @@ void Time::pause_for(float duration)
bool Time::on_interval(double time, float delta, float interval, float offset)
{
return floor((time - offset - delta) / interval) < floor((time - offset) / interval);
auto last = static_cast<long>((time - offset - delta) / interval);
auto next = static_cast<long>((time - offset) / interval);
return last < next;
}
bool Time::on_interval(float delta, float interval, float offset)
@ -39,14 +40,15 @@ bool Time::on_interval(float interval, float offset)
return Time::on_interval(Time::seconds, Time::delta, interval, offset);
}
bool Time::on_time(double time, double timestamp)
bool Time::on_time(double time, double timestamp)
{
return time >= timestamp && time - Time::delta < timestamp;
float c = static_cast<float>(time) - Time::delta;
return time >= timestamp && c < timestamp;
}
bool Time::between_interval(double time, float interval, float offset)
{
return modf(time - offset, interval * 2) >= interval;
return modf(time - offset, ((double)interval) * 2) >= interval;
}
bool Time::between_interval(float interval, float offset)

View File

@ -507,7 +507,7 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int ste
for (int i = 1; i < steps; i++)
{
Vec2 at = Vec2::bezier_lerp(from, b, to, add * i);
Vec2 at = Vec2::lerp_bezier(from, b, to, add * i);
line(prev, at, t, color);
prev = at;
}
@ -522,7 +522,7 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Ve
for (int i = 1; i < steps; i++)
{
Vec2 at = Vec2::bezier_lerp(from, b, c, to, add * i);
Vec2 at = Vec2::lerp_bezier(from, b, c, to, add * i);
line(prev, at, t, color);
prev = at;
}
@ -668,8 +668,8 @@ void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr,
{
// get corners
Rect tl = Rect(rect.top_left(), Vec2(rtl, rtl));
Rect tr = Rect(rect.top_right() + Vec2(-rtr, 0), Vec2(rtr, rtr));
Rect bl = Rect(rect.bottom_left() + Vec2(0, -rbl), Vec2(rbl, rbl));
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));
// rounded corners

View File

@ -39,7 +39,7 @@ namespace Blah
void render(const RenderPass& pass);
// Clears the backbuffer
void clear_backbuffer(Color color);
void clear_backbuffer(Color color, float depth, uint8_t stencil, ClearMask mask);
// Creates a new Texture.
// if the Texture is invalid, this should return an empty reference.

View File

@ -25,7 +25,8 @@ namespace Blah
ID3D11Device* device = nullptr;
ID3D11DeviceContext* context = nullptr;
IDXGISwapChain* swap_chain = nullptr;
ID3D11RenderTargetView* backbuffer = nullptr;
ID3D11RenderTargetView* backbuffer_view = nullptr;
ID3D11DepthStencilView* backbuffer_depth_view = nullptr;
// supported renderer features
RendererFeatures features;
@ -120,12 +121,10 @@ namespace Blah
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
if (is_framebuffer)
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
bool is_depth_stencil = false;
switch (format)
{
@ -144,9 +143,18 @@ namespace Blah
case TextureFormat::DepthStencil:
desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
m_size = width * height * 4;
is_depth_stencil = true;
break;
}
if (!is_depth_stencil)
desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
else
desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
if (is_framebuffer && !is_depth_stencil)
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
m_dxgi_format = desc.Format;
auto hr = state.device->CreateTexture2D(&desc, NULL, &texture);
@ -158,11 +166,14 @@ namespace Blah
return;
}
hr = state.device->CreateShaderResourceView(texture, NULL, &view);
if (!SUCCEEDED(hr))
if (!is_depth_stencil)
{
texture->Release();
texture = nullptr;
hr = state.device->CreateShaderResourceView(texture, NULL, &view);
if (!SUCCEEDED(hr))
{
texture->Release();
texture = nullptr;
}
}
}
@ -219,15 +230,6 @@ namespace Blah
{
HRESULT hr;
// bounds
D3D11_BOX box;
box.left = 0;
box.right = m_width;
box.top = 0;
box.bottom = m_height;
box.front = 0;
box.back = 1;
// create staging texture
if (!staging)
{
@ -257,7 +259,7 @@ namespace Blah
staging, 0,
0, 0, 0,
texture, 0,
&box);
nullptr);
// get data
D3D11_MAPPED_SUBRESOURCE map;
@ -347,12 +349,27 @@ namespace Blah
return m_attachments[0]->height();
}
virtual void clear(Color color) override
virtual void clear(Color color, float depth, uint8_t stencil, ClearMask mask) override
{
float col[4] = { color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f };
for (int i = 0; i < m_attachments.size(); i++)
state.context->ClearRenderTargetView(color_views[i], col);
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
{
for (int i = 0; i < color_views.size(); i++)
state.context->ClearRenderTargetView(color_views[i], col);
}
if (depth_view)
{
UINT flags = 0;
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
flags |= D3D11_CLEAR_DEPTH;
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
flags |= D3D11_CLEAR_STENCIL;
if (flags != 0)
state.context->ClearDepthStencilView(depth_view, flags, depth, stencil);
}
}
};
@ -480,9 +497,9 @@ namespace Blah
hash = 5381;
for (auto& it : attributes)
{
for (int i = 0, n = strlen(it.semantic_name); i < n; i++)
for (size_t i = 0, n = strlen(it.semantic_name); i < n; i++)
hash = ((hash << 5) + hash) + it.semantic_name[i];
hash = it.semantic_index << 5 + hash;
hash = (it.semantic_index << 5) + hash;
}
// Shader is ready for use!
@ -575,7 +592,7 @@ namespace Blah
// buffer description
D3D11_BUFFER_DESC desc = { 0 };
desc.ByteWidth = index_stride * m_index_capacity;
desc.ByteWidth = (UINT)(index_stride * m_index_capacity);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@ -623,7 +640,7 @@ namespace Blah
{
// buffer description
D3D11_BUFFER_DESC desc = { 0 };
desc.ByteWidth = format.stride * m_vertex_capacity;
desc.ByteWidth = (UINT)(format.stride * m_vertex_capacity);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
@ -722,10 +739,13 @@ namespace Blah
state.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer);
if (frame_buffer)
{
state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer);
state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer_view);
frame_buffer->Release();
}
// TODO:
// create a depth backbuffer
// Store Features
state.features.instancing = true;
state.features.max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
@ -802,8 +822,8 @@ namespace Blah
if (state.last_size != next_size)
{
// release old buffer
if (state.backbuffer)
state.backbuffer->Release();
if (state.backbuffer_view)
state.backbuffer_view->Release();
// perform resize
hr = state.swap_chain->ResizeBuffers(0, next_size.x, next_size.y, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
@ -815,7 +835,7 @@ namespace Blah
hr = state.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer);
if (SUCCEEDED(hr) && frame_buffer)
{
hr = state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer);
hr = state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer_view);
BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize");
frame_buffer->Release();
}
@ -870,7 +890,7 @@ namespace Blah
// Set the Target
if (pass.target == App::backbuffer || !pass.target)
{
ctx->OMSetRenderTargets(1, &state.backbuffer, nullptr);
ctx->OMSetRenderTargets(1, &state.backbuffer_view, state.backbuffer_depth_view);
}
else
{
@ -1015,7 +1035,9 @@ namespace Blah
{
if (mesh->instance_count() <= 0)
{
ctx->DrawIndexed(pass.index_count, pass.index_start, 0);
ctx->DrawIndexed(
static_cast<UINT>(pass.index_count),
static_cast<UINT>(pass.index_start), 0);
}
else
{
@ -1034,10 +1056,25 @@ namespace Blah
}
}
void GraphicsBackend::clear_backbuffer(Color color)
void GraphicsBackend::clear_backbuffer(Color color, float depth, uint8_t stencil, ClearMask mask)
{
float clear[4] = { color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f };
state.context->ClearRenderTargetView(state.backbuffer, clear);
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
{
float clear[4] = { color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f };
state.context->ClearRenderTargetView(state.backbuffer_view, clear);
}
if (state.backbuffer_depth_view)
{
UINT flags = 0;
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
flags |= D3D11_CLEAR_DEPTH;
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
flags |= D3D11_CLEAR_STENCIL;
if (flags != 0)
state.context->ClearDepthStencilView(state.backbuffer_depth_view, flags, depth, stencil);
}
}
// Utility Methods
@ -1092,7 +1129,7 @@ namespace Blah
D3D11_SHADER_DESC shader_desc;
reflector->GetDesc(&shader_desc);
for (int i = 0; i < shader_desc.BoundResources; i++)
for (UINT i = 0; i < shader_desc.BoundResources; i++)
{
D3D11_SHADER_INPUT_BIND_DESC desc;
reflector->GetResourceBindingDesc(i, &desc);
@ -1117,7 +1154,7 @@ namespace Blah
}
}
for (int i = 0; i < shader_desc.ConstantBuffers; i++)
for (UINT i = 0; i < shader_desc.ConstantBuffers; i++)
{
D3D11_SHADER_BUFFER_DESC desc;
@ -1138,7 +1175,7 @@ namespace Blah
}
// get the uniforms
for (int j = 0; j < desc.Variables; j++)
for (UINT j = 0; j < desc.Variables; j++)
{
D3D11_SHADER_VARIABLE_DESC var_desc;
D3D11_SHADER_TYPE_DESC type_desc;

View File

@ -749,13 +749,24 @@ namespace Blah
return m_height;
}
virtual void clear(Color color) override
virtual void clear(Color color, float depth, uint8_t stencil, ClearMask mask) override
{
int clear = 0;
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
clear |= GL_COLOR_BUFFER_BIT;
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
clear |= GL_DEPTH_BUFFER_BIT;
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
clear |= GL_STENCIL_BUFFER_BIT;
gl.BindFramebuffer(GL_FRAMEBUFFER, m_id);
gl.Disable(GL_SCISSOR_TEST);
gl.ColorMask(true, true, true, true);
gl.ClearColor(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
gl.Clear(GL_COLOR_BUFFER_BIT);
gl.ClearDepth(depth);
gl.ClearStencil(stencil);
gl.Clear(clear);
}
};
@ -1485,13 +1496,24 @@ namespace Blah
}
}
void GraphicsBackend::clear_backbuffer(Color color)
void GraphicsBackend::clear_backbuffer(Color color, float depth, uint8_t stencil, ClearMask mask)
{
int clear = 0;
if (((int)mask & (int)ClearMask::Color) == (int)ClearMask::Color)
clear |= GL_COLOR_BUFFER_BIT;
if (((int)mask & (int)ClearMask::Depth) == (int)ClearMask::Depth)
clear |= GL_DEPTH_BUFFER_BIT;
if (((int)mask & (int)ClearMask::Stencil) == (int)ClearMask::Stencil)
clear |= GL_STENCIL_BUFFER_BIT;
gl.BindFramebuffer(GL_FRAMEBUFFER, 0);
gl.Disable(GL_SCISSOR_TEST);
gl.ColorMask(true, true, true, true);
gl.ClearColor(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f);
gl.Clear(GL_COLOR_BUFFER_BIT);
gl.ClearDepth(depth);
gl.ClearStencil(stencil);
gl.Clear(clear);
}
}

View File

@ -10,7 +10,6 @@
#include <blah/core/time.h>
#include <SDL.h>
#include <SDL_vulkan.h>
#include <SDL_syswm.h>
#if _WIN32

View File

@ -113,6 +113,11 @@ float Calc::cos(float x)
return cosf(x);
}
float Calc::tan(float x)
{
return tanf(x);
}
float Calc::atan2(float y, float x)
{
return atan2f(y, x);

View File

@ -1,4 +1,5 @@
#include <blah/math/mat4x4.h>
#include <blah/core/log.h>
using namespace Blah;
@ -59,6 +60,29 @@ Mat4x4 Mat4x4::create_ortho_offcenter(float left, float right, float bottom, flo
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;
@ -81,6 +105,34 @@ Mat4x4 Mat4x4::create_scale(float x, float y, float 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;

View File

@ -26,11 +26,68 @@ RectI::RectI(Point pos, Point size)
h = size.y;
}
Point RectI::center() const { return Point(centerX(), centerY()); }
Point RectI::top_left() const { return Point(left(), top()); }
Point RectI::top_right() const { return Point(right(), top()); }
Point RectI::bottom_left() const { return Point(left(), bottom()); }
Point RectI::bottom_right() const { return Point(right(), bottom()); }
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;
}
bool RectI::contains(const Point& point) const
{
@ -84,7 +141,42 @@ char RectI::get_sector(const Vec2& pt) const
return h | v;
}
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 Point& rhs) { x += rhs.x; y += rhs.y; return *this; }
RectI& RectI::operator-=(const Point& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
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

@ -5,28 +5,100 @@
using namespace Blah;
Vec2::Vec2() { x = y = 0; }
Vec2::Vec2(float vx, float vy) { x = vx; y = vy; }
Vec2::Vec2(int vx, float vy) { x = (float)vx; y = vy; }
Vec2::Vec2(float vx, int vy) { x = vx; y = (float)vy; }
Vec2::Vec2(int vx, int vy) { x = (float)vx; y = (float)vy; }
Vec2::Vec2(Point p) { x = (float)p.x; y = (float)p.y; }
Vec2::Vec2()
: x(0)
, y(0)
{}
Vec2 Vec2::operator +(const Vec2 rhs) const { return Vec2(x + rhs.x, y + rhs.y); }
Vec2 Vec2::operator -(const Vec2 rhs) const { return Vec2(x - rhs.x, y - rhs.y); }
Vec2 Vec2::operator /(const float rhs) const { return Vec2(x / rhs, y / rhs); }
Vec2 Vec2::operator *(const float rhs) const { return Vec2(x * rhs, y * rhs); }
Vec2 Vec2::operator-() const { return Vec2(-x, -y); }
Vec2::Vec2(float vx, float vy)
: x(vx)
, y(vy)
{}
Vec2& Vec2::operator +=(const Vec2& rhs) { x += rhs.x; y += rhs.y; return *this; }
Vec2& Vec2::operator -=(const Vec2& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
Vec2& Vec2::operator /=(const Vec2& rhs) { x /= rhs.x; y /= rhs.y; return *this; }
Vec2& Vec2::operator *=(const Vec2& rhs) { x *= rhs.x; y *= rhs.y; return *this; }
Vec2& Vec2::operator/=(float rhs) { x /= rhs; y /= rhs; return *this; }
Vec2& Vec2::operator*=(float rhs) { x *= rhs; y *= rhs; return *this; }
Vec2::Vec2(int vx, float vy)
: x(static_cast<float>(vx))
, y(vy)
{}
bool Vec2::operator ==(const Vec2& rhs) const { return x == rhs.x && y == rhs.y; }
bool Vec2::operator !=(const Vec2& rhs) const { return x != rhs.x || y != rhs.y; }
Vec2::Vec2(float vx, int vy)
: x(vx)
, y(static_cast<float>(vy))
{}
Vec2::Vec2(int vx, int vy)
: x(static_cast<float>(vx))
, y(static_cast<float>(vy))
{}
Vec2::Vec2(Point p)
: x(static_cast<float>(p.x))
, y(static_cast<float>(p.y))
{}
Vec2 Vec2::operator +(const Vec2 rhs) const
{
return Vec2(x + rhs.x, y + rhs.y);
}
Vec2 Vec2::operator -(const Vec2 rhs) const
{
return Vec2(x - rhs.x, y - rhs.y);
}
Vec2 Vec2::operator /(const float rhs) const
{
return Vec2(x / rhs, y / rhs);
}
Vec2 Vec2::operator *(const float rhs) const
{
return Vec2(x * rhs, y * rhs);
}
Vec2 Vec2::operator-() const
{
return Vec2(-x, -y);
}
Vec2& Vec2::operator +=(const Vec2& rhs)
{
x += rhs.x; y += rhs.y; return *this;
}
Vec2& Vec2::operator -=(const Vec2& rhs)
{
x -= rhs.x; y -= rhs.y; return *this;
}
Vec2& Vec2::operator /=(const Vec2& rhs)
{
x /= rhs.x; y /= rhs.y; return *this;
}
Vec2& Vec2::operator *=(const Vec2& rhs)
{
x *= rhs.x; y *= rhs.y; return *this;
}
Vec2& Vec2::operator/=(float rhs)
{
x /= rhs; y /= rhs; return *this;
}
Vec2& Vec2::operator*=(float rhs)
{
x *= rhs; y *= rhs; return *this;
}
bool Vec2::operator ==(const Vec2& rhs) const
{
return x == rhs.x && y == rhs.y;
}
bool Vec2::operator !=(const Vec2& rhs) const
{
return x != rhs.x || y != rhs.y;
}
Vec2 Vec2::normal() const
{
@ -46,8 +118,15 @@ Vec2 Vec2::turn_left() const
return Vec2(-y, x);
}
float Vec2::length() const { return sqrtf(x * x + y * y); }
float Vec2::length_squared() const { return x * x + y * y; }
float Vec2::length() const
{
return sqrtf(x * x + y * y);
}
float Vec2::length_squared() const
{
return x * x + y * y;
}
Vec2 Vec2::perpendicular() const
{
@ -59,9 +138,20 @@ float Vec2::angle() const
return Calc::atan2(y, x);
}
float Vec2::dot(Vec2 a, Vec2 b) { return (a.x * b.x + a.y * b.y); }
float Vec2::dot(float x, float y, Vec2 b) { return (x * b.x + y * b.y); }
float Vec2::dot(float x1, float y1, float x2, float y2) { return (x1 * x2 + y1 * y2); }
float Vec2::dot(Vec2 a, Vec2 b)
{
return (a.x * b.x + a.y * b.y);
}
float Vec2::dot(float x, float y, Vec2 b)
{
return (x * b.x + y * b.y);
}
float Vec2::dot(float x1, float y1, float x2, float y2)
{
return (x1 * x2 + y1 * y2);
}
Vec2 Vec2::transform(const Vec2& vec, const Mat3x2& matrix)
{
@ -77,16 +167,25 @@ Vec2 Vec2::transform(float x, float y, const Mat3x2& matrix)
(x * matrix.m12) + (y * matrix.m22) + matrix.m32);
}
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);
}
Vec2 transform_normal(float x, float y, const Mat3x2& matrix)
{
return Vec2(
x * matrix.m11 + y * matrix.m21,
x * matrix.m12 + y * matrix.m22);
}
Vec2 Vec2::from_angle(float radians, float length)
{
return Vec2((float)cos(radians) * length, (float)sin(radians) * length);
}
Vec2 Vec2::from_angle(float radians)
{
return from_angle(radians, 1);
}
Vec2 Vec2::lerp(Vec2 a, Vec2 b, float t)
{
if (t == 0)
@ -97,14 +196,14 @@ Vec2 Vec2::lerp(Vec2 a, Vec2 b, float t)
return a + (b - a) * t;
}
Vec2 Vec2::bezier_lerp(Vec2 start, Vec2 b, Vec2 end, float t)
Vec2 Vec2::lerp_bezier(Vec2 start, Vec2 b, Vec2 end, float t)
{
return lerp(lerp(start, b, t), lerp(b, end, t), t);
}
Vec2 Vec2::bezier_lerp(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t)
Vec2 Vec2::lerp_bezier(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t)
{
return bezier_lerp(lerp(start, b, t), lerp(b, c, t), lerp(c, end, t), t);
return lerp_bezier(lerp(start, b, t), lerp(b, c, t), lerp(c, end, t), t);
}
Vec2 Vec2::reflect(const Vec2& vector, const Vec2& normal)
@ -116,6 +215,20 @@ Vec2 Vec2::reflect(const Vec2& vector, const Vec2& normal)
vector.y - 2.0f * dot * normal.y);
}
Vec2 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);
}
Vec2 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);
}
const Vec2 Vec2::unit_x = Vec2(1, 0);
const Vec2 Vec2::unit_y = Vec2(0, 1);
const Vec2 Vec2::right = Vec2(1, 0);