Files
ObsidianDragon/src/util/noise_texture.cpp
DanS 3aee55b49c ObsidianDragon - DragonX ImGui Wallet
Full-node GUI wallet for DragonX cryptocurrency.
Built with Dear ImGui, SDL3, and OpenGL3/DX11.

Features:
- Send/receive shielded and transparent transactions
- Autoshield with merged transaction display
- Built-in CPU mining (xmrig)
- Peer management and network monitoring
- Wallet encryption with PIN lock
- QR code generation for receive addresses
- Transaction history with pagination
- Console for direct RPC commands
- Cross-platform (Linux, Windows)
2026-02-27 00:26:01 -06:00

169 lines
5.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#include "noise_texture.h"
#include "texture_loader.h"
#include <cstdlib>
#include <cstring>
namespace dragonx {
namespace util {
static constexpr int kNoiseSize = 256;
ImTextureID GetNoiseTexture(int* texSize)
{
static ImTextureID s_tex = 0;
static bool s_init = false;
if (texSize) *texSize = kNoiseSize;
if (s_init) return s_tex;
s_init = true;
// Generate subtle white-noise RGBA pixels.
// Each pixel is white (RGB=255) with alpha in a narrow band
// around 128 so the grain is uniform and gentle.
const int numPixels = kNoiseSize * kNoiseSize;
unsigned char* pixels = (unsigned char*)malloc(numPixels * 4);
if (!pixels) return 0;
// Simple LCG PRNG (deterministic, fast, no need for crypto quality)
unsigned int seed = 0xDEADBEEF;
for (int i = 0; i < numPixels; ++i) {
seed = seed * 1664525u + 1013904223u;
// Range: 16240 (centered on 128, ±112) for visible, high-contrast grain
unsigned char v = 16 + (unsigned char)((seed >> 24) % 225);
pixels[i * 4 + 0] = 255; // R
pixels[i * 4 + 1] = 255; // G
pixels[i * 4 + 2] = 255; // B
pixels[i * 4 + 3] = v; // A — high contrast variation
}
bool ok = CreateRawTexture(pixels, kNoiseSize, kNoiseSize,
true /* repeat/tile */, &s_tex);
free(pixels);
if (!ok) {
s_tex = 0;
}
return s_tex;
}
// ============================================================================
// Pre-tiled viewport-sized noise texture
// ============================================================================
// Generate the base 256x256 noise pattern into a caller-allocated buffer.
// Same deterministic LCG as GetNoiseTexture().
static void GenerateBaseNoise(unsigned char* out, int sz)
{
unsigned int seed = 0xDEADBEEF;
const int numPixels = sz * sz;
for (int i = 0; i < numPixels; ++i) {
seed = seed * 1664525u + 1013904223u;
unsigned char v = 16 + (unsigned char)((seed >> 24) % 225);
out[i * 4 + 0] = 255;
out[i * 4 + 1] = 255;
out[i * 4 + 2] = 255;
out[i * 4 + 3] = v;
}
}
ImTextureID GetTiledNoiseTexture(int viewportW, int viewportH,
int* outW, int* outH)
{
static ImTextureID s_tex = 0;
static int s_texW = 0;
static int s_texH = 0;
if (outW) *outW = s_texW;
if (outH) *outH = s_texH;
// Re-use if viewport hasn't changed
if (s_tex && s_texW == viewportW && s_texH == viewportH) {
return s_tex;
}
// Destroy old texture
if (s_tex) {
DestroyTexture(s_tex);
s_tex = 0;
s_texW = s_texH = 0;
}
if (viewportW <= 0 || viewportH <= 0) return 0;
// Generate base tile
unsigned char* base = (unsigned char*)malloc(kNoiseSize * kNoiseSize * 4);
if (!base) return 0;
GenerateBaseNoise(base, kNoiseSize);
// Allocate viewport-sized buffer and tile the base pattern
const size_t rowBytes = (size_t)viewportW * 4;
unsigned char* tiled = (unsigned char*)malloc(rowBytes * viewportH);
if (!tiled) { free(base); return 0; }
const int basePitch = kNoiseSize * 4;
for (int y = 0; y < viewportH; ++y) {
int sy = y % kNoiseSize;
unsigned char* dst = tiled + y * rowBytes;
const unsigned char* srcRow = base + sy * basePitch;
int x = 0;
// Copy full tile-width strips
while (x + kNoiseSize <= viewportW) {
memcpy(dst + x * 4, srcRow, basePitch);
x += kNoiseSize;
}
// Partial remaining strip
if (x < viewportW) {
memcpy(dst + x * 4, srcRow, (viewportW - x) * 4);
}
}
free(base);
bool ok = CreateRawTexture(tiled, viewportW, viewportH,
false /* no repeat needed */, &s_tex);
free(tiled);
if (ok) {
s_texW = viewportW;
s_texH = viewportH;
} else {
s_tex = 0;
}
if (outW) *outW = s_texW;
if (outH) *outH = s_texH;
return s_tex;
}
void DrawTiledNoiseRect(ImDrawList* dl, const ImVec2& pMin, const ImVec2& pMax,
ImU32 tintColor)
{
if (!dl || (tintColor & IM_COL32_A_MASK) == 0) return;
ImGuiViewport* vp = ImGui::GetMainViewport();
int vpW = (int)vp->Size.x;
int vpH = (int)vp->Size.y;
if (vpW <= 0 || vpH <= 0) return;
int texW = 0, texH = 0;
ImTextureID tex = GetTiledNoiseTexture(vpW, vpH, &texW, &texH);
if (!tex || texW <= 0 || texH <= 0) return;
// Compute UVs: map screen-space rect to texture coordinates.
// The tiled texture covers the entire viewport, so UV = screenPos / vpSize.
// Subtract viewport origin for multi-viewport support.
float u0 = (pMin.x - vp->Pos.x) / (float)texW;
float v0 = (pMin.y - vp->Pos.y) / (float)texH;
float u1 = (pMax.x - vp->Pos.x) / (float)texW;
float v1 = (pMax.y - vp->Pos.y) / (float)texH;
dl->AddImage(tex, pMin, pMax, ImVec2(u0, v0), ImVec2(u1, v1), tintColor);
}
} // namespace util
} // namespace dragonx