paysages : Terrain canvas - Added loading heightmap from picture file (currently hidden feature).
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@394 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
2d2535deae
commit
a4353f8a64
11 changed files with 182 additions and 50 deletions
|
@ -7,7 +7,7 @@ FormTerrainCanvas::FormTerrainCanvas(QWidget *parent, Layers* layers):
|
||||||
_definition = terrainCanvasCreate();
|
_definition = terrainCanvasCreate();
|
||||||
|
|
||||||
// TODO Area
|
// TODO Area
|
||||||
addInputDouble(tr("Apply at height"), &_definition->offset_z, -20.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Apply at height"), &_definition->offset_y, -20.0, 20.0, 0.1, 1.0);
|
||||||
addInputHeightMap(tr("Height map"), &_definition->height_map);
|
addInputHeightMap(tr("Height map"), &_definition->height_map);
|
||||||
addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0);
|
addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0);
|
||||||
addInputNoise(tr("Detail noise"), _definition->detail_noise);
|
addInputNoise(tr("Detail noise"), _definition->detail_noise);
|
||||||
|
|
|
@ -57,6 +57,54 @@ unsigned int colorTo32BitABGR(Color* col)
|
||||||
return (((unsigned int)(col->r * 255.0)) << 24) | (((unsigned int)(col->g * 255.0)) << 16) | (((unsigned int)(col->b * 255.0)) << 8) | ((unsigned int)(col->a * 255.0));
|
return (((unsigned int)(col->r * 255.0)) << 24) | (((unsigned int)(col->g * 255.0)) << 16) | (((unsigned int)(col->b * 255.0)) << 8) | ((unsigned int)(col->a * 255.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color colorFrom32BitRGBA(unsigned int col)
|
||||||
|
{
|
||||||
|
Color result;
|
||||||
|
|
||||||
|
result.r = ((double)(col & 0x000000FF)) / 255.0;
|
||||||
|
result.g = ((double)((col & 0x0000FF00) >> 8)) / 255.0;
|
||||||
|
result.b = ((double)((col & 0x00FF0000) >> 16)) / 255.0;
|
||||||
|
result.a = ((double)((col & 0xFF000000) >> 24)) / 255.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color colorFrom32BitBGRA(unsigned int col)
|
||||||
|
{
|
||||||
|
Color result;
|
||||||
|
|
||||||
|
result.b = ((double)(col & 0x000000FF)) / 255.0;
|
||||||
|
result.g = ((double)((col & 0x0000FF00) >> 8)) / 255.0;
|
||||||
|
result.r = ((double)((col & 0x00FF0000) >> 16)) / 255.0;
|
||||||
|
result.a = ((double)((col & 0xFF000000) >> 24)) / 255.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color colorFrom32BitARGB(unsigned int col)
|
||||||
|
{
|
||||||
|
Color result;
|
||||||
|
|
||||||
|
result.a = ((double)(col & 0x000000FF)) / 255.0;
|
||||||
|
result.r = ((double)((col & 0x0000FF00) >> 8)) / 255.0;
|
||||||
|
result.g = ((double)((col & 0x00FF0000) >> 16)) / 255.0;
|
||||||
|
result.b = ((double)((col & 0xFF000000) >> 24)) / 255.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color colorFrom32BitABGR(unsigned int col)
|
||||||
|
{
|
||||||
|
Color result;
|
||||||
|
|
||||||
|
result.a = ((double)(col & 0x000000FF)) / 255.0;
|
||||||
|
result.b = ((double)((col & 0x0000FF00) >> 8)) / 255.0;
|
||||||
|
result.g = ((double)((col & 0x00FF0000) >> 16)) / 255.0;
|
||||||
|
result.r = ((double)((col & 0xFF000000) >> 24)) / 255.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void colorMask(Color* base, Color* mask)
|
void colorMask(Color* base, Color* mask)
|
||||||
{
|
{
|
||||||
double new_a;
|
double new_a;
|
||||||
|
|
|
@ -32,6 +32,11 @@ unsigned int colorTo32BitBGRA(Color* col);
|
||||||
unsigned int colorTo32BitARGB(Color* col);
|
unsigned int colorTo32BitARGB(Color* col);
|
||||||
unsigned int colorTo32BitABGR(Color* col);
|
unsigned int colorTo32BitABGR(Color* col);
|
||||||
|
|
||||||
|
Color colorFrom32BitRGBA(unsigned int col);
|
||||||
|
Color colorFrom32BitBGRA(unsigned int col);
|
||||||
|
Color colorFrom32BitARGB(unsigned int col);
|
||||||
|
Color colorFrom32BitABGR(unsigned int col);
|
||||||
|
|
||||||
void colorMask(Color* base, Color* mask);
|
void colorMask(Color* base, Color* mask);
|
||||||
double colorNormalize(Color* col);
|
double colorNormalize(Color* col);
|
||||||
double colorGetValue(Color* col);
|
double colorGetValue(Color* col);
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include "heightmap.h"
|
#include "heightmap.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
HeightMap heightmapCreate()
|
HeightMap heightmapCreate()
|
||||||
{
|
{
|
||||||
|
@ -58,6 +60,19 @@ void heightmapLoad(PackStream* stream, HeightMap* heightmap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _loadFromFilePixel(HeightMap* heightmap, int x, int y, Color col)
|
||||||
|
{
|
||||||
|
assert(x >= 0 && x < heightmap->resolution_x);
|
||||||
|
assert(y >= 0 && y < heightmap->resolution_z);
|
||||||
|
|
||||||
|
heightmap->data[y * heightmap->resolution_x + x] = (col.r + col.g + col.b) / 3.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath)
|
||||||
|
{
|
||||||
|
systemLoadPictureFile(picturepath, (PictureCallbackLoadStarted)heightmapChangeResolution, (PictureCallbackLoadPixel)_loadFromFilePixel, heightmap);
|
||||||
|
}
|
||||||
|
|
||||||
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z)
|
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -32,6 +32,8 @@ void heightmapValidate(HeightMap* heightmap);
|
||||||
void heightmapSave(PackStream* stream, HeightMap* heightmap);
|
void heightmapSave(PackStream* stream, HeightMap* heightmap);
|
||||||
void heightmapLoad(PackStream* stream, HeightMap* heightmap);
|
void heightmapLoad(PackStream* stream, HeightMap* heightmap);
|
||||||
|
|
||||||
|
void heightmapImportFromPicture(HeightMap* heightmap, const char* picturepath);
|
||||||
|
|
||||||
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z);
|
void heightmapChangeResolution(HeightMap* heightmap, int resolution_x, int resolution_z);
|
||||||
double heightmapGetValue(HeightMap* heightmap, double x, double z);
|
double heightmapGetValue(HeightMap* heightmap, double x, double z);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "IL/il.h"
|
|
||||||
#include "IL/ilu.h"
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
|
|
||||||
#include "auto.h"
|
#include "auto.h"
|
||||||
|
@ -21,8 +18,6 @@ void paysagesInit()
|
||||||
CameraDefinition camera;
|
CameraDefinition camera;
|
||||||
|
|
||||||
systemInit();
|
systemInit();
|
||||||
ilInit();
|
|
||||||
iluInit();
|
|
||||||
|
|
||||||
sceneryInit();
|
sceneryInit();
|
||||||
renderInit();
|
renderInit();
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "IL/il.h"
|
|
||||||
#include "IL/ilu.h"
|
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
@ -725,39 +723,7 @@ void renderPostProcess(RenderArea* area, Renderer* renderer, int nbchunks)
|
||||||
|
|
||||||
int renderSaveToFile(RenderArea* area, const char* path)
|
int renderSaveToFile(RenderArea* area, const char* path)
|
||||||
{
|
{
|
||||||
ILuint image_id;
|
return systemSavePictureFile(path, (PictureCallbackSavePixel)_getFinalPixel, area, area->params.width, area->params.height);
|
||||||
ilGenImages(1, &image_id);
|
|
||||||
ilBindImage(image_id);
|
|
||||||
Color result;
|
|
||||||
ILuint x, y;
|
|
||||||
ILuint rgba;
|
|
||||||
ILuint data[area->params.height * area->params.width];
|
|
||||||
ILenum error;
|
|
||||||
int error_count;
|
|
||||||
|
|
||||||
for (y = 0; y < area->params.height; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < area->params.width; x++)
|
|
||||||
{
|
|
||||||
result = _getFinalPixel(area, x, y);
|
|
||||||
rgba = colorTo32BitRGBA(&result);
|
|
||||||
data[y * area->params.width + x] = rgba;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ilTexImage((ILuint)area->params.width, (ILuint)area->params.height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, data);
|
|
||||||
remove(path);
|
|
||||||
ilSaveImage(path);
|
|
||||||
|
|
||||||
ilDeleteImages(1, &image_id);
|
|
||||||
|
|
||||||
error_count = 0;
|
|
||||||
while ((error=ilGetError()) != IL_NO_ERROR)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "IL ERROR : %s\n", iluErrorString(error));
|
|
||||||
error_count++;
|
|
||||||
}
|
|
||||||
return !error_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
|
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "IL/il.h"
|
||||||
|
#include "IL/ilu.h"
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#define DEBUG_ONETHREAD 1
|
#define DEBUG_ONETHREAD 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,9 +49,90 @@ void systemInit()
|
||||||
{
|
{
|
||||||
g_thread_init(NULL);
|
g_thread_init(NULL);
|
||||||
_core_count = _getCoreCount();
|
_core_count = _getCoreCount();
|
||||||
|
ilInit();
|
||||||
|
iluInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
int systemGetCoreCount()
|
int systemGetCoreCount()
|
||||||
{
|
{
|
||||||
return _core_count;
|
return _core_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int systemSavePictureFile(const char* filepath, PictureCallbackSavePixel callback_pixel, void* data, int width, int height)
|
||||||
|
{
|
||||||
|
ILuint image_id;
|
||||||
|
Color result;
|
||||||
|
ILuint x, y;
|
||||||
|
ILuint rgba;
|
||||||
|
ILuint pixels[width * height];
|
||||||
|
ILenum error;
|
||||||
|
int error_count;
|
||||||
|
|
||||||
|
ilGenImages(1, &image_id);
|
||||||
|
ilBindImage(image_id);
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
result = callback_pixel(data, x, y);
|
||||||
|
rgba = colorTo32BitRGBA(&result);
|
||||||
|
pixels[y * width + x] = rgba;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ilTexImage((ILuint)width, (ILuint)height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
|
||||||
|
remove(filepath);
|
||||||
|
ilSaveImage(filepath);
|
||||||
|
|
||||||
|
ilDeleteImages(1, &image_id);
|
||||||
|
|
||||||
|
error_count = 0;
|
||||||
|
while ((error=ilGetError()) != IL_NO_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "IL ERROR : %s\n", iluErrorString(error));
|
||||||
|
error_count++;
|
||||||
|
}
|
||||||
|
return !error_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int systemLoadPictureFile(const char* filepath, PictureCallbackLoadStarted callback_start, PictureCallbackLoadPixel callback_pixel, void* data)
|
||||||
|
{
|
||||||
|
ILuint image_id;
|
||||||
|
ILenum error;
|
||||||
|
int error_count;
|
||||||
|
int width, height;
|
||||||
|
ILuint* pixels;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
ilGenImages(1, &image_id);
|
||||||
|
ilBindImage(image_id);
|
||||||
|
|
||||||
|
if (ilLoadImage(filepath))
|
||||||
|
{
|
||||||
|
width = ilGetInteger(IL_IMAGE_WIDTH);
|
||||||
|
height = ilGetInteger(IL_IMAGE_HEIGHT);
|
||||||
|
callback_start(data, width, height);
|
||||||
|
|
||||||
|
pixels = malloc(sizeof(ILuint) * width * height);
|
||||||
|
ilCopyPixels(0, 0, 0, width, height, 1, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
callback_pixel(data, x, y, colorFrom32BitRGBA(pixels[y * width + x]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
error_count = 0;
|
||||||
|
while ((error=ilGetError()) != IL_NO_ERROR)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "IL ERROR : %s\n", iluErrorString(error));
|
||||||
|
error_count++;
|
||||||
|
}
|
||||||
|
return !error_count;
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,25 @@
|
||||||
#ifndef _PAYSAGES_SYSTEM_H_
|
#ifndef _PAYSAGES_SYSTEM_H_
|
||||||
#define _PAYSAGES_SYSTEM_H_
|
#define _PAYSAGES_SYSTEM_H_
|
||||||
|
|
||||||
|
/* Library dependent features */
|
||||||
|
|
||||||
|
#include "color.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void* (*ThreadFunction)(void* data);
|
typedef void* (*ThreadFunction)(void* data);
|
||||||
|
typedef Color (*PictureCallbackSavePixel)(void* data, int x, int y);
|
||||||
|
typedef void (*PictureCallbackLoadStarted)(void* data, int width, int height);
|
||||||
|
typedef void (*PictureCallbackLoadPixel)(void* data, int x, int y, Color col);
|
||||||
|
|
||||||
void systemInit();
|
void systemInit();
|
||||||
int systemGetCoreCount();
|
int systemGetCoreCount();
|
||||||
|
|
||||||
|
int systemSavePictureFile(const char* filepath, PictureCallbackSavePixel callback_pixel, void* data, int width, int height);
|
||||||
|
int systemLoadPictureFile(const char* filepath, PictureCallbackLoadStarted callback_start, PictureCallbackLoadPixel callback_pixel, void* data);
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
#ifdef HAVE_GLIB
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
|
|
@ -12,16 +12,20 @@ TerrainCanvas* terrainCanvasCreate()
|
||||||
result->area.location_z = -40.0;
|
result->area.location_z = -40.0;
|
||||||
result->area.size_x = 80.0;
|
result->area.size_x = 80.0;
|
||||||
result->area.size_z = 80.0;
|
result->area.size_z = 80.0;
|
||||||
result->offset_z = 0.0;
|
result->offset_y = 0.0;
|
||||||
result->height_map = heightmapCreate();
|
result->height_map = heightmapCreate();
|
||||||
heightmapChangeResolution(&result->height_map, 256, 256);
|
heightmapChangeResolution(&result->height_map, 256, 256);
|
||||||
result->height_factor = 1.0;
|
result->height_factor = 1.0;
|
||||||
result->detail_noise = noiseCreateGenerator();
|
result->detail_noise = noiseCreateGenerator();
|
||||||
result->detail_height_factor = 0.1;
|
noiseAddLevelsSimple(result->detail_noise, 6, 1.0, 1.0);
|
||||||
result->detail_scaling = 1.0;
|
result->detail_height_factor = 0.002;
|
||||||
|
result->detail_scaling = 0.002;
|
||||||
result->mask.mode = INTEGRATIONMASK_MODE_CIRCLE;
|
result->mask.mode = INTEGRATIONMASK_MODE_CIRCLE;
|
||||||
result->mask.smoothing = 0.1;
|
result->mask.smoothing = 0.1;
|
||||||
|
|
||||||
|
/* DEBUG */
|
||||||
|
/*heightmapImportFromPicture(&result->height_map, "output/height.png");*/
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +39,7 @@ void terrainCanvasDelete(TerrainCanvas* canvas)
|
||||||
void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination)
|
void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination)
|
||||||
{
|
{
|
||||||
destination->area = source->area;
|
destination->area = source->area;
|
||||||
destination->offset_z = source->offset_z;
|
destination->offset_y = source->offset_y;
|
||||||
destination->height_factor = source->height_factor;
|
destination->height_factor = source->height_factor;
|
||||||
heightmapCopy(&source->height_map, &destination->height_map);
|
heightmapCopy(&source->height_map, &destination->height_map);
|
||||||
noiseCopy(source->detail_noise, destination->detail_noise);
|
noiseCopy(source->detail_noise, destination->detail_noise);
|
||||||
|
@ -75,7 +79,7 @@ void terrainCanvasSave(PackStream* stream, TerrainCanvas* canvas)
|
||||||
packWriteDouble(stream, &canvas->area.location_z);
|
packWriteDouble(stream, &canvas->area.location_z);
|
||||||
packWriteDouble(stream, &canvas->area.size_x);
|
packWriteDouble(stream, &canvas->area.size_x);
|
||||||
packWriteDouble(stream, &canvas->area.size_z);
|
packWriteDouble(stream, &canvas->area.size_z);
|
||||||
packWriteDouble(stream, &canvas->offset_z);
|
packWriteDouble(stream, &canvas->offset_y);
|
||||||
heightmapSave(stream, &canvas->height_map);
|
heightmapSave(stream, &canvas->height_map);
|
||||||
packWriteDouble(stream, &canvas->height_factor);
|
packWriteDouble(stream, &canvas->height_factor);
|
||||||
noiseSaveGenerator(stream, canvas->detail_noise);
|
noiseSaveGenerator(stream, canvas->detail_noise);
|
||||||
|
@ -92,7 +96,7 @@ void terrainCanvasLoad(PackStream* stream, TerrainCanvas* canvas)
|
||||||
packReadDouble(stream, &canvas->area.location_z);
|
packReadDouble(stream, &canvas->area.location_z);
|
||||||
packReadDouble(stream, &canvas->area.size_x);
|
packReadDouble(stream, &canvas->area.size_x);
|
||||||
packReadDouble(stream, &canvas->area.size_z);
|
packReadDouble(stream, &canvas->area.size_z);
|
||||||
packReadDouble(stream, &canvas->offset_z);
|
packReadDouble(stream, &canvas->offset_y);
|
||||||
heightmapLoad(stream, &canvas->height_map);
|
heightmapLoad(stream, &canvas->height_map);
|
||||||
packReadDouble(stream, &canvas->height_factor);
|
packReadDouble(stream, &canvas->height_factor);
|
||||||
noiseLoadGenerator(stream, canvas->detail_noise);
|
noiseLoadGenerator(stream, canvas->detail_noise);
|
||||||
|
@ -121,6 +125,9 @@ Vector3 terrainCanvasApply(TerrainCanvas* canvas, Vector3 location)
|
||||||
inside_z = (location.z - canvas->area.location_z) / canvas->area.size_z;
|
inside_z = (location.z - canvas->area.location_z) / canvas->area.size_z;
|
||||||
height = heightmapGetValue(&canvas->height_map, inside_x, inside_z);
|
height = heightmapGetValue(&canvas->height_map, inside_x, inside_z);
|
||||||
|
|
||||||
|
/* Apply factor */
|
||||||
|
height = height * canvas->height_factor + canvas->offset_y;
|
||||||
|
|
||||||
/* TODO Apply detail noise */
|
/* TODO Apply detail noise */
|
||||||
|
|
||||||
/* Apply integration mask */
|
/* Apply integration mask */
|
||||||
|
|
|
@ -34,7 +34,7 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GeoArea area;
|
GeoArea area;
|
||||||
double offset_z;
|
double offset_y;
|
||||||
HeightMap height_map;
|
HeightMap height_map;
|
||||||
double height_factor;
|
double height_factor;
|
||||||
NoiseGenerator* detail_noise;
|
NoiseGenerator* detail_noise;
|
||||||
|
|
Loading…
Reference in a new issue