mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-13 15:01:49 +00:00
commit
5502c2e7ad
9 changed files with 75 additions and 35 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue