diff --git a/includes/mlx_extended.h b/includes/mlx_extended.h index 48cae93..3cfe0ae 100644 --- a/includes/mlx_extended.h +++ b/includes/mlx_extended.h @@ -75,7 +75,6 @@ MLX_API void mlx_restore_window(mlx_context mlx, mlx_window win); /* Pixels drawing related functions */ - /** * @brief Put an array of pixels in the window * @@ -115,6 +114,18 @@ MLX_API void mlx_pixel_put_region(mlx_context mlx, mlx_window win, int x, int y, /* Images related functions */ +/** +* @brief Set image rectangle +* +* @param mlx Internal MLX application +* @param img Internal image +* @param x X coordinate in the image +* @param y Y coordinate in the image +* @param w Width of the rectangle +* @param y Height of the rectangle +* @param color Color of the rectangle +*/ +MLX_API void mlx_set_image_rectangle(mlx_context mlx, mlx_image image, int x, int y, int w, int h, mlx_color color); /** * @brief Get image region diff --git a/runtime/Includes/Renderer/Image.h b/runtime/Includes/Renderer/Image.h index 36a41bd..46e0123 100644 --- a/runtime/Includes/Renderer/Image.h +++ b/runtime/Includes/Renderer/Image.h @@ -86,6 +86,7 @@ namespace mlx void SetPixel(int x, int y, mlx_color color) noexcept; void SetRegion(int x, int y, int w, int h, mlx_color* color) noexcept; void SetLinearRegion(int x, int y, std::size_t len, mlx_color* color) noexcept; + void SetRectangle(int x, int y, int w, int h, mlx_color color) noexcept; mlx_color GetPixel(int x, int y) noexcept; void GetRegion(int x, int y, int w, int h, mlx_color* dst) noexcept; void Clear(VkCommandBuffer cmd, Vec4f color) override; diff --git a/runtime/Sources/Core/Bridge.cpp b/runtime/Sources/Core/Bridge.cpp index fd61393..bcbea3e 100644 --- a/runtime/Sources/Core/Bridge.cpp +++ b/runtime/Sources/Core/Bridge.cpp @@ -457,6 +457,15 @@ extern "C" gs->PixelPutRegion(x, y, w, h, pixels); } + void mlx_set_image_rectangle(mlx_context mlx, mlx_image image, int x, int y, int w, int h, mlx_color color) + { + MLX_CHECK_APPLICATION_POINTER(mlx); + mlx::NonOwningPtr texture = mlx->app->GetTexture(image); + if(!texture) + return; + texture->SetRectangle(x, y, w, h, color); + } + void mlx_get_image_region(mlx_context mlx, mlx_image image, int x, int y, int w, int h, mlx_color* dst) { MLX_CHECK_APPLICATION_POINTER(mlx); diff --git a/runtime/Sources/Renderer/Image.cpp b/runtime/Sources/Renderer/Image.cpp index 4d77ae5..6366a39 100644 --- a/runtime/Sources/Renderer/Image.cpp +++ b/runtime/Sources/Renderer/Image.cpp @@ -286,6 +286,36 @@ namespace mlx m_has_been_modified = true; } + void Texture::SetRectangle(int x, int y, int w, int h, mlx_color color) noexcept + { + MLX_PROFILE_FUNCTION(); + if(w < 0 || h < 0 || x < -w || y < -h + || x >= static_cast(m_width) || y >= static_cast(m_height)) + return; + if(!m_staging_buffer.has_value()) + OpenCPUBuffer(); + const int + start_x = std::max(x, 0), + start_row = std::max(y, 0) * m_width, + end_x = std::min(x + w, m_width), + end_row = std::min(y + h, m_height) * m_width; + for(int dx = start_x, row = start_row;; dx++) + { + if(dx >= end_x) + { + dx = start_x; + row += m_width; + if(row >= end_row) + break; + } + if constexpr(std::endian::native == std::endian::little) + m_staging_buffer->GetMap()[row + dx] = ReverseColor(color); + else + m_staging_buffer->GetMap()[row + dx] = color; + } + m_has_been_modified = true; + } + mlx_color Texture::GetPixel(int x, int y) noexcept { MLX_PROFILE_FUNCTION();