From a4353f8a6471523ef33c12715369ad0312ae99b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 19 Jul 2012 15:04:27 +0000 Subject: [PATCH] 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 --- gui_qt/formterraincanvas.cpp | 2 +- lib_paysages/color.c | 48 +++++++++++++++++++++ lib_paysages/color.h | 5 +++ lib_paysages/heightmap.c | 15 +++++++ lib_paysages/heightmap.h | 2 + lib_paysages/main.c | 5 --- lib_paysages/render.c | 36 +--------------- lib_paysages/system.c | 84 ++++++++++++++++++++++++++++++++++++ lib_paysages/system.h | 12 +++++- lib_paysages/terraincanvas.c | 21 ++++++--- lib_paysages/terraincanvas.h | 2 +- 11 files changed, 182 insertions(+), 50 deletions(-) diff --git a/gui_qt/formterraincanvas.cpp b/gui_qt/formterraincanvas.cpp index c925f71..074bec0 100644 --- a/gui_qt/formterraincanvas.cpp +++ b/gui_qt/formterraincanvas.cpp @@ -7,7 +7,7 @@ FormTerrainCanvas::FormTerrainCanvas(QWidget *parent, Layers* layers): _definition = terrainCanvasCreate(); // 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); addInputDouble(tr("Canvas height"), &_definition->height_factor, 0.0, 20.0, 0.1, 1.0); addInputNoise(tr("Detail noise"), _definition->detail_noise); diff --git a/lib_paysages/color.c b/lib_paysages/color.c index a6fd8eb..34bc0f3 100644 --- a/lib_paysages/color.c +++ b/lib_paysages/color.c @@ -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)); } +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) { double new_a; diff --git a/lib_paysages/color.h b/lib_paysages/color.h index 9c38234..efda8b9 100644 --- a/lib_paysages/color.h +++ b/lib_paysages/color.h @@ -32,6 +32,11 @@ unsigned int colorTo32BitBGRA(Color* col); unsigned int colorTo32BitARGB(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); double colorNormalize(Color* col); double colorGetValue(Color* col); diff --git a/lib_paysages/heightmap.c b/lib_paysages/heightmap.c index 1b93922..ddad363 100644 --- a/lib_paysages/heightmap.c +++ b/lib_paysages/heightmap.c @@ -1,9 +1,11 @@ #include "heightmap.h" #include "tools.h" +#include "system.h" #include #include #include +#include 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) { int i; diff --git a/lib_paysages/heightmap.h b/lib_paysages/heightmap.h index e2cb222..16e58ba 100644 --- a/lib_paysages/heightmap.h +++ b/lib_paysages/heightmap.h @@ -32,6 +32,8 @@ void heightmapValidate(HeightMap* heightmap); void heightmapSave(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); double heightmapGetValue(HeightMap* heightmap, double x, double z); diff --git a/lib_paysages/main.c b/lib_paysages/main.c index 39eeb4a..f866962 100644 --- a/lib_paysages/main.c +++ b/lib_paysages/main.c @@ -1,9 +1,6 @@ #include #include -#include "IL/il.h" -#include "IL/ilu.h" - #include "shared/types.h" #include "auto.h" @@ -21,8 +18,6 @@ void paysagesInit() CameraDefinition camera; systemInit(); - ilInit(); - iluInit(); sceneryInit(); renderInit(); diff --git a/lib_paysages/render.c b/lib_paysages/render.c index 53fd2ae..b1d3414 100644 --- a/lib_paysages/render.c +++ b/lib_paysages/render.c @@ -3,8 +3,6 @@ #include #include #include -#include "IL/il.h" -#include "IL/ilu.h" #include "shared/types.h" #include "color.h" @@ -725,39 +723,7 @@ void renderPostProcess(RenderArea* area, Renderer* renderer, int nbchunks) int renderSaveToFile(RenderArea* area, const char* path) { - ILuint image_id; - 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; + return systemSavePictureFile(path, (PictureCallbackSavePixel)_getFinalPixel, area, area->params.width, area->params.height); } void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update) diff --git a/lib_paysages/system.c b/lib_paysages/system.c index 08fa8a9..a0202d5 100644 --- a/lib_paysages/system.c +++ b/lib_paysages/system.c @@ -1,6 +1,9 @@ #include "system.h" #include +#include "IL/il.h" +#include "IL/ilu.h" + #ifndef NDEBUG #define DEBUG_ONETHREAD 1 #endif @@ -46,9 +49,90 @@ void systemInit() { g_thread_init(NULL); _core_count = _getCoreCount(); + ilInit(); + iluInit(); } int systemGetCoreCount() { 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; +} diff --git a/lib_paysages/system.h b/lib_paysages/system.h index 8fee86b..eebf441 100644 --- a/lib_paysages/system.h +++ b/lib_paysages/system.h @@ -1,15 +1,25 @@ #ifndef _PAYSAGES_SYSTEM_H_ #define _PAYSAGES_SYSTEM_H_ +/* Library dependent features */ + +#include "color.h" + #ifdef __cplusplus extern "C" { #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(); 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 #include diff --git a/lib_paysages/terraincanvas.c b/lib_paysages/terraincanvas.c index 0f27bb2..5930841 100644 --- a/lib_paysages/terraincanvas.c +++ b/lib_paysages/terraincanvas.c @@ -12,16 +12,20 @@ TerrainCanvas* terrainCanvasCreate() result->area.location_z = -40.0; result->area.size_x = 80.0; result->area.size_z = 80.0; - result->offset_z = 0.0; + result->offset_y = 0.0; result->height_map = heightmapCreate(); heightmapChangeResolution(&result->height_map, 256, 256); result->height_factor = 1.0; result->detail_noise = noiseCreateGenerator(); - result->detail_height_factor = 0.1; - result->detail_scaling = 1.0; + noiseAddLevelsSimple(result->detail_noise, 6, 1.0, 1.0); + result->detail_height_factor = 0.002; + result->detail_scaling = 0.002; result->mask.mode = INTEGRATIONMASK_MODE_CIRCLE; result->mask.smoothing = 0.1; - + + /* DEBUG */ + /*heightmapImportFromPicture(&result->height_map, "output/height.png");*/ + return result; } @@ -35,7 +39,7 @@ void terrainCanvasDelete(TerrainCanvas* canvas) void terrainCanvasCopy(TerrainCanvas* source, TerrainCanvas* destination) { destination->area = source->area; - destination->offset_z = source->offset_z; + destination->offset_y = source->offset_y; destination->height_factor = source->height_factor; heightmapCopy(&source->height_map, &destination->height_map); 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.size_x); packWriteDouble(stream, &canvas->area.size_z); - packWriteDouble(stream, &canvas->offset_z); + packWriteDouble(stream, &canvas->offset_y); heightmapSave(stream, &canvas->height_map); packWriteDouble(stream, &canvas->height_factor); 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.size_x); packReadDouble(stream, &canvas->area.size_z); - packReadDouble(stream, &canvas->offset_z); + packReadDouble(stream, &canvas->offset_y); heightmapLoad(stream, &canvas->height_map); packReadDouble(stream, &canvas->height_factor); 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; height = heightmapGetValue(&canvas->height_map, inside_x, inside_z); + /* Apply factor */ + height = height * canvas->height_factor + canvas->offset_y; + /* TODO Apply detail noise */ /* Apply integration mask */ diff --git a/lib_paysages/terraincanvas.h b/lib_paysages/terraincanvas.h index 9d44d75..f180fc2 100644 --- a/lib_paysages/terraincanvas.h +++ b/lib_paysages/terraincanvas.h @@ -34,7 +34,7 @@ typedef struct typedef struct { GeoArea area; - double offset_z; + double offset_y; HeightMap height_map; double height_factor; NoiseGenerator* detail_noise;