Generator test mode setting
This commit is contained in:
parent
ccbfaa3a86
commit
91c06537eb
@ -1,12 +1,15 @@
|
||||
#include "png.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "../graphics/ImageData.h"
|
||||
#include "../graphics/Texture.h"
|
||||
#include "../files/files.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
|
||||
#ifndef _WIN32
|
||||
#define LIBPNG
|
||||
#endif
|
||||
@ -15,41 +18,45 @@
|
||||
#include <png.h>
|
||||
|
||||
int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) {
|
||||
int code = 0;
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
png_bytep row = NULL;
|
||||
uint pixsize = alpha ? 4 : 3;
|
||||
|
||||
// Open file for writing (binary mode)
|
||||
FILE* fp = fopen(filename, "wb");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "Could not open file %s for writing\n", filename);
|
||||
code = 1;
|
||||
goto finalize;
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initialize write structure
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) {
|
||||
fprintf(stderr, "Could not allocate write struct\n");
|
||||
code = 1;
|
||||
goto finalize;
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Initialize info structure
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
fprintf(stderr, "Could not allocate info struct\n");
|
||||
code = 1;
|
||||
goto finalize;
|
||||
fclose(fp);
|
||||
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
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fprintf(stderr, "Error during png creation\n");
|
||||
code = 1;
|
||||
goto finalize;
|
||||
fclose(fp);
|
||||
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);
|
||||
@ -65,7 +72,7 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data,
|
||||
|
||||
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
|
||||
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];
|
||||
}
|
||||
}
|
||||
png_write_row(png_ptr, row);
|
||||
png_write_row(png_ptr, row.get());
|
||||
}
|
||||
|
||||
// End write
|
||||
png_write_end(png_ptr, NULL);
|
||||
|
||||
finalize:
|
||||
if (fp != NULL) fclose(fp);
|
||||
if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||
if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
if (row != NULL) free(row);
|
||||
|
||||
return code;
|
||||
fclose(fp);
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ImageData* _png_load(const char* file){
|
||||
|
||||
@ -54,7 +54,7 @@ Engine::Engine(const EngineSettings& settings_) {
|
||||
std::cout << "-- loading world" << std::endl;
|
||||
vec3 playerPosition = vec3(0, 64, 0);
|
||||
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);
|
||||
level = world->loadLevel(player, settings);
|
||||
|
||||
@ -116,7 +116,7 @@ void Engine::mainloop() {
|
||||
level->chunksController->update(settings.chunks.loadSpeed);
|
||||
|
||||
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();
|
||||
if (level->player->debug) {
|
||||
hud.drawDebug( 1 / delta, occlusion);
|
||||
@ -135,7 +135,7 @@ Engine::~Engine() {
|
||||
World* world = level->world;
|
||||
|
||||
std::cout << "-- saving world" << std::endl;
|
||||
world->write(level);
|
||||
world->write(level, !settings.debug.generatorTestMode);
|
||||
|
||||
delete level;
|
||||
delete world;
|
||||
|
||||
@ -56,7 +56,8 @@ float bytes2Float(ubyte* src, uint offset){
|
||||
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];
|
||||
}
|
||||
|
||||
@ -161,6 +162,9 @@ ubyte* WorldFiles::getChunk(int x, int y){
|
||||
}
|
||||
|
||||
ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){
|
||||
if (generatorTestMode)
|
||||
return nullptr;
|
||||
|
||||
int regionX = floordiv(x, REGION_SIZE);
|
||||
int regionY = floordiv(y, REGION_SIZE);
|
||||
|
||||
@ -199,6 +203,8 @@ void WorldFiles::write(){
|
||||
if (!std::filesystem::is_directory(directory)) {
|
||||
std::filesystem::create_directory(directory);
|
||||
}
|
||||
if (generatorTestMode)
|
||||
return;
|
||||
for (auto it = regions.begin(); it != regions.end(); it++){
|
||||
if (it->second.chunksData == nullptr || !it->second.unsaved)
|
||||
continue;
|
||||
@ -264,7 +270,6 @@ bool WorldFiles::readPlayer(Player* player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void WorldFiles::writeRegion(int x, int y, WorldRegion& entry){
|
||||
ubyte** region = entry.chunksData;
|
||||
uint32_t* sizes = entry.compressedSizes;
|
||||
|
||||
@ -31,8 +31,9 @@ public:
|
||||
std::unordered_map<glm::ivec2, WorldRegion> regions;
|
||||
std::string directory;
|
||||
ubyte* compressionBuffer;
|
||||
bool generatorTestMode;
|
||||
|
||||
WorldFiles(std::string directory, size_t mainBufferCapacity);
|
||||
WorldFiles(std::string directory, size_t mainBufferCapacity, bool generatorTestMode);
|
||||
~WorldFiles();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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 {
|
||||
DisplaySettings display;
|
||||
ChunksSettings chunks;
|
||||
CameraSettings camera;
|
||||
|
||||
/* 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;
|
||||
|
||||
|
||||
GraphicsSettings graphics;
|
||||
DebugSettings debug;
|
||||
};
|
||||
|
||||
#endif // SRC_SETTINGS_H_
|
||||
@ -31,7 +31,10 @@ toml::Wrapper create_wrapper(EngineSettings& settings) {
|
||||
camera.add("shaking", &settings.camera.shaking);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -261,7 +261,8 @@ void Chunks::translate(int dx, int dz){
|
||||
continue;
|
||||
if (nx < 0 || nz < 0 || nx >= w || nz >= d){
|
||||
events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
|
||||
worldFiles->put(chunk.get());
|
||||
if (worldFiles)
|
||||
worldFiles->put(chunk.get());
|
||||
chunksCount--;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ void ChunksController::update(int64_t maxDuration) {
|
||||
int64_t mcstotal = 0;
|
||||
for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) {
|
||||
auto start = high_resolution_clock::now();
|
||||
if (loadVisible(level->world->wfile)) {
|
||||
if (loadVisible()) {
|
||||
auto elapsed = high_resolution_clock::now() - start;
|
||||
int64_t mcs = duration_cast<microseconds>(elapsed).count();
|
||||
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 d = chunks->d;
|
||||
const int ox = chunks->ox;
|
||||
@ -103,7 +103,7 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){
|
||||
|
||||
chunk = shared_ptr<Chunk>(new Chunk(nearX+ox, nearZ+oz));
|
||||
level->chunksStorage->store(chunk);
|
||||
ubyte* data = worldFiles->getChunk(chunk->x, chunk->z);
|
||||
ubyte* data = level->world->wfile->getChunk(chunk->x, chunk->z);
|
||||
if (data) {
|
||||
chunk->decode(data);
|
||||
chunk->setLoaded(true);
|
||||
|
||||
@ -22,7 +22,7 @@ public:
|
||||
~ChunksController();
|
||||
|
||||
void update(int64_t maxDuration);
|
||||
bool loadVisible(WorldFiles* worldFiles);
|
||||
bool loadVisible();
|
||||
};
|
||||
|
||||
#endif /* VOXELS_CHUNKSCONTROLLER_H_ */
|
||||
|
||||
@ -20,7 +20,10 @@ Level::Level(World* world, Player* player, ChunksStorage* chunksStorage, LevelEv
|
||||
|
||||
uint matrixSize = (settings.chunks.loadDistance+
|
||||
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);
|
||||
chunksController = new ChunksController(this, chunks, lighting, settings.chunks.padding);
|
||||
playerController = new PlayerController(this, settings);
|
||||
|
||||
@ -14,15 +14,15 @@
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
World::World(std::string name, std::string directory, int seed) : name(name), seed(seed) {
|
||||
wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_DATA_LEN * 2 + 8));
|
||||
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), settings.debug.generatorTestMode);
|
||||
}
|
||||
|
||||
World::~World(){
|
||||
delete wfile;
|
||||
}
|
||||
|
||||
void World::write(Level* level) {
|
||||
void World::write(Level* level, bool writeChunks) {
|
||||
Chunks* chunks = level->chunks;
|
||||
|
||||
for (size_t i = 0; i < chunks->volume; i++) {
|
||||
|
||||
@ -16,10 +16,10 @@ public:
|
||||
WorldFiles* wfile;
|
||||
int seed;
|
||||
|
||||
World(std::string name, std::string directory, int seed);
|
||||
World(std::string name, std::string directory, int seed, EngineSettings& settings);
|
||||
~World();
|
||||
|
||||
void write(Level* level);
|
||||
void write(Level* level, bool writeChunks);
|
||||
Level* loadLevel(Player* player, EngineSettings& settings);
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user