Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3D Text (2D text in 3D space) & render refactor #364

Merged
merged 42 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7969358
refactor Font
MihailRis Nov 11, 2024
c5ca912
move getVoxels from ChunksStorage to Chunks
MihailRis Nov 11, 2024
b3ab037
add 3D text render (WIP)
MihailRis Nov 12, 2024
edbd851
update font rendering
MihailRis Nov 12, 2024
7734d40
cleanup
MihailRis Nov 12, 2024
b12c746
Merge branch 'main' into text3d
MihailRis Nov 12, 2024
a74f5f4
Merge branch 'main' into text3d
MihailRis Nov 12, 2024
aadb04c
minor optimize BlocksRenderer
MihailRis Nov 12, 2024
866f6e9
add NotePreset
MihailRis Nov 12, 2024
c29db60
Merge branch 'main' into text3d
MihailRis Nov 12, 2024
a5c9125
fix clang-format what
MihailRis Nov 12, 2024
60aa0fb
increase max font codepages to 1024
MihailRis Nov 12, 2024
d8fe2f1
fix debug chunk borders render
MihailRis Nov 12, 2024
a7833a7
refactor WorldRenderer
MihailRis Nov 13, 2024
b23d31a
add 'translucent' block property
MihailRis Nov 13, 2024
a21d877
optimize WorldRenderer chunks sort
MihailRis Nov 13, 2024
fc3d5c5
optimize it even more
MihailRis Nov 13, 2024
f50b87e
fix
MihailRis Nov 13, 2024
7b4ddfd
another fix
MihailRis Nov 13, 2024
db565d2
add TextNote
MihailRis Nov 13, 2024
0a8ea7e
disable mip-mapping in fonts
MihailRis Nov 13, 2024
78d5ab0
fix: fatal error on pack removal when no world open
MihailRis Nov 13, 2024
5b6ada6
add more NotePreset properties
MihailRis Nov 13, 2024
5b3fe46
Merge branch 'main' into text3d
MihailRis Nov 13, 2024
42b2670
move 3d texts rendering code to TextsRenderer
MihailRis Nov 14, 2024
f9f4d20
refactor WorldRenderer
MihailRis Nov 14, 2024
e9163f4
refactor WorldRenderer
MihailRis Nov 14, 2024
f0b6521
refactor
MihailRis Nov 14, 2024
c4170c0
refactor
MihailRis Nov 14, 2024
eb5715e
add gfx.text3d.spawn(...)
MihailRis Nov 14, 2024
d74b530
rename spawn to show & add gfx.text3d.hide(...)
MihailRis Nov 14, 2024
501f1b5
add get_text, set_text, get_pos, set_pos
MihailRis Nov 14, 2024
4a74e56
add update_settings
MihailRis Nov 14, 2024
3a1e90f
add gfx.text3d OOP wrapper
MihailRis Nov 14, 2024
ef644ca
add 'xray_opacity' NotePreset property
MihailRis Nov 14, 2024
2147f50
add 'projected' display mode support
MihailRis Nov 14, 2024
525cf1e
add 'perspective' NotePreset property
MihailRis Nov 14, 2024
a8388a6
add text3d.get_axis_x, .set_axis_x, .get_axis_y, .set_axis_y
MihailRis Nov 15, 2024
a7404c2
add missing methods to the OOP wrapper
MihailRis Nov 15, 2024
04da2f5
add .set_rotation(mat4)
MihailRis Nov 15, 2024
4cbd3f4
cleanup
MihailRis Nov 15, 2024
7aacadc
remove 'translucent' block property (will be reverted later)
MihailRis Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions res/scripts/hud_classes.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
local Text3D = {__index={
hide=function(self) return gfx.text3d.hide(self.id) end,
get_pos=function(self) return gfx.text3d.get_pos(self.id) end,
set_pos=function(self, v) return gfx.text3d.set_pos(self.id, v) end,
get_axis_x=function(self) return gfx.text3d.get_axis_x(self.id) end,
set_axis_x=function(self, v) return gfx.text3d.set_axis_x(self.id, v) end,
get_axis_y=function(self) return gfx.text3d.get_axis_y(self.id) end,
set_axis_y=function(self, v) return gfx.text3d.set_axis_y(self.id, v) end,
set_rotation=function(self, m) return gfx.text3d.set_rotation(self.id, m) end,
get_text=function(self) return gfx.text3d.get_text(self.id) end,
set_text=function(self, s) return gfx.text3d.set_text(self.id, s) end,
update_settings=function(self, t) return gfx.text3d.update_settings(self.id, t) end,
}}

gfx.text3d.new = function(pos, text, preset, extension)
local id = gfx.text3d.show(pos, text, preset, extension)
return setmetatable({id=id}, Text3D)
end
52 changes: 36 additions & 16 deletions src/assets/assetload_funcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static debug::Logger logger("assetload-funcs");

namespace fs = std::filesystem;

static bool animation(
static bool load_animation(
Assets* assets,
const ResPaths* paths,
const std::string& atlasName,
Expand Down Expand Up @@ -102,8 +102,13 @@ static bool append_atlas(AtlasBuilder& atlas, const fs::path& file) {
return true;
}

assetload::postfunc assetload::
atlas(AssetsLoader*, const ResPaths* paths, const std::string& directory, const std::string& name, const std::shared_ptr<AssetCfg>&) {
assetload::postfunc assetload::atlas(
AssetsLoader*,
const ResPaths* paths,
const std::string& directory,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
AtlasBuilder builder;
for (const auto& file : paths->listdir(directory)) {
if (!imageio::is_read_supported(file.extension().u8string())) continue;
Expand All @@ -115,24 +120,41 @@ assetload::postfunc assetload::
atlas->prepare();
assets->store(std::unique_ptr<Atlas>(atlas), name);
for (const auto& file : names) {
animation(assets, paths, name, directory, file, atlas);
load_animation(assets, paths, name, directory, file, atlas);
}
};
}

assetload::postfunc assetload::
font(AssetsLoader*, const ResPaths* paths, const std::string& filename, const std::string& name, const std::shared_ptr<AssetCfg>&) {
assetload::postfunc assetload::font(
AssetsLoader*,
const ResPaths* paths,
const std::string& filename,
const std::string& name,
const std::shared_ptr<AssetCfg>&
) {
auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>();
for (size_t i = 0; i <= 4; i++) {
for (size_t i = 0; i <= 1024; i++) {
std::string pagefile = filename + "_" + std::to_string(i) + ".png";
pagefile = paths->find(pagefile).string();
pages->push_back(imageio::read(pagefile));
auto file = paths->find(pagefile);
if (fs::exists(file)) {
pages->push_back(imageio::read(file.u8string()));
} else if (i == 0) {
throw std::runtime_error("font must have page 0");
} else {
pages->push_back(nullptr);
}
}
return [=](auto assets) {
int res = pages->at(0)->getHeight() / 16;
std::vector<std::unique_ptr<Texture>> textures;
for (auto& page : *pages) {
textures.emplace_back(Texture::from(page.get()));
if (page == nullptr) {
textures.emplace_back(nullptr);
} else {
auto texture = Texture::from(page.get());
texture->setMipMapping(false);
textures.emplace_back(std::move(texture));
}
}
assets->store(
std::make_unique<Font>(std::move(textures), res, 4), name
Expand Down Expand Up @@ -316,11 +338,9 @@ static TextureAnimation create_animation(
if (elem.second > 0) {
frame.duration = static_cast<float>(elem.second) / 1000.0f;
}
frame.srcPos =
glm::ivec2(
region.u1 * srcWidth, srcHeight - region.v2 * srcHeight
) -
extension;
frame.srcPos = glm::ivec2(
region.u1 * srcWidth, srcHeight - region.v2 * srcHeight
) - extension;
animation.addFrame(frame);
}
return animation;
Expand All @@ -338,7 +358,7 @@ inline bool contains(
return false;
}

static bool animation(
static bool load_animation(
Assets* assets,
const ResPaths* paths,
const std::string& atlasName,
Expand Down
16 changes: 8 additions & 8 deletions src/frontend/ContentGfxCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,33 @@
#include "maths/UVRegion.hpp"
#include "voxels/Block.hpp"

ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets)
ContentGfxCache::ContentGfxCache(const Content* content, const Assets& assets)
: content(content) {
auto indices = content->getIndices();
sideregions = std::make_unique<UVRegion[]>(indices->blocks.count() * 6);
auto atlas = assets->get<Atlas>("blocks");
const auto& atlas = assets.require<Atlas>("blocks");

const auto& blocks = indices->blocks.getIterable();
for (blockid_t i = 0; i < blocks.size(); i++) {
auto def = blocks[i];
for (uint side = 0; side < 6; side++) {
const std::string& tex = def->textureFaces[side];
if (atlas->has(tex)) {
sideregions[i * 6 + side] = atlas->get(tex);
} else if (atlas->has(TEXTURE_NOTFOUND)) {
sideregions[i * 6 + side] = atlas->get(TEXTURE_NOTFOUND);
if (atlas.has(tex)) {
sideregions[i * 6 + side] = atlas.get(tex);
} else if (atlas.has(TEXTURE_NOTFOUND)) {
sideregions[i * 6 + side] = atlas.get(TEXTURE_NOTFOUND);
}
}
if (def->model == BlockModel::custom) {
auto model = assets->require<model::Model>(def->modelName);
auto model = assets.require<model::Model>(def->modelName);
// temporary dirty fix tbh
if (def->modelName.find(':') == std::string::npos) {
for (auto& mesh : model.meshes) {
size_t pos = mesh.texture.find(':');
if (pos == std::string::npos) {
continue;
}
if (auto region = atlas->getIf(mesh.texture.substr(pos+1))) {
if (auto region = atlas.getIf(mesh.texture.substr(pos+1))) {
for (auto& vertex : mesh.vertices) {
vertex.uv = region->apply(vertex.uv);
}
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/ContentGfxCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ class ContentGfxCache {
std::unique_ptr<UVRegion[]> sideregions;
std::unordered_map<blockid_t, model::Model> models;
public:
ContentGfxCache(const Content* content, Assets* assets);
ContentGfxCache(const Content* content, const Assets& assets);
~ContentGfxCache();

inline const UVRegion& getRegion(blockid_t id, int side) const {
return sideregions[id * 6 + side];
}

const model::Model& getModel(blockid_t id) const;

const Content* getContent() const;
};
35 changes: 21 additions & 14 deletions src/frontend/LevelFrontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@
#include "world/Level.hpp"

LevelFrontend::LevelFrontend(
Player* currentPlayer, LevelController* controller, Assets* assets
) : level(controller->getLevel()),
Player* currentPlayer, LevelController* controller, Assets& assets
) : level(*controller->getLevel()),
controller(controller),
assets(assets),
contentCache(std::make_unique<ContentGfxCache>(level->content, assets))
contentCache(std::make_unique<ContentGfxCache>(level.content, assets))
{
assets->store(
BlocksPreview::build(contentCache.get(), assets, level->content),
assets.store(
BlocksPreview::build(
*contentCache, assets, *level.content->getIndices()
),
"block-previews"
);
controller->getBlocksController()->listenBlockInteraction(
[=](auto player, const auto& pos, const auto& def, BlockInteraction type) {
auto material = level->content->findBlockMaterial(def.material);
[currentPlayer, controller, &assets](auto player, const auto& pos, const auto& def, BlockInteraction type) {
const auto& level = *controller->getLevel();
auto material = level.content->findBlockMaterial(def.material);
if (material == nullptr) {
return;
}

if (type == BlockInteraction::step) {
auto sound = assets->get<audio::Sound>(material->stepsSound);
auto sound = assets.get<audio::Sound>(material->stepsSound);
glm::vec3 pos {};
auto soundsCamera = currentPlayer->currentCamera.get();
if (soundsCamera == currentPlayer->spCamera.get() ||
Expand All @@ -58,10 +61,10 @@ LevelFrontend::LevelFrontend(
audio::Sound* sound = nullptr;
switch (type) {
case BlockInteraction::placing:
sound = assets->get<audio::Sound>(material->placeSound);
sound = assets.get<audio::Sound>(material->placeSound);
break;
case BlockInteraction::destruction:
sound = assets->get<audio::Sound>(material->breakSound);
sound = assets.get<audio::Sound>(material->breakSound);
break;
default:
break;
Expand All @@ -83,16 +86,20 @@ LevelFrontend::LevelFrontend(

LevelFrontend::~LevelFrontend() = default;

Level* LevelFrontend::getLevel() const {
Level& LevelFrontend::getLevel() {
return level;
}

Assets* LevelFrontend::getAssets() const {
const Level& LevelFrontend::getLevel() const {
return level;
}

const Assets& LevelFrontend::getAssets() const {
return assets;
}

ContentGfxCache* LevelFrontend::getContentGfxCache() const {
return contentCache.get();
const ContentGfxCache& LevelFrontend::getContentGfxCache() const {
return *contentCache;
}

LevelController* LevelFrontend::getController() const {
Expand Down
13 changes: 7 additions & 6 deletions src/frontend/LevelFrontend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ class ContentGfxCache;
class LevelController;

class LevelFrontend {
Level* level;
Level& level;
LevelController* controller;
Assets* assets;
const Assets& assets;
std::unique_ptr<ContentGfxCache> contentCache;
public:
LevelFrontend(Player* currentPlayer, LevelController* controller, Assets* assets);
LevelFrontend(Player* currentPlayer, LevelController* controller, Assets& assets);
~LevelFrontend();

Level* getLevel() const;
Assets* getAssets() const;
ContentGfxCache* getContentGfxCache() const;
Level& getLevel();
const Level& getLevel() const;
const Assets& getAssets() const;
const ContentGfxCache& getContentGfxCache() const;
LevelController* getController() const;
};
Loading
Loading