From bdd3fbf7d4f9b73cbe5fa2ba9108cafb673a967d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 14 Jul 2022 19:23:31 +0300 Subject: [PATCH] Added 3 unicode pages for font, fixed UI, added Block.breakable Added 1, 2, 3 and 4 unicode pages from Minecraft. Font now uses std::wstring instead of std::string Added Block.breakable field (the only unbreakable block is bedrock) Bedrock is now selectable --- res/font_0.png | Bin 0 -> 6483 bytes res/font_1.png | Bin 0 -> 27588 bytes res/font_2.png | Bin 0 -> 5711 bytes res/font_3.png | Bin 0 -> 5457 bytes res/font_4.png | Bin 0 -> 6201 bytes src/declarations.h | 22 ++++++++++------- src/files/WorldFiles.cpp | 2 +- src/graphics/Batch2D.cpp | 11 +++++++-- src/graphics/Font.cpp | 44 ++++++++++++++++++++++------------ src/graphics/Font.h | 11 +++++---- src/lighting/Lighting.cpp | 2 ++ src/player_control.cpp | 3 ++- src/voxel_engine.cpp | 4 ++-- src/voxels/Block.h | 1 + src/voxels/ChunksLoader.cpp | 8 +++++++ src/voxels/WorldGenerator.cpp | 14 ++++++++--- src/world_render.h | 19 +++++++-------- 17 files changed, 94 insertions(+), 47 deletions(-) create mode 100644 res/font_0.png create mode 100644 res/font_1.png create mode 100644 res/font_2.png create mode 100644 res/font_3.png create mode 100644 res/font_4.png diff --git a/res/font_0.png b/res/font_0.png new file mode 100644 index 0000000000000000000000000000000000000000..0f15661240f2589c102c344392a0257d44f42148 GIT binary patch literal 6483 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ⅆdRCQmc zjtUS&UA>{2uTU0D-Emp~F EFWeP*!vFvP literal 0 HcmV?d00001 diff --git a/res/font_1.png b/res/font_1.png new file mode 100644 index 0000000000000000000000000000000000000000..92d7b2b35e7ef000e22ac6d8f524db05a5a72c1a GIT binary patch literal 27588 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 literal 0 HcmV?d00001 diff --git a/res/font_2.png b/res/font_2.png new file mode 100644 index 0000000000000000000000000000000000000000..984affe852d81090adb746fb10274ebc247f20e5 GIT binary patch literal 5711 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 Y)~YI=)?_wa5=94SYdlu3R7HmU5C4;iQ~&?~ literal 0 HcmV?d00001 diff --git a/res/font_3.png b/res/font_3.png new file mode 100644 index 0000000000000000000000000000000000000000..49b44eec77081ac5195d61ea73b89661af03c6c5 GIT binary patch literal 5457 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 RMAkr-~DT4GWNE2yN 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 pages; + for (size_t i = 0; i <= 4; i++){ + Texture* texture = load_texture(filename+"_"+std::to_string(i)+".png"); + if (texture == nullptr){ + std::cerr << "failed to load bitmap font '" << name << "' (missing page " << std::to_string(i) << ")" << std::endl; + return false; + } + pages.push_back(texture); } - Font* font = new Font(texture); + Font* font = new Font(pages); assets->store(font, name); return true; } @@ -62,13 +66,15 @@ int initialize_assets(Assets* assets) { LOAD_TEXTURE("res/block.png", "block"); - LOAD_FONT("res/font.png", "normal"); + LOAD_FONT("res/font", "normal"); return 0; } // All in-game definitions (blocks, items, etc..) void setup_definitions() { + for (size_t i = 0; i < 256; i++) + Block::blocks[i] = nullptr; // AIR 0 Block* block = new Block(0,0); block->drawGroup = 1; @@ -128,13 +134,13 @@ void setup_definitions() { block->selectable = false; Block::blocks[block->id] = block; - // SEND 10 + // SAND 10 block = new Block(10,12); Block::blocks[block->id] = block; // BEDROCK 11 block = new Block(11,13); - block->selectable = false; + block->breakable = false; Block::blocks[block->id] = block; } #endif // DECLARATIONS_H diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 850d045a..f9ae26ba 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -210,7 +210,7 @@ bool WorldFiles::readPlayer(Player* player) { size_t length = 0; char* data = read_binary_file(getPlayerFile(), length); if (data == nullptr){ - std::cerr << "could not to read player.bin" << std::endl; + std::cerr << "could not to read player.bin (ignored)" << std::endl; return false; } glm::vec3 position = player->hitbox->position; diff --git a/src/graphics/Batch2D.cpp b/src/graphics/Batch2D.cpp index fe2dc250..45a00579 100644 --- a/src/graphics/Batch2D.cpp +++ b/src/graphics/Batch2D.cpp @@ -4,6 +4,8 @@ #include +#define VERTEX_SIZE 8 + Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){ @@ -11,7 +13,7 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), 2, 2, 4, 0 //null terminator }; - buffer = new float[capacity * 8]; + buffer = new float[capacity * VERTEX_SIZE]; mesh = new Mesh(buffer, 0, attrs); index = 0; @@ -49,6 +51,7 @@ void Batch2D::vertex(float x, float y, void Batch2D::texture(Texture* new_texture){ if (_texture == new_texture) return; + render(); _texture = new_texture; if (new_texture == nullptr) blank->bind(); @@ -61,6 +64,8 @@ void Batch2D::rect(float x, float y, float w, float h){ const float g = color.g; const float b = color.b; const float a = color.a; + if (index + 6*VERTEX_SIZE >= capacity) + render(); vertex(x, y, 0, 0, r,g,b,a); vertex(x+w, y+h, 1, 1, r,g,b,a); @@ -81,6 +86,8 @@ void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index void Batch2D::rect(float x, float y, float w, float h, float u, float v, float tx, float ty, float r, float g, float b, float a){ + if (index + 6*VERTEX_SIZE >= capacity) + render(); vertex(x, y, u, v+ty, r,g,b,a); vertex(x+w, y+h, u+tx, v, r,g,b,a); vertex(x, y+h, u, v, r,g,b,a); @@ -91,7 +98,7 @@ void Batch2D::rect(float x, float y, float w, float h, } void Batch2D::render() { - mesh->reload(buffer, index / 8); + mesh->reload(buffer, index / VERTEX_SIZE); mesh->draw(GL_TRIANGLES); index = 0; } diff --git a/src/graphics/Font.cpp b/src/graphics/Font.cpp index a2b98e80..b35257bd 100644 --- a/src/graphics/Font.cpp +++ b/src/graphics/Font.cpp @@ -2,11 +2,12 @@ #include "Texture.h" #include "Batch2D.h" -Font::Font(Texture* texture) : texture(texture) { +Font::Font(std::vector pages) : pages(pages) { } Font::~Font(){ - delete texture; + for (Texture* texture : pages) + delete texture; } int Font::getGlyphWidth(char c) { @@ -26,7 +27,7 @@ int Font::getGlyphWidth(char c) { } -bool Font::isPrintableChar(char c) { +bool Font::isPrintableChar(int c) { switch (c){ case ' ': case '\t': @@ -39,20 +40,33 @@ bool Font::isPrintableChar(char c) { } } +#define RES 16 -void Font::draw(Batch2D* batch, std::string text, int x, int y) { - for (char c : text){ - if (isPrintableChar(c)) - batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); - x += getGlyphWidth(c); - } -} - -void Font::drawWithShadow(Batch2D* batch, std::string text, int x, int y) { - for (char c : text){ +void Font::draw(Batch2D* batch, std::wstring text, int x, int y) { + for (unsigned c : text){ if (isPrintableChar(c)){ - batch->sprite(x+1, y+1, 8, 8, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); + batch->texture(pages[c >> 8]); + batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); + } + x += getGlyphWidth(c); + } +} + +void Font::drawWithShadow(Batch2D* batch, std::wstring text, int x, int y) { + for (unsigned c : text){ + if (isPrintableChar(c)){ + batch->texture(pages[c >> 8]); + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + batch->sprite(x-1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y-1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(x-1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f)); } x += getGlyphWidth(c); } diff --git a/src/graphics/Font.h b/src/graphics/Font.h index f65ba3d7..61976903 100644 --- a/src/graphics/Font.h +++ b/src/graphics/Font.h @@ -2,20 +2,21 @@ #define GRAPHICS_FONT_H_ #include +#include class Texture; class Batch2D; class Font { public: - Texture* texture; - Font(Texture* texture); + std::vector pages; + Font(std::vector pages); ~Font(); int getGlyphWidth(char c); - bool isPrintableChar(char c); - void draw(Batch2D* batch, std::string text, int x, int y); - void drawWithShadow(Batch2D* batch, std::string text, int x, int y); + bool isPrintableChar(int c); + void draw(Batch2D* batch, std::wstring text, int x, int y); + void drawWithShadow(Batch2D* batch, std::wstring text, int x, int y); }; #endif /* GRAPHICS_FONT_H_ */ diff --git a/src/lighting/Lighting.cpp b/src/lighting/Lighting.cpp index 12bca112..b1fe4f80 100644 --- a/src/lighting/Lighting.cpp +++ b/src/lighting/Lighting.cpp @@ -6,6 +6,8 @@ #include "../voxels/voxel.h" #include "../voxels/Block.h" +#include + Lighting::Lighting(Chunks* chunks){ this->chunks = chunks; solverR = new LightSolver(chunks, 0); diff --git a/src/player_control.cpp b/src/player_control.cpp index 6b814fba..b8e5f407 100644 --- a/src/player_control.cpp +++ b/src/player_control.cpp @@ -6,6 +6,7 @@ #include "physics/Hitbox.h" #include "lighting/Lighting.h" #include "world/Level.h" +#include "voxels/Block.h" #include "voxels/voxel.h" #include "voxels/Chunks.h" #include "window/Camera.h" @@ -175,7 +176,7 @@ void update_interaction(Level* level, LineBatch* lineBatch){ if (vox != nullptr){ lineBatch->box(iend.x+0.5f, iend.y+0.5f, iend.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f); - if (Events::jclicked(GLFW_MOUSE_BUTTON_1)){ + if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && Block::blocks[vox->id]->breakable){ int x = (int)iend.x; int y = (int)iend.y; int z = (int)iend.z; diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 4eafd412..d4a986d6 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -104,7 +104,7 @@ Level* load_level(World* world, Player* player) { int initialize(Assets*& assets){ Audio::initialize(); - Window::initialize(WIDTH, HEIGHT, "Window 2.0"); + Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v.12"); Events::initialize(); assets = new Assets(); @@ -127,7 +127,7 @@ int main() { if (status) return status; std::cout << "-- loading world" << std::endl; - vec3 playerPosition = vec3(-320,200,32); + vec3 playerPosition = vec3(0,150,-10); Camera* camera = new Camera(playerPosition, radians(90.0f)); World* world = new World("world-1", "world/", 42); Player* player = new Player(playerPosition, 4.0f, camera); diff --git a/src/voxels/Block.h b/src/voxels/Block.h index 58010e70..cd66322b 100644 --- a/src/voxels/Block.h +++ b/src/voxels/Block.h @@ -14,6 +14,7 @@ public: bool skyLightPassing = false; bool obstacle = true; bool selectable = true; + bool breakable = true; Block(unsigned int id, int texture); }; diff --git a/src/voxels/ChunksLoader.cpp b/src/voxels/ChunksLoader.cpp index 4c4796ad..0b41241d 100644 --- a/src/voxels/ChunksLoader.cpp +++ b/src/voxels/ChunksLoader.cpp @@ -3,6 +3,8 @@ #include "Chunk.h" #include "Chunks.h" +#include "Block.h" +#include "voxel.h" #include "../world/World.h" #include "WorldGenerator.h" #include "../lighting/Lighting.h" @@ -36,6 +38,12 @@ void ChunksLoader::_thread(){ WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed); } + for (size_t i = 0; i < CHUNK_VOL; i++){ + if (Block::blocks[chunk->voxels[i].id] == nullptr){ + std::cout << "corruped block detected at " << i << " of chunk " << chunk->x << "x" << chunk->z << std::endl; + chunk->voxels[i].id = 11; + } + } lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true); } else if (state == RENDER){ diff --git a/src/voxels/WorldGenerator.cpp b/src/voxels/WorldGenerator.cpp index a1495004..d7be2a78 100644 --- a/src/voxels/WorldGenerator.cpp +++ b/src/voxels/WorldGenerator.cpp @@ -28,12 +28,16 @@ public: }; float calc_height(fnl_state *noise, int real_x, int real_z){ - const float s = 0.2f; + const float s = 0.18f; float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f); height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f; height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; + height += fnlGetNoise3D(noise, + real_x*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*50, + real_z*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32+4363,real_z*0.1f*s*32, 0.0f)*50, + 0.0f)*0.1f; height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.0625f; // height += fnlGetNoise3D(noise, real_x*s*32,real_z*s*32, 0.0f)*0.03f; height = height * 0.5f + 0.5f; @@ -44,13 +48,17 @@ float calc_height(fnl_state *noise, int real_x, int real_z){ } float calc_height_faster(fnl_state *noise, int real_x, int real_z){ - const float s = 0.2f; + const float s = 0.18f; float height = fnlGetNoise3D(noise, real_x*0.0125f*s*32,real_z*0.0125f*s*32, 0.0f); height += fnlGetNoise3D(noise, real_x*0.025f*s*32,real_z*0.025f*s*32, 0.0f)*0.5f; height += fnlGetNoise3D(noise, real_x*0.05f*s*32,real_z*0.05f*s*32, 0.0f)*0.25f; height += fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*0.225f; height += fnlGetNoise3D(noise, real_x*0.2f*s*32,real_z*0.2f*s*32, 0.0f)*0.125f; - //height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F; + height += fnlGetNoise3D(noise, + real_x*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32,real_z*0.1f*s*32, 0.0f)*50, + real_z*0.2f*s*32 + fnlGetNoise3D(noise, real_x*0.1f*s*32+4363,real_z*0.1f*s*32, 0.0f)*50, + 0.0f)*0.1f; + // height += fnlGetNoise3D(noise, real_x*0.4f*s*32,real_z*0.4f*s*32, 0.0f)*0.125f*0.5F; height = height * 0.5f + 0.5f; height *= height; height *= (140.0f)*0.12f/s; diff --git a/src/world_render.h b/src/world_render.h index d50c68f6..fb876138 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -41,7 +41,7 @@ int attrs[] = { 2, 0 //null terminator }; -int uiscale = 2; +int uiscale = 1; LineBatch *lineBatch; Batch2D *batch; @@ -127,14 +127,13 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) // draw debug info Font* font = assets->getFont("normal"); batch->begin(); - batch->texture(font->texture); if (devdata){ - font->drawWithShadow(batch, "chunks: "+std::to_string(chunks->chunksCount), 16, 16); - font->drawWithShadow(batch, std::to_string((int)player->camera->position.x), 10, 30); - font->drawWithShadow(batch, std::to_string((int)player->camera->position.y), 50, 30); - font->drawWithShadow(batch, std::to_string((int)player->camera->position.z), 90, 30); - font->drawWithShadow(batch, "fps:", 16, 42); - font->drawWithShadow(batch, std::to_string(fps), 40, 42); + font->drawWithShadow(batch, L"рандом chunks: "+std::to_wstring(chunks->chunksCount), 16, 16); + font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.x), 10, 30); + font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.y), 50, 30); + font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.z), 90, 30); + font->drawWithShadow(batch, L"fps:", 16, 42); + font->drawWithShadow(batch, std::to_wstring(fps), 40, 42); } batch->render(); @@ -143,8 +142,8 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps) batch->texture(blocks); int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block - batch->sprite(14, 278, 68, 68, 16, texid, vec4(0.0f, 0.0f, 0.0f, 1.0f)); - batch->sprite(16, 280, 64, 64, 16, texid, vec4(1.0f)); + batch->sprite(14, Window::height-82, 68, 68, 16, texid, vec4(0.0f, 0.0f, 0.0f, 1.0f)); + batch->sprite(16, Window::height-80, 64, 64, 16, texid, vec4(1.0f)); batch->render(); }