Generator test mode setting
This commit is contained in:
parent
ccbfaa3a86
commit
91c06537eb
@ -1,12 +1,15 @@
|
|||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
#include "../graphics/ImageData.h"
|
#include "../graphics/ImageData.h"
|
||||||
#include "../graphics/Texture.h"
|
#include "../graphics/Texture.h"
|
||||||
#include "../files/files.h"
|
#include "../files/files.h"
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#define LIBPNG
|
#define LIBPNG
|
||||||
#endif
|
#endif
|
||||||
@ -15,41 +18,45 @@
|
|||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) {
|
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) {
|
||||||
int code = 0;
|
|
||||||
png_structp png_ptr = NULL;
|
png_structp png_ptr = NULL;
|
||||||
png_infop info_ptr = NULL;
|
png_infop info_ptr = NULL;
|
||||||
png_bytep row = NULL;
|
|
||||||
uint pixsize = alpha ? 4 : 3;
|
uint pixsize = alpha ? 4 : 3;
|
||||||
|
|
||||||
// Open file for writing (binary mode)
|
// Open file for writing (binary mode)
|
||||||
FILE* fp = fopen(filename, "wb");
|
FILE* fp = fopen(filename, "wb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
fprintf(stderr, "Could not open file %s for writing\n", filename);
|
fprintf(stderr, "Could not open file %s for writing\n", filename);
|
||||||
code = 1;
|
fclose(fp);
|
||||||
goto finalize;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize write structure
|
// Initialize write structure
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
if (png_ptr == NULL) {
|
if (png_ptr == NULL) {
|
||||||
fprintf(stderr, "Could not allocate write struct\n");
|
fprintf(stderr, "Could not allocate write struct\n");
|
||||||
code = 1;
|
fclose(fp);
|
||||||
goto finalize;
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize info structure
|
// Initialize info structure
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
if (info_ptr == NULL) {
|
if (info_ptr == NULL) {
|
||||||
fprintf(stderr, "Could not allocate info struct\n");
|
fprintf(stderr, "Could not allocate info struct\n");
|
||||||
code = 1;
|
fclose(fp);
|
||||||
goto finalize;
|
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||||
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||||
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup Exception handling
|
// Setup Exception handling
|
||||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||||
fprintf(stderr, "Error during png creation\n");
|
fprintf(stderr, "Error during png creation\n");
|
||||||
code = 1;
|
fclose(fp);
|
||||||
goto finalize;
|
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||||
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_init_io(png_ptr, fp);
|
png_init_io(png_ptr, fp);
|
||||||
@ -65,7 +72,7 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
|||||||
|
|
||||||
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
row = (png_bytep) malloc(pixsize * width * sizeof(png_byte));
|
unique_ptr<png_byte[]> row(new png_byte[pixsize * width]);
|
||||||
|
|
||||||
// Write image data
|
// Write image data
|
||||||
for (uint y = 0; y < height; y++) {
|
for (uint y = 0; y < height; y++) {
|
||||||
@ -74,19 +81,16 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
|||||||
row[x * pixsize + i] = (png_byte)data[(y * width + x) * pixsize + i];
|
row[x * pixsize + i] = (png_byte)data[(y * width + x) * pixsize + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
png_write_row(png_ptr, row);
|
png_write_row(png_ptr, row.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// End write
|
// End write
|
||||||
png_write_end(png_ptr, NULL);
|
png_write_end(png_ptr, NULL);
|
||||||
|
|
||||||
finalize:
|
fclose(fp);
|
||||||
if (fp != NULL) fclose(fp);
|
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||||
if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||||
if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
return 0;
|
||||||
if (row != NULL) free(row);
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageData* _png_load(const char* file){
|
ImageData* _png_load(const char* file){
|
||||||
|
|||||||
@ -54,7 +54,7 @@ Engine::Engine(const EngineSettings& settings_) {
|
|||||||
std::cout << "-- loading world" << std::endl;
|
std::cout << "-- loading world" << std::endl;
|
||||||
vec3 playerPosition = vec3(0, 64, 0);
|
vec3 playerPosition = vec3(0, 64, 0);
|
||||||
Camera* camera = new Camera(playerPosition, radians(90.0f));
|
Camera* camera = new Camera(playerPosition, radians(90.0f));
|
||||||
World* world = new World("world-1", "world/", 42);
|
World* world = new World("world-1", "world/", 42, settings);
|
||||||
Player* player = new Player(playerPosition, 4.0f, camera);
|
Player* player = new Player(playerPosition, 4.0f, camera);
|
||||||
level = world->loadLevel(player, settings);
|
level = world->loadLevel(player, settings);
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ void Engine::mainloop() {
|
|||||||
level->chunksController->update(settings.chunks.loadSpeed);
|
level->chunksController->update(settings.chunks.loadSpeed);
|
||||||
|
|
||||||
float fovFactor = 18.0f / (float)settings.chunks.loadDistance;
|
float fovFactor = 18.0f / (float)settings.chunks.loadDistance;
|
||||||
worldRenderer.draw(camera, occlusion, fovFactor, settings.fogCurve);
|
worldRenderer.draw(camera, occlusion, fovFactor, settings.graphics.fogCurve);
|
||||||
hud.draw();
|
hud.draw();
|
||||||
if (level->player->debug) {
|
if (level->player->debug) {
|
||||||
hud.drawDebug( 1 / delta, occlusion);
|
hud.drawDebug( 1 / delta, occlusion);
|
||||||
@ -135,7 +135,7 @@ Engine::~Engine() {
|
|||||||
World* world = level->world;
|
World* world = level->world;
|
||||||
|
|
||||||
std::cout << "-- saving world" << std::endl;
|
std::cout << "-- saving world" << std::endl;
|
||||||
world->write(level);
|
world->write(level, !settings.debug.generatorTestMode);
|
||||||
|
|
||||||
delete level;
|
delete level;
|
||||||
delete world;
|
delete world;
|
||||||
|
|||||||
@ -56,7 +56,8 @@ float bytes2Float(ubyte* src, uint offset){
|
|||||||
return *(float*)(&value);
|
return *(float*)(&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity) : directory(directory){
|
WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity, bool generatorTestMode)
|
||||||
|
: directory(directory), generatorTestMode(generatorTestMode) {
|
||||||
compressionBuffer = new ubyte[CHUNK_DATA_LEN * 2];
|
compressionBuffer = new ubyte[CHUNK_DATA_LEN * 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +162,9 @@ ubyte* WorldFiles::getChunk(int x, int y){
|
|||||||
}
|
}
|
||||||
|
|
||||||
ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){
|
ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){
|
||||||
|
if (generatorTestMode)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
int regionX = floordiv(x, REGION_SIZE);
|
int regionX = floordiv(x, REGION_SIZE);
|
||||||
int regionY = floordiv(y, REGION_SIZE);
|
int regionY = floordiv(y, REGION_SIZE);
|
||||||
|
|
||||||
@ -199,6 +203,8 @@ void WorldFiles::write(){
|
|||||||
if (!std::filesystem::is_directory(directory)) {
|
if (!std::filesystem::is_directory(directory)) {
|
||||||
std::filesystem::create_directory(directory);
|
std::filesystem::create_directory(directory);
|
||||||
}
|
}
|
||||||
|
if (generatorTestMode)
|
||||||
|
return;
|
||||||
for (auto it = regions.begin(); it != regions.end(); it++){
|
for (auto it = regions.begin(); it != regions.end(); it++){
|
||||||
if (it->second.chunksData == nullptr || !it->second.unsaved)
|
if (it->second.chunksData == nullptr || !it->second.unsaved)
|
||||||
continue;
|
continue;
|
||||||
@ -264,7 +270,6 @@ bool WorldFiles::readPlayer(Player* player) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WorldFiles::writeRegion(int x, int y, WorldRegion& entry){
|
void WorldFiles::writeRegion(int x, int y, WorldRegion& entry){
|
||||||
ubyte** region = entry.chunksData;
|
ubyte** region = entry.chunksData;
|
||||||
uint32_t* sizes = entry.compressedSizes;
|
uint32_t* sizes = entry.compressedSizes;
|
||||||
|
|||||||
@ -31,8 +31,9 @@ public:
|
|||||||
std::unordered_map<glm::ivec2, WorldRegion> regions;
|
std::unordered_map<glm::ivec2, WorldRegion> regions;
|
||||||
std::string directory;
|
std::string directory;
|
||||||
ubyte* compressionBuffer;
|
ubyte* compressionBuffer;
|
||||||
|
bool generatorTestMode;
|
||||||
|
|
||||||
WorldFiles(std::string directory, size_t mainBufferCapacity);
|
WorldFiles(std::string directory, size_t mainBufferCapacity, bool generatorTestMode);
|
||||||
~WorldFiles();
|
~WorldFiles();
|
||||||
|
|
||||||
void put(Chunk* chunk);
|
void put(Chunk* chunk);
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
#include "settings.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "files/files.h"
|
|
||||||
#include "coders/json.h"
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
void load_settings(EngineSettings& settings, string filename) {
|
|
||||||
string source = files::read_string(filename);
|
|
||||||
unique_ptr<json::JObject> obj(json::parse(filename, source));
|
|
||||||
{
|
|
||||||
auto& display = settings.display;
|
|
||||||
obj->num("display-width", display.width);
|
|
||||||
obj->num("display-height", display.height);
|
|
||||||
obj->num("display-samples", display.samples);
|
|
||||||
obj->num("display-swap-interval", display.swapInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto& chunks = settings.chunks;
|
|
||||||
obj->num("chunks-load-distance", chunks.loadDistance);
|
|
||||||
obj->num("chunks-load-speed", chunks.loadSpeed);
|
|
||||||
obj->num("chunks-padding", chunks.padding);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto& camera = settings.camera;
|
|
||||||
obj->flag("camera-fov-effects", camera.fovEvents);
|
|
||||||
obj->flag("camera-shaking", camera.shaking);
|
|
||||||
}
|
|
||||||
obj->num("fog-curve", settings.fogCurve);
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_settings(EngineSettings& settings, string filename) {
|
|
||||||
json::JObject obj;
|
|
||||||
{
|
|
||||||
auto& display = settings.display;
|
|
||||||
obj.put("display-width", display.width);
|
|
||||||
obj.put("display-height", display.height);
|
|
||||||
obj.put("display-samples", display.samples);
|
|
||||||
obj.put("display-swap-interval", display.swapInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto& chunks = settings.chunks;
|
|
||||||
obj.put("chunks-load-distance", chunks.loadDistance);
|
|
||||||
obj.put("chunks-load-speed", chunks.loadSpeed);
|
|
||||||
obj.put("chunks-padding", chunks.padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto& camera = settings.camera;
|
|
||||||
obj.put("camera-fov-effects", camera.fovEvents);
|
|
||||||
obj.put("camera-shaking", camera.shaking);
|
|
||||||
}
|
|
||||||
obj.put("fog-curve", settings.fogCurve);
|
|
||||||
files::write_string(filename, json::stringify(&obj, true, " "));
|
|
||||||
}
|
|
||||||
@ -34,17 +34,23 @@ struct CameraSettings {
|
|||||||
bool shaking = true;
|
bool shaking = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GraphicsSettings {
|
||||||
|
/* Fog opacity is calculated as `pow(depth*k, fogCurve)` where k depends on chunksLoadDistance.
|
||||||
|
Use values in range [1.0 - 2.0] where 1.0 is linear, 2.0 is quadratic */
|
||||||
|
float fogCurve = 1.6f;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DebugSettings {
|
||||||
|
/* Turns off chunks saving/loading */
|
||||||
|
bool generatorTestMode = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct EngineSettings {
|
struct EngineSettings {
|
||||||
DisplaySettings display;
|
DisplaySettings display;
|
||||||
ChunksSettings chunks;
|
ChunksSettings chunks;
|
||||||
CameraSettings camera;
|
CameraSettings camera;
|
||||||
|
GraphicsSettings graphics;
|
||||||
/* Fog opacity is calculated as `pow(depth*k, fogCurve)` where k depends on chunksLoadDistance.
|
DebugSettings debug;
|
||||||
Use values in range [1.0 - 2.0] where 1.0 is linear, 2.0 is quadratic
|
|
||||||
*/
|
|
||||||
float fogCurve = 1.6f;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRC_SETTINGS_H_
|
#endif // SRC_SETTINGS_H_
|
||||||
@ -31,7 +31,10 @@ toml::Wrapper create_wrapper(EngineSettings& settings) {
|
|||||||
camera.add("shaking", &settings.camera.shaking);
|
camera.add("shaking", &settings.camera.shaking);
|
||||||
|
|
||||||
toml::Section& graphics = wrapper.add("graphics");
|
toml::Section& graphics = wrapper.add("graphics");
|
||||||
graphics.add("fog-curve", &settings.fogCurve);
|
graphics.add("fog-curve", &settings.graphics.fogCurve);
|
||||||
|
|
||||||
|
toml::Section& debug = wrapper.add("debug");
|
||||||
|
debug.add("generator-test-mode", &settings.debug.generatorTestMode);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -261,6 +261,7 @@ void Chunks::translate(int dx, int dz){
|
|||||||
continue;
|
continue;
|
||||||
if (nx < 0 || nz < 0 || nx >= w || nz >= d){
|
if (nx < 0 || nz < 0 || nx >= w || nz >= d){
|
||||||
events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
|
events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
|
||||||
|
if (worldFiles)
|
||||||
worldFiles->put(chunk.get());
|
worldFiles->put(chunk.get());
|
||||||
chunksCount--;
|
chunksCount--;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -42,7 +42,7 @@ void ChunksController::update(int64_t maxDuration) {
|
|||||||
int64_t mcstotal = 0;
|
int64_t mcstotal = 0;
|
||||||
for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) {
|
for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) {
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
if (loadVisible(level->world->wfile)) {
|
if (loadVisible()) {
|
||||||
auto elapsed = high_resolution_clock::now() - start;
|
auto elapsed = high_resolution_clock::now() - start;
|
||||||
int64_t mcs = duration_cast<microseconds>(elapsed).count();
|
int64_t mcs = duration_cast<microseconds>(elapsed).count();
|
||||||
avgDurationMcs = mcs * 0.2 + avgDurationMcs * 0.8;
|
avgDurationMcs = mcs * 0.2 + avgDurationMcs * 0.8;
|
||||||
@ -55,7 +55,7 @@ void ChunksController::update(int64_t maxDuration) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChunksController::loadVisible(WorldFiles* worldFiles){
|
bool ChunksController::loadVisible(){
|
||||||
const int w = chunks->w;
|
const int w = chunks->w;
|
||||||
const int d = chunks->d;
|
const int d = chunks->d;
|
||||||
const int ox = chunks->ox;
|
const int ox = chunks->ox;
|
||||||
@ -103,7 +103,7 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){
|
|||||||
|
|
||||||
chunk = shared_ptr<Chunk>(new Chunk(nearX+ox, nearZ+oz));
|
chunk = shared_ptr<Chunk>(new Chunk(nearX+ox, nearZ+oz));
|
||||||
level->chunksStorage->store(chunk);
|
level->chunksStorage->store(chunk);
|
||||||
ubyte* data = worldFiles->getChunk(chunk->x, chunk->z);
|
ubyte* data = level->world->wfile->getChunk(chunk->x, chunk->z);
|
||||||
if (data) {
|
if (data) {
|
||||||
chunk->decode(data);
|
chunk->decode(data);
|
||||||
chunk->setLoaded(true);
|
chunk->setLoaded(true);
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public:
|
|||||||
~ChunksController();
|
~ChunksController();
|
||||||
|
|
||||||
void update(int64_t maxDuration);
|
void update(int64_t maxDuration);
|
||||||
bool loadVisible(WorldFiles* worldFiles);
|
bool loadVisible();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* VOXELS_CHUNKSCONTROLLER_H_ */
|
#endif /* VOXELS_CHUNKSCONTROLLER_H_ */
|
||||||
|
|||||||
@ -20,7 +20,10 @@ Level::Level(World* world, Player* player, ChunksStorage* chunksStorage, LevelEv
|
|||||||
|
|
||||||
uint matrixSize = (settings.chunks.loadDistance+
|
uint matrixSize = (settings.chunks.loadDistance+
|
||||||
settings.chunks.padding) * 2;
|
settings.chunks.padding) * 2;
|
||||||
chunks = new Chunks(matrixSize, matrixSize, 0, 0, world->wfile, events);
|
chunks = new Chunks(matrixSize, matrixSize,
|
||||||
|
0, 0,
|
||||||
|
world->wfile,
|
||||||
|
events);
|
||||||
lighting = new Lighting(chunks);
|
lighting = new Lighting(chunks);
|
||||||
chunksController = new ChunksController(this, chunks, lighting, settings.chunks.padding);
|
chunksController = new ChunksController(this, chunks, lighting, settings.chunks.padding);
|
||||||
playerController = new PlayerController(this, settings);
|
playerController = new PlayerController(this, settings);
|
||||||
|
|||||||
@ -14,15 +14,15 @@
|
|||||||
|
|
||||||
using std::shared_ptr;
|
using std::shared_ptr;
|
||||||
|
|
||||||
World::World(std::string name, std::string directory, int seed) : name(name), seed(seed) {
|
World::World(std::string name, std::string directory, int seed, EngineSettings& settings) : name(name), seed(seed) {
|
||||||
wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_DATA_LEN * 2 + 8));
|
wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_DATA_LEN * 2 + 8), settings.debug.generatorTestMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
World::~World(){
|
World::~World(){
|
||||||
delete wfile;
|
delete wfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::write(Level* level) {
|
void World::write(Level* level, bool writeChunks) {
|
||||||
Chunks* chunks = level->chunks;
|
Chunks* chunks = level->chunks;
|
||||||
|
|
||||||
for (size_t i = 0; i < chunks->volume; i++) {
|
for (size_t i = 0; i < chunks->volume; i++) {
|
||||||
|
|||||||
@ -16,10 +16,10 @@ public:
|
|||||||
WorldFiles* wfile;
|
WorldFiles* wfile;
|
||||||
int seed;
|
int seed;
|
||||||
|
|
||||||
World(std::string name, std::string directory, int seed);
|
World(std::string name, std::string directory, int seed, EngineSettings& settings);
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
void write(Level* level);
|
void write(Level* level, bool writeChunks);
|
||||||
Level* loadLevel(Player* player, EngineSettings& settings);
|
Level* loadLevel(Player* player, EngineSettings& settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user