diff --git a/CMakeLists.txt b/CMakeLists.txt index 73ac60f..187cf6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(image-gp-2 VERSION 0.0.11) +project(image-gp-2 VERSION 0.0.12) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) @@ -14,6 +14,13 @@ add_subdirectory(lib/FastNoise2) find_package(OpenCV REQUIRED) +include(CheckCXXCompilerFlag) +CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE) +if(COMPILER_SUPPORTS_MARCH_NATIVE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") +endif() + + include_directories( ${OpenCV_INCLUDE_DIRS} ) include_directories(lib/stb) diff --git a/include/gp_system.h b/include/gp_system.h index ad8a3f4..856b2ee 100644 --- a/include/gp_system.h +++ b/include/gp_system.h @@ -41,6 +41,8 @@ void cleanup(); std::array& get_reference_image(); +std::array get_best_image_index(); + std::array to_gl_image(const std::array& image); #endif //GP_SYSTEM_H diff --git a/include/image_storage.h b/include/image_storage.h index aeaedff..c1a3845 100644 --- a/include/image_storage.h +++ b/include/image_storage.h @@ -27,8 +27,12 @@ #include #include +#ifndef BLT_IMAGE_SIZE +#define BLT_IMAGE_SIZE 256 +#endif + using image_pixel_t = float; -constexpr blt::i32 IMAGE_DIMENSIONS = 256; +constexpr blt::i32 IMAGE_DIMENSIONS = BLT_IMAGE_SIZE; constexpr blt::i32 IMAGE_CHANNELS = 1; constexpr blt::size_t IMAGE_SIZE = IMAGE_DIMENSIONS * IMAGE_DIMENSIONS; diff --git a/lib/blt b/lib/blt index 729a16a..bc34be9 160000 --- a/lib/blt +++ b/lib/blt @@ -1 +1 @@ -Subproject commit 729a16ab574e31bf1b44446a777e4ee834518c6e +Subproject commit bc34be94966e31aa59eb6945b419d228424304d2 diff --git a/lib/blt-gp b/lib/blt-gp index 2e09696..cb16be1 160000 --- a/lib/blt-gp +++ b/lib/blt-gp @@ -1 +1 @@ -Subproject commit 2e09696a673eeae099bc87024e6f32e6c5815fa3 +Subproject commit cb16be1baeaa52ef7d46c5265edd18bdb2e18c29 diff --git a/lib/blt-with-graphics b/lib/blt-with-graphics index ebcdbeb..1808af6 160000 --- a/lib/blt-with-graphics +++ b/lib/blt-with-graphics @@ -1 +1 @@ -Subproject commit ebcdbeb172bc8874b7898a01acad29560ad5d068 +Subproject commit 1808af68b55e6bbcbc8ce82dcccbe12c21a7b38a diff --git a/src/gp_system.cpp b/src/gp_system.cpp index 5d5dc3f..601eeba 100644 --- a/src/gp_system.cpp +++ b/src/gp_system.cpp @@ -21,6 +21,7 @@ #include #include #include "opencv2/imgcodecs.hpp" +#include "opencv2/imgproc.hpp" #include using namespace blt::gp; @@ -209,11 +210,34 @@ void setup_operations(gp_program* program) static auto lit = operation_t([program]() { return program->get_random().get_float(-1.0f, 1.0f); }, "lit_float").set_ephemeral(); + static operation_t op_erode([](const image_t a, float erosion_size) { + image_t ret{}; + erosion_size = std::min(std::max(erosion_size, 0.0f), 21.0f); + const cv::Mat src{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, a.as_void_const()}; + cv::Mat dst{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, ret.get_data().data.data()}; + const cv::Mat element = cv::getStructuringElement( cv::MORPH_CROSS, + cv::Size( static_cast(2*erosion_size + 1), static_cast(2*erosion_size+1) ), + cv::Point( static_cast(erosion_size), static_cast(erosion_size) ) ); + cv::erode( src, dst, element ); + return ret; + }, "erode_image"); + + static operation_t op_dilate([](const image_t a, float dilate_size) { + image_t ret{}; + dilate_size = std::min(std::max(dilate_size, 0.0f), 21.0f); + const cv::Mat src{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, a.as_void_const()}; + cv::Mat dst{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, ret.get_data().data.data()}; + const cv::Mat element = cv::getStructuringElement( cv::MORPH_CROSS, + cv::Size( static_cast(2*dilate_size + 1), static_cast(2*dilate_size+1) ), + cv::Point( static_cast(dilate_size), static_cast(dilate_size) ) ); + cv::dilate( src, dst, element ); + return ret; + }, "erode_image"); operator_builder builder{}; builder.build(op_image_ephemeral, make_add(), make_sub(), make_mul(), make_div(), op_image_x, op_image_y, op_image_sin, op_image_gt, op_image_lt, op_image_cos, op_image_log, op_image_exp, op_image_or, op_image_and, op_image_xor, - op_image_not, op_image_perlin_bounded, op_image_blend, make_add(), make_sub(), make_mul(), + op_image_not, op_image_perlin_bounded, op_image_blend, op_erode, op_dilate, make_add(), make_sub(), make_mul(), make_prot_div(), op_sin, op_cos, op_exp, op_log, lit); program->set_operations(builder.grab()); } @@ -336,6 +360,14 @@ void reset_programs() program->reset_program(program->get_typesystem().get_type().id()); } +std::array get_best_image_index() +{ + std::array best_index{}; + for (const auto [slot, program] : blt::zip(best_index, programs)) + slot = program->get_best_indexes<1>()[0]; + return best_index; +} + void regenerate_image(blt::size_t index, float& image_storage, blt::i32 width, blt::i32 height) { diff --git a/src/main.cpp b/src/main.cpp index ed2d058..bab2853 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "blt/gfx/renderer/camera.h" #include #include +#include #include "../cmake-build-release-examples/_deps/imgui-src/imgui_internal.h" @@ -97,6 +98,7 @@ void update(const blt::gfx::window_data& data) static blt::i32 image_to_enlarge = -1; bool clicked_on_image = false; + static bool show_best = false; // Create the tab bar if (ImGui::BeginTabBar("MainTabs")) @@ -108,6 +110,7 @@ void update(const blt::gfx::window_data& data) static int images_y = 6; static bool run_gp = false; static int generation_limit = 0; + static int min_between_runs = 100; if (ImGui::BeginTabItem("Run GP")) { @@ -121,8 +124,10 @@ void update(const blt::gfx::window_data& data) if (ImGui::InputInt("Images X", &images_x) || ImGui::InputInt("Images Y", &images_y)) update_population_size(images_x * images_y); ImGui::InputInt("Generation Limit", &generation_limit); - if (run_gp && (generation_limit == 0 || get_generation() < generation_limit)) + if (run_gp && (generation_limit == 0 || get_generation() < static_cast(generation_limit))) run_generation = true; + ImGui::InputInt("Min Time Between Runs (ms)", &min_between_runs); + ImGui::Checkbox("Show Best", &show_best); } ImGui::EndChild(); @@ -191,8 +196,8 @@ void update(const blt::gfx::window_data& data) if (ImGui::BeginTabItem("Reference")) { - auto w = data.width; - auto h = data.height - top_bar_height - 10; + auto w = static_cast(data.width); + auto h = static_cast(data.height) - top_bar_height - 10; renderer_2d.drawRectangle({w / 2, h / 2, w, h}, "reference"); ImGui::EndTabItem(); } @@ -237,6 +242,19 @@ void update(const blt::gfx::window_data& data) if ((blt::gfx::isMousePressed(0) && blt::gfx::mousePressedLastFrame() && !clicked_on_image) || (blt::gfx::isKeyPressed(GLFW_KEY_ESCAPE) && blt::gfx::keyPressedLastFrame())) image_to_enlarge = -1; + if (show_best) + { + auto best_images = get_best_image_index(); + for (const auto [i, best_image] : blt::enumerate(best_images)) + { + const auto width = std::min(static_cast(data.width) - side_bar_width, static_cast(256) * 3) / 3; + const auto height = std::min(static_cast(data.height) - top_bar_height, static_cast(256) * 3) / 3; + renderer_2d.drawRectangle(blt::gfx::rectangle2d_t{blt::gfx::anchor_t::BOTTOM_LEFT, + side_bar_width + 256 + i * width, 64, width, height + }, std::to_string(best_image), 1); + } + } + if (image_to_enlarge != -1) { if (blt::gfx::isKeyPressed(GLFW_KEY_R) && blt::gfx::keyPressedLastFrame())