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
This commit is contained in:
MihailRis 2022-07-14 19:23:31 +03:00 committed by GitHub
parent b2872650d6
commit bdd3fbf7d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 94 additions and 47 deletions

BIN
res/font_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
res/font_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
res/font_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
res/font_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
res/font_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -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){ bool _load_font(Assets* assets, std::string filename, std::string name){
Texture* texture = load_texture(filename); std::vector<Texture*> pages;
if (texture == nullptr){ for (size_t i = 0; i <= 4; i++){
std::cerr << "failed to load bitmap font '" << name << "'" << std::endl; Texture* texture = load_texture(filename+"_"+std::to_string(i)+".png");
return false; 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); assets->store(font, name);
return true; return true;
} }
@ -62,13 +66,15 @@ int initialize_assets(Assets* assets) {
LOAD_TEXTURE("res/block.png", "block"); LOAD_TEXTURE("res/block.png", "block");
LOAD_FONT("res/font.png", "normal"); LOAD_FONT("res/font", "normal");
return 0; return 0;
} }
// All in-game definitions (blocks, items, etc..) // All in-game definitions (blocks, items, etc..)
void setup_definitions() { void setup_definitions() {
for (size_t i = 0; i < 256; i++)
Block::blocks[i] = nullptr;
// AIR 0 // AIR 0
Block* block = new Block(0,0); Block* block = new Block(0,0);
block->drawGroup = 1; block->drawGroup = 1;
@ -128,13 +134,13 @@ void setup_definitions() {
block->selectable = false; block->selectable = false;
Block::blocks[block->id] = block; Block::blocks[block->id] = block;
// SEND 10 // SAND 10
block = new Block(10,12); block = new Block(10,12);
Block::blocks[block->id] = block; Block::blocks[block->id] = block;
// BEDROCK 11 // BEDROCK 11
block = new Block(11,13); block = new Block(11,13);
block->selectable = false; block->breakable = false;
Block::blocks[block->id] = block; Block::blocks[block->id] = block;
} }
#endif // DECLARATIONS_H #endif // DECLARATIONS_H

View File

@ -210,7 +210,7 @@ bool WorldFiles::readPlayer(Player* player) {
size_t length = 0; size_t length = 0;
char* data = read_binary_file(getPlayerFile(), length); char* data = read_binary_file(getPlayerFile(), length);
if (data == nullptr){ 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; return false;
} }
glm::vec3 position = player->hitbox->position; glm::vec3 position = player->hitbox->position;

View File

@ -4,6 +4,8 @@
#include <GL/glew.h> #include <GL/glew.h>
#define VERTEX_SIZE 8
Batch2D::Batch2D(size_t capacity) : capacity(capacity), Batch2D::Batch2D(size_t capacity) : capacity(capacity),
offset(0), offset(0),
color(1.0f, 1.0f, 1.0f, 1.0f){ 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 2, 2, 4, 0 //null terminator
}; };
buffer = new float[capacity * 8]; buffer = new float[capacity * VERTEX_SIZE];
mesh = new Mesh(buffer, 0, attrs); mesh = new Mesh(buffer, 0, attrs);
index = 0; index = 0;
@ -49,6 +51,7 @@ void Batch2D::vertex(float x, float y,
void Batch2D::texture(Texture* new_texture){ void Batch2D::texture(Texture* new_texture){
if (_texture == new_texture) if (_texture == new_texture)
return; return;
render();
_texture = new_texture; _texture = new_texture;
if (new_texture == nullptr) if (new_texture == nullptr)
blank->bind(); blank->bind();
@ -61,6 +64,8 @@ void Batch2D::rect(float x, float y, float w, float h){
const float g = color.g; const float g = color.g;
const float b = color.b; const float b = color.b;
const float a = color.a; const float a = color.a;
if (index + 6*VERTEX_SIZE >= capacity)
render();
vertex(x, y, 0, 0, r,g,b,a); vertex(x, y, 0, 0, r,g,b,a);
vertex(x+w, y+h, 1, 1, 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, void Batch2D::rect(float x, float y, float w, float h,
float u, float v, float tx, float ty, float u, float v, float tx, float ty,
float r, float g, float b, float a){ 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, y, u, v+ty, r,g,b,a);
vertex(x+w, y+h, u+tx, v, 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); 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() { void Batch2D::render() {
mesh->reload(buffer, index / 8); mesh->reload(buffer, index / VERTEX_SIZE);
mesh->draw(GL_TRIANGLES); mesh->draw(GL_TRIANGLES);
index = 0; index = 0;
} }

View File

@ -2,11 +2,12 @@
#include "Texture.h" #include "Texture.h"
#include "Batch2D.h" #include "Batch2D.h"
Font::Font(Texture* texture) : texture(texture) { Font::Font(std::vector<Texture*> pages) : pages(pages) {
} }
Font::~Font(){ Font::~Font(){
delete texture; for (Texture* texture : pages)
delete texture;
} }
int Font::getGlyphWidth(char c) { 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){ switch (c){
case ' ': case ' ':
case '\t': 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) { void Font::draw(Batch2D* batch, std::wstring text, int x, int y) {
for (char c : text){ for (unsigned 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){
if (isPrintableChar(c)){ if (isPrintableChar(c)){
batch->sprite(x+1, y+1, 8, 8, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f)); batch->texture(pages[c >> 8]);
batch->sprite(x, y, 8, 8, 16, c, vec4(1.0f)); 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); x += getGlyphWidth(c);
} }

View File

@ -2,20 +2,21 @@
#define GRAPHICS_FONT_H_ #define GRAPHICS_FONT_H_
#include <string> #include <string>
#include <vector>
class Texture; class Texture;
class Batch2D; class Batch2D;
class Font { class Font {
public: public:
Texture* texture; std::vector<Texture*> pages;
Font(Texture* texture); Font(std::vector<Texture*> pages);
~Font(); ~Font();
int getGlyphWidth(char c); int getGlyphWidth(char c);
bool isPrintableChar(char c); bool isPrintableChar(int c);
void draw(Batch2D* batch, std::string text, int x, int y); void draw(Batch2D* batch, std::wstring text, int x, int y);
void drawWithShadow(Batch2D* batch, std::string text, int x, int y); void drawWithShadow(Batch2D* batch, std::wstring text, int x, int y);
}; };
#endif /* GRAPHICS_FONT_H_ */ #endif /* GRAPHICS_FONT_H_ */

View File

@ -6,6 +6,8 @@
#include "../voxels/voxel.h" #include "../voxels/voxel.h"
#include "../voxels/Block.h" #include "../voxels/Block.h"
#include <iostream>
Lighting::Lighting(Chunks* chunks){ Lighting::Lighting(Chunks* chunks){
this->chunks = chunks; this->chunks = chunks;
solverR = new LightSolver(chunks, 0); solverR = new LightSolver(chunks, 0);

View File

@ -6,6 +6,7 @@
#include "physics/Hitbox.h" #include "physics/Hitbox.h"
#include "lighting/Lighting.h" #include "lighting/Lighting.h"
#include "world/Level.h" #include "world/Level.h"
#include "voxels/Block.h"
#include "voxels/voxel.h" #include "voxels/voxel.h"
#include "voxels/Chunks.h" #include "voxels/Chunks.h"
#include "window/Camera.h" #include "window/Camera.h"
@ -175,7 +176,7 @@ void update_interaction(Level* level, LineBatch* lineBatch){
if (vox != nullptr){ 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); 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 x = (int)iend.x;
int y = (int)iend.y; int y = (int)iend.y;
int z = (int)iend.z; int z = (int)iend.z;

View File

@ -104,7 +104,7 @@ Level* load_level(World* world, Player* player) {
int initialize(Assets*& assets){ int initialize(Assets*& assets){
Audio::initialize(); Audio::initialize();
Window::initialize(WIDTH, HEIGHT, "Window 2.0"); Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v.12");
Events::initialize(); Events::initialize();
assets = new Assets(); assets = new Assets();
@ -127,7 +127,7 @@ int main() {
if (status) return status; if (status) return status;
std::cout << "-- loading world" << std::endl; 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)); Camera* camera = new Camera(playerPosition, radians(90.0f));
World* world = new World("world-1", "world/", 42); World* world = new World("world-1", "world/", 42);
Player* player = new Player(playerPosition, 4.0f, camera); Player* player = new Player(playerPosition, 4.0f, camera);

View File

@ -14,6 +14,7 @@ public:
bool skyLightPassing = false; bool skyLightPassing = false;
bool obstacle = true; bool obstacle = true;
bool selectable = true; bool selectable = true;
bool breakable = true;
Block(unsigned int id, int texture); Block(unsigned int id, int texture);
}; };

View File

@ -3,6 +3,8 @@
#include "Chunk.h" #include "Chunk.h"
#include "Chunks.h" #include "Chunks.h"
#include "Block.h"
#include "voxel.h"
#include "../world/World.h" #include "../world/World.h"
#include "WorldGenerator.h" #include "WorldGenerator.h"
#include "../lighting/Lighting.h" #include "../lighting/Lighting.h"
@ -36,6 +38,12 @@ void ChunksLoader::_thread(){
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed); 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); lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true);
} }
else if (state == RENDER){ else if (state == RENDER){

View File

@ -28,12 +28,16 @@ public:
}; };
float calc_height(fnl_state *noise, int real_x, int real_z){ 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); 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.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.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.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,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*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 += fnlGetNoise3D(noise, real_x*s*32,real_z*s*32, 0.0f)*0.03f;
height = height * 0.5f + 0.5f; 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){ 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); 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.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.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.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,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 * 0.5f + 0.5f;
height *= height; height *= height;
height *= (140.0f)*0.12f/s; height *= (140.0f)*0.12f/s;

View File

@ -41,7 +41,7 @@ int attrs[] = {
2, 0 //null terminator 2, 0 //null terminator
}; };
int uiscale = 2; int uiscale = 1;
LineBatch *lineBatch; LineBatch *lineBatch;
Batch2D *batch; Batch2D *batch;
@ -127,14 +127,13 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps)
// draw debug info // draw debug info
Font* font = assets->getFont("normal"); Font* font = assets->getFont("normal");
batch->begin(); batch->begin();
batch->texture(font->texture);
if (devdata){ if (devdata){
font->drawWithShadow(batch, "chunks: "+std::to_string(chunks->chunksCount), 16, 16); font->drawWithShadow(batch, L"рандом chunks: "+std::to_wstring(chunks->chunksCount), 16, 16);
font->drawWithShadow(batch, std::to_string((int)player->camera->position.x), 10, 30); font->drawWithShadow(batch, std::to_wstring((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_wstring((int)player->camera->position.y), 50, 30);
font->drawWithShadow(batch, std::to_string((int)player->camera->position.z), 90, 30); font->drawWithShadow(batch, std::to_wstring((int)player->camera->position.z), 90, 30);
font->drawWithShadow(batch, "fps:", 16, 42); font->drawWithShadow(batch, L"fps:", 16, 42);
font->drawWithShadow(batch, std::to_string(fps), 40, 42); font->drawWithShadow(batch, std::to_wstring(fps), 40, 42);
} }
batch->render(); batch->render();
@ -143,8 +142,8 @@ void draw_hud(World* world, Level* level, Assets* assets, bool devdata, int fps)
batch->texture(blocks); batch->texture(blocks);
int texid = Block::blocks[player->choosenBlock]->textureFaces[3]; // face-3 is top face of block 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(14, Window::height-82, 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(16, Window::height-80, 64, 64, 16, texid, vec4(1.0f));
batch->render(); batch->render();
} }