mam problem z funkcją rysowania ognia, a mianowicie do rozdzielczości 256x256 jest dobrze a jak np zwiększe na 512x256 to zamiast namalować szerszy to dubluje obraz w poziomie co jest źle z tym algorytmem, image to tło a pixels wynik wyjściowy:
void generate_fire_frame(unsigned char* image,unsigned char* &pixels, int width, int height)
{
// minimalne sprawdzenia
if (!pixels || width < 2 || height < 2) return;
// statyczne struktury by zachować stan między wywołaniami
static std::vector<uint8_t> heat;
static std::vector<uint8_t> palette; // 256 * 3
static std::mt19937 rng((unsigned)std::random_device{}());
static std::uniform_int_distribution<int> smallRand(0, 2);
static std::uniform_int_distribution<int> baseRand(160, 255);
// (re)alokacja przy zmianie rozmiaru
if ((int)heat.size() != width * height) {
heat.assign(width * height, 0);
}
if (palette.size() != 256 * 3) {
palette.resize(256 * 3);
// prosta paleta: black -> red -> yellow -> white
for (int i = 0; i < 256; ++i) {
float t = i / 255.0f;
uint8_t r, g, b;
if (t < 0.33f) {
// black -> red
float u = t / 0.33f;
r = (uint8_t)(u * 255.0f);
g = 0;
b = 0;
}
else if (t < 0.66f) {
// red -> yellow (increase green)
float u = (t - 0.33f) / 0.33f;
r = 255;
g = (uint8_t)(u * 255.0f);
b = 0;
}
else {
// yellow -> white (increase blue)
float u = (t - 0.66f) / (1.0f - 0.66f);
r = 255;
g = 255;
b = (uint8_t)(u * 255.0f);
}
palette[i * 3 + 0] = r;
palette[i * 3 + 1] = g;
palette[i * 3 + 2] = b;
}
}
// --- 1) Odśwież dolny wiersz (źródło ognia) ---
// Można modyfikować intensywność bazową
int bottom = (height - 1) * width;
for (int x = 0; x < width; ++x) {
// losujemy podstawową siłę płomienia w dolnym wierszu
heat[bottom + x] = (uint8_t)baseRand(rng);
}
// --- 2) Propagacja: rozprzestrzenianie w górę z lekkim rozpylaniem ---
// Dla każdego piksela od dna-1 do góry:
for (int y = height - 2; y >= 0; --y) {
int row = y * width;
int rowBelow = (y + 1) * width;
for (int x = 0; x < width; ++x) {
// weź wartość spodem i zastosuj decay (0..2)
int belowVal = heat[rowBelow + x];
int decay = smallRand(rng);
int v = belowVal - decay;
if (v < 0) v = 0;
// rozprosz (spread) - przesunięcie docelowe na boki
int shift = smallRand(rng) - 1; // -1,0,1
int dstX = x + shift;
if (dstX < 0) dstX = 0;
if (dstX >= width) dstX = width - 1;
heat[row + dstX] = (uint8_t)v;
}
}
// --- 3) Mapowanie heat -> RGB do bufora pixels ---
// pixels jest w porządku RGB, równe width*height*3
for (int i = 0; i < width * height; ++i) {
uint8_t h = heat[i];
float alpha = h / 255.0f;
int idx = i * 3;
unsigned char r = palette[h * 3 + 0];
unsigned char g = palette[h * 3 + 1];
unsigned char b = palette[h * 3 + 2];
// mieszanie ognia z tłem
pixels[idx + 2] = (unsigned char)(r * alpha + image[idx + 2] * (1 - alpha));
pixels[idx + 1] = (unsigned char)(g * alpha + image[idx + 1] * (1 - alpha));
pixels[idx + 0] = (unsigned char)(b * alpha + image[idx + 0] * (1 - alpha));
}
}



