Brett 2024-01-16 18:44:50 -05:00
parent dc7bd2fd22
commit 28ccdc2102
7 changed files with 135 additions and 95 deletions

Binary file not shown.

View File

@ -210,3 +210,5 @@
2237 2427 1705433088022195202 libraries/BLT-With-Graphics-Template/libraries/BLT/libBLT.a 5e3491f3bb42050d
9 3115 1705433088714186351 CMakeFiles/gp_image_test.dir/src/main.cpp.o d2247c8eaef04c80
3116 3265 1705433088862184459 gp_image_test 627b40e9bcf815e3
22 1261 1705448034056787170 CMakeFiles/gp_image_test.dir/src/main.cpp.o d2247c8eaef04c80
1261 1331 1705448034128783930 gp_image_test 627b40e9bcf815e3

View File

@ -1,3 +1,3 @@
Start testing: Jan 16 14:24 EST
Start testing: Jan 16 18:33 EST
----------------------------------------------------------
End testing: Jan 16 14:24 EST
End testing: Jan 16 18:33 EST

Binary file not shown.

View File

@ -31,16 +31,16 @@ inline constexpr i32 width = 1024, height = 1024;
class image
{
private:
std::array<u8, width * height * 4> data;
std::array<blt::vec4, width * height> data;
public:
image() = default;
u8 get(i32 x, i32 y)
const blt::vec4& get(i32 x, i32 y)
{
return data[y * height + x];
}
void set(u8 c, i32 x, i32 y)
void set(const blt::vec4& c, i32 x, i32 y)
{
data[y * height + x] = c;
}
@ -92,23 +92,23 @@ inline i32 inputs(function_t op)
struct op_con
{
function_t op;
std::optional<image*> i1, i2;
const function_t op;
const std::optional<image*> i1, i2;
op_con(function_t op, const std::optional<image*>& i1, const std::optional<image*>& i2): op(op), i1(i1), i2(i2)
{}
[[nodiscard]] bool has_both() const
[[nodiscard]] bool has_both() const noexcept
{
return i1.has_value() && i2.has_value();
}
[[nodiscard]] bool has_one() const
[[nodiscard]] bool has_one() const noexcept
{
return i1.has_value() || i2.has_value();
}
[[nodiscard]] image* getOne()
[[nodiscard]] image* getOne() const
{
if (i1)
return i1.value();

View File

@ -21,6 +21,8 @@ struct node;
blt::area_allocator<node, 32000> node_allocator;
blt::area_allocator<image, 32000> img_allocator;
using data_t = std::array<float, 5>;
node* createNode()
{
auto* n = node_allocator.allocate(1);
@ -47,90 +49,6 @@ void destroyImage(image* img)
img_allocator.deallocate(img, 1);
}
image* apply_operator(op_con operation)
{
auto* ret = createImage();
for (i32 y = 0; y < height; y++)
{
for (i32 x = 0; x < width; x++)
{
switch (operation.op)
{
case function_t::ADD:
{
BLT_ASSERT(operation.has_both());
ret->set((operation.i1.value()->get(x, y) + operation.i2.value()->get(x, y)) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::SUB:
{
BLT_ASSERT(operation.has_both());
ret->set((operation.i1.value()->get(x, y) - operation.i2.value()->get(x, y)) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::MUL:
{
BLT_ASSERT(operation.has_both());
ret->set((operation.i1.value()->get(x, y) * operation.i2.value()->get(x, y)) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::DIV:
{
BLT_ASSERT(operation.has_both());
auto den = operation.i2.value()->get(x, y);
if (den == 0)
ret->set(0, x, y);
else
ret->set((operation.i1.value()->get(x, y) / den) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::EXP:
{
BLT_ASSERT(operation.has_both());
ret->set(static_cast<u8>(std::pow(operation.i1.value()->get(x, y), operation.i2.value()->get(x, y))), x, y);
break;
}
case function_t::LOG:
{
BLT_ASSERT(operation.has_one());
ret->set(static_cast<u8>(std::log(static_cast<double>(operation.getOne()->get(x, y)))), x, y);
break;
}
case function_t::SQRT:
{
BLT_ASSERT(operation.has_one());
ret->set(static_cast<u8>(std::sqrt(static_cast<double>(operation.getOne()->get(x, y)))), x, y);
break;
}
case function_t::QUAD:
{
BLT_ASSERT(operation.has_one());
auto v = operation.getOne()->get(x, y);
ret->set(static_cast<u8>(v * v), x, y);
break;
}
case function_t::RANDOM:
{
break;
}
case function_t::NOISE:
{
break;
}
case function_t::COLOR:
{
break;
}
case function_t::SCALAR:
{
break;
}
}
}
}
}
static constexpr int OPERATOR_COUNT = 13;
class tree;
@ -142,7 +60,28 @@ struct node
node* left;
node* right;
function_t type;
std::array<float, 7> data;
data_t data;
image* img = nullptr;
[[nodiscard]] bool has_both() const
{
return left->img != nullptr && right->img != nullptr;
}
[[nodiscard]] bool has_one() const
{
return left->img != nullptr || right->img != nullptr;
}
[[nodiscard]] image* get_one() const
{
if (left->img != nullptr)
return left->img;
if (right->img != nullptr)
return right->img;
BLT_THROW(std::runtime_error("Unable to get when one is missing! You have an error in your GA!"));
}
public:
static node* construct_random()
@ -161,6 +100,105 @@ struct node
return n;
}
void evaluate()
{
img = createImage();
for (i32 y = 0; y < height; y++)
{
for (i32 x = 0; x < width; x++)
{
switch (type)
{
case function_t::ADD:
{
BLT_ASSERT(has_both());
img->set((left->img->get(x, y) + right->img->get(x, y)) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::SUB:
{
BLT_ASSERT(has_both());
img->set((left->img->get(x, y) - right->img->get(x, y)) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::MUL:
{
BLT_ASSERT(has_both());
img->set((left->img->get(x, y) * right->img->get(x, y)) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::DIV:
{
BLT_ASSERT(has_both());
auto den = right->img->get(x, y);
if (den == 0)
img->set(0, x, y);
else
img->set((left->img->get(x, y) / den) % std::numeric_limits<u8>::max(), x, y);
break;
}
case function_t::EXP:
{
BLT_ASSERT(has_both());
img->set(static_cast<u8>(std::pow(left->img->get(x, y), right->img->get(x, y))), x, y);
break;
}
case function_t::LOG:
{
BLT_ASSERT(has_one());
const auto& v = get_one()->get(x, y);
auto v_x = v.x() == 0 ? 0.000001f : v.x();
auto v_y = v.y() == 0 ? 0.000001f : v.y();
auto v_z = v.z() == 0 ? 0.000001f : v.z();
img->set({std::log(v_x), std::log(v_y), std::log(v_z)}, x, y);
break;
}
case function_t::SQRT:
{
BLT_ASSERT(has_one());
const auto& v = get_one()->get(x, y);
img->set({std::sqrt(v.x()), std::sqrt(v.y()), std::sqrt(v.z())}, x, y);
break;
}
case function_t::QUAD:
{
BLT_ASSERT(has_one());
auto v = get_one()->get(x, y);
img->set(v * v, x, y);
break;
}
case function_t::RANDOM:
{
static std::random_device dev;
static std::mt19937_64 engine(dev());
static std::uniform_real_distribution<float> dist(0, 1);
img->set({dist(engine), dist(engine), dist(engine), 1.0f}, x, y);
break;
}
case function_t::NOISE:
{
auto v = std::numeric_limits<u8>::max() *
stb_perlin_noise3(static_cast<float>(x) / ((256.0f * (data[0] + 1.0f) / 2.0f)),
static_cast<float>(y) / ((256 * (data[1] + 1) / 2)), data[2] / 2.0f + 0.5f, 0,
0, 0);
img->set(blt::vec4{v,v,v,1.0f}, x, y);
break;
}
case function_t::COLOR:
{
img->set(blt::vec4{data[0], data[1], data[2], 1.0f}, x, y);
break;
}
case function_t::SCALAR:
{
img->set(blt::vec4{data[0], data[0], data[0], 1.0f}, x, y);
break;
}
}
}
}
}
~node()
{
destroyNode(left);