push
This commit is contained in:
403
util/noise/noisegui.cpp
Normal file
403
util/noise/noisegui.cpp
Normal file
@@ -0,0 +1,403 @@
|
||||
// noisegui.cpp
|
||||
#include "pnoise.hpp"
|
||||
#include "../bmpwriter.hpp"
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
// Convert noise value to grayscale color
|
||||
Vec3 noiseToColor(double noiseValue) {
|
||||
float value = static_cast<float>(noiseValue);
|
||||
return Vec3(value, value, value);
|
||||
}
|
||||
|
||||
// Convert noise value to color using a blue-to-red colormap
|
||||
Vec3 noiseToHeatmap(double noiseValue) {
|
||||
float value = static_cast<float>(noiseValue);
|
||||
|
||||
if (value < 0.25f) {
|
||||
float t = value / 0.25f;
|
||||
return Vec3(0.0f, t, 1.0f);
|
||||
} else if (value < 0.5f) {
|
||||
float t = (value - 0.25f) / 0.25f;
|
||||
return Vec3(0.0f, 1.0f, 1.0f - t);
|
||||
} else if (value < 0.75f) {
|
||||
float t = (value - 0.5f) / 0.25f;
|
||||
return Vec3(t, 1.0f, 0.0f);
|
||||
} else {
|
||||
float t = (value - 0.75f) / 0.25f;
|
||||
return Vec3(1.0f, 1.0f - t, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert noise value to terrain-like colors
|
||||
Vec3 noiseToTerrain(double noiseValue) {
|
||||
float value = static_cast<float>(noiseValue);
|
||||
|
||||
if (value < 0.3f) {
|
||||
return Vec3(0.0f, 0.0f, 0.3f + value * 0.4f);
|
||||
} else if (value < 0.4f) {
|
||||
return Vec3(0.76f, 0.70f, 0.50f);
|
||||
} else if (value < 0.6f) {
|
||||
float t = (value - 0.4f) / 0.2f;
|
||||
return Vec3(0.0f, 0.4f + t * 0.3f, 0.0f);
|
||||
} else if (value < 0.8f) {
|
||||
return Vec3(0.0f, 0.3f, 0.0f);
|
||||
} else {
|
||||
float t = (value - 0.8f) / 0.2f;
|
||||
return Vec3(0.8f + t * 0.2f, 0.8f + t * 0.2f, 0.8f + t * 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
class NoiseTexture {
|
||||
private:
|
||||
GLuint textureID;
|
||||
int width, height;
|
||||
std::vector<unsigned char> pixelData;
|
||||
|
||||
public:
|
||||
NoiseTexture(int w, int h) : width(w), height(h) {
|
||||
pixelData.resize(width * height * 3);
|
||||
glGenTextures(1, &textureID);
|
||||
updateTexture();
|
||||
}
|
||||
|
||||
~NoiseTexture() {
|
||||
glDeleteTextures(1, &textureID);
|
||||
}
|
||||
|
||||
void generateNoise(const PerlinNoise& pn, double scale, int octaves,
|
||||
const std::string& noiseType, const std::string& colorMap) {
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = 0.0;
|
||||
|
||||
if (noiseType == "Basic") {
|
||||
noise = pn.noise(x * scale, y * scale);
|
||||
} else if (noiseType == "FBM") {
|
||||
noise = pn.fractal(octaves, x * scale, y * scale);
|
||||
} else if (noiseType == "Turbulence") {
|
||||
noise = pn.turbulence(octaves, x * scale, y * scale);
|
||||
} else if (noiseType == "Ridged") {
|
||||
noise = pn.ridgedMultiFractal(octaves, x * scale, y * scale, 0.0, 2.0, 0.5, 1.0);
|
||||
}
|
||||
|
||||
Vec3 color;
|
||||
if (colorMap == "Grayscale") {
|
||||
color = noiseToColor(noise);
|
||||
} else if (colorMap == "Heatmap") {
|
||||
color = noiseToHeatmap(noise);
|
||||
} else if (colorMap == "Terrain") {
|
||||
color = noiseToTerrain(noise);
|
||||
}
|
||||
|
||||
int index = (y * width + x) * 3;
|
||||
pixelData[index] = static_cast<unsigned char>(color.x * 255);
|
||||
pixelData[index + 1] = static_cast<unsigned char>(color.y * 255);
|
||||
pixelData[index + 2] = static_cast<unsigned char>(color.z * 255);
|
||||
}
|
||||
}
|
||||
updateTexture();
|
||||
}
|
||||
|
||||
void updateTexture() {
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData.data());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
void draw(const char* label, const ImVec2& size) {
|
||||
ImGui::Image((void*)(intptr_t)textureID, size);
|
||||
ImGui::Text("%s", label);
|
||||
}
|
||||
|
||||
GLuint getTextureID() const { return textureID; }
|
||||
};
|
||||
|
||||
class NoiseComparisonApp {
|
||||
private:
|
||||
GLFWwindow* window;
|
||||
int windowWidth, windowHeight;
|
||||
|
||||
// Noise parameters
|
||||
double scale;
|
||||
int octaves;
|
||||
unsigned int seed;
|
||||
std::string noiseType;
|
||||
std::string colorMap;
|
||||
|
||||
// Comparison views
|
||||
struct ComparisonView {
|
||||
std::unique_ptr<NoiseTexture> texture;
|
||||
double scale;
|
||||
int octaves;
|
||||
unsigned int seed;
|
||||
std::string noiseType;
|
||||
std::string colorMap;
|
||||
std::string label;
|
||||
};
|
||||
|
||||
std::vector<ComparisonView> views;
|
||||
int textureSize;
|
||||
|
||||
// Preset management
|
||||
struct Preset {
|
||||
std::string name;
|
||||
double scale;
|
||||
int octaves;
|
||||
std::string noiseType;
|
||||
std::string colorMap;
|
||||
};
|
||||
|
||||
std::vector<Preset> presets;
|
||||
int selectedPreset;
|
||||
|
||||
public:
|
||||
NoiseComparisonApp() : windowWidth(1400), windowHeight(900), scale(0.01), octaves(4),
|
||||
seed(42), noiseType("FBM"), colorMap("Grayscale"), textureSize(256) {
|
||||
initializePresets();
|
||||
}
|
||||
|
||||
bool initialize() {
|
||||
if (!glfwInit()) return false;
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
|
||||
window = glfwCreateWindow(windowWidth, windowHeight, "Perlin Noise Comparison Tool", NULL, NULL);
|
||||
if (!window) {
|
||||
glfwTerminate();
|
||||
return false;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init("#version 130");
|
||||
|
||||
// Initialize with some default views
|
||||
addComparisonView("FBM", "Grayscale", 0.01, 4, 42, "FBM Grayscale");
|
||||
addComparisonView("FBM", "Heatmap", 0.01, 4, 42, "FBM Heatmap");
|
||||
addComparisonView("FBM", "Terrain", 0.01, 4, 42, "FBM Terrain");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void initializePresets() {
|
||||
presets = {
|
||||
{"Basic Grayscale", 0.01, 1, "Basic", "Grayscale"},
|
||||
{"FBM Grayscale", 0.01, 4, "FBM", "Grayscale"},
|
||||
{"FBM Terrain", 0.01, 4, "FBM", "Terrain"},
|
||||
{"Turbulence", 0.01, 4, "Turbulence", "Grayscale"},
|
||||
{"Ridged Multi", 0.01, 4, "Ridged", "Grayscale"},
|
||||
{"Large Scale", 0.002, 4, "FBM", "Grayscale"},
|
||||
{"Small Scale", 0.05, 4, "FBM", "Grayscale"},
|
||||
{"High Octaves", 0.01, 8, "FBM", "Grayscale"}
|
||||
};
|
||||
selectedPreset = 0;
|
||||
}
|
||||
|
||||
void addComparisonView(const std::string& type, const std::string& cmap,
|
||||
double sc, int oct, unsigned int sd, const std::string& lbl) {
|
||||
ComparisonView view;
|
||||
view.texture = std::make_unique<NoiseTexture>(textureSize, textureSize);
|
||||
view.scale = sc;
|
||||
view.octaves = oct;
|
||||
view.seed = sd;
|
||||
view.noiseType = type;
|
||||
view.colorMap = cmap;
|
||||
view.label = lbl;
|
||||
|
||||
PerlinNoise pn(view.seed);
|
||||
view.texture->generateNoise(pn, view.scale, view.octaves, view.noiseType, view.colorMap);
|
||||
|
||||
views.push_back(std::move(view));
|
||||
}
|
||||
|
||||
void run() {
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwPollEvents();
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
renderUI();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
}
|
||||
|
||||
void renderUI() {
|
||||
// Main control panel
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||
ImGui::SetNextWindowSize(ImVec2(300, windowHeight));
|
||||
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
|
||||
|
||||
ImGui::Text("Noise Parameters");
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::SliderDouble("Scale", &scale, 0.001, 0.1, "%.3f");
|
||||
ImGui::SliderInt("Octaves", &octaves, 1, 8);
|
||||
ImGui::InputInt("Seed", (int*)&seed);
|
||||
|
||||
const char* noiseTypes[] = {"Basic", "FBM", "Turbulence", "Ridged"};
|
||||
ImGui::Combo("Noise Type", [](void* data, int idx, const char** out_text) {
|
||||
*out_text = noiseTypes[idx];
|
||||
return true;
|
||||
}, nullptr, IM_ARRAYSIZE(noiseTypes));
|
||||
noiseType = noiseTypes[ImGui::GetStateStorage()->GetInt(ImGui::GetID("Noise Type"), 0)];
|
||||
|
||||
const char* colorMaps[] = {"Grayscale", "Heatmap", "Terrain"};
|
||||
ImGui::Combo("Color Map", [](void* data, int idx, const char** out_text) {
|
||||
*out_text = colorMaps[idx];
|
||||
return true;
|
||||
}, nullptr, IM_ARRAYSIZE(colorMaps));
|
||||
colorMap = colorMaps[ImGui::GetStateStorage()->GetInt(ImGui::GetID("Color Map"), 0)];
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Texture Size: %d", textureSize);
|
||||
ImGui::SliderInt("##TexSize", &textureSize, 64, 512);
|
||||
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Generate Current")) {
|
||||
std::string label = noiseType + " " + colorMap;
|
||||
addComparisonView(noiseType, colorMap, scale, octaves, seed, label);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Clear All")) {
|
||||
views.clear();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Presets");
|
||||
|
||||
std::vector<const char*> presetNames;
|
||||
for (const auto& preset : presets) {
|
||||
presetNames.push_back(preset.name.c_str());
|
||||
}
|
||||
|
||||
ImGui::Combo("##Presets", &selectedPreset, presetNames.data(), presetNames.size());
|
||||
|
||||
if (ImGui::Button("Add Preset")) {
|
||||
if (selectedPreset >= 0 && selectedPreset < presets.size()) {
|
||||
const auto& preset = presets[selectedPreset];
|
||||
addComparisonView(preset.noiseType, preset.colorMap,
|
||||
preset.scale, preset.octaves, seed, preset.name);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Add All Presets")) {
|
||||
for (const auto& preset : presets) {
|
||||
addComparisonView(preset.noiseType, preset.colorMap,
|
||||
preset.scale, preset.octaves, seed, preset.name);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Quick Comparisons");
|
||||
|
||||
if (ImGui::Button("Scale Comparison")) {
|
||||
std::vector<double> scales = {0.002, 0.005, 0.01, 0.02, 0.05};
|
||||
for (double sc : scales) {
|
||||
std::string label = "Scale " + std::to_string(sc);
|
||||
addComparisonView("FBM", "Grayscale", sc, 4, seed, label);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Octave Comparison")) {
|
||||
for (int oct = 1; oct <= 6; ++oct) {
|
||||
std::string label = oct + " Octaves";
|
||||
addComparisonView("FBM", "Grayscale", 0.01, oct, seed, label);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
// Main view area
|
||||
ImGui::SetNextWindowPos(ImVec2(300, 0));
|
||||
ImGui::SetNextWindowSize(ImVec2(windowWidth - 300, windowHeight));
|
||||
ImGui::Begin("Noise Comparison", nullptr,
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
|
||||
ImVec2 imageSize(textureSize, textureSize);
|
||||
int itemsPerRow = std::max(1, (int)((windowWidth - 320) / (textureSize + 20)));
|
||||
|
||||
for (size_t i = 0; i < views.size(); ++i) {
|
||||
auto& view = views[i];
|
||||
|
||||
if (i % itemsPerRow != 0) ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
view.texture->draw(view.label.c_str(), imageSize);
|
||||
|
||||
// Mini controls for each view
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
if (ImGui::SmallButton("Regenerate")) {
|
||||
PerlinNoise pn(view.seed);
|
||||
view.texture->generateNoise(pn, view.scale, view.octaves, view.noiseType, view.colorMap);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Remove")) {
|
||||
views.erase(views.begin() + i);
|
||||
ImGui::PopID();
|
||||
break;
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
~NoiseComparisonApp() {
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
NoiseComparisonApp app;
|
||||
|
||||
if (!app.initialize()) {
|
||||
std::cerr << "Failed to initialize application!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
app.run();
|
||||
return 0;
|
||||
}
|
||||
306
util/noise/noisetest.cpp
Normal file
306
util/noise/noisetest.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
// noisetest.cpp
|
||||
#include "pnoise.hpp"
|
||||
#include "../bmpwriter.hpp"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
// Convert noise value to grayscale color
|
||||
Vec3 noiseToColor(double noiseValue) {
|
||||
float value = static_cast<float>(noiseValue);
|
||||
return Vec3(value, value, value);
|
||||
}
|
||||
|
||||
// Convert noise value to color using a blue-to-red colormap
|
||||
Vec3 noiseToHeatmap(double noiseValue) {
|
||||
// Blue (0.0) -> Cyan -> Green -> Yellow -> Red (1.0)
|
||||
float value = static_cast<float>(noiseValue);
|
||||
|
||||
if (value < 0.25f) {
|
||||
// Blue to Cyan
|
||||
float t = value / 0.25f;
|
||||
return Vec3(0.0f, t, 1.0f);
|
||||
} else if (value < 0.5f) {
|
||||
// Cyan to Green
|
||||
float t = (value - 0.25f) / 0.25f;
|
||||
return Vec3(0.0f, 1.0f, 1.0f - t);
|
||||
} else if (value < 0.75f) {
|
||||
// Green to Yellow
|
||||
float t = (value - 0.5f) / 0.25f;
|
||||
return Vec3(t, 1.0f, 0.0f);
|
||||
} else {
|
||||
// Yellow to Red
|
||||
float t = (value - 0.75f) / 0.25f;
|
||||
return Vec3(1.0f, 1.0f - t, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert noise value to terrain-like colors
|
||||
Vec3 noiseToTerrain(double noiseValue) {
|
||||
float value = static_cast<float>(noiseValue);
|
||||
|
||||
if (value < 0.3f) {
|
||||
// Deep water to shallow water
|
||||
return Vec3(0.0f, 0.0f, 0.3f + value * 0.4f);
|
||||
} else if (value < 0.4f) {
|
||||
// Sand
|
||||
return Vec3(0.76f, 0.70f, 0.50f);
|
||||
} else if (value < 0.6f) {
|
||||
// Grass
|
||||
float t = (value - 0.4f) / 0.2f;
|
||||
return Vec3(0.0f, 0.4f + t * 0.3f, 0.0f);
|
||||
} else if (value < 0.8f) {
|
||||
// Forest
|
||||
return Vec3(0.0f, 0.3f, 0.0f);
|
||||
} else {
|
||||
// Mountain to snow
|
||||
float t = (value - 0.8f) / 0.2f;
|
||||
return Vec3(0.8f + t * 0.2f, 0.8f + t * 0.2f, 0.8f + t * 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate basic 2D noise map
|
||||
void generateBasicNoise(const std::string& filename, int width, int height,
|
||||
double scale = 0.01, unsigned int seed = 42) {
|
||||
std::cout << "Generating basic noise: " << filename << std::endl;
|
||||
|
||||
PerlinNoise pn(seed);
|
||||
std::vector<std::vector<Vec3>> pixels(height, std::vector<Vec3>(width));
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.noise(x * scale, y * scale);
|
||||
pixels[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
|
||||
BMPWriter::saveBMP(filename, pixels);
|
||||
}
|
||||
|
||||
// Generate fractal Brownian motion noise
|
||||
void generateFBMNoise(const std::string& filename, int width, int height,
|
||||
size_t octaves, double scale = 0.01, unsigned int seed = 42) {
|
||||
std::cout << "Generating FBM noise (" << octaves << " octaves): " << filename << std::endl;
|
||||
|
||||
PerlinNoise pn(seed);
|
||||
std::vector<std::vector<Vec3>> pixels(height, std::vector<Vec3>(width));
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.fractal(octaves, x * scale, y * scale);
|
||||
pixels[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
|
||||
BMPWriter::saveBMP(filename, pixels);
|
||||
}
|
||||
|
||||
// Generate turbulence noise
|
||||
void generateTurbulenceNoise(const std::string& filename, int width, int height,
|
||||
size_t octaves, double scale = 0.01, unsigned int seed = 42) {
|
||||
std::cout << "Generating turbulence noise (" << octaves << " octaves): " << filename << std::endl;
|
||||
|
||||
PerlinNoise pn(seed);
|
||||
std::vector<std::vector<Vec3>> pixels(height, std::vector<Vec3>(width));
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.turbulence(octaves, x * scale, y * scale);
|
||||
pixels[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
|
||||
BMPWriter::saveBMP(filename, pixels);
|
||||
}
|
||||
|
||||
// Generate ridged multi-fractal noise
|
||||
void generateRidgedNoise(const std::string& filename, int width, int height,
|
||||
size_t octaves, double scale = 0.01, unsigned int seed = 42,
|
||||
double lacunarity = 2.0, double gain = 0.5, double offset = 1.0) {
|
||||
std::cout << "Generating ridged multi-fractal noise (" << octaves << " octaves): " << filename << std::endl;
|
||||
|
||||
PerlinNoise pn(seed);
|
||||
std::vector<std::vector<Vec3>> pixels(height, std::vector<Vec3>(width));
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.ridgedMultiFractal(octaves, x * scale, y * scale,
|
||||
0.0, lacunarity, gain, offset);
|
||||
pixels[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
|
||||
BMPWriter::saveBMP(filename, pixels);
|
||||
}
|
||||
|
||||
// Generate noise with different color mappings
|
||||
void generateColoredNoise(const std::string& filename, int width, int height,
|
||||
double scale = 0.01, unsigned int seed = 42,
|
||||
const std::string& colorMap = "heatmap") {
|
||||
std::cout << "Generating colored noise (" << colorMap << "): " << filename << std::endl;
|
||||
|
||||
PerlinNoise pn(seed);
|
||||
std::vector<std::vector<Vec3>> pixels(height, std::vector<Vec3>(width));
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.noise(x * scale, y * scale);
|
||||
|
||||
if (colorMap == "heatmap") {
|
||||
pixels[y][x] = noiseToHeatmap(noise);
|
||||
} else if (colorMap == "terrain") {
|
||||
pixels[y][x] = noiseToTerrain(noise);
|
||||
} else {
|
||||
pixels[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMPWriter::saveBMP(filename, pixels);
|
||||
}
|
||||
|
||||
// Generate multi-octave comparison
|
||||
void generateOctaveComparison(const std::string& baseFilename, int width, int height,
|
||||
double scale = 0.01, unsigned int seed = 42) {
|
||||
for (size_t octaves = 1; octaves <= 6; ++octaves) {
|
||||
std::string filename = baseFilename + "_octaves_" + std::to_string(octaves) + ".bmp";
|
||||
generateFBMNoise(filename, width, height, octaves, scale, seed);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate scale comparison
|
||||
void generateScaleComparison(const std::string& baseFilename, int width, int height,
|
||||
unsigned int seed = 42) {
|
||||
std::vector<double> scales = {0.002, 0.005, 0.01, 0.02, 0.05, 0.1};
|
||||
|
||||
for (double scale : scales) {
|
||||
std::string filename = baseFilename + "_scale_" + std::to_string(scale) + ".bmp";
|
||||
generateBasicNoise(filename, width, height, scale, seed);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate seed comparison
|
||||
void generateSeedComparison(const std::string& baseFilename, int width, int height,
|
||||
double scale = 0.01) {
|
||||
std::vector<unsigned int> seeds = {42, 123, 456, 789, 1000};
|
||||
|
||||
for (unsigned int seed : seeds) {
|
||||
std::string filename = baseFilename + "_seed_" + std::to_string(seed) + ".bmp";
|
||||
generateBasicNoise(filename, width, height, scale, seed);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate combined effects (FBM with different color maps)
|
||||
void generateCombinedEffects(const std::string& baseFilename, int width, int height,
|
||||
double scale = 0.01, unsigned int seed = 42) {
|
||||
PerlinNoise pn(seed);
|
||||
|
||||
// FBM with grayscale
|
||||
std::vector<std::vector<Vec3>> pixels1(height, std::vector<Vec3>(width));
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.fractal(4, x * scale, y * scale);
|
||||
pixels1[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
BMPWriter::saveBMP(baseFilename + "_fbm_grayscale.bmp", pixels1);
|
||||
|
||||
// FBM with heatmap
|
||||
std::vector<std::vector<Vec3>> pixels2(height, std::vector<Vec3>(width));
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.fractal(4, x * scale, y * scale);
|
||||
pixels2[y][x] = noiseToHeatmap(noise);
|
||||
}
|
||||
}
|
||||
BMPWriter::saveBMP(baseFilename + "_fbm_heatmap.bmp", pixels2);
|
||||
|
||||
// FBM with terrain
|
||||
std::vector<std::vector<Vec3>> pixels3(height, std::vector<Vec3>(width));
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.fractal(4, x * scale, y * scale);
|
||||
pixels3[y][x] = noiseToTerrain(noise);
|
||||
}
|
||||
}
|
||||
BMPWriter::saveBMP(baseFilename + "_fbm_terrain.bmp", pixels3);
|
||||
}
|
||||
|
||||
// Generate 3D slice noise (showing different Z slices)
|
||||
void generate3DSlices(const std::string& baseFilename, int width, int height,
|
||||
double scale = 0.01, unsigned int seed = 42) {
|
||||
PerlinNoise pn(seed);
|
||||
|
||||
std::vector<double> zSlices = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0};
|
||||
|
||||
for (size_t i = 0; i < zSlices.size(); ++i) {
|
||||
std::vector<std::vector<Vec3>> pixels(height, std::vector<Vec3>(width));
|
||||
double z = zSlices[i] * 10.0; // Scale Z for meaningful variation
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
double noise = pn.noise(x * scale, y * scale, z);
|
||||
pixels[y][x] = noiseToColor(noise);
|
||||
}
|
||||
}
|
||||
|
||||
std::string filename = baseFilename + "_zslice_" + std::to_string(i) + ".bmp";
|
||||
BMPWriter::saveBMP(filename, pixels);
|
||||
std::cout << "Generated 3D slice " << i << ": " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
const int WIDTH = 512;
|
||||
const int HEIGHT = 512;
|
||||
|
||||
std::cout << "Generating Perlin noise variations..." << std::endl;
|
||||
std::cout << "=====================================" << std::endl;
|
||||
|
||||
// 1. Basic noise variations
|
||||
std::cout << "\n1. Basic Noise Variations:" << std::endl;
|
||||
generateBasicNoise("output/basic_noise.bmp", WIDTH, HEIGHT, 0.01, 42);
|
||||
|
||||
// 2. Fractal Brownian Motion with different octaves
|
||||
std::cout << "\n2. FBM Noise (Multiple Octaves):" << std::endl;
|
||||
generateOctaveComparison("output/fbm", WIDTH, HEIGHT, 0.01, 42);
|
||||
|
||||
// 3. Turbulence noise
|
||||
std::cout << "\n3. Turbulence Noise:" << std::endl;
|
||||
generateTurbulenceNoise("output/turbulence_4oct.bmp", WIDTH, HEIGHT, 4, 0.01, 42);
|
||||
generateTurbulenceNoise("output/turbulence_6oct.bmp", WIDTH, HEIGHT, 6, 0.01, 42);
|
||||
|
||||
// 4. Ridged multi-fractal noise
|
||||
std::cout << "\n4. Ridged Multi-Fractal Noise:" << std::endl;
|
||||
generateRidgedNoise("output/ridged_4oct.bmp", WIDTH, HEIGHT, 4, 0.01, 42, 2.0, 0.5, 1.0);
|
||||
generateRidgedNoise("output/ridged_6oct.bmp", WIDTH, HEIGHT, 6, 0.01, 42, 2.0, 0.5, 1.0);
|
||||
|
||||
// 5. Different color mappings
|
||||
std::cout << "\n5. Color Mappings:" << std::endl;
|
||||
generateColoredNoise("output/heatmap_noise.bmp", WIDTH, HEIGHT, 0.01, 42, "heatmap");
|
||||
generateColoredNoise("output/terrain_noise.bmp", WIDTH, HEIGHT, 0.01, 42, "terrain");
|
||||
|
||||
// 6. Scale variations
|
||||
std::cout << "\n6. Scale Variations:" << std::endl;
|
||||
generateScaleComparison("output/scale_test", WIDTH, HEIGHT, 42);
|
||||
|
||||
// 7. Seed variations
|
||||
std::cout << "\n7. Seed Variations:" << std::endl;
|
||||
generateSeedComparison("output/seed_test", WIDTH, HEIGHT, 0.01);
|
||||
|
||||
// 8. Combined effects
|
||||
std::cout << "\n8. Combined Effects:" << std::endl;
|
||||
generateCombinedEffects("output/combined", WIDTH, HEIGHT, 0.01, 42);
|
||||
|
||||
// 9. 3D slices
|
||||
std::cout << "\n9. 3D Slices:" << std::endl;
|
||||
generate3DSlices("output/3d_slice", WIDTH, HEIGHT, 0.01, 42);
|
||||
|
||||
std::cout << "\n=====================================" << std::endl;
|
||||
std::cout << "All noise maps generated successfully!" << std::endl;
|
||||
std::cout << "Check the 'output' directory for BMP files." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user