mirror of https://github.com/OpenRCT2/OpenRCT2.git
Add support for loading PNG files
This needs to be refactored
This commit is contained in:
parent
8548f60453
commit
0d07ea69f8
|
@ -220,7 +220,7 @@ rct_window *window_loadsave_open(sint32 type, char *defaultName)
|
||||||
openrct2_assert(isSave == false, "Cannot save images through loadsave window");
|
openrct2_assert(isSave == false, "Cannot save images through loadsave window");
|
||||||
w->widgets[WIDX_TITLE].text = STR_FILE_DIALOG_TITLE_LOAD_HEIGHTMAP;
|
w->widgets[WIDX_TITLE].text = STR_FILE_DIALOG_TITLE_LOAD_HEIGHTMAP;
|
||||||
if (window_loadsave_get_dir(gConfigGeneral.last_save_track_directory, path, "", sizeof(path))) {
|
if (window_loadsave_get_dir(gConfigGeneral.last_save_track_directory, path, "", sizeof(path))) {
|
||||||
window_loadsave_populate_list(w, false, path, ".bmp");
|
window_loadsave_populate_list(w, false, path, ".bmp;.png");
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
|
#include "../Imaging.h"
|
||||||
#include "../core/Guard.hpp"
|
#include "../core/Guard.hpp"
|
||||||
#include "../object.h"
|
#include "../object.h"
|
||||||
#include "../util/util.h"
|
#include "../util/util.h"
|
||||||
|
@ -771,28 +772,20 @@ static void mapgen_simplex(mapgen_settings *settings)
|
||||||
/**
|
/**
|
||||||
* Applies box blur to the surface N times
|
* Applies box blur to the surface N times
|
||||||
*/
|
*/
|
||||||
void mapgen_smooth_heightmap(SDL_Surface *surface, sint32 strength)
|
void mapgen_smooth_heightmap(uint8 *pixels, const sint32 width, const sint32 height, const sint32 numChannels, const size_t pitch, sint32 strength)
|
||||||
{
|
{
|
||||||
SDL_LockSurface(surface);
|
|
||||||
|
|
||||||
const sint32 width = surface->w;
|
|
||||||
const sint32 height = surface->h;
|
|
||||||
const sint32 numChannels = surface->format->BytesPerPixel;
|
|
||||||
const size_t pitch = surface->pitch;
|
|
||||||
|
|
||||||
// Create buffer to store one channel
|
// Create buffer to store one channel
|
||||||
uint8 *dest = (uint8*)malloc(width * height);
|
uint8 *dest = (uint8*)malloc(width * height);
|
||||||
uint8 *src = surface->pixels;
|
|
||||||
|
|
||||||
// Overwrite the red channel with the average of the RGB channels
|
// Overwrite the red channel with the average of the RGB channels
|
||||||
for (sint32 y = 0; y < height; y++)
|
for (sint32 y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (sint32 x = 0; x < width; x++)
|
for (sint32 x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
const uint8 red = src[x * numChannels + y * pitch];
|
const uint8 red = pixels[x * numChannels + y * pitch];
|
||||||
const uint8 green = src[x * numChannels + y * pitch + 1];
|
const uint8 green = pixels[x * numChannels + y * pitch + 1];
|
||||||
const uint8 blue = src[x * numChannels + y * pitch + 2];
|
const uint8 blue = pixels[x * numChannels + y * pitch + 2];
|
||||||
src[x * numChannels + y * pitch] = (red + green + blue) / 3;
|
pixels[x * numChannels + y * pitch] = (red + green + blue) / 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,7 +807,7 @@ void mapgen_smooth_heightmap(SDL_Surface *surface, sint32 strength)
|
||||||
// This assumes the height map is not tiled, and increases the weight of the edges
|
// This assumes the height map is not tiled, and increases the weight of the edges
|
||||||
const sint32 readX = clamp(x + offsetX, 0, width - 1);
|
const sint32 readX = clamp(x + offsetX, 0, width - 1);
|
||||||
const sint32 readY = clamp(y + offsetY, 0, height - 1);
|
const sint32 readY = clamp(y + offsetY, 0, height - 1);
|
||||||
heightSum += src[readX * numChannels + readY * pitch];
|
heightSum += pixels[readX * numChannels + readY * pitch];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,30 +821,61 @@ void mapgen_smooth_heightmap(SDL_Surface *surface, sint32 strength)
|
||||||
{
|
{
|
||||||
for (sint32 x = 0; x < width; x++)
|
for (sint32 x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
src[x * numChannels + y * pitch] = dest[x + y * width];
|
pixels[x * numChannels + y * pitch] = dest[x + y * width];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dest);
|
free(dest);
|
||||||
SDL_UnlockSurface(surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||||
{
|
{
|
||||||
openrct2_assert(settings->simplex_high != settings->simplex_low, "Low and high setting cannot be the same");
|
openrct2_assert(settings->simplex_high != settings->simplex_low, "Low and high setting cannot be the same");
|
||||||
|
|
||||||
SDL_Surface *bitmap = SDL_LoadBMP(heightmap_path);
|
// TODO: Move all loading to a callback
|
||||||
if (bitmap == NULL)
|
const char* extension = path_get_extension(heightmap_path);
|
||||||
{
|
sint32 width;
|
||||||
printf("Failed to load bitmap: %s\n", SDL_GetError());
|
sint32 height;
|
||||||
|
uint8 numChannels;
|
||||||
|
uint8 *pixels;
|
||||||
|
size_t pitch;
|
||||||
|
|
||||||
|
if (strcicmp(extension, ".png") == 0) {
|
||||||
|
uint32 w, h;
|
||||||
|
if (!image_io_png_read(&pixels, &w, &h, heightmap_path)) {
|
||||||
|
printf("Error reading PNG\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
numChannels = 4;
|
||||||
|
pitch = width * numChannels;
|
||||||
|
} else if (strcicmp(extension, ".bmp") == 0) {
|
||||||
|
SDL_Surface *bitmap = SDL_LoadBMP(heightmap_path);
|
||||||
|
if (bitmap == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to load bitmap: %s\n", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = bitmap->w;
|
||||||
|
height = bitmap->h;
|
||||||
|
numChannels = bitmap->format->BytesPerPixel;
|
||||||
|
pitch = bitmap->pitch;
|
||||||
|
|
||||||
|
// Copy pixels over to our own array
|
||||||
|
SDL_LockSurface(bitmap);
|
||||||
|
pixels = malloc(height * bitmap->pitch);
|
||||||
|
memcpy(pixels, bitmap->pixels, width * height * numChannels);
|
||||||
|
SDL_UnlockSurface(bitmap);
|
||||||
|
SDL_FreeSurface(bitmap);
|
||||||
|
} else {
|
||||||
|
openrct2_assert(false, "A file with an invalid file extension was selected.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sint32 width = bitmap->w;
|
|
||||||
const sint32 height = bitmap->h;
|
|
||||||
const uint8 numChannels = bitmap->format->BytesPerPixel;
|
|
||||||
|
|
||||||
map_init(width + 2); // + 2 for the black tiles around the map
|
map_init(width + 2); // + 2 for the black tiles around the map
|
||||||
|
|
||||||
uint8 maxValue = 255;
|
uint8 maxValue = 255;
|
||||||
|
@ -860,11 +884,9 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||||
if (settings->smooth_height_map)
|
if (settings->smooth_height_map)
|
||||||
{
|
{
|
||||||
// Smooth height map
|
// Smooth height map
|
||||||
mapgen_smooth_heightmap(bitmap, settings->smooth_strength);
|
mapgen_smooth_heightmap(pixels, width, height, numChannels, pitch, settings->smooth_strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockSurface(bitmap);
|
|
||||||
uint8 *src = (uint8*)bitmap->pixels;
|
|
||||||
if (settings->normalize_height)
|
if (settings->normalize_height)
|
||||||
{
|
{
|
||||||
// Get highest and lowest pixel value
|
// Get highest and lowest pixel value
|
||||||
|
@ -874,7 +896,7 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||||
{
|
{
|
||||||
for (sint32 x = 0; x < width; x++)
|
for (sint32 x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
uint8 value = src[x * numChannels + y * bitmap->pitch];
|
uint8 value = pixels[x * numChannels + y * pitch];
|
||||||
maxValue = max(maxValue, value);
|
maxValue = max(maxValue, value);
|
||||||
minValue = min(minValue, value);
|
minValue = min(minValue, value);
|
||||||
}
|
}
|
||||||
|
@ -902,7 +924,7 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||||
rct_map_element *const surfaceElement = map_get_surface_element_at(y + 1, x + 1);
|
rct_map_element *const surfaceElement = map_get_surface_element_at(y + 1, x + 1);
|
||||||
|
|
||||||
// Read value from bitmap, and convert its range
|
// Read value from bitmap, and convert its range
|
||||||
uint8 value = src[x * numChannels + y * bitmap->pitch];
|
uint8 value = pixels[x * numChannels + y * pitch];
|
||||||
value = (uint8)((float)(value - minValue) / rangeIn * rangeOut) + settings->simplex_low;
|
value = (uint8)((float)(value - minValue) / rangeIn * rangeOut) + settings->simplex_low;
|
||||||
surfaceElement->base_height = value;
|
surfaceElement->base_height = value;
|
||||||
|
|
||||||
|
@ -939,8 +961,7 @@ void mapgen_generate_from_heightmap(mapgen_settings *settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_UnlockSurface(bitmap);
|
free(pixels);
|
||||||
SDL_FreeSurface(bitmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
Loading…
Reference in New Issue