This commit is contained in:
@clasher113 2023-12-05 09:27:00 +02:00
commit 9e5d1eec5f
34 changed files with 485 additions and 410 deletions

View File

@ -8,7 +8,8 @@
"pane" "pane"
], ],
"model": "aabb", "model": "aabb",
"hitbox": [0.0, 0.0, 0.0, 1.0, 1.0, 0.1], "hitbox": [0.0, 0.0, 0.0, 1.0, 1.0, 0.2],
"light-passing": true, "light-passing": true,
"sky-light-passing": true "sky-light-passing": true,
"rotation": "pipe"
} }

View File

@ -7,10 +7,10 @@
#include <map> #include <map>
#include <queue> #include <queue>
#define ASSET_TEXTURE 1 const short ASSET_TEXTURE = 1;
#define ASSET_SHADER 2 const short ASSET_SHADER = 2;
#define ASSET_FONT 3 const short ASSET_FONT = 3;
#define ASSET_ATLAS 4 const short ASSET_ATLAS = 4;
class Assets; class Assets;

View File

@ -17,12 +17,12 @@ std::vector<ALBuffer*> Audio::freebuffers;
bool ALSource::setBuffer(ALBuffer* buffer) { bool ALSource::setBuffer(ALBuffer* buffer) {
alSourcei(id, AL_BUFFER, buffer->id); alSourcei(id, AL_BUFFER, buffer->id);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALSource::play(){ bool ALSource::play(){
alSourcePlay(id); alSourcePlay(id);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALSource::isPlaying() { bool ALSource::isPlaying() {
@ -33,33 +33,33 @@ bool ALSource::isPlaying() {
bool ALSource::setPosition(glm::vec3 position) { bool ALSource::setPosition(glm::vec3 position) {
alSource3f(id, AL_POSITION, position.x, position.y, position.z); alSource3f(id, AL_POSITION, position.x, position.y, position.z);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALSource::setVelocity(glm::vec3 velocity) { bool ALSource::setVelocity(glm::vec3 velocity) {
alSource3f(id, AL_VELOCITY, velocity.x, velocity.y, velocity.z); alSource3f(id, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALSource::setLoop(bool loop) { bool ALSource::setLoop(bool loop) {
alSourcei(id, AL_LOOPING, AL_TRUE ? loop : AL_FALSE); alSourcei(id, AL_LOOPING, AL_TRUE ? loop : AL_FALSE);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALSource::setGain(float gain) { bool ALSource::setGain(float gain) {
alSourcef(id, AL_GAIN, gain); alSourcef(id, AL_GAIN, gain);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALSource::setPitch(float pitch) { bool ALSource::setPitch(float pitch) {
alSourcef(id, AL_PITCH, pitch); alSourcef(id, AL_PITCH, pitch);
return alCheck(); return alCheckErrorsMacro();
} }
bool ALBuffer::load(int format, const char* data, int size, int freq) { bool ALBuffer::load(int format, const char* data, int size, int freq) {
alBufferData(id, format, data, size, freq); alBufferData(id, format, data, size, freq);
return alCheck(); return alCheckErrorsMacro();
} }
@ -72,7 +72,7 @@ bool Audio::initialize() {
alcCloseDevice(device); alcCloseDevice(device);
return false; return false;
} }
if (!alCheck()) if (!alCheckErrorsMacro())
return false; return false;
ALCint size; ALCint size;
@ -91,13 +91,13 @@ bool Audio::initialize() {
void Audio::finalize(){ void Audio::finalize(){
for (ALSource* source : allsources){ for (ALSource* source : allsources){
if (source->isPlaying()){ if (source->isPlaying()){
alSourceStop(source->id); alCheck(); alSourceStop(source->id); alCheckErrorsMacro();
} }
alDeleteSources(1, &source->id); alCheck(); alDeleteSources(1, &source->id); alCheckErrorsMacro();
} }
for (ALBuffer* buffer : allbuffers){ for (ALBuffer* buffer : allbuffers){
alDeleteBuffers(1, &buffer->id); alCheck(); alDeleteBuffers(1, &buffer->id); alCheckErrorsMacro();
} }
alcMakeContextCurrent(context); alcMakeContextCurrent(context);
@ -121,7 +121,7 @@ ALSource* Audio::getFreeSource(){
} }
ALuint id; ALuint id;
alGenSources(1, &id); alGenSources(1, &id);
if (!alCheck()) if (!alCheckErrorsMacro())
return nullptr; return nullptr;
ALSource* source = new ALSource(id); ALSource* source = new ALSource(id);
@ -141,7 +141,7 @@ ALBuffer* Audio::getFreeBuffer(){
} }
ALuint id; ALuint id;
alGenBuffers(1, &id); alGenBuffers(1, &id);
if (!alCheck()) if (!alCheckErrorsMacro())
return nullptr; return nullptr;
ALBuffer* buffer = new ALBuffer(id); ALBuffer* buffer = new ALBuffer(id);
@ -160,7 +160,7 @@ void Audio::freeBuffer(ALBuffer* buffer){
bool Audio::get_available_devices(std::vector<std::string>& devicesVec){ bool Audio::get_available_devices(std::vector<std::string>& devicesVec){
const ALCchar* devices; const ALCchar* devices;
devices = alcGetString(device, ALC_DEVICE_SPECIFIER); devices = alcGetString(device, ALC_DEVICE_SPECIFIER);
if (!alCheck()) if (!alCheckErrorsMacro())
return false; return false;
const char* ptr = devices; const char* ptr = devices;
@ -180,9 +180,9 @@ void Audio::setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, gl
ALfloat listenerOri[] = { at.x, at.y, at.z, up.x, up.y, up.z }; ALfloat listenerOri[] = { at.x, at.y, at.z, up.x, up.y, up.z };
alListener3f(AL_POSITION, position.x, position.y, position.z); alListener3f(AL_POSITION, position.x, position.y, position.z);
alCheck(); alCheckErrorsMacro();
alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
alCheck(); alCheckErrorsMacro();
alListenerfv(AL_ORIENTATION, listenerOri); alListenerfv(AL_ORIENTATION, listenerOri);
alCheck(); alCheckErrorsMacro();
} }

View File

@ -7,7 +7,7 @@
#include <AL/al.h> #include <AL/al.h>
#define alCheck() check_al_errors(__FILE__, __LINE__) #define alCheckErrorsMacro() check_al_errors(__FILE__, __LINE__)
bool check_al_errors(const std::string& filename, const std::uint_fast32_t line); bool check_al_errors(const std::string& filename, const std::uint_fast32_t line);

View File

@ -1,29 +1,27 @@
#ifndef SRC_CONSTANTS_H_ #ifndef SRC_CONSTANTS_H_
#define SRC_CONSTANTS_H_ #define SRC_CONSTANTS_H_
#include <limits.h> #include <limits>
#include "typedefs.h" #include "typedefs.h"
#define ENGINE_VERSION_MAJOR 0 const int ENGINE_VERSION_MAJOR = 0;
#define ENGINE_VERSION_MINOR 15 const int ENGINE_VERSION_MINOR = 15;
#define STR_(x) #x
#define STR(x) STR_(x)
#define ENGINE_VERSION STR(ENGINE_VERSION_MAJOR) "." STR(ENGINE_VERSION_MINOR)
#define CHUNK_W 16 const int CHUNK_W = 16;
#define CHUNK_H 256 const int CHUNK_H = 256;
#define CHUNK_D 16 const int CHUNK_D = 16;
/* Chunk volume (count of voxels per Chunk) */ /* Chunk volume (count of voxels per Chunk) */
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D) const int CHUNK_VOL = (CHUNK_W * CHUNK_H * CHUNK_D);
/* BLOCK_VOID is block id used to mark non-existing voxel (voxel of missing chunk) */ /* BLOCK_VOID is block id used to mark non-existing voxel (voxel of missing chunk) */
#define BLOCK_VOID (blockid_t)((2 << (sizeof(blockid_t)*CHAR_BIT)) - 1) const blockid_t BLOCK_VOID = std::numeric_limits<blockid_t>::max();
inline uint vox_index(int x, int y, int z, int w=CHUNK_W, int d=CHUNK_D) { inline uint vox_index(int x, int y, int z, int w=CHUNK_W, int d=CHUNK_D) {
return (y * d + z) * w + x; return (y * d + z) * w + x;
} }
//cannot replace defines with const while used for substitution
#define SHADERS_FOLDER "shaders" #define SHADERS_FOLDER "shaders"
#define TEXTURES_FOLDER "textures" #define TEXTURES_FOLDER "textures"
#define FONTS_FOLDER "fonts" #define FONTS_FOLDER "fonts"

View File

@ -3,22 +3,22 @@
/* blocks and bindings used in engine code */ /* blocks and bindings used in engine code */
#define BLOCK_AIR 0 const int BLOCK_AIR = 0;
#define BIND_MOVE_FORWARD "movement.forward" const std::string BIND_MOVE_FORWARD = "movement.forward";
#define BIND_MOVE_BACK "movement.back" const std::string BIND_MOVE_BACK = "movement.back";
#define BIND_MOVE_LEFT "movement.left" const std::string BIND_MOVE_LEFT = "movement.left";
#define BIND_MOVE_RIGHT "movement.right" const std::string BIND_MOVE_RIGHT = "movement.right";
#define BIND_MOVE_JUMP "movement.jump" const std::string BIND_MOVE_JUMP = "movement.jump";
#define BIND_MOVE_SPRINT "movement.sprint" const std::string BIND_MOVE_SPRINT = "movement.sprint";
#define BIND_MOVE_CROUCH "movement.crouch" const std::string BIND_MOVE_CROUCH = "movement.crouch";
#define BIND_MOVE_CHEAT "movement.cheat" const std::string BIND_MOVE_CHEAT = "movement.cheat";
#define BIND_CAM_ZOOM "camera.zoom" const std::string BIND_CAM_ZOOM = "camera.zoom";
#define BIND_PLAYER_NOCLIP "player.noclip" const std::string BIND_PLAYER_NOCLIP = "player.noclip";
#define BIND_PLAYER_FLIGHT "player.flight" const std::string BIND_PLAYER_FLIGHT = "player.flight";
#define BIND_PLAYER_ATTACK "player.attack" const std::string BIND_PLAYER_ATTACK = "player.attack";
#define BIND_PLAYER_BUILD "player.build" const std::string BIND_PLAYER_BUILD = "player.build";
#define BIND_PLAYER_PICK "player.pick" const std::string BIND_PLAYER_PICK = "player.pick";
#define BIND_HUD_INVENTORY "hud.inventory" const std::string BIND_HUD_INVENTORY = "hud.inventory";
#endif // SRC_CORE_DEFS_H_ #endif // SRC_CORE_DEFS_H_

View File

@ -98,7 +98,7 @@ void Engine::mainloop() {
Window::swapInterval(settings.display.swapInterval); Window::swapInterval(settings.display.swapInterval);
Window::swapBuffers(); Window::swapBuffers();
Events::pullEvents(); Events::pollEvents();
} }
} }

View File

@ -25,14 +25,14 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#define SECTION_POSITION 1 const int SECTION_POSITION = 1;
#define SECTION_ROTATION 2 const int SECTION_ROTATION = 2;
#define SECTION_FLAGS 3 const int SECTION_FLAGS = 3;
#define PLAYER_FLAG_FLIGHT 0x1 const int PLAYER_FLAG_FLIGHT = 0x1;
#define PLAYER_FLAG_NOCLIP 0x2 const int PLAYER_FLAG_NOCLIP = 0x2;
#define WORLD_SECTION_MAIN 1 const int WORLD_SECTION_MAIN = 1;
#define WORLD_SECTION_DAYNIGHT 2 const int WORLD_SECTION_DAYNIGHT = 2;
using glm::ivec2; using glm::ivec2;
using glm::vec3; using glm::vec3;

View File

@ -13,13 +13,13 @@
#include "../typedefs.h" #include "../typedefs.h"
#define REGION_SIZE_BIT 5 const uint REGION_SIZE_BIT = 5;
#define REGION_SIZE (1 << (REGION_SIZE_BIT)) const uint REGION_SIZE = (1 << (REGION_SIZE_BIT));
#define REGION_VOL ((REGION_SIZE) * (REGION_SIZE)) const uint REGION_VOL = ((REGION_SIZE) * (REGION_SIZE));
#define REGION_FORMAT_VERSION 1 const uint REGION_FORMAT_VERSION = 1;
const uint WORLD_FORMAT_VERSION = 1;
#define REGION_FORMAT_MAGIC ".VOXREG" #define REGION_FORMAT_MAGIC ".VOXREG"
#define WORLD_FORMAT_MAGIC ".VOXWLD" #define WORLD_FORMAT_MAGIC ".VOXWLD"
#define WORLD_FORMAT_VERSION 1
class Player; class Player;
class Chunk; class Chunk;

View File

@ -193,7 +193,12 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera){
const vec3 pos = PlayerController::selectedBlockPosition; const vec3 pos = PlayerController::selectedBlockPosition;
const vec3 point = PlayerController::selectedPointPosition; const vec3 point = PlayerController::selectedPointPosition;
const vec3 norm = PlayerController::selectedBlockNormal; const vec3 norm = PlayerController::selectedBlockNormal;
const AABB& hitbox = block->hitbox; AABB hitbox = block->hitbox;
if (block->rotatable) {
auto states = PlayerController::selectedBlockStates;
block->rotations.variants[states].transform(hitbox);
}
const vec3 center = pos + hitbox.center(); const vec3 center = pos + hitbox.center();
const vec3 size = hitbox.size(); const vec3 size = hitbox.size();
linesShader->use(); linesShader->use();

View File

@ -14,9 +14,9 @@ using glm::vec2;
using glm::vec3; using glm::vec3;
using glm::vec4; using glm::vec4;
#define KEY_ESCAPE 256 const uint KEY_ESCAPE = 256;
#define KEY_ENTER 257 const uint KEY_ENTER = 257;
#define KEY_BACKSPACE 259 const uint KEY_BACKSPACE = 259;
using namespace gui; using namespace gui;

View File

@ -5,7 +5,7 @@
#include <GL/glew.h> #include <GL/glew.h>
#define VERTEX_SIZE 8 const uint B2D_VERTEX_SIZE = 8;
using glm::vec2; using glm::vec2;
using glm::vec3; using glm::vec3;
@ -16,7 +16,7 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1
{2}, {2}, {4}, {0} {2}, {2}, {4}, {0}
}; };
buffer = new float[capacity * VERTEX_SIZE]; buffer = new float[capacity * B2D_VERTEX_SIZE];
mesh = new Mesh(buffer, 0, attrs); mesh = new Mesh(buffer, 0, attrs);
index = 0; index = 0;
@ -75,7 +75,7 @@ void Batch2D::texture(Texture* new_texture){
} }
void Batch2D::point(float x, float y, float r, float g, float b, float a){ void Batch2D::point(float x, float y, float r, float g, float b, float a){
if (index + 6*VERTEX_SIZE >= capacity) if (index + 6*B2D_VERTEX_SIZE >= capacity)
render(GL_TRIANGLES); render(GL_TRIANGLES);
vertex(x, y, 0, 0, r,g,b,a); vertex(x, y, 0, 0, r,g,b,a);
@ -83,7 +83,7 @@ void Batch2D::point(float x, float y, float r, float g, float b, float a){
} }
void Batch2D::line(float x1, float y1, float x2, float y2, float r, float g, float b, float a){ void Batch2D::line(float x1, float y1, float x2, float y2, float r, float g, float b, float a){
if (index + 6*VERTEX_SIZE >= capacity) if (index + 6*B2D_VERTEX_SIZE >= capacity)
render(GL_TRIANGLES); render(GL_TRIANGLES);
vertex(x1, y1, 0, 0, r,g,b,a); vertex(x1, y1, 0, 0, r,g,b,a);
@ -96,7 +96,7 @@ 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) if (index + 6*B2D_VERTEX_SIZE >= capacity)
render(GL_TRIANGLES); render(GL_TRIANGLES);
vertex(x, y, 0, 0, r,g,b,a); vertex(x, y, 0, 0, r,g,b,a);
@ -117,7 +117,7 @@ void Batch2D::rect(
bool flippedX, bool flippedX,
bool flippedY, bool flippedY,
vec4 tint) { vec4 tint) {
if (index + 6*VERTEX_SIZE >= capacity) if (index + 6*B2D_VERTEX_SIZE >= capacity)
render(GL_TRIANGLES); render(GL_TRIANGLES);
float centerX = w*ox; float centerX = w*ox;
@ -205,7 +205,7 @@ void Batch2D::rect(
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) if (index + 6*B2D_VERTEX_SIZE >= capacity)
render(GL_TRIANGLES); render(GL_TRIANGLES);
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);
@ -222,7 +222,7 @@ void Batch2D::rect(float x, float y, float w, float h,
float r2, float g2, float b2, float r2, float g2, float b2,
float r3, float g3, float b3, float r3, float g3, float b3,
float r4, float g4, float b4, int sh){ float r4, float g4, float b4, int sh){
if (index + 30*VERTEX_SIZE >= capacity) if (index + 30*B2D_VERTEX_SIZE >= capacity)
render(GL_TRIANGLES); render(GL_TRIANGLES);
vec2 v0 = vec2(x+h/2,y+h/2); vec2 v0 = vec2(x+h/2,y+h/2);
vec2 v1 = vec2(x+w-sh,y); vec2 v1 = vec2(x+w-sh,y);
@ -317,7 +317,7 @@ void Batch2D::blockSprite(float x, float y, float w, float h, const UVRegion reg
float scalex = regions[3].u2-regions[3].u1; float scalex = regions[3].u2-regions[3].u1;
float scaley = regions[3].v2-regions[3].v1; float scaley = regions[3].v2-regions[3].v1;
if (this->index + 18*VERTEX_SIZE >= capacity) if (this->index + 18*B2D_VERTEX_SIZE >= capacity)
render(); render();
float d = (w + h) * 0.5f; float d = (w + h) * 0.5f;
@ -376,7 +376,7 @@ void Batch2D::blockSprite(float x, float y, float w, float h, const UVRegion reg
} }
void Batch2D::render(unsigned int gl_primitive) { void Batch2D::render(unsigned int gl_primitive) {
mesh->reload(buffer, index / VERTEX_SIZE); mesh->reload(buffer, index / B2D_VERTEX_SIZE);
mesh->draw(gl_primitive); mesh->draw(gl_primitive);
index = 0; index = 0;
} }

View File

@ -6,7 +6,7 @@
#include <GL/glew.h> #include <GL/glew.h>
#include "../typedefs.h" #include "../typedefs.h"
#define VERTEX_SIZE 9 const uint B3D_VERTEX_SIZE = 9;
using glm::vec2; using glm::vec2;
using glm::vec3; using glm::vec3;
@ -19,7 +19,7 @@ Batch3D::Batch3D(size_t capacity)
{3}, {2}, {4}, {0} {3}, {2}, {4}, {0}
}; };
buffer = new float[capacity * VERTEX_SIZE]; buffer = new float[capacity * B3D_VERTEX_SIZE];
mesh = new Mesh(buffer, 0, attrs); mesh = new Mesh(buffer, 0, attrs);
index = 0; index = 0;
@ -84,7 +84,7 @@ void Batch3D::face(const vec3& coord, float w, float h,
const vec3& axisY, const vec3& axisY,
const UVRegion& region, const UVRegion& region,
const vec4& tint) { const vec4& tint) {
if (index + VERTEX_SIZE * 6 > capacity) { if (index + B3D_VERTEX_SIZE * 6 > capacity) {
flush(); flush();
} }
vertex(coord, region.u1, region.v1, vertex(coord, region.u1, region.v1,
@ -118,7 +118,7 @@ void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h, const UVRe
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) { if (index + 6*B3D_VERTEX_SIZE >= capacity) {
flush(); flush();
} }
@ -179,7 +179,7 @@ void Batch3D::blockCube(const vec3 size, const UVRegion(&texfaces)[6], const vec
} }
void Batch3D::flush() { void Batch3D::flush() {
mesh->reload(buffer, index / VERTEX_SIZE); mesh->reload(buffer, index / B3D_VERTEX_SIZE);
mesh->draw(); mesh->draw();
index = 0; index = 0;
} }

View File

@ -17,7 +17,7 @@ using glm::ivec3;
using glm::vec3; using glm::vec3;
using glm::vec4; using glm::vec4;
#define VERTEX_SIZE 6 const uint BlocksRenderer::VERTEX_SIZE = 6;
BlocksRenderer::BlocksRenderer(size_t capacity, BlocksRenderer::BlocksRenderer(size_t capacity,
const Content* content, const Content* content,
@ -42,6 +42,7 @@ BlocksRenderer::~BlocksRenderer() {
delete[] indexBuffer; delete[] indexBuffer;
} }
/* Basic vertex add method */
void BlocksRenderer::vertex(const vec3& coord, void BlocksRenderer::vertex(const vec3& coord,
float u, float v, float u, float v,
const vec4& light) { const vec4& light) {
@ -75,13 +76,15 @@ void BlocksRenderer::index(int a, int b, int c, int d, int e, int f) {
indexOffset += 4; indexOffset += 4;
} }
void BlocksRenderer::face(const vec3& coord, float w, float h, /* Add face with precalculated lights */
const vec3& axisX, void BlocksRenderer::face(const vec3& coord,
const vec3& axisY, float w, float h,
const UVRegion& region, const vec3& axisX,
const vec4(&lights)[4], const vec3& axisY,
const vec4& tint) { const UVRegion& region,
if (vertexOffset + VERTEX_SIZE * 4 > capacity) { const vec4(&lights)[4],
const vec4& tint) {
if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) {
overflow = true; overflow = true;
return; return;
} }
@ -92,34 +95,8 @@ void BlocksRenderer::face(const vec3& coord, float w, float h,
index(0, 1, 3, 1, 2, 3); index(0, 1, 3, 1, 2, 3);
} }
void BlocksRenderer::face(const vec3& coord, float w, float h, void BlocksRenderer::vertex(const ivec3& coord,
const vec3& axisX, float u, float v,
const vec3& axisY,
const UVRegion& region,
const vec4(&lights)[4],
const vec4& tint,
bool rotated) {
if (vertexOffset + VERTEX_SIZE * 4 > capacity) {
overflow = true;
return;
}
if (rotated) {
vertex(coord, region.u2, region.v1, lights[0] * tint);
vertex(coord + axisX * w, region.u2, region.v2, lights[1] * tint);
vertex(coord + axisX * w + axisY * h, region.u1, region.v2, lights[2] * tint);
vertex(coord + axisY * h, region.u1, region.v1, lights[3] * tint);
index(0, 1, 2, 0, 2, 3);
}
else {
vertex(coord, region.u1, region.v1, lights[0] * tint);
vertex(coord + axisX * w, region.u2, region.v1, lights[1] * tint);
vertex(coord + axisX * w + axisY * h, region.u2, region.v2, lights[2] * tint);
vertex(coord + axisY * h, region.u1, region.v2, lights[3] * tint);
index(0, 1, 2, 0, 2, 3);
}
}
void BlocksRenderer::vertex(const ivec3& coord, float u, float v,
const vec4& tint, const vec4& tint,
const ivec3& axisX, const ivec3& axisX,
const ivec3& axisY, const ivec3& axisY,
@ -128,13 +105,23 @@ void BlocksRenderer::vertex(const ivec3& coord, float u, float v,
vertex(coord, u, v, light * tint); vertex(coord, u, v, light * tint);
} }
void BlocksRenderer::vertex(const vec3& coord,
float u, float v,
const vec4& tint,
const ivec3& axisX,
const ivec3& axisY,
const ivec3& axisZ) {
vec4 light = pickSoftLight(ivec3(coord.x, coord.y, coord.z)+axisZ, axisX, axisY);
vertex(coord, u, v, light * tint);
}
void BlocksRenderer::face(const ivec3& coord, void BlocksRenderer::face(const ivec3& coord,
const ivec3& axisX, const ivec3& axisX,
const ivec3& axisY, const ivec3& axisY,
const ivec3& axisZ, const ivec3& axisZ,
const ivec3& laxisZ, const ivec3& laxisZ,
const UVRegion& region) { const UVRegion& region) {
if (vertexOffset + VERTEX_SIZE * 4 > capacity) { if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) {
overflow = true; overflow = true;
return; return;
} }
@ -152,45 +139,69 @@ void BlocksRenderer::face(const ivec3& coord,
index(0, 1, 2, 0, 2, 3); index(0, 1, 2, 0, 2, 3);
} }
void BlocksRenderer::cube(const vec3& coord, const vec3& size, const UVRegion(&texfaces)[6]) { void BlocksRenderer::face(const ivec3& coord_,
vec4 lights[]{ vec4(),vec4(),vec4(),vec4() }; const ivec3& axisX,
const ivec3& axisY,
const ivec3& axisZ,
const ivec3& laxisZ,
const vec3& offset,
float width,
float height,
float depth,
const UVRegion& region) {
if (vertexOffset + BlocksRenderer::VERTEX_SIZE * 4 > capacity) {
overflow = true;
return;
}
face(coord, size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[0], lights); const vec3 X(axisX);
face(coord + vec3(size.x, 0, -size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[1], lights); const vec3 Y(axisY);
const vec3 Z(axisZ);
face(coord + vec3(0, size.y, 0), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[2], lights); const vec3 sunVector = vec3(0.431934f, 0.863868f, 0.259161f);
face(coord + vec3(0, 0, -size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[3], lights); float d = glm::dot(Z, sunVector);
d = 0.75f + d*0.25f;
face(coord + vec3(0, 0, -size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[4], lights); vec4 tint(d);
face(coord + vec3(size.x, 0, 0), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[5], lights); vec3 coord(vec3(coord_) + offset);
vertex(coord + Z*depth, region.u1, region.v1, tint, axisX, axisY, laxisZ);
vertex(coord + Z*depth + X*width, region.u2, region.v1, tint, axisX, axisY, laxisZ);
vertex(coord + Z*depth + X*width + Y*height, region.u2, region.v2, tint, axisX, axisY, laxisZ);
vertex(coord + Z*depth + Y*height, region.u1, region.v2, tint, axisX, axisY, laxisZ);
index(0, 1, 2, 0, 2, 3);
} }
void BlocksRenderer::blockCube(int x, int y, int z, const vec3& size, const UVRegion(&texfaces)[6], ubyte group) { void BlocksRenderer::blockCube(int x, int y, int z, const UVRegion(&texfaces)[6], ubyte group) {
vec4 lights[]{ vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f) }; vec4 lights[]{ vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f) };
if (isOpen(x, y, z + 1, group)) { if (isOpen(x, y, z + 1, group)) {
face(vec3(x, y, z), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], lights, vec4(1.0f)); face(vec3(x, y, z), 1, 1, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], lights, vec4(1.0f));
} }
if (isOpen(x, y, z - 1, group)) { if (isOpen(x, y, z - 1, group)) {
face(vec3(x + size.x, y, z - size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], lights, vec4(1.0f)); face(vec3(x + 1, y, z - 1), 1, 1, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], lights, vec4(1.0f));
} }
if (isOpen(x, y + 1, z, group)) { if (isOpen(x, y + 1, z, group)) {
face(vec3(x, y + size.y, z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], lights); face(vec3(x, y + 1, z), 1, 1, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], lights);
} }
if (isOpen(x, y - 1, z, group)) { if (isOpen(x, y - 1, z, group)) {
face(vec3(x, y, z - size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], lights, vec4(1.0f)); face(vec3(x, y, z - 1), 1, 1, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], lights, vec4(1.0f));
} }
if (isOpen(x - 1, y, z, group)) { if (isOpen(x - 1, y, z, group)) {
face(vec3(x, y, z - size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], lights, vec4(1.0f)); face(vec3(x, y, z - 1), 1, 1, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], lights, vec4(1.0f));
} }
if (isOpen(x + 1, y, z, group)) { if (isOpen(x + 1, y, z, group)) {
face(vec3(x + size.x, y, z), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], lights, vec4(1.0f)); face(vec3(x + 1, y, z), 1, 1, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], lights, vec4(1.0f));
} }
} }
void BlocksRenderer::blockXSprite(int x, int y, int z, const vec3& size, const UVRegion& texface1, const UVRegion& texface2, float spread) { void BlocksRenderer::blockXSprite(int x, int y, int z,
const vec3& size,
const UVRegion& texface1,
const UVRegion& texface2,
float spread) {
vec4 lights[]{ vec4 lights[]{
pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}), pickSoftLight({x, y + 1, z}, {1, 0, 0}, {0, 1, 0}),
pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}), pickSoftLight({x + 1, y + 1, z}, {1, 0, 0}, {0, 1, 0}),
@ -204,73 +215,64 @@ void BlocksRenderer::blockXSprite(int x, int y, int z, const vec3& size, const U
const float w = size.x / 1.41f; const float w = size.x / 1.41f;
const float tint = 0.8f; const float tint = 0.8f;
face(vec3(x + xs + (1.0 - w) * 0.5f, y, face(vec3(x + xs + (1.0 - w) * 0.5f, y, z + zs - 1 + (1.0 - w) * 0.5f),
z + zs - 1 + (1.0 - w) * 0.5f), w, size.y, w, size.y, vec3(1.0f, 0, 1.0f), vec3(0, 1, 0),
vec3(1.0f, 0, 1.0f), vec3(0, 1, 0), texface1, lights, vec4(tint)); texface1, lights, vec4(tint));
face(vec3(x + xs - (1.0 - w) * 0.5f + 1, y, face(vec3(x + xs - (1.0 - w) * 0.5f + 1, y, z + zs - (1.0 - w) * 0.5f),
z + zs - (1.0 - w) * 0.5f), w, size.y, w, size.y, vec3(-1.0f, 0, -1.0f), vec3(0, 1, 0),
vec3(-1.0f, 0, -1.0f), vec3(0, 1, 0), texface1, lights, vec4(tint)); texface1, lights, vec4(tint));
face(vec3(x + xs + (1.0 - w) * 0.5f, y, face(vec3(x + xs + (1.0 - w) * 0.5f, y, z + zs - (1.0 - w) * 0.5f),
z + zs - (1.0 - w) * 0.5f), w, size.y, w, size.y, vec3(1.0f, 0, -1.0f), vec3(0, 1, 0),
vec3(1.0f, 0, -1.0f), vec3(0, 1, 0), texface2, lights, vec4(tint)); texface2, lights, vec4(tint));
face(vec3(x + xs - (1.0 - w) * 0.5f + 1, y, face(vec3(x + xs - (1.0 - w) * 0.5f + 1, y, z + zs + (1.0 - w) * 0.5f - 1),
z + zs + (1.0 - w) * 0.5f - 1), w, size.y, w, size.y, vec3(-1.0f, 0, 1.0f), vec3(0, 1, 0),
vec3(-1.0f, 0, 1.0f), vec3(0, 1, 0), texface2, lights, vec4(tint)); texface2, lights, vec4(tint));
} }
void BlocksRenderer::blockCubeShaded(const vec3& pos, const vec3& size, const UVRegion(&texfaces)[6], const Block* block, ubyte states) { /* AABB blocks render method (WIP) */
int rot = 0; void BlocksRenderer::blockCubeShaded(const ivec3& icoord,
float x = pos.x; const vec3& offset,
float y = pos.y; const vec3& size,
float z = pos.z; const UVRegion(&texfaces)[6],
{ const Block* block, ubyte states) {
vec4 lights[]{
pickSoftLight(x, y, z + 1, {1, 0, 0}, {0, 1, 0}),
pickSoftLight(x + 1, y, z + 1, {1, 0, 0}, {0, 1, 0}),
pickSoftLight(x + 1, y + 1, z + 1, {1, 0, 0}, {0, 1, 0}),
pickSoftLight(x, y + 1, z + 1, {1, 0, 0}, {0, 1, 0}) };
face(vec3(x, y, z), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], lights, vec4(0.9f), rot == 1);
} {
vec4 lights[]{
pickSoftLight(pos.x, pos.y, pos.z - 1, {-1, 0, 0}, {0, 1, 0}),
pickSoftLight(pos.x - 1, pos.y, pos.z - 1, {-1, 0, 0}, {0, 1, 0}),
pickSoftLight(pos.x - 1, pos.y + 1, pos.z - 1, {-1, 0, 0}, {0, 1, 0}),
pickSoftLight(pos.x, pos.y + 1, pos.z - 1, {-1, 0, 0}, {0, 1, 0}) };
face(vec3(x + size.x, y, z - size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], lights, vec4(0.75f), rot == 1);
} {
vec4 lights[]{
pickSoftLight(x, pos.y + 1, pos.z + 1, {1, 0, 0}, {0, 0, 1}),
pickSoftLight(x + 1, pos.y + 1, pos.z + 1, {1, 0, 0}, {0, 0, 1}),
pickSoftLight(x + 1, pos.y + 1, pos.z, {1, 0, 0}, {0, 0, 1}),
pickSoftLight(x, pos.y + 1, pos.z, {1, 0, 0}, {0, 0, 1}) };
face(vec3(x, y + size.y, z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], lights, vec4(1.0f), rot == 1); ivec3 X(1, 0, 0);
} { ivec3 Y(0, 1, 0);
vec4 lights[]{ ivec3 Z(0, 0, 1);
pickSoftLight(pos.x, pos.y - 1, pos.z - 1, {1, 0, 0}, {0, 0, -1}), ivec3 loff(0);
pickSoftLight(pos.x + 1, y - 1, pos.z - 1, {1, 0, 0}, {0, 0,-1}), ivec3 coord = icoord;
pickSoftLight(pos.x + 1, y - 1, pos.z, {1, 0, 0}, {0, 0, -1}), if (block->rotatable) {
pickSoftLight(x, y - 1, z, {1, 0, 0}, {0, 0, -1}) }; auto& rotations = block->rotations;
face(vec3(x, y, z - size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], lights, vec4(0.6f), rot == 1); auto& orient = rotations.variants[states & BLOCK_ROT_MASK];
} { X = orient.axisX;
vec4 lights[]{ Y = orient.axisY;
pickSoftLight(x - 1, y, z - 1, {0, 0, -1}, {0, 1, 0}), Z = orient.axisZ;
pickSoftLight(x - 1, y, z, {0, 0, -1}, {0, 1, 0}), coord += orient.fix;
pickSoftLight(x - 1, y + 1, z, {0, 0, -1}, {0, 1, 0}), loff -= orient.fix;
pickSoftLight(x - 1, y + 1, z - 1, {0, 0, -1}, {0, 1, 0}) };
face(vec3(x, y, z - size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], lights, vec4(0.7f), rot == 3);
} {
vec4 lights[]{
pickSoftLight(x + 1, y, z, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x + 1, y, z - 1, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x + 1, y + 1, z - 1, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x + 1, y + 1, z, {0, 0, -1}, {0, 1, 0}) };
face(vec3(x + size.x, y, z), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], lights, vec4(0.8f), rot == 3);
} }
vec3 fX(X);
vec3 fY(Y);
vec3 fZ(Z);
vec3 local = offset.x*vec3(X)+offset.y*vec3(Y)+offset.z*vec3(-Z);
//local -= loff;
face(coord, X, Y, Z, Z+loff, local-size.z*fZ, size.x, size.y, size.z, texfaces[5]);
face(coord+X, -X, Y, -Z, Z-Z-X+loff, local-size.z*fZ, size.x, size.y, 0.0f, texfaces[4]);
face(coord+Y, X, -Z, Y, Y-Y+loff, local, size.x, size.z, 0.0f, texfaces[3]); //;
face(coord+X, -X, -Z, -Y, -Y+Z+loff, local, size.x, size.z, 0.0f, texfaces[2]); //;
face(coord+X, -Z, Y, X, X-X+loff, local, size.z, size.y, 0.0f, texfaces[1]); //;
face(coord+Y, -Z, -Y, -X, -X+Z+loff, local, size.z, size.y, 0.0f, texfaces[0]); //;
} }
void BlocksRenderer::blockCubeShaded(int x, int y, int z, const UVRegion(&texfaces)[6], const Block* block, ubyte states) { /* Fastest solid shaded blocks render method */
void BlocksRenderer::blockCubeShaded(int x, int y, int z,
const UVRegion(&texfaces)[6],
const Block* block,
ubyte states) {
ubyte group = block->drawGroup; ubyte group = block->drawGroup;
ivec3 X(1, 0, 0); ivec3 X(1, 0, 0);
@ -310,7 +312,9 @@ void BlocksRenderer::blockCubeShaded(int x, int y, int z, const UVRegion(&texfac
// Does block allow to see other blocks sides (is it transparent) // Does block allow to see other blocks sides (is it transparent)
bool BlocksRenderer::isOpen(int x, int y, int z, ubyte group) const { bool BlocksRenderer::isOpen(int x, int y, int z, ubyte group) const {
blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x,
y,
chunk->z * CHUNK_D + z);
if (id == BLOCK_VOID) if (id == BLOCK_VOID)
return false; return false;
const Block& block = *blockDefsCache[id]; const Block& block = *blockDefsCache[id];
@ -321,7 +325,9 @@ bool BlocksRenderer::isOpen(int x, int y, int z, ubyte group) const {
} }
bool BlocksRenderer::isOpenForLight(int x, int y, int z) const { bool BlocksRenderer::isOpenForLight(int x, int y, int z) const {
blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); blockid_t id = voxelsBuffer->pickBlockId(chunk->x * CHUNK_W + x,
y,
chunk->z * CHUNK_D + z);
if (id == BLOCK_VOID) if (id == BLOCK_VOID)
return false; return false;
const Block& block = *blockDefsCache[id]; const Block& block = *blockDefsCache[id];
@ -333,7 +339,9 @@ bool BlocksRenderer::isOpenForLight(int x, int y, int z) const {
vec4 BlocksRenderer::pickLight(int x, int y, int z) const { vec4 BlocksRenderer::pickLight(int x, int y, int z) const {
if (isOpenForLight(x, y, z)) { if (isOpenForLight(x, y, z)) {
light_t light = voxelsBuffer->pickLight(chunk->x * CHUNK_W + x, y, chunk->z * CHUNK_D + z); light_t light = voxelsBuffer->pickLight(chunk->x * CHUNK_W + x,
y,
chunk->z * CHUNK_D + z);
return vec4(Lightmap::extract(light, 0) / 15.0f, return vec4(Lightmap::extract(light, 0) / 15.0f,
Lightmap::extract(light, 1) / 15.0f, Lightmap::extract(light, 1) / 15.0f,
Lightmap::extract(light, 2) / 15.0f, Lightmap::extract(light, 2) / 15.0f,
@ -349,7 +357,8 @@ vec4 BlocksRenderer::pickLight(const ivec3& coord) const {
} }
vec4 BlocksRenderer::pickSoftLight(const ivec3& coord, vec4 BlocksRenderer::pickSoftLight(const ivec3& coord,
const ivec3& right, const ivec3& up) const { const ivec3& right,
const ivec3& up) const {
return ( return (
pickLight(coord) + pickLight(coord) +
pickLight(coord - right) + pickLight(coord - right) +
@ -358,11 +367,13 @@ vec4 BlocksRenderer::pickSoftLight(const ivec3& coord,
} }
vec4 BlocksRenderer::pickSoftLight(float x, float y, float z, vec4 BlocksRenderer::pickSoftLight(float x, float y, float z,
const ivec3& right, const ivec3& up) const { const ivec3& right,
const ivec3& up) const {
return pickSoftLight({int(round(x)), int(round(y)), int(round(z))}, right, up); return pickSoftLight({int(round(x)), int(round(y)), int(round(z))}, right, up);
} }
void BlocksRenderer::render(const voxel* voxels, int atlas_size) { #include <iostream>
void BlocksRenderer::render(const voxel* voxels) {
int begin = chunk->bottom * (CHUNK_W * CHUNK_D); int begin = chunk->bottom * (CHUNK_W * CHUNK_D);
int end = chunk->top * (CHUNK_W * CHUNK_D); int end = chunk->top * (CHUNK_W * CHUNK_D);
for (const auto drawGroup : *content->drawGroups) { for (const auto drawGroup : *content->drawGroups) {
@ -372,31 +383,42 @@ void BlocksRenderer::render(const voxel* voxels, int atlas_size) {
const Block& def = *blockDefsCache[id]; const Block& def = *blockDefsCache[id];
if (!id || def.drawGroup != drawGroup) if (!id || def.drawGroup != drawGroup)
continue; continue;
const UVRegion texfaces[6]{ cache->getRegion(id, 0), cache->getRegion(id, 1), const UVRegion texfaces[6]{ cache->getRegion(id, 0),
cache->getRegion(id, 2), cache->getRegion(id, 3), cache->getRegion(id, 1),
cache->getRegion(id, 4), cache->getRegion(id, 5)}; cache->getRegion(id, 2),
cache->getRegion(id, 3),
cache->getRegion(id, 4),
cache->getRegion(id, 5)};
int x = i % CHUNK_W; int x = i % CHUNK_W;
int y = i / (CHUNK_D * CHUNK_W); int y = i / (CHUNK_D * CHUNK_W);
int z = (i / CHUNK_D) % CHUNK_W; int z = (i / CHUNK_D) % CHUNK_W;
switch (def.model) { switch (def.model) {
case BlockModel::block: case BlockModel::block:
if (def.rt.emissive) { if (def.rt.emissive) {
blockCube(x, y, z, vec3(1.0f), texfaces, def.drawGroup); blockCube(x, y, z, texfaces, def.drawGroup);
} }
else { else {
blockCubeShaded(x, y, z, texfaces, &def, vox.states); blockCubeShaded(x, y, z, texfaces, &def, vox.states);
} }
break; break;
case BlockModel::xsprite: { case BlockModel::xsprite: {
blockXSprite(x, y, z, vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f); blockXSprite(x, y, z, vec3(1.0f),
texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f);
break; break;
} }
case BlockModel::aabb: { case BlockModel::aabb: {
vec3 size = def.hitbox.size(); AABB hitbox = def.hitbox;
vec3 off = def.hitbox.min(); hitbox.a = vec3(1.0f)-hitbox.a;
off.z *= -1.0f; hitbox.b = vec3(1.0f)-hitbox.b;
off.z = -1.0f-off.z + size.z; std::cout << hitbox.a.x << " " << hitbox.a.y << " " << hitbox.a.z << " --- ";
blockCubeShaded(off+vec3(x,y,z), size, texfaces, &def, vox.states); std::cout << hitbox.b.x << " " << hitbox.b.y << " " << hitbox.b.z << std::endl;
vec3 size = hitbox.size();
std::cout << "s " << size.x << " " << size.y << " " << size.z << std::endl;
vec3 off = hitbox.min();
std::cout << "m " << off.x << " " << off.y << " " << off.z << std::endl;
blockCubeShaded(ivec3(x,y,z), off, size, texfaces, &def, vox.states);
break; break;
} }
default: default:
@ -408,7 +430,7 @@ void BlocksRenderer::render(const voxel* voxels, int atlas_size) {
} }
} }
Mesh* BlocksRenderer::render(const Chunk* chunk, int atlas_size, const ChunksStorage* chunks) { Mesh* BlocksRenderer::render(const Chunk* chunk, const ChunksStorage* chunks) {
this->chunk = chunk; this->chunk = chunk;
voxelsBuffer->setPosition(chunk->x * CHUNK_W - 1, 0, chunk->z * CHUNK_D - 1); voxelsBuffer->setPosition(chunk->x * CHUNK_W - 1, 0, chunk->z * CHUNK_D - 1);
chunks->getVoxels(voxelsBuffer, settings.graphics.backlight); chunks->getVoxels(voxelsBuffer, settings.graphics.backlight);
@ -416,10 +438,11 @@ Mesh* BlocksRenderer::render(const Chunk* chunk, int atlas_size, const ChunksSto
vertexOffset = 0; vertexOffset = 0;
indexOffset = indexSize = 0; indexOffset = indexSize = 0;
const voxel* voxels = chunk->voxels; const voxel* voxels = chunk->voxels;
render(voxels, atlas_size); render(voxels);
const vattr attrs[]{ {3}, {2}, {1}, {0} }; const vattr attrs[]{ {3}, {2}, {1}, {0} };
Mesh* mesh = new Mesh(vertexBuffer, vertexOffset / VERTEX_SIZE, indexBuffer, indexSize, attrs); size_t vcount = vertexOffset / BlocksRenderer::VERTEX_SIZE;
Mesh* mesh = new Mesh(vertexBuffer, vcount, indexBuffer, indexSize, attrs);
return mesh; return mesh;
} }

View File

@ -18,6 +18,7 @@ class ChunksStorage;
class ContentGfxCache; class ContentGfxCache;
class BlocksRenderer { class BlocksRenderer {
static const uint VERTEX_SIZE;
const Content* const content; const Content* const content;
float* vertexBuffer; float* vertexBuffer;
int* indexBuffer; int* indexBuffer;
@ -43,6 +44,12 @@ class BlocksRenderer {
const glm::ivec3& axisY, const glm::ivec3& axisY,
const glm::ivec3& axisZ); const glm::ivec3& axisZ);
void vertex(const glm::vec3& coord, float u, float v,
const glm::vec4& brightness,
const glm::ivec3& axisX,
const glm::ivec3& axisY,
const glm::ivec3& axisZ);
void face(const glm::vec3& coord, float w, float h, void face(const glm::vec3& coord, float w, float h,
const glm::vec3& axisX, const glm::vec3& axisX,
const glm::vec3& axisY, const glm::vec3& axisY,
@ -50,19 +57,22 @@ class BlocksRenderer {
const glm::vec4(&lights)[4], const glm::vec4(&lights)[4],
const glm::vec4& tint); const glm::vec4& tint);
void face(const glm::vec3& coord, float w, float h, void face(const glm::ivec3& coord,
const glm::vec3& axisX, const glm::ivec3& axisX,
const glm::vec3& axisY, const glm::ivec3& axisY,
const UVRegion& region, const glm::ivec3& axisZ,
const glm::vec4(&lights)[4], const glm::ivec3& laxisZ,
const glm::vec4& tint, const UVRegion& region);
bool rotated);
void face(const glm::ivec3& coord, void face(const glm::ivec3& coord,
const glm::ivec3& axisX, const glm::ivec3& axisX,
const glm::ivec3& axisY, const glm::ivec3& axisY,
const glm::ivec3& axisZ, const glm::ivec3& axisZ,
const glm::ivec3& laxisZ, const glm::ivec3& laxisZ,
const glm::vec3& offset,
float width,
float height,
float depth,
const UVRegion& region); const UVRegion& region);
void face(const glm::vec3& coord, float w, float h, void face(const glm::vec3& coord, float w, float h,
@ -73,12 +83,15 @@ class BlocksRenderer {
face(coord, w, h, axisX, axisY, region, lights, glm::vec4(1.0f)); face(coord, w, h, axisX, axisY, region, lights, glm::vec4(1.0f));
} }
void cube(const glm::vec3& coord, const glm::vec3& size, const UVRegion(&faces)[6]); void blockCube(int x, int y, int z, const UVRegion(&faces)[6], ubyte group);
void blockCube(int x, int y, int z, const glm::vec3& size, const UVRegion(&faces)[6], ubyte group);
/* Fastest solid shaded blocks render method */
void blockCubeShaded(int x, int y, int z, const UVRegion(&faces)[6], const Block* block, ubyte states); void blockCubeShaded(int x, int y, int z, const UVRegion(&faces)[6], const Block* block, ubyte states);
/* AABB blocks render method (WIP)*/ void blockCubeShaded(const glm::ivec3& coord,
void blockCubeShaded(const glm::vec3& pos, const glm::vec3& size, const UVRegion(&faces)[6], const Block* block, ubyte states); const glm::vec3& offset,
const glm::vec3& size,
const UVRegion(&faces)[6],
const Block* block,
ubyte states);
void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread); void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread);
bool isOpenForLight(int x, int y, int z) const; bool isOpenForLight(int x, int y, int z) const;
@ -88,12 +101,12 @@ class BlocksRenderer {
glm::vec4 pickLight(const glm::ivec3& coord) const; glm::vec4 pickLight(const glm::ivec3& coord) const;
glm::vec4 pickSoftLight(const glm::ivec3& coord, const glm::ivec3& right, const glm::ivec3& up) const; glm::vec4 pickSoftLight(const glm::ivec3& coord, const glm::ivec3& right, const glm::ivec3& up) const;
glm::vec4 pickSoftLight(float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up) const; glm::vec4 pickSoftLight(float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up) const;
void render(const voxel* voxels, int atlas_size); void render(const voxel* voxels);
public: public:
BlocksRenderer(size_t capacity, const Content* content, const ContentGfxCache* cache, const EngineSettings& settings); BlocksRenderer(size_t capacity, const Content* content, const ContentGfxCache* cache, const EngineSettings& settings);
virtual ~BlocksRenderer(); virtual ~BlocksRenderer();
Mesh* render(const Chunk* chunk, int atlas_size, const ChunksStorage* chunks); Mesh* render(const Chunk* chunk, const ChunksStorage* chunks);
VoxelsVolume* getVoxelsBuffer() const; VoxelsVolume* getVoxelsBuffer() const;
}; };

View File

@ -22,7 +22,7 @@ ChunksRenderer::~ChunksRenderer() {
shared_ptr<Mesh> ChunksRenderer::render(Chunk* chunk) { shared_ptr<Mesh> ChunksRenderer::render(Chunk* chunk) {
chunk->setModified(false); chunk->setModified(false);
Mesh* mesh = renderer->render(chunk, 16, level->chunksStorage); Mesh* mesh = renderer->render(chunk, level->chunksStorage);
auto sptr = shared_ptr<Mesh>(mesh); auto sptr = shared_ptr<Mesh>(mesh);
meshes[ivec2(chunk->x, chunk->z)] = sptr; meshes[ivec2(chunk->x, chunk->z)] = sptr;
return sptr; return sptr;

View File

@ -29,7 +29,7 @@ bool Font::isPrintableChar(int c) {
} }
} }
#define RES 16 const int RES = 16;
int Font::calcWidth(std::wstring text) { int Font::calcWidth(std::wstring text) {
return text.length() * 8; return text.length() * 8;

View File

@ -7,9 +7,9 @@
class Texture; class Texture;
class Batch2D; class Batch2D;
#define STYLE_NONE 0 const uint STYLE_NONE = 0;
#define STYLE_SHADOW 1 const uint STYLE_SHADOW = 1;
#define STYLE_OUTLINE 2 const uint STYLE_OUTLINE = 2;
class Font { class Font {
int lineHeight_; int lineHeight_;

View File

@ -3,7 +3,7 @@
#include <GL/glew.h> #include <GL/glew.h>
#define LB_VERTEX_SIZE (3+4) const uint LB_VERTEX_SIZE = (3+4);
LineBatch::LineBatch(size_t capacity) : capacity(capacity) { LineBatch::LineBatch(size_t capacity) : capacity(capacity) {
const vattr attrs[] = { {3},{4}, {0} }; const vattr attrs[] = { {3},{4}, {0} };

View File

@ -18,8 +18,8 @@
#include "../world/World.h" #include "../world/World.h"
#include "../maths/voxmaths.h" #include "../maths/voxmaths.h"
#define MAX_WORK_PER_FRAME 16 const uint MAX_WORK_PER_FRAME = 16;
#define MIN_SURROUNDING 9 const uint MIN_SURROUNDING = 9;
using std::unique_ptr; using std::unique_ptr;
using std::shared_ptr; using std::shared_ptr;

View File

@ -15,15 +15,15 @@
#include "../core_defs.h" #include "../core_defs.h"
#define CAM_SHAKE_OFFSET 0.025f const float CAM_SHAKE_OFFSET = 0.025f;
#define CAM_SHAKE_OFFSET_Y 0.031f const float CAM_SHAKE_OFFSET_Y = 0.031f;
#define CAM_SHAKE_SPEED 1.6f const float CAM_SHAKE_SPEED = 1.6f;
#define CAM_SHAKE_DELTA_K 10.0f const float CAM_SHAKE_DELTA_K = 10.0f;
#define ZOOM_SPEED 16.0f const float ZOOM_SPEED = 16.0f;
#define CROUCH_ZOOM 0.9f const float CROUCH_ZOOM = 0.9f;
#define RUN_ZOOM 1.1f const float RUN_ZOOM = 1.1f;
#define C_ZOOM 0.1f const float C_ZOOM = 0.1f;
#define CROUCH_SHIFT_Y -0.2f const float CROUCH_SHIFT_Y = -0.2f;
using glm::vec2; using glm::vec2;
using glm::vec3; using glm::vec3;
@ -110,6 +110,7 @@ vec3 PlayerController::selectedBlockPosition;
vec3 PlayerController::selectedPointPosition; vec3 PlayerController::selectedPointPosition;
vec3 PlayerController::selectedBlockNormal; vec3 PlayerController::selectedBlockNormal;
int PlayerController::selectedBlockId = -1; int PlayerController::selectedBlockId = -1;
int PlayerController::selectedBlockStates = 0;
PlayerController::PlayerController(Level* level, const EngineSettings& settings) PlayerController::PlayerController(Level* level, const EngineSettings& settings)
: level(level), : level(level),
@ -133,6 +134,7 @@ void PlayerController::update(float delta, bool input, bool pause) {
updateInteraction(); updateInteraction();
} else { } else {
selectedBlockId = -1; selectedBlockId = -1;
selectedBlockStates = 0;
} }
} }
@ -207,6 +209,7 @@ void PlayerController::updateInteraction(){
if (vox != nullptr){ if (vox != nullptr){
player->selectedVoxel = *vox; player->selectedVoxel = *vox;
selectedBlockId = vox->id; selectedBlockId = vox->id;
selectedBlockStates = vox->states;
selectedBlockPosition = iend; selectedBlockPosition = iend;
selectedPointPosition = end; selectedPointPosition = end;
selectedBlockNormal = norm; selectedBlockNormal = norm;
@ -248,5 +251,6 @@ void PlayerController::updateInteraction(){
} }
} else { } else {
selectedBlockId = -1; selectedBlockId = -1;
selectedBlockStates = 0;
} }
} }

View File

@ -40,6 +40,7 @@ public:
static glm::vec3 selectedBlockNormal; static glm::vec3 selectedBlockNormal;
static glm::vec3 selectedPointPosition; static glm::vec3 selectedPointPosition;
static int selectedBlockId; static int selectedBlockId;
static int selectedBlockStates;
PlayerController(Level* level, const EngineSettings& settings); PlayerController(Level* level, const EngineSettings& settings);
void update(float delta, bool input, bool pause); void update(float delta, bool input, bool pause);

View File

@ -8,13 +8,13 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#define CROUCH_SPEED_MUL 0.35f const float CROUCH_SPEED_MUL = 0.35f;
#define RUN_SPEED_MUL 1.5f const float RUN_SPEED_MUL = 1.5f;
#define PLAYER_GROUND_DAMPING 10.0f const float PLAYER_GROUND_DAMPING = 10.0f;
#define PLAYER_AIR_DAMPING 7.0f const float PLAYER_AIR_DAMPING = 7.0f;
#define FLIGHT_SPEED_MUL 4.0f const float FLIGHT_SPEED_MUL = 4.0f;
#define CHEAT_SPEED_MUL 5.0f const float CHEAT_SPEED_MUL = 5.0f;
#define JUMP_FORCE 7.0f const float JUMP_FORCE = 7.0f;
Player::Player(glm::vec3 position, float speed, Camera* camera) : Player::Player(glm::vec3 position, float speed, Camera* camera) :
speed(speed), speed(speed),

View File

@ -5,7 +5,7 @@
#include "../voxels/Block.h" #include "../voxels/Block.h"
#include "../voxels/Chunks.h" #include "../voxels/Chunks.h"
#define E 0.03 const double E = 0.03;
using glm::vec3; using glm::vec3;

View File

@ -18,7 +18,9 @@ struct DisplaySettings {
/* GLFW swap interval value, 0 - unlimited fps, 1 - vsync*/ /* GLFW swap interval value, 0 - unlimited fps, 1 - vsync*/
int swapInterval = 1; int swapInterval = 1;
/* Window title */ /* Window title */
const char* title = "VoxelEngine-Cpp v" ENGINE_VERSION; std::string title = "VoxelEngine-Cpp v" +
std::to_string(ENGINE_VERSION_MAJOR) + "." +
std::to_string(ENGINE_VERSION_MINOR);
}; };
struct ChunksSettings { struct ChunksSettings {

View File

@ -1,12 +1,24 @@
#include "Block.h" #include "Block.h"
BlockRotProfile BlockRotProfile::PIPE {{ using glm::vec3;
{ { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 } }, // BLOCK_DIR_PY
{ { 0,-1, 0 }, { 1, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 } }, // BLOCK_DIR_PX void CoordSystem::transform(AABB& aabb) {
{ { 1, 0, 0 }, { 0, 0, 1 }, { 0,-1, 0 }, { 0, 0,-1 } }, // BLOCK_DIR_PZ vec3 X(axisX);
{ { 0, 1, 0 }, {-1, 0, 0 }, { 0, 0, 1 }, { 1, 0, 0 } }, // BLOCK_DIR_MX vec3 Y(axisY);
{ {-1, 0, 0 }, { 0,-1, 0 }, { 0, 0, 1 }, { 1, 1, 0 } }, // BLOCK_DIR_MY vec3 Z(axisZ);
{ { 1, 0, 0 }, { 0, 0,-1 }, { 0, 1, 0 }, { 0, 1, 0 } }, // BLOCK_DIR_MZ aabb.a = X * aabb.a.x + Y * aabb.a.y + Z * aabb.a.z;
aabb.b = X * aabb.b.x + Y * aabb.b.y + Z * aabb.b.z;
aabb.a += fix2;
aabb.b += fix2;
}
const BlockRotProfile BlockRotProfile::PIPE {{
// Vertical
{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}, {0, 0, 0}},
// X-Aligned
{{0, -1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 0}},
// Z-Aligned
{{1, 0, 0}, {0, 0, 1}, {0, -1, 0}, {0, 0, -1}, {0, 1, 0}},
}}; }};
Block::Block(std::string name) Block::Block(std::string name)

View File

@ -7,14 +7,14 @@
#include "../maths/aabb.h" #include "../maths/aabb.h"
#include "../typedefs.h" #include "../typedefs.h"
#define FACE_MX 0 const uint FACE_MX = 0;
#define FACE_PX 1 const uint FACE_PX = 1;
#define FACE_MY 2 const uint FACE_MY = 2;
#define FACE_PY 3 const uint FACE_PY = 3;
#define FACE_MZ 4 const uint FACE_MZ = 4;
#define FACE_PZ 5 const uint FACE_PZ = 5;
#define BLOCK_AABB_GRID 16 const uint BLOCK_AABB_GRID = 16;
struct CoordSystem { struct CoordSystem {
glm::ivec3 axisX; glm::ivec3 axisX;
@ -22,6 +22,9 @@ struct CoordSystem {
glm::ivec3 axisZ; glm::ivec3 axisZ;
// Grid 3d position fix offset (for negative vectors) // Grid 3d position fix offset (for negative vectors)
glm::ivec3 fix; glm::ivec3 fix;
glm::ivec3 fix2;
void transform(AABB& aabb);
}; };
struct BlockRotProfile { struct BlockRotProfile {
@ -30,7 +33,7 @@ struct BlockRotProfile {
/* Wood logs, pillars, pipes /* Wood logs, pillars, pipes
3 orientations supported 3 orientations supported
*/ */
static BlockRotProfile PIPE; static const BlockRotProfile PIPE;
}; };
enum class BlockModel { enum class BlockModel {

View File

@ -4,11 +4,13 @@
#include <stdlib.h> #include <stdlib.h>
#include "../constants.h" #include "../constants.h"
#define CHUNK_MODIFIED 0x1 struct ChunkFlag{
#define CHUNK_READY 0x2 static const int MODIFIED = 0x1;
#define CHUNK_LOADED 0x4 static const int READY = 0x2;
#define CHUNK_LIGHTED 0x8 static const int LOADED = 0x4;
#define CHUNK_UNSAVED 0x10 static const int LIGHTED = 0x8;
static const int UNSAVED = 0x10;
};
#define CHUNK_DATA_LEN (CHUNK_VOL*2) #define CHUNK_DATA_LEN (CHUNK_VOL*2)
struct voxel; struct voxel;
@ -19,10 +21,6 @@ struct RenderData {
size_t size; size_t size;
}; };
#define BIT_ON(f,i) do{f|= i;} while(0)
#define BIT_OFF(f,i) do{f&=~(i);} while(0)
#define BITSET(f,i,s) if (s) BIT_ON(f,i); else BIT_OFF(f,i);
class Chunk { class Chunk {
public: public:
int x, z; int x, z;
@ -44,25 +42,32 @@ public:
// flags getters/setters below // flags getters/setters below
inline bool isUnsaved() const {return flags & CHUNK_UNSAVED;} void SETFLAGS(int mask, bool value){
if (value)
flags |= mask;
else
flags &= ~(mask);
}
inline bool isModified() const {return flags & CHUNK_MODIFIED;} inline bool isUnsaved() const {return flags & ChunkFlag::UNSAVED;}
inline bool isLighted() const {return flags & CHUNK_LIGHTED;} inline bool isModified() const {return flags & ChunkFlag::MODIFIED;}
inline bool isLoaded() const {return flags & CHUNK_LOADED;} inline bool isLighted() const {return flags & ChunkFlag::LIGHTED;}
inline bool isReady() const {return flags & CHUNK_READY;} inline bool isLoaded() const {return flags & ChunkFlag::LOADED;}
inline void setUnsaved(bool flag) {BITSET(flags, CHUNK_UNSAVED, flag);} inline bool isReady() const {return flags & ChunkFlag::READY;}
inline void setModified(bool flag) {BITSET(flags, CHUNK_MODIFIED, flag);} inline void setUnsaved(bool newState) {SETFLAGS(ChunkFlag::UNSAVED, newState);}
inline void setLoaded(bool flag) {BITSET(flags, CHUNK_LOADED, flag);} inline void setModified(bool newState) {SETFLAGS(ChunkFlag::MODIFIED, newState);}
inline void setLighted(bool flag) {BITSET(flags, CHUNK_LIGHTED, flag);} inline void setLoaded(bool newState) {SETFLAGS(ChunkFlag::LOADED, newState);}
inline void setReady(bool flag) {BITSET(flags, CHUNK_READY, flag);} inline void setLighted(bool newState) {SETFLAGS(ChunkFlag::LIGHTED, newState);}
inline void setReady(bool newState) {SETFLAGS(ChunkFlag::READY, newState);}
ubyte* encode() const; ubyte* encode() const;
bool decode(ubyte* data); bool decode(ubyte* data);

View File

@ -16,7 +16,7 @@
#include "../maths/voxmaths.h" #include "../maths/voxmaths.h"
#include "../core_defs.h" #include "../core_defs.h"
#define SEA_LEVEL 55 const int SEA_LEVEL = 55;
class Map2D { class Map2D {
int x, z; int x, z;

View File

@ -3,15 +3,12 @@
#include "../typedefs.h" #include "../typedefs.h"
#define BLOCK_DIR_PX 0x1 #define BLOCK_DIR_X 0x1
#define BLOCK_DIR_PY 0x0 #define BLOCK_DIR_Y 0x0
#define BLOCK_DIR_PZ 0x2 #define BLOCK_DIR_Z 0x2
#define BLOCK_DIR_MX 0x3
#define BLOCK_DIR_MY 0x4
#define BLOCK_DIR_MZ 0x5
// limited to 16 block orientations // limited to 16 block orientations
#define BLOCK_ROT_MASK 0xF const int BLOCK_ROT_MASK = 0xF;
struct voxel { struct voxel {
blockid_t id; blockid_t id;

View File

@ -1,8 +1,12 @@
#include <iostream>
#include "Events.h" #include "Events.h"
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <string.h> #include <string.h>
const short KEYS_BUFFER_SIZE = 1032;
const short _MOUSE_KEYS_OFFSET = 1024;
bool* Events::_keys; bool* Events::_keys;
uint* Events::_frames; uint* Events::_frames;
uint Events::_current = 0; uint Events::_current = 0;
@ -18,11 +22,11 @@ std::vector<int> Events::pressedKeys;
std::unordered_map<std::string, Binding> Events::bindings; std::unordered_map<std::string, Binding> Events::bindings;
int Events::initialize(){ int Events::initialize(){
_keys = new bool[1032]; _keys = new bool[KEYS_BUFFER_SIZE];
_frames = new uint[1032]; _frames = new uint[KEYS_BUFFER_SIZE];
memset(_keys, false, 1032*sizeof(bool)); memset(_keys, false, KEYS_BUFFER_SIZE*sizeof(bool));
memset(_frames, 0, 1032*sizeof(uint)); memset(_frames, 0, KEYS_BUFFER_SIZE*sizeof(uint));
return 0; return 0;
} }
@ -32,26 +36,28 @@ void Events::finalize(){
delete[] _frames; delete[] _frames;
} }
// Returns bool repr. of key state
bool Events::pressed(int keycode){ bool Events::pressed(int keycode){
if (keycode < 0 || keycode >= _MOUSE_BUTTONS) if (keycode < 0 || keycode >= KEYS_BUFFER_SIZE){
// VERY bad behaviour and it happens constantly! (so console-printing is not a good idea)
return false; return false;
}
return _keys[keycode]; return _keys[keycode];
} }
// Returns bool repr. of key state
bool Events::jpressed(int keycode){ bool Events::jpressed(int keycode){
if (keycode < 0 || keycode >= _MOUSE_BUTTONS) return Events::pressed(keycode) && _frames[keycode] == _current;
return false;
return _keys[keycode] && _frames[keycode] == _current;
} }
// Returns bool repr. of mouse key state
bool Events::clicked(int button){ bool Events::clicked(int button){
int index = _MOUSE_BUTTONS+button; return Events::pressed(_MOUSE_KEYS_OFFSET + button);
return _keys[index];
} }
// Returns bool repr. of mouse key state
bool Events::jclicked(int button){ bool Events::jclicked(int button){
int index = _MOUSE_BUTTONS+button; return Events::jpressed(_MOUSE_KEYS_OFFSET + button);
return _keys[index] && _frames[index] == _current;
} }
void Events::toggleCursor(){ void Events::toggleCursor(){
@ -59,7 +65,7 @@ void Events::toggleCursor(){
Window::setCursorMode(_cursor_locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL); Window::setCursorMode(_cursor_locked ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
} }
void Events::pullEvents(){ void Events::pollEvents(){
_current++; _current++;
deltaX = 0.0f; deltaX = 0.0f;
deltaY = 0.0f; deltaY = 0.0f;

View File

@ -10,6 +10,9 @@
typedef unsigned int uint; typedef unsigned int uint;
extern const short KEYS_BUFFER_SIZE;
extern const short _MOUSE_KEYS_OFFSET;
class Events { class Events {
public: public:
static bool* _keys; static bool* _keys;
@ -28,7 +31,7 @@ public:
static int initialize(); static int initialize();
static void finalize(); static void finalize();
static void pullEvents(); static void pollEvents();
static bool pressed(int keycode); static bool pressed(int keycode);
static bool jpressed(int keycode); static bool jpressed(int keycode);
@ -43,6 +46,4 @@ public:
static bool jactive(std::string name); static bool jactive(std::string name);
}; };
#define _MOUSE_BUTTONS 1024
#endif /* WINDOW_EVENTS_H_ */ #endif /* WINDOW_EVENTS_H_ */

View File

@ -34,23 +34,27 @@ void cursor_position_callback(GLFWwindow*, double xpos, double ypos) {
void mouse_button_callback(GLFWwindow*, int button, int action, int) { void mouse_button_callback(GLFWwindow*, int button, int action, int) {
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
Events::_keys[_MOUSE_BUTTONS + button] = true; // Unsafe assignments! (no checks)
Events::_frames[_MOUSE_BUTTONS + button] = Events::_current; Events::_keys[_MOUSE_KEYS_OFFSET + button] = true;
Events::_frames[_MOUSE_KEYS_OFFSET + button] = Events::_current;
} }
else if (action == GLFW_RELEASE) { else if (action == GLFW_RELEASE) {
Events::_keys[_MOUSE_BUTTONS + button] = false; // Unsafe assignments! (no checks)
Events::_frames[_MOUSE_BUTTONS + button] = Events::_current; Events::_keys[_MOUSE_KEYS_OFFSET + button] = false;
Events::_frames[_MOUSE_KEYS_OFFSET + button] = Events::_current;
} }
} }
void key_callback(GLFWwindow*, int key, int scancode, int action, int /*mode*/) { void key_callback(GLFWwindow*, int key, int scancode, int action, int /*mode*/) {
if (key == GLFW_KEY_UNKNOWN) return; if (key == GLFW_KEY_UNKNOWN) return;
if (action == GLFW_PRESS) { if (action == GLFW_PRESS) {
// Unsafe assignments! (no checks)
Events::_keys[key] = true; Events::_keys[key] = true;
Events::_frames[key] = Events::_current; Events::_frames[key] = Events::_current;
Events::pressedKeys.push_back(key); Events::pressedKeys.push_back(key);
} }
else if (action == GLFW_RELEASE) { else if (action == GLFW_RELEASE) {
// Unsafe assignments! (no checks)
Events::_keys[key] = false; Events::_keys[key] = false;
Events::_frames[key] = Events::_current; Events::_frames[key] = Events::_current;
} }
@ -124,7 +128,7 @@ int Window::initialize(DisplaySettings& settings){
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, settings.samples); glfwWindowHint(GLFW_SAMPLES, settings.samples);
window = glfwCreateWindow(width, height, settings.title, nullptr, nullptr); window = glfwCreateWindow(width, height, settings.title.c_str(), nullptr, nullptr);
if (window == nullptr){ if (window == nullptr){
cerr << "Failed to create GLFW Window" << endl; cerr << "Failed to create GLFW Window" << endl;
glfwTerminate(); glfwTerminate();

View File

@ -3,96 +3,96 @@
#include <string> #include <string>
namespace keycode { struct keycode {
extern int ENTER; static int ENTER;
extern int TAB; static int TAB;
extern int SPACE; static int SPACE;
extern int BACKSPACE; static int BACKSPACE;
extern int LEFT_CONTROL; static int LEFT_CONTROL;
extern int LEFT_SHIFT; static int LEFT_SHIFT;
extern int LEFT_ALT; static int LEFT_ALT;
extern int RIGHT_CONTROL; static int RIGHT_CONTROL;
extern int RIGHT_SHIFT; static int RIGHT_SHIFT;
extern int RIGHT_ALT; static int RIGHT_ALT;
extern int ESCAPE; static int ESCAPE;
extern int CAPS_LOCK; static int CAPS_LOCK;
extern int LEFT; static int LEFT;
extern int RIGHT; static int RIGHT;
extern int DOWN; static int DOWN;
extern int UP; static int UP;
extern int F1; static int F1;
extern int F2; static int F2;
extern int F3; static int F3;
extern int F4; static int F4;
extern int F5; static int F5;
extern int F6; static int F6;
extern int F7; static int F7;
extern int F8; static int F8;
extern int F9; static int F9;
extern int F10; static int F10;
extern int F11; static int F11;
extern int F12; static int F12;
extern int A; static int A;
extern int B; static int B;
extern int C; static int C;
extern int D; static int D;
extern int E; static int E;
extern int F; static int F;
extern int G; static int G;
extern int H; static int H;
extern int I; static int I;
extern int J; static int J;
extern int K; static int K;
extern int L; static int L;
extern int M; static int M;
extern int N; static int N;
extern int O; static int O;
extern int P; static int P;
extern int Q; static int Q;
extern int R; static int R;
extern int S; static int S;
extern int T; static int T;
extern int U; static int U;
extern int V; static int V;
extern int W; static int W;
extern int X; static int X;
extern int Y; static int Y;
extern int Z; static int Z;
extern int NUM_0; static int NUM_0;
extern int NUM_1; static int NUM_1;
extern int NUM_2; static int NUM_2;
extern int NUM_3; static int NUM_3;
extern int NUM_4; static int NUM_4;
extern int NUM_5; static int NUM_5;
extern int NUM_6; static int NUM_6;
extern int NUM_7; static int NUM_7;
extern int NUM_8; static int NUM_8;
extern int NUM_9; static int NUM_9;
extern int MENU; static int MENU;
extern int PAUSE; static int PAUSE;
extern int INSERT; static int INSERT;
extern int LEFT_SUPER; static int LEFT_SUPER;
extern int RIGHT_SUPER; static int RIGHT_SUPER;
extern int DELETE; static int DELETE;
extern int PAGE_UP; static int PAGE_UP;
extern int PAGE_DOWN; static int PAGE_DOWN;
extern int HOME; static int HOME;
extern int END; static int END;
extern int PRINT_SCREEN; static int PRINT_SCREEN;
extern int NUM_LOCK; static int NUM_LOCK;
extern int LEFT_BRACKET; static int LEFT_BRACKET;
extern int RIGHT_BRACKET; static int RIGHT_BRACKET;
extern const std::string name(int code); static const std::string name(int code);
} };
namespace mousecode { struct mousecode {
extern int BUTTON_1; static int BUTTON_1;
extern int BUTTON_2; static int BUTTON_2;
extern int BUTTON_3; static int BUTTON_3;
extern const std::string name(int code); static const std::string name(int code);
} };
enum class inputtype { enum class inputtype {
keyboard, keyboard,