silly
parent
339046cc36
commit
4bb2b2b3af
|
@ -80,7 +80,7 @@
|
|||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="CppTooWideScope" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
|
@ -5,6 +5,9 @@
|
|||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/imgui-src" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-release-examples/_deps/freetype-src" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-release-examples/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-release-examples/_deps/imgui-src" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/freetype-src/subprojects/dlg" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/cmake-build-release/_deps/imgui-src" vcs="Git" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(image-gp-2 VERSION 0.0.8)
|
||||
project(image-gp-2 VERSION 0.0.9)
|
||||
|
||||
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
||||
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
||||
|
|
|
@ -31,4 +31,8 @@ std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3>& get_image(bl
|
|||
|
||||
void cleanup();
|
||||
|
||||
std::array<image_storage_t, 3>& get_reference_image();
|
||||
|
||||
std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3> to_gl_image(const std::array<image_storage_t, 3>& image);
|
||||
|
||||
#endif //GP_SYSTEM_H
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <blt/logging/logging.h>
|
||||
#include <blt/std/types.h>
|
||||
#include <mutex>
|
||||
#include <blt/std/hashmap.h>
|
||||
|
||||
using image_pixel_t = float;
|
||||
constexpr blt::i32 IMAGE_DIMENSIONS = 256;
|
||||
|
@ -49,6 +50,8 @@ struct image_storage_t
|
|||
{
|
||||
return data[(y * IMAGE_DIMENSIONS + x) * IMAGE_CHANNELS];
|
||||
}
|
||||
|
||||
void normalize();
|
||||
};
|
||||
|
||||
inline std::atomic_uint64_t g_allocated_blocks = 0;
|
||||
|
@ -68,11 +71,10 @@ struct image_cleaner_t
|
|||
};
|
||||
|
||||
inline image_cleaner_t g_image_list;
|
||||
inline std::atomic_uint64_t g_image_counter = 0;
|
||||
|
||||
struct image_t
|
||||
{
|
||||
image_t(): id(++g_image_counter)
|
||||
explicit image_t()
|
||||
{
|
||||
image_storage_t* front = nullptr;
|
||||
{
|
||||
|
@ -88,14 +90,8 @@ struct image_t
|
|||
else
|
||||
data = new image_storage_t;
|
||||
++g_allocated_blocks;
|
||||
|
||||
BLT_TRACE("Allocated {}!", id);
|
||||
}
|
||||
|
||||
image_t(const image_t& other) = default;
|
||||
|
||||
image_t& operator=(const image_t& other) = default;
|
||||
|
||||
void drop()
|
||||
{
|
||||
{
|
||||
|
@ -104,7 +100,6 @@ struct image_t
|
|||
}
|
||||
data = nullptr;
|
||||
++g_deallocated_blocks;
|
||||
BLT_TRACE("Deallocated {}!", id);
|
||||
}
|
||||
|
||||
[[nodiscard]] void* as_void_const() const
|
||||
|
@ -117,6 +112,11 @@ struct image_t
|
|||
return data->data.data();
|
||||
}
|
||||
|
||||
void normalize() const
|
||||
{
|
||||
data->normalize();
|
||||
}
|
||||
|
||||
friend image_t operator+(const image_t& lhs, const image_t& rhs);
|
||||
|
||||
friend image_t operator-(const image_t& lhs, const image_t& rhs);
|
||||
|
@ -137,7 +137,6 @@ struct image_t
|
|||
|
||||
private:
|
||||
image_storage_t* data;
|
||||
blt::size_t id;
|
||||
};
|
||||
|
||||
#endif //IMAGE_STORAGE_H
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0eea2189e37a372f7a012a07120ee0aed2b1646a
|
||||
Subproject commit 0dc083e095393beaf88d58f07b6f06c04439cdb8
|
|
@ -21,9 +21,17 @@
|
|||
#include <operations.h>
|
||||
#include <random>
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include <stb_perlin.h>
|
||||
|
||||
using namespace blt::gp;
|
||||
|
||||
float filter_nan(const float f)
|
||||
{
|
||||
if (std::isnan(f) || std::isinf(f) || std::isinf(-f))
|
||||
return 0.0f;
|
||||
return f;
|
||||
}
|
||||
|
||||
std::array<gp_program*, 3> programs;
|
||||
|
||||
std::vector<std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3>> images;
|
||||
|
@ -33,6 +41,7 @@ template <size_t Channel>
|
|||
void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t index)
|
||||
{
|
||||
auto image = tree.get_evaluation_ref<image_t>();
|
||||
image->normalize();
|
||||
|
||||
// std::memcpy(images[index].data.data(), image->get_data().data.data(), IMAGE_SIZE_BYTES);
|
||||
auto& data = image->get_data();
|
||||
|
@ -44,8 +53,8 @@ void fitness_func(const tree_t& tree, fitness_t& fitness, const blt::size_t inde
|
|||
|
||||
auto multiplier = (1 - std::abs((static_cast<float>(x) / (static_cast<float>(IMAGE_DIMENSIONS) / 2)) - 1)) + (1 - std::abs(
|
||||
(static_cast<float>(y) / (static_cast<float>(IMAGE_DIMENSIONS) / 2)) - 1));
|
||||
const auto diff = data.get(x, y) - reference_image[Channel].get(x, y);
|
||||
fitness.raw_fitness += (diff * diff) * multiplier;
|
||||
const auto diff = filter_nan(data.get(x, y)) - reference_image[Channel].get(x, y);
|
||||
fitness.raw_fitness += diff * diff * multiplier;
|
||||
}
|
||||
}
|
||||
fitness.raw_fitness /= static_cast<float>(IMAGE_SIZE_CHANNELS);
|
||||
|
@ -57,7 +66,7 @@ template <typename T>
|
|||
void setup_operations(gp_program* program)
|
||||
{
|
||||
static operation_t op_image_x([]() {
|
||||
image_t ret;
|
||||
image_t ret{};
|
||||
for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x)
|
||||
{
|
||||
for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y)
|
||||
|
@ -66,7 +75,7 @@ void setup_operations(gp_program* program)
|
|||
return ret;
|
||||
});
|
||||
static operation_t op_image_y([]() {
|
||||
image_t ret;
|
||||
image_t ret{};
|
||||
for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x)
|
||||
{
|
||||
for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y)
|
||||
|
@ -75,47 +84,97 @@ void setup_operations(gp_program* program)
|
|||
return ret;
|
||||
});
|
||||
static auto op_image_ephemeral = operation_t([program]() {
|
||||
image_t ret;
|
||||
image_t ret{};
|
||||
const auto value = program->get_random().get_float();
|
||||
for (auto& v : ret.get_data().data)
|
||||
v = value;
|
||||
return ret;
|
||||
}).set_ephemeral();
|
||||
static operation_t op_image_blend([](const image_t& a, const image_t& b, const float f) {
|
||||
static operation_t op_image_blend([](const image_t a, const image_t b, const float f) {
|
||||
const auto blend = std::min(std::max(f, 0.0f), 1.0f);
|
||||
const auto beta = 1.0f - blend;
|
||||
image_t ret;
|
||||
const cv::Mat src1{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC1, a.as_void()};
|
||||
const cv::Mat src2{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC1, b.as_void()};
|
||||
cv::Mat dst{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32FC1, ret.get_data().data.data()};
|
||||
image_t ret{};
|
||||
const cv::Mat src1{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, a.as_void_const()};
|
||||
const cv::Mat src2{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, b.as_void_const()};
|
||||
cv::Mat dst{IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, CV_32F, ret.get_data().data.data()};
|
||||
addWeighted(src1, blend, src2, beta, 0.0, dst);
|
||||
return ret;
|
||||
}, "blend_image");
|
||||
static operation_t op_image_sin([](const image_t& a) {
|
||||
image_t ret;
|
||||
static operation_t op_image_sin([](const image_t a) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
|
||||
ret.get_data().data[i] = std::sin(v);
|
||||
ret.get_data().data[i] = filter_nan(std::sin(v));
|
||||
return ret;
|
||||
}, "sin_image");
|
||||
static operation_t op_image_cos([](const image_t& a) {
|
||||
image_t ret;
|
||||
static operation_t op_image_cos([](const image_t a) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
|
||||
ret.get_data().data[i] = std::cos(v);
|
||||
ret.get_data().data[i] = filter_nan(std::cos(v));
|
||||
return ret;
|
||||
}, "cos_image");
|
||||
static operation_t op_image_log([](const image_t& a) {
|
||||
image_t ret;
|
||||
static operation_t op_image_log([](const image_t a) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
|
||||
{
|
||||
if (blt::f_equal(v, 0))
|
||||
ret.get_data().data[i] = 0;
|
||||
else if (v < 0)
|
||||
ret.get_data().data[i] = -std::log(-v);
|
||||
ret.get_data().data[i] = -filter_nan(std::log(-v));
|
||||
else
|
||||
ret.get_data().data[i] = std::log(v);
|
||||
ret.get_data().data[i] = filter_nan(std::log(v));
|
||||
}
|
||||
return ret;
|
||||
}, "sin_image");
|
||||
}, "log_image");
|
||||
static operation_t op_image_exp([](const image_t a) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, v] : blt::enumerate(std::as_const(a.get_data().data)))
|
||||
ret.get_data().data[i] = filter_nan(std::exp(v));
|
||||
return ret;
|
||||
}, "exp_image");
|
||||
static operation_t op_image_or([](const image_t a, const image_t b) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, av, bv] : blt::in_pairs(std::as_const(a.get_data().data), std::as_const(b.get_data().data)).enumerate().flatten())
|
||||
ret.get_data().data[i] = blt::mem::type_cast<float>(blt::mem::type_cast<blt::u32>(av) | blt::mem::type_cast<blt::u32>(bv));
|
||||
return ret;
|
||||
}, "bit_or_image");
|
||||
static operation_t op_image_and([](const image_t a, const image_t b) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, av, bv] : blt::in_pairs(std::as_const(a.get_data().data), std::as_const(b.get_data().data)).enumerate().flatten())
|
||||
ret.get_data().data[i] = blt::mem::type_cast<float>(blt::mem::type_cast<blt::u32>(av) & blt::mem::type_cast<blt::u32>(bv));
|
||||
return ret;
|
||||
}, "bit_and_image");
|
||||
static operation_t op_image_xor([](const image_t a, const image_t b) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, av, bv] : blt::in_pairs(std::as_const(a.get_data().data), std::as_const(b.get_data().data)).enumerate().flatten())
|
||||
ret.get_data().data[i] = blt::mem::type_cast<float>(blt::mem::type_cast<blt::u32>(av) ^ blt::mem::type_cast<blt::u32>(bv));
|
||||
return ret;
|
||||
}, "bit_xor_image");
|
||||
static operation_t op_image_not([](const image_t a, const image_t b) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, av, bv] : blt::in_pairs(std::as_const(a.get_data().data), std::as_const(b.get_data().data)).enumerate().flatten())
|
||||
ret.get_data().data[i] = blt::mem::type_cast<float>(~blt::mem::type_cast<blt::u32>(av));
|
||||
return ret;
|
||||
}, "bit_not_image");
|
||||
static operation_t op_image_gt([](const image_t a, const image_t b) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, av, bv] : blt::in_pairs(std::as_const(a.get_data().data), std::as_const(b.get_data().data)).enumerate().flatten())
|
||||
ret.get_data().data[i] = av > bv ? av : bv;
|
||||
return ret;
|
||||
}, "gt_image");
|
||||
static operation_t op_image_lt([](const image_t a, const image_t b) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, av, bv] : blt::in_pairs(std::as_const(a.get_data().data), std::as_const(b.get_data().data)).enumerate().flatten())
|
||||
ret.get_data().data[i] = av < bv ? av : bv;
|
||||
return ret;
|
||||
}, "lt_image");
|
||||
static operation_t op_image_perlin([](const float ofx, const float ofy, const float ofz, const float lacunarity, const float gain,
|
||||
const float octaves) {
|
||||
image_t ret{};
|
||||
for (const auto& [i, out] : blt::enumerate(ret.get_data().data))
|
||||
out = stb_perlin_ridge_noise3(static_cast<float>(i % IMAGE_DIMENSIONS) + ofx, static_cast<float>(i / IMAGE_DIMENSIONS) + ofy, ofz,
|
||||
lacunarity + 2, gain + 0.5f, 1.0f, static_cast<int>(octaves));
|
||||
return ret;
|
||||
}, "perlin_image");
|
||||
static operation_t op_sin([](const float a) {
|
||||
return std::sin(a);
|
||||
}, "sin_float");
|
||||
|
@ -137,18 +196,20 @@ void setup_operations(gp_program* program)
|
|||
}, "lit_float").set_ephemeral();
|
||||
|
||||
operator_builder builder{};
|
||||
builder.build(make_add<image_t>(), make_sub<image_t>(), make_mul<image_t>(), make_div<image_t>(), op_image_x, op_image_y, op_image_sin,
|
||||
op_image_cos, op_image_log, make_add<float>(), make_sub<float>(), make_mul<float>(), make_prot_div<float>(),
|
||||
op_sin, op_cos, op_exp, op_log, lit);
|
||||
builder.build(op_image_ephemeral, make_add<image_t>(), make_sub<image_t>(), make_mul<image_t>(), make_div<image_t>(), 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, make_add<float>(), make_sub<float>(), make_mul<float>(), make_prot_div<float>(), op_sin, op_cos,
|
||||
op_exp, op_log, lit);
|
||||
program->set_operations(builder.grab());
|
||||
}
|
||||
|
||||
void setup_gp_system(const blt::size_t population_size)
|
||||
{
|
||||
prog_config_t config{};
|
||||
config.set_pop_size(1);
|
||||
config.set_elite_count(0);
|
||||
config.set_pop_size(population_size);
|
||||
config.set_elite_count(2);
|
||||
config.set_thread_count(0);
|
||||
config.set_reproduction_chance(0);
|
||||
// config.set_crossover_chance(0);
|
||||
// config.set_mutation_chance(0);
|
||||
// config.set_reproduction_chance(0);
|
||||
|
@ -219,3 +280,23 @@ void cleanup()
|
|||
for (const auto program : programs)
|
||||
delete program;
|
||||
}
|
||||
|
||||
std::array<image_storage_t, 3>& get_reference_image()
|
||||
{
|
||||
return reference_image;
|
||||
}
|
||||
|
||||
std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3> to_gl_image(const std::array<image_storage_t, 3>& image)
|
||||
{
|
||||
std::array<image_pixel_t, IMAGE_DIMENSIONS * IMAGE_DIMENSIONS * 3> image_data{};
|
||||
for (blt::size_t x = 0; x < IMAGE_DIMENSIONS; ++x)
|
||||
{
|
||||
for (blt::size_t y = 0; y < IMAGE_DIMENSIONS; ++y)
|
||||
{
|
||||
image_data[(x * IMAGE_DIMENSIONS + y) * 3 + 0] = image[0].get(x, y);
|
||||
image_data[(x * IMAGE_DIMENSIONS + y) * 3 + 1] = image[1].get(x, y);
|
||||
image_data[(x * IMAGE_DIMENSIONS + y) * 3 + 2] = image[2].get(x, y);
|
||||
}
|
||||
}
|
||||
return image_data;
|
||||
}
|
||||
|
|
|
@ -48,9 +48,28 @@ std::array<image_storage_t, 3> image_storage_t::from_file(const std::string& pat
|
|||
return {storage_r, storage_g, storage_b};
|
||||
}
|
||||
|
||||
void image_storage_t::normalize()
|
||||
{
|
||||
float min = std::numeric_limits<float>::max();
|
||||
float max = std::numeric_limits<float>::min();
|
||||
|
||||
for (auto& pixel : data)
|
||||
{
|
||||
if (std::isnan(pixel) || std::isinf(pixel))
|
||||
pixel = 0;
|
||||
if (pixel > max)
|
||||
max = pixel;
|
||||
if (pixel < min)
|
||||
min = pixel;
|
||||
}
|
||||
|
||||
for (auto& pixel : data)
|
||||
pixel = (pixel - min) / (max - min);
|
||||
}
|
||||
|
||||
image_t operator/(const image_t& lhs, const image_t& rhs)
|
||||
{
|
||||
const image_t ret;
|
||||
const image_t ret{};
|
||||
for (auto [ref, l, r] : blt::zip(ret.data->data, lhs.data->data, rhs.data->data))
|
||||
ref = blt::f_equal(r, 0) ? 0 : l / r;
|
||||
return ret;
|
||||
|
@ -58,7 +77,7 @@ image_t operator/(const image_t& lhs, const image_t& rhs)
|
|||
|
||||
image_t operator*(const image_t& lhs, const image_t& rhs)
|
||||
{
|
||||
const image_t ret;
|
||||
const image_t ret{};
|
||||
for (auto [ref, l, r] : blt::zip(ret.data->data, lhs.data->data, rhs.data->data))
|
||||
ref = l * r;
|
||||
return ret;
|
||||
|
@ -66,7 +85,7 @@ image_t operator*(const image_t& lhs, const image_t& rhs)
|
|||
|
||||
image_t operator-(const image_t& lhs, const image_t& rhs)
|
||||
{
|
||||
const image_t ret;
|
||||
const image_t ret{};
|
||||
for (auto [ref, l, r] : blt::zip(ret.data->data, lhs.data->data, rhs.data->data))
|
||||
ref = l - r;
|
||||
return ret;
|
||||
|
@ -74,7 +93,7 @@ image_t operator-(const image_t& lhs, const image_t& rhs)
|
|||
|
||||
image_t operator+(const image_t& lhs, const image_t& rhs)
|
||||
{
|
||||
const image_t ret;
|
||||
const image_t ret{};
|
||||
for (auto [ref, l, r] : blt::zip(ret.data->data, lhs.data->data, rhs.data->data))
|
||||
ref = l + r;
|
||||
return ret;
|
||||
|
|
54
src/main.cpp
54
src/main.cpp
|
@ -49,6 +49,9 @@ void init(const blt::gfx::window_data&)
|
|||
gl_images.push_back(texture);
|
||||
resources.set(std::to_string(i), texture);
|
||||
}
|
||||
const auto texture = new texture_gl2D(IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, GL_RGBA8);
|
||||
texture->upload(to_gl_image(get_reference_image()).data(), IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, GL_RGB, GL_FLOAT);
|
||||
resources.set("reference", texture);
|
||||
global_matrices.create_internals();
|
||||
resources.load_resources();
|
||||
renderer_2d.create();
|
||||
|
@ -58,6 +61,9 @@ void init(const blt::gfx::window_data&)
|
|||
|
||||
void update(const blt::gfx::window_data& data)
|
||||
{
|
||||
constexpr float side_bar_width = 250;
|
||||
static float top_bar_height = 0;
|
||||
|
||||
global_matrices.update_perspectives(data.width, data.height, 90, 0.1, 2000);
|
||||
|
||||
camera.update();
|
||||
|
@ -75,11 +81,11 @@ void update(const blt::gfx::window_data& data)
|
|||
// Create the tab bar
|
||||
if (ImGui::BeginTabBar("MainTabs"))
|
||||
{
|
||||
top_bar_height = ImGui::GetFrameHeight();
|
||||
// 1. Run GP tab
|
||||
if (ImGui::BeginTabItem("Run GP"))
|
||||
{
|
||||
// Left child - fixed width (250px)
|
||||
ImGui::BeginChild("ControlPanel", ImVec2(250, 0), true);
|
||||
ImGui::BeginChild("ControlPanel", ImVec2(side_bar_width, 0), true);
|
||||
{
|
||||
ImGui::Text("Control Panel");
|
||||
ImGui::Separator();
|
||||
|
@ -94,7 +100,24 @@ void update(const blt::gfx::window_data& data)
|
|||
// Right child - take the remaining space
|
||||
ImGui::SameLine();
|
||||
// ImGui::BeginChild("MainContent", ImVec2(0, 0), false, ImGuiWindowFlags_NoBackground);
|
||||
{}
|
||||
{
|
||||
constexpr int images_x = 10;
|
||||
constexpr int images_y = 6;
|
||||
for (int i = 0; i < images_x; i++)
|
||||
{
|
||||
for (int j = 0; j < images_y; j++)
|
||||
{
|
||||
constexpr float padding_x = 32;
|
||||
constexpr float padding_y = 32;
|
||||
const float img_width = (static_cast<float>(data.width) - padding_x * 2 - padding_x * (images_x - 1) - 256) / images_x;
|
||||
const float img_height = (static_cast<float>(data.height) - padding_y * 2 - padding_y * (images_y - 1) - 32) / images_y;
|
||||
const float x = 256 + static_cast<float>(i) * img_width + padding_x * static_cast<float>(i) + img_width;
|
||||
const float y = static_cast<float>(data.height) - (16 + static_cast<float>(j) * img_height + padding_y * static_cast<float>(j) +
|
||||
img_height);
|
||||
renderer_2d.drawRectangle(blt::gfx::rectangle2d_t{x, y, img_width, img_height}, std::to_string(i * images_y + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
// ImGui::EndChild();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
|
@ -116,6 +139,14 @@ void update(const blt::gfx::window_data& data)
|
|||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Reference"))
|
||||
{
|
||||
auto w = data.width;
|
||||
auto h = data.height - top_bar_height - 10;
|
||||
renderer_2d.drawRectangle({w/2, h/2, w, h}, "reference");
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
|
@ -153,23 +184,6 @@ void update(const blt::gfx::window_data& data)
|
|||
gl_images[i]->upload(get_image(i).data(), IMAGE_DIMENSIONS, IMAGE_DIMENSIONS, GL_RGB, GL_FLOAT);
|
||||
}
|
||||
|
||||
constexpr int images_x = 10;
|
||||
constexpr int images_y = 6;
|
||||
for (int i = 0; i < images_x; i++)
|
||||
{
|
||||
for (int j = 0; j < images_y; j++)
|
||||
{
|
||||
constexpr float padding_x = 32;
|
||||
constexpr float padding_y = 32;
|
||||
const float img_width = (static_cast<float>(data.width) - padding_x * 2 - padding_x * (images_x - 1) - 256) / images_x;
|
||||
const float img_height = (static_cast<float>(data.height) - padding_y * 2 - padding_y * (images_y - 1) - 32) / images_y;
|
||||
const float x = 256 + static_cast<float>(i) * img_width + padding_x * static_cast<float>(i) + img_width;
|
||||
const float y = static_cast<float>(data.height) - (16 + static_cast<float>(j) * img_height + padding_y * static_cast<float>(j) +
|
||||
img_height);
|
||||
renderer_2d.drawRectangle(blt::gfx::rectangle2d_t{x, y, img_width, img_height}, std::to_string(i * images_y + j));
|
||||
}
|
||||
}
|
||||
|
||||
renderer_2d.render(data.width, data.height);
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 235 KiB |
Loading…
Reference in New Issue