mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-09-03 01:10:00 +02:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42f0d52bfa | ||
|
|
63fe3088bf | ||
|
|
c9df651a14 | ||
|
|
2d0c02ae7e | ||
|
|
ddfbe32cea |
@@ -153,7 +153,7 @@ MLX_API void mlx_set_image_region(mlx_context mlx, mlx_image image, int x, int y
|
||||
* @param scale_y Scale y of the image
|
||||
* @param angle Rotation angle of the image (clockwise)
|
||||
*/
|
||||
MLX_API void mlx_put_transformed_image_to_window(mlx_context mlx, mlx_window win, mlx_image image, int x, int y, float scale_x, float scale_y, float angle);
|
||||
MLX_API void mlx_put_transformed_image_to_window(mlx_context mlx, mlx_window win, mlx_image image, float x, float y, float scale_x, float scale_y, float angle);
|
||||
|
||||
/**
|
||||
* @brief Get direct pointers to hidden functions
|
||||
|
||||
@@ -19,9 +19,10 @@ namespace mlx
|
||||
|
||||
enum class Event
|
||||
{
|
||||
ResizeEventCode = 56,
|
||||
FrameBeginEventCode = 57,
|
||||
FatalErrorEventCode = 168,
|
||||
ResizeEventCode = 1,
|
||||
SwapchainResizeEventCode,
|
||||
FrameBeginEventCode,
|
||||
FatalErrorEventCode,
|
||||
|
||||
EndEnum
|
||||
};
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
#ifndef __MLX_FPS__
|
||||
#define __MLX_FPS__
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
typedef std::chrono::steady_clock fps_clock;
|
||||
|
||||
class FpsManager
|
||||
{
|
||||
public:
|
||||
FpsManager() = default;
|
||||
|
||||
void Init();
|
||||
bool Update();
|
||||
inline void SetMaxFPS(std::uint32_t fps) noexcept { m_max_fps = fps; m_ns = 1000000000.0 / fps; }
|
||||
void WaitUntilNextFrame();
|
||||
inline void SetMaxFPS(std::uint32_t fps) noexcept { m_target_delta = fps_clock::duration(std::chrono::seconds(1)) / fps;}
|
||||
|
||||
~FpsManager() = default;
|
||||
|
||||
private:
|
||||
double m_ns = 1000000000.0 / 1'337'000.0;
|
||||
std::int64_t m_fps_before = 0;
|
||||
std::int64_t m_fps_now = 0;
|
||||
std::int64_t m_timer = 0;
|
||||
std::uint32_t m_max_fps = 1'337'000;
|
||||
std::uint32_t m_fps_elapsed_time = 0;
|
||||
fps_clock::time_point m_current_time;
|
||||
fps_clock::time_point m_target_time;
|
||||
fps_clock::time_point m_last_time_record;
|
||||
fps_clock::duration m_delta_time = fps_clock::duration().zero();
|
||||
fps_clock::duration m_target_delta = fps_clock::duration().zero();
|
||||
fps_clock::duration m_sleep_margin = std::chrono::microseconds(200);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace mlx
|
||||
void PixelPutArray(int x, int y, mlx_color* color, std::size_t pixels_size) noexcept;
|
||||
void PixelPutRegion(int x, int y, int w, int h, mlx_color* color) noexcept;
|
||||
void StringPut(int x, int y, mlx_color color, std::string str);
|
||||
void TexturePut(NonOwningPtr<class Texture> texture, int x, int y, float scale_x, float scale_y, float angle);
|
||||
void TexturePut(NonOwningPtr<class Texture> texture, float x, float y, float scale_x, float scale_y, float angle);
|
||||
|
||||
inline void TryEraseSpritesInScene(NonOwningPtr<Texture> texture) noexcept;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
Application::Application() : p_mem_manager(std::make_unique<MemManager>()), p_sdl_manager(std::make_unique<SDLManager>()), m_fps(), m_in()
|
||||
Application::Application() : p_mem_manager(std::make_unique<MemManager>()), p_sdl_manager(std::make_unique<SDLManager>()), m_fps(), m_in()
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
std::srand(std::time(nullptr));
|
||||
@@ -33,8 +33,7 @@ namespace mlx
|
||||
|
||||
while(m_in.IsRunning())
|
||||
{
|
||||
if(!m_fps.Update())
|
||||
continue;
|
||||
m_fps.WaitUntilNextFrame();
|
||||
|
||||
m_in.FetchInputs();
|
||||
|
||||
|
||||
@@ -45,10 +45,9 @@ extern "C"
|
||||
void mlx_set_fps_goal(mlx_context mlx, int fps)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
if(fps < 0)
|
||||
mlx::Error("You cannot set a negative FPS cap (nice try)");
|
||||
else
|
||||
mlx->app->SetFPSCap(static_cast<std::uint32_t>(fps));
|
||||
if(fps <= 0)
|
||||
fps = -1;
|
||||
mlx->app->SetFPSCap(static_cast<std::uint32_t>(fps));
|
||||
}
|
||||
|
||||
void mlx_destroy_context(mlx_context mlx)
|
||||
@@ -313,14 +312,14 @@ extern "C"
|
||||
mlx::Error("Font loader: filepath is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::filesystem::path file(filepath);
|
||||
if (std::strcmp(filepath, "default") != 0 && !std::filesystem::exists(file))
|
||||
{
|
||||
mlx::Error("TTF loader: unable to find file '%'", filepath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(std::strcmp(filepath, "default") != 0)
|
||||
{
|
||||
if(file.extension() != ".ttf" && file.extension() != ".tte")
|
||||
@@ -350,7 +349,7 @@ extern "C"
|
||||
mlx::Error("Font loader: filepath is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::filesystem::path file(filepath);
|
||||
if (std::strcmp(filepath, "default") != 0 && !std::filesystem::exists(file))
|
||||
{
|
||||
@@ -459,7 +458,7 @@ extern "C"
|
||||
texture->SetRegion(x, y, w, h, pixels);
|
||||
}
|
||||
|
||||
void mlx_put_transformed_image_to_window(mlx_context mlx, mlx_window win, mlx_image image, int x, int y, float scale_x, float scale_y, float angle)
|
||||
void mlx_put_transformed_image_to_window(mlx_context mlx, mlx_window win, mlx_image image, float x, float y, float scale_x, float scale_y, float angle)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
mlx::NonOwningPtr<mlx::GraphicsSupport> gs = mlx->app->GetGraphicsSupport(win);
|
||||
|
||||
@@ -1,30 +1,37 @@
|
||||
#include <PreCompiled.h>
|
||||
#include <Core/Fps.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void FpsManager::Init()
|
||||
{
|
||||
m_timer = static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
|
||||
m_fps_before = m_timer;
|
||||
m_fps_now = m_timer;
|
||||
m_current_time = fps_clock::now();
|
||||
m_target_time = m_current_time + m_target_delta;
|
||||
}
|
||||
|
||||
bool FpsManager::Update()
|
||||
void FpsManager::WaitUntilNextFrame()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
m_fps_now = static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
|
||||
|
||||
if(std::chrono::duration<std::uint64_t>{m_fps_now - m_timer} >= 1s)
|
||||
m_timer += m_fps_now;
|
||||
|
||||
m_fps_elapsed_time = m_fps_now - m_fps_before;
|
||||
if(m_fps_elapsed_time >= m_ns)
|
||||
m_current_time = fps_clock::now();
|
||||
if(m_current_time < m_target_time)
|
||||
{
|
||||
m_fps_before += m_ns;
|
||||
return true;
|
||||
std::this_thread::sleep_until(m_target_time - m_sleep_margin);
|
||||
m_current_time = fps_clock::now();
|
||||
while (m_current_time < m_target_time)
|
||||
{
|
||||
#ifndef __APPLE__
|
||||
_mm_pause(); // reduces CPU usage on x86 without yielding
|
||||
#endif
|
||||
m_current_time = fps_clock::now();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::duration<double, std::nano>(m_ns - 1));
|
||||
return false;
|
||||
else if (m_target_time < m_current_time - m_target_delta * 4)
|
||||
m_target_time = m_current_time;
|
||||
m_target_time += m_target_delta;
|
||||
m_delta_time = m_current_time - m_last_time_record;
|
||||
m_last_time_record = m_current_time;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace mlx
|
||||
p_scene->BringToDrawLayer(text.Get(), m_draw_layer);
|
||||
}
|
||||
|
||||
void GraphicsSupport::TexturePut(NonOwningPtr<Texture> texture, int x, int y, float scale_x, float scale_y, float angle)
|
||||
void GraphicsSupport::TexturePut(NonOwningPtr<Texture> texture, float x, float y, float scale_x, float scale_y, float angle)
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
NonOwningPtr<Sprite> sprite = p_scene->GetSpriteFromTexturePositionScaleRotation(texture, Vec2f{ static_cast<float>(x), static_cast<float>(y) }, scale_x, scale_y, angle);
|
||||
@@ -146,14 +146,14 @@ namespace mlx
|
||||
{
|
||||
m_draw_layer++;
|
||||
m_pixelput_called = false;
|
||||
}
|
||||
}
|
||||
Sprite& new_sprite = p_scene->CreateSprite(texture);
|
||||
new_sprite.SetCenter(Vec2f{ texture->GetWidth() * 0.5f, texture->GetHeight() * 0.5f });
|
||||
new_sprite.SetPosition(Vec2f{ static_cast<float>(x), static_cast<float>(y) });
|
||||
new_sprite.SetScale(Vec2f{ scale_x, scale_y });
|
||||
new_sprite.SetRotation(angle);
|
||||
}
|
||||
else if(!p_scene->IsTextureAtGivenDrawLayer(texture, m_draw_layer))
|
||||
else if(!p_scene->IsTextureAtGivenDrawLayer(texture, m_draw_layer))
|
||||
p_scene->BringToDrawLayer(sprite.Get(), m_draw_layer);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ namespace mlx
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
struct ResizeEventBroadcast : public EventBase
|
||||
struct SwapchainResizeEventBroadcast : public EventBase
|
||||
{
|
||||
Event What() const override { return Event::ResizeEventCode; }
|
||||
Event What() const override { return Event::SwapchainResizeEventCode; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace mlx
|
||||
if(!m_events_hooks.contains(window_id) || m_events_hooks[window_id][event].empty())
|
||||
return;
|
||||
if(event == MLX_WINDOW_EVENT && code == 8)
|
||||
EventBus::SendBroadcast(Internal::ResizeEventBroadcast{});
|
||||
EventBus::SendBroadcast(Internal::SwapchainResizeEventBroadcast{});
|
||||
for(const auto& hook : m_events_hooks[window_id][event])
|
||||
{
|
||||
if(hook.fn)
|
||||
|
||||
@@ -226,25 +226,34 @@ namespace mlx
|
||||
void Texture::SetRegion(int x, int y, int w, int h, mlx_color* pixels) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) >= m_width || static_cast<std::uint32_t>(y) >= m_height)
|
||||
return;
|
||||
if(w < 0 || h < 0)
|
||||
if(w < 0 || h < 0 || x < -w || y < -h
|
||||
|| x >= static_cast<int>(m_width) || y >= static_cast<int>(m_height))
|
||||
return;
|
||||
if(!m_staging_buffer.has_value())
|
||||
OpenCPUBuffer();
|
||||
for(std::uint32_t i = 0, moving_x = x, moving_y = y;; i++, moving_x++)
|
||||
const int
|
||||
start_x = std::max<int>(x, 0),
|
||||
start_y = std::max<int>(y, 0),
|
||||
start_row = start_y * m_width,
|
||||
start_i = (start_y - y) * w + (start_x - x),
|
||||
end_x = std::min<int>(x + w, m_width),
|
||||
end_y = std::min<int>(y + h, m_height),
|
||||
end_row = end_y * m_width,
|
||||
incr = (x + w) - end_x + (start_x - x);
|
||||
for(int i = start_i, dx = start_x, row = start_row;; i++, dx++)
|
||||
{
|
||||
if(moving_x >= static_cast<std::uint32_t>(x + w) || moving_x >= m_width)
|
||||
if(dx >= end_x)
|
||||
{
|
||||
moving_x = x;
|
||||
moving_y++;
|
||||
if(moving_y >= static_cast<std::uint32_t>(y + h) || moving_y >= m_height)
|
||||
i += incr;
|
||||
dx = start_x;
|
||||
row += m_width;
|
||||
if(row >= end_row)
|
||||
break;
|
||||
}
|
||||
if constexpr(std::endian::native == std::endian::little)
|
||||
m_staging_buffer->GetMap<mlx_color*>()[(moving_y * m_width) + moving_x] = ReverseColor(pixels[i]);
|
||||
m_staging_buffer->GetMap<mlx_color*>()[row + dx] = ReverseColor(pixels[i]);
|
||||
else
|
||||
m_staging_buffer->GetMap<mlx_color*>()[(moving_y * m_width) + moving_x] = pixels[i];
|
||||
m_staging_buffer->GetMap<mlx_color*>()[row + dx] = pixels[i];
|
||||
}
|
||||
m_has_been_modified = true;
|
||||
}
|
||||
@@ -252,23 +261,25 @@ namespace mlx
|
||||
void Texture::SetLinearRegion(int x, int y, std::size_t len, mlx_color* pixels) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) >= m_width || static_cast<std::uint32_t>(y) >= m_height)
|
||||
if(x >= static_cast<int>(m_width) || y >= static_cast<int>(m_height))
|
||||
return;
|
||||
if(!m_staging_buffer.has_value())
|
||||
OpenCPUBuffer();
|
||||
int
|
||||
start = y * m_width + x,
|
||||
dest_start = std::max<int>(start, 0),
|
||||
src_start = dest_start - start,
|
||||
dest_end = std::min<int>(start + len, m_width * m_height);
|
||||
if constexpr(std::endian::native == std::endian::little)
|
||||
{
|
||||
for(std::size_t i = 0; i < len && (y * m_width) + x + i < m_width * m_height; i++)
|
||||
m_staging_buffer->GetMap<mlx_color*>()[(y * m_width) + x + i] = ReverseColor(pixels[i]);
|
||||
for(int i = dest_start, j = src_start; i < dest_end; i++, j++)
|
||||
m_staging_buffer->GetMap<mlx_color*>()[i] = ReverseColor(pixels[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::size_t len_guard;
|
||||
if((y * m_width + x + len) < m_width * m_height)
|
||||
len_guard = len;
|
||||
else
|
||||
len_guard = len - (m_width * m_height - (y * m_width + x + len));
|
||||
std::memcpy(&m_staging_buffer->GetMap<mlx_color*>()[(y * m_width) + x], pixels, len_guard);
|
||||
std::memcpy(
|
||||
&m_staging_buffer->GetMap<mlx_color*>()[dest_start],
|
||||
&pixels[src_start], dest_end - dest_start);
|
||||
}
|
||||
m_has_been_modified = true;
|
||||
}
|
||||
@@ -289,23 +300,23 @@ namespace mlx
|
||||
void Texture::GetRegion(int x, int y, int w, int h, mlx_color* dst) noexcept
|
||||
{
|
||||
MLX_PROFILE_FUNCTION();
|
||||
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) >= m_width || static_cast<std::uint32_t>(y) >= m_height)
|
||||
if(w < 0 || h < 0 || x < 0 || y < 0 || static_cast<std::uint32_t>(x + w) >= m_width || static_cast<std::uint32_t>(y + h) >= m_height)
|
||||
return;
|
||||
if(!m_staging_buffer.has_value())
|
||||
OpenCPUBuffer();
|
||||
for(std::uint32_t i = 0, moving_x = x, moving_y = y;; i++, moving_x++)
|
||||
for(std::uint32_t i = 0, dx = x, row = y * m_width;; i++, dx++)
|
||||
{
|
||||
if(moving_x >= static_cast<std::uint32_t>(x + w) || moving_x >= m_width)
|
||||
if(dx >= m_width)
|
||||
{
|
||||
moving_x = x;
|
||||
moving_y++;
|
||||
if(moving_y >= static_cast<std::uint32_t>(y + h) || moving_y >= m_height)
|
||||
dx = x;
|
||||
row += m_width;
|
||||
if(row >= m_height * m_width)
|
||||
break;
|
||||
}
|
||||
if constexpr(std::endian::native == std::endian::little)
|
||||
dst[i] = ReverseColor(m_staging_buffer->GetMap<mlx_color*>()[(moving_y * m_width) + moving_x]);
|
||||
dst[i] = ReverseColor(m_staging_buffer->GetMap<mlx_color*>()[row + dx]);
|
||||
else
|
||||
dst[i] = m_staging_buffer->GetMap<mlx_color*>()[(moving_y * m_width) + moving_x];
|
||||
dst[i] = m_staging_buffer->GetMap<mlx_color*>()[row + dx];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,16 +331,8 @@ namespace mlx
|
||||
processed_color.g = static_cast<std::uint8_t>(color.g * 255.f);
|
||||
processed_color.b = static_cast<std::uint8_t>(color.b * 255.f);
|
||||
processed_color.a = static_cast<std::uint8_t>(color.a * 255.f);
|
||||
if(processed_color.r == 0 && processed_color.g == 0 && processed_color.b == 0)
|
||||
std::memset(m_staging_buffer->GetMap(), processed_color.a, m_staging_buffer->GetSize());
|
||||
else
|
||||
{
|
||||
for(std::size_t y = 0; y < m_height; y++)
|
||||
{
|
||||
for(std::size_t x = 0; x < m_width; x++)
|
||||
m_staging_buffer->GetMap<mlx_color*>()[y * m_width + x] = processed_color;
|
||||
}
|
||||
}
|
||||
for(std::size_t i = 0; i < m_width * m_height; i++)
|
||||
m_staging_buffer->GetMap<mlx_color*>()[i] = processed_color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace mlx
|
||||
Event What() const override { return Event::ResizeEventCode; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
std::string VulkanFormatName(VkFormat format)
|
||||
{
|
||||
#define STRINGIFY(x) case x: return #x
|
||||
@@ -161,7 +161,7 @@ namespace mlx
|
||||
|
||||
std::function<void(const EventBase&)> functor = [this](const EventBase& event)
|
||||
{
|
||||
if(event.What() == Event::ResizeEventCode && !m_resize)
|
||||
if(event.What() == Event::SwapchainResizeEventCode && !m_resize)
|
||||
m_resize = true;
|
||||
};
|
||||
EventBus::RegisterListener({ functor, "mlx_swapchain_" + std::to_string(reinterpret_cast<std::uintptr_t>(this)) });
|
||||
|
||||
Vendored
+2
-2
@@ -3176,7 +3176,7 @@ void kvfGPipelineBuilderEnableAdditiveBlending(KvfGraphicsPipelineBuilder* build
|
||||
builder->color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
builder->color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
builder->color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
builder->color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
builder->color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
builder->color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
}
|
||||
|
||||
@@ -3189,7 +3189,7 @@ void kvfGPipelineBuilderEnableAlphaBlending(KvfGraphicsPipelineBuilder* builder)
|
||||
builder->color_blend_attachment_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
builder->color_blend_attachment_state.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
builder->color_blend_attachment_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
builder->color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
builder->color_blend_attachment_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
builder->color_blend_attachment_state.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user