Merge pull request #813 from clasher113/main

bug fix
This commit is contained in:
MihailRis 2026-03-16 21:45:59 +03:00 • committed by GitHub
commit 5502c2e7ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 75 additions and 35 deletions

View file

@ -190,6 +190,10 @@ void audio::initialize(
audio::get_channel(channel.name)->setVolume(value * value); audio::get_channel(channel.name)->setVolume(value * value);
}, true)); }, true));
} }
objects_keeper.keepAlive(settings.acousticEffects.observe([=](auto value) {
if (value) return;
backend->setAcoustics(audio::Acoustics {});
}, true));
if (inputEnabled) { if (inputEnabled) {
::input_device = backend->openInputDevice("", 44100, 1, 16); ::input_device = backend->openInputDevice("", 44100, 1, 16);

View file

@ -23,6 +23,10 @@ enum AttributeType {
COLOR COLOR
}; };
enum MaterialFlag {
SHADELESS = 1
};
struct VertexAttribute { struct VertexAttribute {
AttributeType type; AttributeType type;
int flags; int flags;
@ -62,7 +66,7 @@ static VertexAttribute load_attribute(ByteReader& reader) {
static model::Mesh build_mesh( static model::Mesh build_mesh(
const std::vector<VertexAttribute>& attrs, const std::vector<VertexAttribute>& attrs,
const util::Buffer<uint16_t>& indices, const util::Buffer<uint16_t>& indices,
const std::string& texture const Material& material
) { ) {
const glm::vec3* coords = nullptr; const glm::vec3* coords = nullptr;
const glm::vec2* uvs = nullptr; const glm::vec2* uvs = nullptr;
@ -112,7 +116,11 @@ static model::Mesh build_mesh(
} }
vertices.push_back(std::move(vertex)); vertices.push_back(std::move(vertex));
} }
return model::Mesh {texture, std::move(vertices)}; return model::Mesh {
material.name,
std::move(vertices),
(material.flags & MaterialFlag::SHADELESS) == 0
};
} }
static model::Mesh load_mesh( static model::Mesh load_mesh(
@ -154,7 +162,7 @@ static model::Mesh load_mesh(
return build_mesh( return build_mesh(
attributes, attributes,
indices, indices,
materials.at(materialId).name materials.at(materialId)
); );
} }

View file

@ -4,6 +4,7 @@
#include "logic/CommandsInterpreter.hpp" #include "logic/CommandsInterpreter.hpp"
#include "coders/json.hpp" #include "coders/json.hpp"
#include "debug/Logger.hpp" #include "debug/Logger.hpp"
#include "util/platform.hpp"
#include <thread> #include <thread>
#include <iostream> #include <iostream>
@ -18,7 +19,12 @@ void cmd::start_stdin_cmd_reader(Engine& engine) {
logger.info() << "reader thread started"; logger.info() << "reader thread started";
std::string line; std::string line;
while (std::getline(std::cin, line)) { while (true) {
if (!platform::stdin_has_data()) {
platform::sleep(10);
continue;
}
std::getline(std::cin, line);
if (line.empty()) { if (line.empty()) {
continue; continue;
} }

View file

@ -8,18 +8,16 @@
#include "graphics/core/DrawContext.hpp" #include "graphics/core/DrawContext.hpp"
#include "graphics/render/MainBatch.hpp" #include "graphics/render/MainBatch.hpp"
#include "lighting/Lightmap.hpp" #include "lighting/Lightmap.hpp"
#include "objects/Player.hpp"
#include "voxels/Block.hpp" #include "voxels/Block.hpp"
#include "voxels/Chunks.hpp" #include "voxels/Chunks.hpp"
#include "world/Level.hpp"
#include <algorithm> #include <algorithm>
BlockWrapsRenderer::BlockWrapsRenderer( BlockWrapsRenderer::BlockWrapsRenderer(
const Assets& assets, const Level& level, const Chunks& chunks const Assets& assets, const Content& content, const Chunks& chunks
) )
: assets(assets), : assets(assets),
level(level), content(content),
chunks(chunks), chunks(chunks),
batch(std::make_unique<MainBatch>(1024)) { batch(std::make_unique<MainBatch>(1024)) {
} }
@ -43,16 +41,14 @@ void BlockWrapsRenderer::draw(BlockWrapper& wrapper, const Texture* texture) {
} }
const voxel* vox = chunks.get(wrapper.position); const voxel* vox = chunks.get(wrapper.position);
if (vox == nullptr || vox->id == BLOCK_VOID) { if (vox == nullptr || vox->id == BLOCK_AIR) {
return; return;
} }
// one frame can be invalid due to texture change but ok // one frame can be invalid due to texture change but ok
const auto& def = const auto& def = content.getIndices()->blocks.require(vox->id);
level.content.getIndices()->blocks.require(vox->id);
if (wrapper.modelType != def.getModel(vox->state.userbits).type) { if (wrapper.modelType != def.getModel(vox->state.userbits).type) {
wrapper.dirtySides = 0xFF; wrapper.dirtySides = 0xFF;
refreshWrapper(wrapper);
} }
glm::vec4 light(1, 1, 1, 0); glm::vec4 light(1, 1, 1, 0);
if (wrapper.emission < 1.0f) { if (wrapper.emission < 1.0f) {
@ -95,6 +91,8 @@ void BlockWrapsRenderer::draw(BlockWrapper& wrapper, const Texture* texture) {
} }
void BlockWrapsRenderer::refreshWrapper(BlockWrapper& wrapper) { void BlockWrapsRenderer::refreshWrapper(BlockWrapper& wrapper) {
clearOrder(&wrapper);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
if ((wrapper.cullingBits & (1 << i)) == 0) { if ((wrapper.cullingBits & (1 << i)) == 0) {
continue; continue;
@ -104,15 +102,22 @@ void BlockWrapsRenderer::refreshWrapper(BlockWrapper& wrapper) {
wrapper.texRegions[i] = texRegion; wrapper.texRegions[i] = texRegion;
wrapper.uvRegions[i] = texRegion.region; wrapper.uvRegions[i] = texRegion.region;
renderOrder.insert({texRegion.texture, &wrapper}); auto range = renderOrder.equal_range(texRegion.texture);
auto it =
std::find_if(range.first, range.second, [&wrapper](auto& elem) {
return elem.second == &wrapper;
});
if (it == range.second) {
renderOrder.emplace(texRegion.texture, &wrapper);
}
} }
wrapper.dirtySides = 0x0; wrapper.dirtySides = 0x0;
const voxel* vox = chunks.get(wrapper.position); const voxel* vox = chunks.get(wrapper.position);
if (vox == nullptr || vox->id == BLOCK_VOID) { if (vox == nullptr || vox->id == BLOCK_AIR) {
return; return;
} }
const auto& def = level.content.getIndices()->blocks.require(vox->id); const auto& def = content.getIndices()->blocks.require(vox->id);
wrapper.modelType = def.getModel(vox->state.userbits).type; wrapper.modelType = def.getModel(vox->state.userbits).type;
switch (wrapper.modelType) { switch (wrapper.modelType) {
case BlockModelType::AABB: { case BlockModelType::AABB: {
@ -133,7 +138,7 @@ void BlockWrapsRenderer::refreshWrapper(BlockWrapper& wrapper) {
} }
} }
void BlockWrapsRenderer::draw(const DrawContext& pctx, const Player& player) { void BlockWrapsRenderer::draw(const DrawContext& pctx) {
auto ctx = pctx.sub(); auto ctx = pctx.sub();
auto& shader = assets.require<Shader>("entity"); auto& shader = assets.require<Shader>("entity");
@ -145,7 +150,6 @@ void BlockWrapsRenderer::draw(const DrawContext& pctx, const Player& player) {
refreshWrapper(*wrapper); refreshWrapper(*wrapper);
} }
} }
for (const auto& [texture, wrapper] : renderOrder) { for (const auto& [texture, wrapper] : renderOrder) {
batch->setTexture(texture); batch->setTexture(texture);
draw(*wrapper, texture); draw(*wrapper, texture);
@ -181,15 +185,17 @@ void BlockWrapsRenderer::remove(u64id_t id) {
if (found == wrappers.end()) { if (found == wrappers.end()) {
return; return;
} }
auto wrapper = std::move(found->second); clearOrder(found->second.get());
wrappers.erase(id); wrappers.erase(id);
}
void BlockWrapsRenderer::clearOrder(const BlockWrapper* const wrapper) {
auto it = renderOrder.begin(); auto it = renderOrder.begin();
while (it != renderOrder.end()) { while (it != renderOrder.end()) {
if (it->second == wrapper.get()) { if (it->second == wrapper) {
it = renderOrder.erase(it); it = renderOrder.erase(it);
} else { } else {
++it; ++it;
} }
} }
} }

View file

@ -10,12 +10,9 @@
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <map> #include <map>
#include <glm/vec4.hpp>
class Assets; class Assets;
class Player; class Content;
class Level;
struct voxel;
class Chunks; class Chunks;
class Texture; class Texture;
class DrawContext; class DrawContext;
@ -36,7 +33,7 @@ struct BlockWrapper {
class BlockWrapsRenderer { class BlockWrapsRenderer {
const Assets& assets; const Assets& assets;
const Level& level; const Content& content;
const Chunks& chunks; const Chunks& chunks;
std::unique_ptr<MainBatch> batch; std::unique_ptr<MainBatch> batch;
@ -47,13 +44,14 @@ class BlockWrapsRenderer {
void draw(BlockWrapper& wrapper, const Texture* texture); void draw(BlockWrapper& wrapper, const Texture* texture);
void refreshWrapper(BlockWrapper& wrapper); void refreshWrapper(BlockWrapper& wrapper);
void clearOrder(const BlockWrapper* const wrapper);
public: public:
BlockWrapsRenderer( BlockWrapsRenderer(
const Assets& assets, const Level& level, const Chunks& chunks const Assets& assets, const Content& content, const Chunks& chunks
); );
~BlockWrapsRenderer(); ~BlockWrapsRenderer();
void draw(const DrawContext& ctx, const Player& player); void draw(const DrawContext& ctx);
u64id_t add( u64id_t add(
const glm::ivec3& position, const glm::ivec3& position,

View file

@ -94,9 +94,9 @@ WorldRenderer::WorldRenderer(
assets, level, *player.chunks, engine.getSettings().graphics assets, level, *player.chunks, engine.getSettings().graphics
)), )),
texts(std::make_unique<TextsRenderer>(*batch3d, assets, *frustumCulling)), texts(std::make_unique<TextsRenderer>(*batch3d, assets, *frustumCulling)),
blockWraps( blockWraps(std::make_unique<BlockWrapsRenderer>(
std::make_unique<BlockWrapsRenderer>(assets, level, *player.chunks) assets, level.content, *player.chunks
) { )) {
auto& settings = engine.getSettings(); auto& settings = engine.getSettings();
level.events->listen( level.events->listen(
LevelEventType::CHUNK_HIDDEN, LevelEventType::CHUNK_HIDDEN,
@ -214,7 +214,7 @@ void WorldRenderer::renderOpaque(
setupWorldShader(shader, camera, settings, fogFactor); setupWorldShader(shader, camera, settings, fogFactor);
chunksRenderer->drawChunks(camera, shader); chunksRenderer->drawChunks(camera, shader);
blockWraps->draw(ctx, player); blockWraps->draw(ctx);
int cloudsQuality = settings.graphics.cloudsQuality.get(); int cloudsQuality = settings.graphics.cloudsQuality.get();
if (cloudsQuality > 0) { if (cloudsQuality > 0) {

View file

@ -34,10 +34,14 @@ static int l_set_pos(lua::State* L) {
static int l_set_texture(lua::State* L) { static int l_set_texture(lua::State* L) {
if (auto wrapper = renderer->blockWraps->get(lua::tointeger(L, 1))) { if (auto wrapper = renderer->blockWraps->get(lua::tointeger(L, 1))) {
const char* newTexture = lua::require_string(L, 2);
for (int i = 0; i < wrapper->textureFaces.size(); i++) { for (int i = 0; i < wrapper->textureFaces.size(); i++) {
wrapper->textureFaces[i] = lua::require_string(L, 2); if (wrapper->textureFaces[i] != newTexture) {
wrapper->textureFaces[i] = newTexture;
wrapper->dirtySides = 0xFF;
}
} }
wrapper->dirtySides = 0xFF;
} }
return 0; return 0;
} }
@ -52,7 +56,7 @@ static int l_set_faces(lua::State* L) {
wrapper->dirtySides |= (1 << i); wrapper->dirtySides |= (1 << i);
} }
} else { } else {
auto texture = lua::require_string(L, 2 + i);; auto texture = lua::require_string(L, 2 + i);
if ((wrapper->cullingBits & (1 << i)) == 0x0 if ((wrapper->cullingBits & (1 << i)) == 0x0
|| wrapper->textureFaces[i] != texture) { || wrapper->textureFaces[i] != texture) {
wrapper->cullingBits |= (1 << i); wrapper->cullingBits |= (1 << i);
@ -73,7 +77,6 @@ static int l_set_tints(lua::State* L) {
wrapper->tints[i] = lua::tovec3(L, 2 + i); wrapper->tints[i] = lua::tovec3(L, 2 + i);
} }
} }
wrapper->dirtySides = 0xFF;
} }
return 0; return 0;
} }

View file

@ -14,8 +14,10 @@
#ifdef _WIN32 #ifdef _WIN32
#include <Windows.h> #include <Windows.h>
#include <conio.h>
#pragma comment(lib, "winmm.lib") #pragma comment(lib, "winmm.lib")
#else #else
#include <sys/poll.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -290,3 +292,14 @@ void platform::new_engine_instance(const std::vector<std::string>& args) {
} }
#endif #endif
} }
bool platform::stdin_has_data() {
#ifdef _WIN32
return _kbhit();
#else
struct pollfd fds;
fds.fd = STDIN_FILENO;
fds.events = POLLIN;
return poll(&fds, 1, 0) == 1;
#endif
}

View file

@ -21,4 +21,6 @@ namespace platform {
void new_engine_instance(const std::vector<std::string>& args); void new_engine_instance(const std::vector<std::string>& args);
/// @brief Open URL in web browser /// @brief Open URL in web browser
bool open_url(const std::string& url); bool open_url(const std::string& url);
/// @brief Check if stdin has input
bool stdin_has_data();
} }