104 lines
2.6 KiB
C++
104 lines
2.6 KiB
C++
#include "app.hh"
|
|
#include "input.hh"
|
|
|
|
#include <vector>
|
|
|
|
#include <imgui.h>
|
|
|
|
|
|
namespace pg {
|
|
namespace {
|
|
|
|
class Noise final : public App, public Input::Data {
|
|
public:
|
|
static inline TypeInfo kType = TypeInfo::Create<Noise>("Input_Noise");
|
|
|
|
static uint32_t xorshift(uint32_t x) noexcept {
|
|
x ^= x<<13;
|
|
x ^= x>>17;
|
|
x ^= x<<5;
|
|
return x;
|
|
}
|
|
|
|
Noise() noexcept : Data("random noise") {
|
|
}
|
|
|
|
void Update() noexcept override {
|
|
const auto id = std::to_string(index())+" Input_Noise | "+
|
|
std::to_string(reinterpret_cast<uintptr_t>(this));
|
|
|
|
if (ImGui::Begin(id.c_str())) {
|
|
ImGui::DragInt("src", &src_, 1, 0, 1024);
|
|
|
|
ImGui::DragInt("w", &w_, 1, 1, 1024);
|
|
ImGui::DragInt("h", &h_, 1, 1, 1024);
|
|
|
|
ImGui::DragFloat("level", &level_, 1e-4f, 0, 1);
|
|
ImGui::DragInt("seed", &seed_);
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
Frame Fetch(size_t n) noexcept override {
|
|
auto src = Input::instance().slots(static_cast<size_t>(src_));
|
|
if (!src) return {};
|
|
|
|
const auto w = static_cast<size_t>(w_);
|
|
const auto h = static_cast<size_t>(h_);
|
|
|
|
buf_.resize(w*h*4);
|
|
uint8_t* buf = buf_.data();
|
|
|
|
auto srcf = src->Fetch(n);
|
|
for (size_t y = 0; y < h; ++y) {
|
|
const auto yf = static_cast<float>(y)/static_cast<float>(h);
|
|
for (size_t x = 0; x < w; ++x) {
|
|
const auto xf = static_cast<float>(x)/static_cast<float>(w);
|
|
const auto srcx = static_cast<float>(srcf.w) * xf;
|
|
const auto srcy = static_cast<float>(srcf.h) * yf;
|
|
const auto srcxi = static_cast<size_t>(srcx);
|
|
const auto srcyi = static_cast<size_t>(srcy);
|
|
|
|
auto v = srcf.rgba + 4*(srcxi+srcyi*srcf.w);
|
|
for (size_t i = 0; i < 4; ++i) {
|
|
*(buf++) = TryAttack(n, x, y, i, *(v++));
|
|
}
|
|
}
|
|
}
|
|
return Frame { .w = w, .h = h, .rgba = buf_.data(), };
|
|
}
|
|
size_t frames() noexcept override {
|
|
auto src = Input::instance().slots(static_cast<size_t>(src_));
|
|
if(!src) return 0;
|
|
return src->frames();
|
|
}
|
|
|
|
uint8_t TryAttack(
|
|
size_t n, size_t x, size_t y, size_t i, uint8_t v) const noexcept {
|
|
if (i == 3) return v;
|
|
|
|
const auto s = static_cast<uint32_t>(seed_);
|
|
const auto seed = static_cast<uint32_t>(s*s*s*n + s*s*x + s*y + i);
|
|
|
|
const auto rand = xorshift(seed);
|
|
if (rand%100 < 50) {
|
|
const auto t = static_cast<float>(rand%100)/100.f*level_;
|
|
const auto a = static_cast<uint8_t>(t*UINT8_MAX);
|
|
return v+a;
|
|
} else {
|
|
return v;
|
|
}
|
|
}
|
|
|
|
private:
|
|
int src_ = 0;
|
|
int w_ = 100, h_ = 100;
|
|
float level_ = 0.01f;
|
|
int seed_ = 1234;
|
|
|
|
std::vector<uint8_t> buf_;
|
|
};
|
|
|
|
}
|
|
} // namespace pg
|