diff --git a/res/font_0.png b/res/font_0.png new file mode 100644 index 00000000..0f156612 Binary files /dev/null and b/res/font_0.png differ diff --git a/res/font_1.png b/res/font_1.png new file mode 100644 index 00000000..92d7b2b3 Binary files /dev/null and b/res/font_1.png differ diff --git a/res/font_2.png b/res/font_2.png new file mode 100644 index 00000000..984affe8 Binary files /dev/null and b/res/font_2.png differ diff --git a/res/font_3.png b/res/font_3.png new file mode 100644 index 00000000..49b44eec Binary files /dev/null and b/res/font_3.png differ diff --git a/res/font_4.png b/res/font_4.png new file mode 100644 index 00000000..b2c0445c Binary files /dev/null and b/res/font_4.png differ diff --git a/src/declarations.h b/src/declarations.h index 43bacaeb..8890b849 100644 --- a/src/declarations.h +++ b/src/declarations.h @@ -34,12 +34,16 @@ bool _load_texture(Assets* assets, std::string filename, std::string name){ } bool _load_font(Assets* assets, std::string filename, std::string name){ - Texture* texture = load_texture(filename); - if (texture == nullptr){ - std::cerr << "failed to load bitmap font '" << name << "'" << std::endl; - return false; + std::vector 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(); }