add debug world generator visualization
This commit is contained in:
parent
88752806e6
commit
75d66b644b
@ -1,9 +1,8 @@
|
||||
BLOCKS_PER_CHUNK = 65536
|
||||
|
||||
local _, dir = parse_path(__DIR__)
|
||||
ores = file.read_combined_list(dir.."/ores.json")
|
||||
|
||||
local function place_ores(placements, x, z, w, d, seed, hmap, chunk_height)
|
||||
local BLOCKS_PER_CHUNK = w * d * chunk_height
|
||||
for _, ore in ipairs(ores) do
|
||||
local count = BLOCKS_PER_CHUNK / ore.rarity
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "graphics/core/Mesh.hpp"
|
||||
#include "graphics/core/Shader.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "graphics/core/ImageData.hpp"
|
||||
#include "graphics/render/WorldRenderer.hpp"
|
||||
#include "graphics/ui/elements/InventoryView.hpp"
|
||||
#include "graphics/ui/elements/Menu.hpp"
|
||||
@ -29,6 +30,8 @@
|
||||
#include "items/Inventory.hpp"
|
||||
#include "items/ItemDef.hpp"
|
||||
#include "logic/scripting/scripting.hpp"
|
||||
#include "logic/LevelController.hpp"
|
||||
#include "world/generator/WorldGenerator.hpp"
|
||||
#include "maths/voxmaths.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
#include "physics/Hitbox.hpp"
|
||||
@ -140,12 +143,16 @@ std::shared_ptr<InventoryView> Hud::createHotbar() {
|
||||
return view;
|
||||
}
|
||||
|
||||
static constexpr uint WORLDGEN_IMG_SIZE = 64U;
|
||||
|
||||
Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
||||
: assets(engine->getAssets()),
|
||||
gui(engine->getGUI()),
|
||||
frontend(frontend),
|
||||
player(player)
|
||||
{
|
||||
player(player),
|
||||
debugImgWorldGen(std::make_unique<ImageData>(
|
||||
ImageFormat::rgba8888, WORLDGEN_IMG_SIZE, WORLDGEN_IMG_SIZE
|
||||
)) {
|
||||
contentAccess = createContentAccess();
|
||||
contentAccess->setId("hud.content-access");
|
||||
contentAccessPanel = std::make_shared<Panel>(
|
||||
@ -177,6 +184,14 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player)
|
||||
dplotter->setGravity(Gravity::bottom_right);
|
||||
dplotter->setInteractive(false);
|
||||
add(HudElement(hud_element_mode::permanent, nullptr, dplotter, true));
|
||||
|
||||
assets->store(Texture::from(debugImgWorldGen.get()), DEBUG_WORLDGEN_IMAGE);
|
||||
|
||||
add(HudElement(hud_element_mode::permanent, nullptr,
|
||||
guiutil::create(
|
||||
"<image src='"+DEBUG_WORLDGEN_IMAGE+
|
||||
"' pos='0' size='256' gravity='top-right' margin='0,20,0,0'/>"
|
||||
), true));
|
||||
}
|
||||
|
||||
Hud::~Hud() {
|
||||
@ -250,6 +265,40 @@ void Hud::updateHotbarControl() {
|
||||
}
|
||||
}
|
||||
|
||||
void Hud::updateWorldGenDebugVisualization() {
|
||||
auto level = frontend->getLevel();
|
||||
auto generator =
|
||||
frontend->getController()->getChunksController()->getGenerator();
|
||||
auto debugInfo = generator->createDebugInfo();
|
||||
uint width = debugImgWorldGen->getWidth();
|
||||
uint height = debugImgWorldGen->getHeight();
|
||||
ubyte* data = debugImgWorldGen->getData();
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (x >= debugInfo.areaWidth || y >= debugInfo.areaHeight) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
data[(y * width + x) * 4 + i] = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int cx = x + debugInfo.areaOffsetX;
|
||||
int cz = y + debugInfo.areaOffsetY;
|
||||
auto value = debugInfo.areaLevels[y * debugInfo.areaWidth + x] * 35;
|
||||
// Chunk is already generated
|
||||
if (level->chunks->getChunk(cx, cz)) {
|
||||
value = 255;
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
data[(y * width + x) * 4 + i] = value;
|
||||
}
|
||||
data[(y * width + x) * 4 + 3] = 100;
|
||||
}
|
||||
}
|
||||
|
||||
auto texture = assets->get<Texture>(DEBUG_WORLDGEN_IMAGE);
|
||||
texture->reload(*debugImgWorldGen);
|
||||
}
|
||||
|
||||
void Hud::update(bool visible) {
|
||||
auto level = frontend->getLevel();
|
||||
auto menu = gui->getMenu();
|
||||
@ -296,6 +345,10 @@ void Hud::update(bool visible) {
|
||||
}
|
||||
}
|
||||
cleanup();
|
||||
|
||||
if (player->debug) {
|
||||
updateWorldGenDebugVisualization();
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Show inventory on the screen and turn on inventory mode blocking movement
|
||||
|
||||
@ -18,6 +18,7 @@ class LevelFrontend;
|
||||
class UiDocument;
|
||||
class DrawContext;
|
||||
class Viewport;
|
||||
class ImageData;
|
||||
|
||||
namespace gui {
|
||||
class GUI;
|
||||
@ -108,6 +109,8 @@ class Hud : public util::ObjectsKeeper {
|
||||
/// @brief UI element will be dynamicly positioned near to inventory or in screen center
|
||||
std::shared_ptr<gui::UINode> secondUI = nullptr;
|
||||
|
||||
std::unique_ptr<ImageData> debugImgWorldGen;
|
||||
|
||||
std::shared_ptr<gui::InventoryView> createContentAccess();
|
||||
std::shared_ptr<gui::InventoryView> createHotbar();
|
||||
|
||||
@ -117,6 +120,7 @@ class Hud : public util::ObjectsKeeper {
|
||||
void cleanup();
|
||||
|
||||
void showExchangeSlot();
|
||||
void updateWorldGenDebugVisualization();
|
||||
public:
|
||||
Hud(Engine* engine, LevelFrontend* frontend, Player* player);
|
||||
~Hud();
|
||||
@ -167,4 +171,7 @@ public:
|
||||
Player* getPlayer() const;
|
||||
|
||||
std::shared_ptr<Inventory> getBlockInventory();
|
||||
|
||||
/// @brief Runtime updating debug visualization texture
|
||||
inline static std::string DEBUG_WORLDGEN_IMAGE = "#debug.img.worldgen";
|
||||
};
|
||||
|
||||
@ -41,6 +41,12 @@ void GLTexture::unbind() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void GLTexture::reload(const ImageData& image) {
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
reload(image.getData());
|
||||
}
|
||||
|
||||
void GLTexture::reload(const ubyte* data) {
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||
|
||||
@ -16,6 +16,8 @@ public:
|
||||
|
||||
void setNearestFilter();
|
||||
|
||||
virtual void reload(const ImageData& image) override;
|
||||
|
||||
virtual std::unique_ptr<ImageData> readData() override;
|
||||
virtual uint getId() const override;
|
||||
|
||||
|
||||
@ -20,6 +20,8 @@ public:
|
||||
virtual void bind() = 0;
|
||||
virtual void unbind() = 0;
|
||||
|
||||
virtual void reload(const ImageData& image) = 0;
|
||||
|
||||
virtual std::unique_ptr<ImageData> readData() = 0;
|
||||
|
||||
virtual uint getWidth() const {
|
||||
|
||||
@ -33,4 +33,8 @@ public:
|
||||
int loadDistance,
|
||||
int centerX,
|
||||
int centerY);
|
||||
|
||||
const WorldGenerator* getGenerator() const {
|
||||
return generator.get();
|
||||
}
|
||||
};
|
||||
|
||||
@ -95,6 +95,10 @@ BlocksController* LevelController::getBlocksController() {
|
||||
return blocks.get();
|
||||
}
|
||||
|
||||
ChunksController* LevelController::getChunksController() {
|
||||
return chunks.get();
|
||||
}
|
||||
|
||||
PlayerController* LevelController::getPlayerController() {
|
||||
return player.get();
|
||||
}
|
||||
|
||||
@ -34,5 +34,6 @@ public:
|
||||
Player* getPlayer();
|
||||
|
||||
BlocksController* getBlocksController();
|
||||
ChunksController* getChunksController();
|
||||
PlayerController* getPlayerController();
|
||||
};
|
||||
|
||||
@ -355,3 +355,21 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorldGenDebugInfo WorldGenerator::createDebugInfo() const {
|
||||
const auto& area = surroundMap.getArea();
|
||||
const auto& levels = area.getBuffer();
|
||||
auto values = std::make_unique<ubyte[]>(area.getWidth()*area.getHeight());
|
||||
|
||||
for (uint i = 0; i < levels.size(); i++) {
|
||||
values[i] = levels[i];
|
||||
}
|
||||
|
||||
return WorldGenDebugInfo {
|
||||
area.getOffsetX(),
|
||||
area.getOffsetY(),
|
||||
static_cast<uint>(area.getWidth()),
|
||||
static_cast<uint>(area.getHeight()),
|
||||
std::move(values)
|
||||
};
|
||||
}
|
||||
|
||||
@ -34,6 +34,14 @@ struct ChunkPrototype {
|
||||
std::vector<StructurePlacement> structures;
|
||||
};
|
||||
|
||||
struct WorldGenDebugInfo {
|
||||
int areaOffsetX;
|
||||
int areaOffsetY;
|
||||
uint areaWidth;
|
||||
uint areaHeight;
|
||||
std::unique_ptr<ubyte[]> areaLevels;
|
||||
};
|
||||
|
||||
/// @brief High-level world generation controller
|
||||
class WorldGenerator {
|
||||
/// @param def generator definition
|
||||
@ -80,5 +88,8 @@ public:
|
||||
/// @param z chunk position Y divided by CHUNK_D
|
||||
void generate(voxel* voxels, int x, int z);
|
||||
|
||||
WorldGenDebugInfo createDebugInfo() const;
|
||||
|
||||
/// @brief Default generator name // TODO: move to config
|
||||
inline static std::string DEFAULT = "core:default";
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user