diff --git a/src/frontend/BlocksPreview.h b/src/frontend/BlocksPreview.h index 5c4ab4c1..586fce38 100644 --- a/src/frontend/BlocksPreview.h +++ b/src/frontend/BlocksPreview.h @@ -15,18 +15,19 @@ class Content; class ContentGfxCache; class BlocksPreview { -public: static ImageData* draw( const ContentGfxCache* cache, Framebuffer* framebuffer, Batch3D* batch, const Block* block, - int size); - + int size + ); +public: static std::unique_ptr build( const ContentGfxCache* cache, Assets* assets, - const Content* content); + const Content* content + ); }; #endif // FRONTEND_BLOCKS_PREVIEW_H_ diff --git a/src/frontend/WorldRenderer.cpp b/src/frontend/WorldRenderer.cpp index e83e1ed8..64c9a728 100644 --- a/src/frontend/WorldRenderer.cpp +++ b/src/frontend/WorldRenderer.cpp @@ -34,167 +34,172 @@ #include "graphics/Skybox.h" #include "graphics/ChunksRenderer.h" -using glm::vec3; -using glm::vec4; -using glm::mat4; - WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend) - : engine(engine), - level(frontend->getLevel()), - frustumCulling(new Frustum()), - lineBatch(new LineBatch()), - renderer(new ChunksRenderer(level, - frontend->getContentGfxCache(), - engine->getSettings())), - batch3d(new Batch3D(4096)) { + : engine(engine), + level(frontend->getLevel()) +{ + frustumCulling = std::make_unique(); + lineBatch = std::make_unique(); + renderer = std::make_unique( + level, + frontend->getContentGfxCache(), + engine->getSettings() + ); + batch3d = std::make_unique(4096); - auto& settings = engine->getSettings(); - level->events->listen(EVT_CHUNK_HIDDEN, - [this](lvl_event_type type, Chunk* chunk) { - renderer->unload(chunk); - } - ); - auto assets = engine->getAssets(); - skybox = new Skybox(settings.graphics.skyboxResolution, - assets->getShader("skybox_gen")); + auto& settings = engine->getSettings(); + level->events->listen(EVT_CHUNK_HIDDEN, + [this](lvl_event_type type, Chunk* chunk) { + renderer->unload(chunk); + } + ); + auto assets = engine->getAssets(); + skybox = std::make_unique( + settings.graphics.skyboxResolution, + assets->getShader("skybox_gen") + ); } WorldRenderer::~WorldRenderer() { - delete skybox; - delete lineBatch; - delete renderer; - delete frustumCulling; } -bool WorldRenderer::drawChunk(size_t index, - Camera* camera, - Shader* shader, - bool culling){ - auto chunk = level->chunks->chunks[index]; - if (!chunk->isLighted()) { - return false; - } +bool WorldRenderer::drawChunk( + size_t index, + Camera* camera, + Shader* shader, + bool culling +){ + auto chunk = level->chunks->chunks[index]; + if (!chunk->isLighted()) { + return false; + } float distance = glm::distance( camera->position, - glm::vec3((chunk->x + 0.5f) * CHUNK_W, camera->position.y, (chunk->z + 0.5f) * CHUNK_D) + glm::vec3((chunk->x + 0.5f) * CHUNK_W, + camera->position.y, + (chunk->z + 0.5f) * CHUNK_D) ); - auto mesh = renderer->getOrRender(chunk, distance < CHUNK_W*1.5f); - if (mesh == nullptr) { - return false; - } - if (culling){ - vec3 min(chunk->x * CHUNK_W, - chunk->bottom, - chunk->z * CHUNK_D); - vec3 max(chunk->x * CHUNK_W + CHUNK_W, - chunk->top, - chunk->z * CHUNK_D + CHUNK_D); + auto mesh = renderer->getOrRender(chunk, distance < CHUNK_W*1.5f); + if (mesh == nullptr) { + return false; + } + if (culling){ + glm::vec3 min( + chunk->x * CHUNK_W, + chunk->bottom, + chunk->z * CHUNK_D + ); + glm::vec3 max( + chunk->x * CHUNK_W + CHUNK_W, + chunk->top, + chunk->z * CHUNK_D + CHUNK_D + ); - if (!frustumCulling->IsBoxVisible(min, max)) return false; - } - vec3 coord = vec3(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f); - mat4 model = glm::translate(mat4(1.0f), coord); - shader->uniformMatrix("u_model", model); - mesh->draw(); - return true; + if (!frustumCulling->IsBoxVisible(min, max)) + return false; + } + glm::vec3 coord(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f); + glm::mat4 model = glm::translate(glm::mat4(1.0f), coord); + shader->uniformMatrix("u_model", model); + mesh->draw(); + return true; } -void WorldRenderer::drawChunks(Chunks* chunks, - Camera* camera, - Shader* shader) { +void WorldRenderer::drawChunks(Chunks* chunks, Camera* camera, Shader* shader) { renderer->update(); - std::vector indices; - for (size_t i = 0; i < chunks->volume; i++){ - if (chunks->chunks[i] == nullptr) - continue; - indices.push_back(i); - } - float px = camera->position.x / (float)CHUNK_W; - float pz = camera->position.z / (float)CHUNK_D; - std::sort(indices.begin(), indices.end(), [chunks, px, pz](size_t i, size_t j) { - auto a = chunks->chunks[i]; - auto b = chunks->chunks[j]; - return ((a->x + 0.5f - px)*(a->x + 0.5f - px) + - (a->z + 0.5f - pz)*(a->z + 0.5f - pz) - > - (b->x + 0.5f - px)*(b->x + 0.5f - px) + - (b->z + 0.5f - pz)*(b->z + 0.5f - pz)); - }); + std::vector indices; + for (size_t i = 0; i < chunks->volume; i++){ + if (chunks->chunks[i] == nullptr) + continue; + indices.push_back(i); + } + float px = camera->position.x / (float)CHUNK_W; + float pz = camera->position.z / (float)CHUNK_D; + std::sort(indices.begin(), indices.end(), [chunks, px, pz](size_t i, size_t j) { + auto a = chunks->chunks[i]; + auto b = chunks->chunks[j]; + return ((a->x + 0.5f - px)*(a->x + 0.5f - px) + + (a->z + 0.5f - pz)*(a->z + 0.5f - pz) + > + (b->x + 0.5f - px)*(b->x + 0.5f - px) + + (b->z + 0.5f - pz)*(b->z + 0.5f - pz)); + }); - bool culling = engine->getSettings().graphics.frustumCulling; - if (culling) { - frustumCulling->update(camera->getProjView()); - } - chunks->visible = 0; - for (size_t i = 0; i < indices.size(); i++){ - chunks->visible += drawChunk(indices[i], camera, shader, culling); - } + bool culling = engine->getSettings().graphics.frustumCulling; + if (culling) { + frustumCulling->update(camera->getProjView()); + } + chunks->visible = 0; + for (size_t i = 0; i < indices.size(); i++){ + chunks->visible += drawChunk(indices[i], camera, shader, culling); + } } void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible){ + EngineSettings& settings = engine->getSettings(); + Window::clearDepth(); - EngineSettings& settings = engine->getSettings(); - skybox->refresh(pctx, level->world->daytime, 1.0f+fog*2.0f, 4); + skybox->refresh(pctx, level->world->daytime, 1.0f+fog*2.0f, 4); - const Content* content = level->content; - auto indices = content->getIndices(); - Assets* assets = engine->getAssets(); - Atlas* atlas = assets->getAtlas("blocks"); - Shader* shader = assets->getShader("main"); + const Content* content = level->content; + auto indices = content->getIndices(); + Assets* assets = engine->getAssets(); + Atlas* atlas = assets->getAtlas("blocks"); + Shader* shader = assets->getShader("main"); - const Viewport& viewport = pctx.getViewport(); - int displayWidth = viewport.getWidth(); - int displayHeight = viewport.getHeight(); + const Viewport& viewport = pctx.getViewport(); + int displayWidth = viewport.getWidth(); + int displayHeight = viewport.getHeight(); - // Drawing background sky plane - skybox->draw(pctx, camera, assets, level->getWorld()->daytime, fog); + // Drawing background sky plane + skybox->draw(pctx, camera, assets, level->getWorld()->daytime, fog); - Shader* linesShader = assets->getShader("lines"); - { - GfxContext ctx = pctx.sub(); - ctx.depthTest(true); - ctx.cullFace(true); + Shader* linesShader = assets->getShader("lines"); + { + GfxContext ctx = pctx.sub(); + ctx.depthTest(true); + ctx.cullFace(true); - float fogFactor = 15.0f / ((float)settings.chunks.loadDistance-2); + float fogFactor = 15.0f / ((float)settings.chunks.loadDistance-2); - // Setting up main shader - shader->use(); - shader->uniformMatrix("u_proj", camera->getProjection()); - shader->uniformMatrix("u_view", camera->getView()); - shader->uniform1f("u_gamma", settings.graphics.gamma); - shader->uniform1f("u_fogFactor", fogFactor); - shader->uniform1f("u_fogCurve", settings.graphics.fogCurve); - shader->uniform3f("u_cameraPos", camera->position); - shader->uniform1i("u_cubemap", 1); - { + // Setting up main shader + shader->use(); + shader->uniformMatrix("u_proj", camera->getProjection()); + shader->uniformMatrix("u_view", camera->getView()); + shader->uniform1f("u_gamma", settings.graphics.gamma); + shader->uniform1f("u_fogFactor", fogFactor); + shader->uniform1f("u_fogCurve", settings.graphics.fogCurve); + shader->uniform3f("u_cameraPos", camera->position); + shader->uniform1i("u_cubemap", 1); + { auto player = level->player; auto inventory = player->getInventory(); ItemStack& stack = inventory->getSlot(player->getChosenSlot()); ItemDef* item = indices->getItemDef(stack.getItemId()); - assert(item != nullptr); - float multiplier = 0.5f; - shader->uniform3f("u_torchlightColor", - item->emission[0] / 15.0f * multiplier, - item->emission[1] / 15.0f * multiplier, - item->emission[2] / 15.0f * multiplier); - shader->uniform1f("u_torchlightDistance", 6.0f); - } + assert(item != nullptr); + float multiplier = 0.5f; + shader->uniform3f("u_torchlightColor", + item->emission[0] / 15.0f * multiplier, + item->emission[1] / 15.0f * multiplier, + item->emission[2] / 15.0f * multiplier); + shader->uniform1f("u_torchlightDistance", 6.0f); + } - // Binding main shader textures - skybox->bind(); - atlas->getTexture()->bind(); + // Binding main shader textures + skybox->bind(); + atlas->getTexture()->bind(); - drawChunks(level->chunks, camera, shader); + drawChunks(level->chunks, camera, shader); - // Selected block - if (PlayerController::selectedBlockId != -1 && hudVisible){ - blockid_t id = PlayerController::selectedBlockId; - Block* block = indices->getBlockDef(id); - assert(block != nullptr); - const vec3 pos = PlayerController::selectedBlockPosition; - const vec3 point = PlayerController::selectedPointPosition; - const vec3 norm = PlayerController::selectedBlockNormal; + // Selected block + if (PlayerController::selectedBlockId != -1 && hudVisible){ + blockid_t id = PlayerController::selectedBlockId; + Block* block = indices->getBlockDef(id); + assert(block != nullptr); + const glm::vec3 pos = PlayerController::selectedBlockPosition; + const glm::vec3 point = PlayerController::selectedPointPosition; + const glm::vec3 norm = PlayerController::selectedBlockNormal; std::vector& hitboxes = block->rotatable ? block->rt.hitboxes[PlayerController::selectedBlockStates] @@ -204,95 +209,96 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible linesShader->uniformMatrix("u_projview", camera->getProjView()); lineBatch->lineWidth(2.0f); for (auto& hitbox: hitboxes) { - const vec3 center = pos + hitbox.center(); - const vec3 size = hitbox.size(); - lineBatch->box(center, size + vec3(0.02), vec4(0.f, 0.f, 0.f, 0.5f)); - if (level->player->debug) - lineBatch->line(point, point+norm*0.5f, vec4(1.0f, 0.0f, 1.0f, 1.0f)); + const glm::vec3 center = pos + hitbox.center(); + const glm::vec3 size = hitbox.size(); + lineBatch->box(center, size + glm::vec3(0.02), glm::vec4(0.f, 0.f, 0.f, 0.5f)); + if (level->player->debug) { + lineBatch->line(point, point+norm*0.5f, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f)); + } } - lineBatch->render(); - } - skybox->unbind(); - } + lineBatch->render(); + } + skybox->unbind(); + } - if (hudVisible && level->player->debug) { - GfxContext ctx = pctx.sub(); - ctx.depthTest(true); + if (hudVisible && level->player->debug) { + GfxContext ctx = pctx.sub(); + ctx.depthTest(true); - linesShader->use(); + linesShader->use(); - if (settings.debug.showChunkBorders){ - linesShader->uniformMatrix("u_projview", camera->getProjView()); - vec3 coord = level->player->camera->position; - if (coord.x < 0) coord.x--; - if (coord.z < 0) coord.z--; - int cx = floordiv((int)coord.x, CHUNK_W); - int cz = floordiv((int)coord.z, CHUNK_D); + if (settings.debug.showChunkBorders){ + linesShader->uniformMatrix("u_projview", camera->getProjView()); + glm::vec3 coord = level->player->camera->position; + if (coord.x < 0) coord.x--; + if (coord.z < 0) coord.z--; + int cx = floordiv((int)coord.x, CHUNK_W); + int cz = floordiv((int)coord.z, CHUNK_D); - drawBorders(cx * CHUNK_W, 0, cz * CHUNK_D, - (cx + 1) * CHUNK_W, CHUNK_H, (cz + 1) * CHUNK_D); - } + drawBorders(cx * CHUNK_W, 0, cz * CHUNK_D, + (cx + 1) * CHUNK_W, CHUNK_H, (cz + 1) * CHUNK_D); + } - float length = 40.f; - vec3 tsl = vec3(displayWidth/2, displayHeight/2, 0.f); - glm::mat4 model(glm::translate(glm::mat4(1.f), tsl)); - linesShader->uniformMatrix("u_projview", glm::ortho( - 0.f, (float)displayWidth, - 0.f, (float)displayHeight, - -length, length) * model * glm::inverse(camera->rotation)); + float length = 40.f; + glm::vec3 tsl(displayWidth/2, displayHeight/2, 0.f); + glm::mat4 model(glm::translate(glm::mat4(1.f), tsl)); + linesShader->uniformMatrix("u_projview", glm::ortho( + 0.f, (float)displayWidth, + 0.f, (float)displayHeight, + -length, length) * model * glm::inverse(camera->rotation)); - ctx.depthTest(false); - lineBatch->lineWidth(4.0f); - lineBatch->line(0.f, 0.f, 0.f, length, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); - lineBatch->line(0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 0.f, 0.f, 1.f); - lineBatch->line(0.f, 0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 0.f, 1.f); - lineBatch->render(); + ctx.depthTest(false); + lineBatch->lineWidth(4.0f); + lineBatch->line(0.f, 0.f, 0.f, length, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); + lineBatch->line(0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 0.f, 0.f, 1.f); + lineBatch->line(0.f, 0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 0.f, 1.f); + lineBatch->render(); - ctx.depthTest(true); - lineBatch->lineWidth(2.0f); - lineBatch->line(0.f, 0.f, 0.f, length, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f); - lineBatch->line(0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 1.f, 0.f, 1.f); - lineBatch->line(0.f, 0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 1.f, 1.f); - lineBatch->render(); - } + ctx.depthTest(true); + lineBatch->lineWidth(2.0f); + lineBatch->line(0.f, 0.f, 0.f, length, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f); + lineBatch->line(0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 1.f, 0.f, 1.f); + lineBatch->line(0.f, 0.f, 0.f, 0.f, 0.f, length, 0.f, 0.f, 1.f, 1.f); + lineBatch->render(); + } } void WorldRenderer::drawBorders(int sx, int sy, int sz, int ex, int ey, int ez) { - int ww = ex-sx; - int dd = ez-sz; - /*corner*/ { - lineBatch->line(sx, sy, sz, - sx, ey, sz, 0.8f, 0, 0.8f, 1); - lineBatch->line(sx, sy, ez, - sx, ey, ez, 0.8f, 0, 0.8f, 1); - lineBatch->line(ex, sy, sz, - ex, ey, sz, 0.8f, 0, 0.8f, 1); - lineBatch->line(ex, sy, ez, - ex, ey, ez, 0.8f, 0, 0.8f, 1); - } - for (int i = 2; i < ww; i+=2) { - lineBatch->line(sx + i, sy, sz, - sx + i, ey, sz, 0, 0, 0.8f, 1); - lineBatch->line(sx + i, sy, ez, - sx + i, ey, ez, 0, 0, 0.8f, 1); - } - for (int i = 2; i < dd; i+=2) { - lineBatch->line(sx, sy, sz + i, - sx, ey, sz + i, 0.8f, 0, 0, 1); - lineBatch->line(ex, sy, sz + i, - ex, ey, sz + i, 0.8f, 0, 0, 1); - } - for (int i = sy; i < ey; i+=2){ - lineBatch->line(sx, i, sz, - sx, i, ez, 0, 0.8f, 0, 1); - lineBatch->line(sx, i, ez, - ex, i, ez, 0, 0.8f, 0, 1); - lineBatch->line(ex, i, ez, - ex, i, sz, 0, 0.8f, 0, 1); - lineBatch->line(ex, i, sz, - sx, i, sz, 0, 0.8f, 0, 1); - } - lineBatch->render(); + int ww = ex-sx; + int dd = ez-sz; + /*corner*/ { + lineBatch->line(sx, sy, sz, + sx, ey, sz, 0.8f, 0, 0.8f, 1); + lineBatch->line(sx, sy, ez, + sx, ey, ez, 0.8f, 0, 0.8f, 1); + lineBatch->line(ex, sy, sz, + ex, ey, sz, 0.8f, 0, 0.8f, 1); + lineBatch->line(ex, sy, ez, + ex, ey, ez, 0.8f, 0, 0.8f, 1); + } + for (int i = 2; i < ww; i+=2) { + lineBatch->line(sx + i, sy, sz, + sx + i, ey, sz, 0, 0, 0.8f, 1); + lineBatch->line(sx + i, sy, ez, + sx + i, ey, ez, 0, 0, 0.8f, 1); + } + for (int i = 2; i < dd; i+=2) { + lineBatch->line(sx, sy, sz + i, + sx, ey, sz + i, 0.8f, 0, 0, 1); + lineBatch->line(ex, sy, sz + i, + ex, ey, sz + i, 0.8f, 0, 0, 1); + } + for (int i = sy; i < ey; i+=2){ + lineBatch->line(sx, i, sz, + sx, i, ez, 0, 0.8f, 0, 1); + lineBatch->line(sx, i, ez, + ex, i, ez, 0, 0.8f, 0, 1); + lineBatch->line(ex, i, ez, + ex, i, sz, 0, 0.8f, 0, 1); + lineBatch->line(ex, i, sz, + sx, i, sz, 0, 0.8f, 0, 1); + } + lineBatch->render(); } float WorldRenderer::fog = 0.0f; diff --git a/src/frontend/WorldRenderer.h b/src/frontend/WorldRenderer.h index c08b37fb..289f3b2f 100644 --- a/src/frontend/WorldRenderer.h +++ b/src/frontend/WorldRenderer.h @@ -27,24 +27,24 @@ class LevelFrontend; class Skybox; class WorldRenderer { - Engine* engine; - Level* level; - Frustum* frustumCulling; - LineBatch* lineBatch; - ChunksRenderer* renderer; - Skybox* skybox; + Engine* engine; + Level* level; + std::unique_ptr frustumCulling; + std::unique_ptr lineBatch; + std::unique_ptr renderer; + std::unique_ptr skybox; std::unique_ptr batch3d; - bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); - void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); + bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling); + void drawChunks(Chunks* chunks, Camera* camera, Shader* shader); public: - WorldRenderer(Engine* engine, LevelFrontend* frontend); - ~WorldRenderer(); + WorldRenderer(Engine* engine, LevelFrontend* frontend); + ~WorldRenderer(); - void draw(const GfxContext& context, Camera* camera, bool hudVisible); - void drawDebug(const GfxContext& context, Camera* camera); - void drawBorders(int sx, int sy, int sz, int ex, int ey, int ez); + void draw(const GfxContext& context, Camera* camera, bool hudVisible); + void drawDebug(const GfxContext& context, Camera* camera); + void drawBorders(int sx, int sy, int sz, int ex, int ey, int ez); - static float fog; + static float fog; }; diff --git a/src/logic/scripting/lua/api_lua.cpp b/src/logic/scripting/lua/api_lua.cpp index 54ef6909..aaa490be 100644 --- a/src/logic/scripting/lua/api_lua.cpp +++ b/src/logic/scripting/lua/api_lua.cpp @@ -106,7 +106,7 @@ int l_file_read_bytes(lua_State* L) { lua_createtable(L, length, 0); int newTable = lua_gettop(L); - for(int i = 0;i < length;i++) { + for(size_t i = 0; i < length; i++) { lua_pushnumber(L, bytes[i]); lua_rawseti(L, newTable, i+1); } diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 1832d17e..d0403261 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -11,14 +11,14 @@ #define BLOCK_ITEM_SUFFIX ".item" -const uint FACE_MX = 0; -const uint FACE_PX = 1; -const uint FACE_MY = 2; -const uint FACE_PY = 3; -const uint FACE_MZ = 4; -const uint FACE_PZ = 5; +inline constexpr uint FACE_MX = 0; +inline constexpr uint FACE_PX = 1; +inline constexpr uint FACE_MY = 2; +inline constexpr uint FACE_PY = 3; +inline constexpr uint FACE_MZ = 4; +inline constexpr uint FACE_PZ = 5; -const uint BLOCK_AABB_GRID = 16; +inline constexpr uint BLOCK_AABB_GRID = 16; struct block_funcs_set { bool init: 1; diff --git a/src/voxels/Chunk.h b/src/voxels/Chunk.h index 55978b2b..3eeff2c9 100644 --- a/src/voxels/Chunk.h +++ b/src/voxels/Chunk.h @@ -17,7 +17,7 @@ struct ChunkFlag { static const int UNSAVED = 0x10; static const int LOADED_LIGHTS = 0x20; }; -constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4; +inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4; class Lightmap; class ContentLUT;