#include "texture_generator.h" #include #include #include BEGIN_NAMESPACE texture_generator::texture_generator(uint16_t w, uint16_t h) : width(w), height(h) { for (auto &layer: layers) layer = new uint8_t[width * height * 4]; } texture_generator::~texture_generator() { for (auto &layer: layers) delete[] layer; } texture_generator &texture_generator::checker_board(uint8_t layer, uint8_t block_size, colour on, colour off) { auto *input = reinterpret_cast(layers[layer]); uint32_t on_color = as_int(on); uint32_t off_color = as_int(off); for (auto y = 0; y < height; y++) { for (auto x = 0; x < width; x++) { bool in_block = ( ((x % (2 * block_size)) < block_size) && ((y % (2 * block_size)) < block_size) ); *input++ = in_block ? on_color : off_color; // *input++ = 0xffffffff; } } return *this; } texture_generator &texture_generator::env_map(uint8_t layer, uint8_t size) { auto *input = reinterpret_cast(layers[layer]); colour col{1}; float size_squared = size * size; for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) { int32_t rx = x - width / 2; int32_t ry = y - height / 2; float r_square = static_cast(rx * rx + ry * ry); if (r_square <= size_squared) { float a = 1.0f - (r_square / size_squared); col.r = col.g = col.b = a; // col.a = 1; } else { col.r = col.g = col.b = 0; // col.a = 1; } *input++ = as_int(col); } } return *this; } texture_generator &texture_generator::lens(uint8_t layer, uint8_t size) { auto *input = reinterpret_cast(layers[layer]); colour col{0}; float size_squared = size * size; float c; for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) { int32_t rx = x - width / 2; int32_t ry = y - height / 2; auto r_squared = static_cast(rx * rx + ry * ry); if (r_squared <= size_squared) { // double r = sqrt(static_castrsquare) / static_cast(size); float r = 0; c = 1.0f - r; c = c * c; if (r > 1.0f) c = 0.0f; col = glm::vec4(c); } else { col = glm::vec4(0); } *input++ = as_int(col); } } return *this; } texture_generator &texture_generator::roll(uint8_t layer, uint8_t x, uint8_t y) { uint8_t *input = layers[layer]; auto *output = new uint8_t[width * height * 4]; uint8_t *out_ptr = output; for (uint16_t j = 0; j < height; j++) { for (uint16_t i = 0; i < width; i++) { uint32_t index = ((j + y) % height) * width + ((i + x) % width); *out_ptr++ = input[index * 4 + 0]; *out_ptr++ = input[index * 4 + 1]; *out_ptr++ = input[index * 4 + 2]; *out_ptr++ = input[index * 4 + 3]; } } memcpy(input, output, width * height * 4); delete[] output; return *this; } uint8_t *texture_generator::get(uint8_t layer) { return layers[layer]; } std::shared_ptr texture_generator::get_texture(uint8_t layer) { return std::make_shared(width, height, get(layer)); } texture_generator &texture_generator::white_noise(uint8_t layer) { auto *input = reinterpret_cast(layers[layer]); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) { *input++ = rand(); } } return *this; } texture_generator &texture_generator::polar_grid(uint8_t layer) { uint8_t *input = layers[layer]; auto *output = new uint8_t[width * height * 4]; uint8_t *out_ptr = output; for (int j = 0; j < height; j++) { double theta = M_PI * (j - (height - 1) / 2.0) / static_cast(height - 1); for (int i = 0; i < width; i++) { double phi = 2 * M_PI * (i - width / 2.0) / static_cast(width); double phi2 = phi * cos(theta); int i2 = phi2 * width / (2 * M_PI) + width / 2; if (i2 < 0 || i2 > width - 1) { *out_ptr++ = 255; *out_ptr++ = 0; *out_ptr++ = 0; *out_ptr++ = 1; } else { *out_ptr++ = input[(j * width + i2) * 4 + 0]; *out_ptr++ = input[(j * width + i2) * 4 + 1]; *out_ptr++ = input[(j * width + i2) * 4 + 2]; *out_ptr++ = input[(j * width + i2) * 4 + 3]; } } } memcpy(input, output, width * height * 4); delete[] output; return *this; } texture_generator &texture_generator::brick(uint8_t layer, uint8_t brick_width, uint8_t brick_height, uint8_t gap_size, colour mortar_col, colour brick_col) { auto *input = reinterpret_cast(layers[layer]); uint32_t mortar = as_int(mortar_col); uint32_t brick = as_int(brick_col); for (int i = 0; i < width * height; i++) { input[i] = brick; } int y = 0; while (y < height) { for (int i = 0; i < gap_size; i++) { if ((y + i) < height) { for (int x = 0; x < width; x++) { input[x + (y + i) * width] = mortar; } } } y += brick_height + gap_size; } int offset = 0; bool is_odd_row = false; y = gap_size; while (y < height) { int x = is_odd_row ? 0 : brick_width / 2; while (x < width) { for (int i = 0; i < gap_size; i++) { for (int current_brick_y = 0; current_brick_y < brick_height; current_brick_y++) { input[x + i + (current_brick_y + y) * width] = mortar; } } x += gap_size + brick_width; } y += brick_height + gap_size; is_odd_row = !is_odd_row; } return *this; } END_NAMESPACE