world-wide commit to ruin everything
This commit is contained in:
parent
fbce36a05c
commit
8a073e4e8a
@ -11,6 +11,9 @@ CPP_SRCS += \
|
||||
../src/graphics/Mesh.cpp \
|
||||
../src/graphics/Shader.cpp \
|
||||
../src/graphics/Texture.cpp \
|
||||
../src/graphics/Sprite.cpp \
|
||||
../src/graphics/UVRegion.cpp \
|
||||
../src/graphics/Framebuffer.cpp \
|
||||
../src/graphics/VoxelRenderer.cpp
|
||||
|
||||
OBJS += \
|
||||
@ -21,6 +24,9 @@ OBJS += \
|
||||
./src/graphics/Mesh.o \
|
||||
./src/graphics/Shader.o \
|
||||
./src/graphics/Texture.o \
|
||||
./src/graphics/Sprite.o \
|
||||
./src/graphics/UVRegion.o \
|
||||
./src/graphics/Framebuffer.o \
|
||||
./src/graphics/VoxelRenderer.o
|
||||
|
||||
CPP_DEPS += \
|
||||
@ -31,6 +37,9 @@ CPP_DEPS += \
|
||||
./src/graphics/Mesh.d \
|
||||
./src/graphics/Shader.d \
|
||||
./src/graphics/Texture.d \
|
||||
./src/graphics/Sprite.d \
|
||||
./src/graphics/UVRegion.d \
|
||||
./src/graphics/Framebuffer.d \
|
||||
./src/graphics/VoxelRenderer.d
|
||||
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ CPP_SRCS += \
|
||||
../src/player_control.cpp \
|
||||
../src/hud_render.cpp \
|
||||
../src/world_render.cpp \
|
||||
../src/declarations.cpp \
|
||||
../src/voxel_engine.cpp
|
||||
|
||||
OBJS += \
|
||||
@ -15,6 +16,7 @@ OBJS += \
|
||||
./src/player_control.o \
|
||||
./src/hud_render.o \
|
||||
./src/world_render.o \
|
||||
./src/declarations.o \
|
||||
./src/voxel_engine.o
|
||||
|
||||
CPP_DEPS += \
|
||||
@ -22,6 +24,7 @@ CPP_DEPS += \
|
||||
./src/player_control.d \
|
||||
./src/hud_render.d \
|
||||
./src/world_render.d \
|
||||
./src/declarations.d \
|
||||
./src/voxel_engine.d
|
||||
|
||||
|
||||
|
||||
BIN
res/block.png
BIN
res/block.png
Binary file not shown.
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 12 KiB |
BIN
res/img.png
BIN
res/img.png
Binary file not shown.
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 793 B |
@ -11,10 +11,11 @@ uniform float u_fogFactor;
|
||||
|
||||
void main(){
|
||||
vec4 tex_color = texture(u_texture0, a_texCoord);
|
||||
//if (tex_color.a < 0.5)
|
||||
// discard;
|
||||
float depth = (a_distance/256.0)*(a_distance/256.0)*256.0/6;
|
||||
float depth = (a_distance/256.0);
|
||||
float alpha = a_color.a * tex_color.a;
|
||||
// anyway it's any alpha-test alternative required
|
||||
if (alpha < 0.1f)
|
||||
discard;
|
||||
f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth*u_fogFactor));
|
||||
f_color.a = alpha;
|
||||
}
|
||||
|
||||
@ -15,12 +15,19 @@ uniform vec3 u_skyLightColor;
|
||||
uniform vec3 u_cameraPos;
|
||||
uniform float u_gamma;
|
||||
|
||||
uniform vec3 u_torchlightColor;
|
||||
uniform float u_torchlightDistance;
|
||||
|
||||
void main(){
|
||||
vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz;
|
||||
vec4 viewmodelpos = u_view * u_model * vec4(v_position+vec3(0,pow(length(pos2d)*0.0, 3.0),0), 1.0);
|
||||
a_color = vec4(pow(v_light.rgb, vec3(u_gamma)),1.0f);
|
||||
vec4 modelpos = u_model * vec4(v_position+vec3(0,pow(length(pos2d)*0.0, 3.0),0), 1.0);
|
||||
vec4 viewmodelpos = u_view * modelpos;
|
||||
vec3 light = v_light.rgb;
|
||||
float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz)/u_torchlightDistance);
|
||||
light += torchlight * u_torchlightColor;
|
||||
a_color = vec4(pow(light, vec3(u_gamma)),1.0f);
|
||||
a_texCoord = v_texCoord;
|
||||
a_color.rgb += u_skyLightColor * v_light.a*0.5;
|
||||
a_distance = length(viewmodelpos);
|
||||
a_color.rgb += u_skyLightColor * v_light.a;
|
||||
a_distance = pow(length(viewmodelpos), 1.5);
|
||||
gl_Position = u_proj * viewmodelpos;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 257 KiB |
@ -12,5 +12,5 @@ uniform mat4 u_projview;
|
||||
void main(){
|
||||
a_textureCoord = v_textureCoord;
|
||||
a_color = v_color;
|
||||
gl_Position = u_projview * vec4(v_position, 0.0, 1.0);
|
||||
gl_Position = u_projview * vec4(v_position, 0.5, 1.0);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ std::vector<ALSource*> Audio::freesources;
|
||||
std::vector<ALBuffer*> Audio::allbuffers;
|
||||
std::vector<ALBuffer*> Audio::freebuffers;
|
||||
|
||||
bool ALSource::setBuffer(ALBuffer* buffer){
|
||||
bool ALSource::setBuffer(ALBuffer* buffer) {
|
||||
alSourcei(id, AL_BUFFER, buffer->id);
|
||||
return alCheck();
|
||||
}
|
||||
@ -25,17 +25,23 @@ bool ALSource::play(){
|
||||
return alCheck();
|
||||
}
|
||||
|
||||
bool ALSource::setPosition(glm::vec3 position){
|
||||
bool ALSource::isPlaying() {
|
||||
int state;
|
||||
alGetSourcei(id, AL_SOURCE_STATE, &state);
|
||||
return state == AL_PLAYING;
|
||||
}
|
||||
|
||||
bool ALSource::setPosition(glm::vec3 position) {
|
||||
alSource3f(id, AL_POSITION, position.x, position.y, position.z);
|
||||
return alCheck();
|
||||
}
|
||||
|
||||
bool ALSource::setVelocity(glm::vec3 velocity){
|
||||
bool ALSource::setVelocity(glm::vec3 velocity) {
|
||||
alSource3f(id, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
|
||||
return alCheck();
|
||||
}
|
||||
|
||||
bool ALSource::setLoop(bool loop){
|
||||
bool ALSource::setLoop(bool loop) {
|
||||
alSourcei(id, AL_LOOPING, AL_TRUE ? loop : AL_FALSE);
|
||||
return alCheck();
|
||||
}
|
||||
@ -51,13 +57,13 @@ bool ALSource::setPitch(float pitch) {
|
||||
return alCheck();
|
||||
}
|
||||
|
||||
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);
|
||||
return alCheck();
|
||||
}
|
||||
|
||||
|
||||
bool Audio::initialize(){
|
||||
bool Audio::initialize() {
|
||||
device = alcOpenDevice(nullptr);
|
||||
if (device == nullptr)
|
||||
return false;
|
||||
@ -84,7 +90,9 @@ bool Audio::initialize(){
|
||||
|
||||
void Audio::finalize(){
|
||||
for (ALSource* source : allsources){
|
||||
alSourceStop(source->id); alCheck();
|
||||
if (source->isPlaying()){
|
||||
alSourceStop(source->id); alCheck();
|
||||
}
|
||||
alDeleteSources(1, &source->id); alCheck();
|
||||
}
|
||||
|
||||
@ -168,7 +176,7 @@ bool Audio::get_available_devices(std::vector<std::string>& devicesVec){
|
||||
return true;
|
||||
}
|
||||
|
||||
void Audio::setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){
|
||||
void Audio::setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up){
|
||||
ALfloat listenerOri[] = { at.x, at.y, at.z, up.x, up.y, up.z };
|
||||
|
||||
alListener3f(AL_POSITION, position.x, position.y, position.z);
|
||||
|
||||
@ -16,6 +16,7 @@ struct ALSource {
|
||||
ALuint id;
|
||||
ALSource(ALuint id) : id(id) {}
|
||||
|
||||
bool isPlaying();
|
||||
bool setPosition(glm::vec3 position);
|
||||
bool setVelocity(glm::vec3 velocity);
|
||||
bool setBuffer(ALBuffer* buffer);
|
||||
@ -54,7 +55,7 @@ public:
|
||||
static void finalize();
|
||||
static bool get_available_devices(std::vector<std::string>& devicesVec);
|
||||
|
||||
static void setOrientation(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up);
|
||||
static void setListener(glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up);
|
||||
|
||||
};
|
||||
|
||||
|
||||
154
src/declarations.cpp
Normal file
154
src/declarations.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
#include "declarations.h"
|
||||
|
||||
#include "Assets.h"
|
||||
#include "graphics/Shader.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/Font.h"
|
||||
#include "window/Window.h"
|
||||
|
||||
#include "voxels/Block.h"
|
||||
|
||||
// Shaders, textures
|
||||
bool _load_shader(Assets* assets, std::string vertex_file, std::string fragment_file, std::string name){
|
||||
Shader* shader = load_shader(vertex_file, fragment_file);
|
||||
if (shader == nullptr){
|
||||
std::cerr << "failed to load shader '" << name << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
assets->store(shader, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _load_texture(Assets* assets, std::string filename, std::string name){
|
||||
Texture* texture = load_texture(filename);
|
||||
if (texture == nullptr){
|
||||
std::cerr << "failed to load texture '" << name << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
assets->store(texture, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _load_font(Assets* assets, std::string filename, std::string name){
|
||||
std::vector<Texture*> 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(pages);
|
||||
assets->store(font, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
int initialize_assets(Assets* assets) {
|
||||
#define LOAD_SHADER(VERTEX, FRAGMENT, NAME) \
|
||||
if (!_load_shader(assets, VERTEX, FRAGMENT, NAME))\
|
||||
return 1;
|
||||
#define LOAD_TEXTURE(FILENAME, NAME) \
|
||||
if (!_load_texture(assets, FILENAME, NAME))\
|
||||
return 1;
|
||||
#define LOAD_FONT(FILENAME, NAME) \
|
||||
if (!_load_font(assets, FILENAME, NAME))\
|
||||
return 1;
|
||||
|
||||
LOAD_SHADER("res/main.glslv", "res/main.glslf", "main");
|
||||
LOAD_SHADER("res/crosshair.glslv", "res/crosshair.glslf", "crosshair");
|
||||
LOAD_SHADER("res/lines.glslv", "res/lines.glslf", "lines");
|
||||
LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui");
|
||||
|
||||
LOAD_TEXTURE("res/block.png", "block");
|
||||
LOAD_TEXTURE("res/slot.png", "slot");
|
||||
|
||||
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;
|
||||
|
||||
Block* block = new Block(BLOCK_AIR, 0);
|
||||
block->drawGroup = 1;
|
||||
block->lightPassing = true;
|
||||
block->skyLightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->selectable = false;
|
||||
block->model = 0;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_DIRT, 2);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_GRASS_BLOCK, 4);
|
||||
block->textureFaces[2] = 2;
|
||||
block->textureFaces[3] = 1;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_LAMP, 3);
|
||||
block->emission[0] = 15;
|
||||
block->emission[1] = 14;
|
||||
block->emission[2] = 13;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_GLASS,5);
|
||||
block->drawGroup = 2;
|
||||
block->lightPassing = true;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_PLANKS, 6);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_WOOD, 7);
|
||||
block->textureFaces[2] = 8;
|
||||
block->textureFaces[3] = 8;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_LEAVES, 9);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_STONE, 10);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_WATER, 11);
|
||||
block->drawGroup = 4;
|
||||
block->lightPassing = true;
|
||||
block->skyLightPassing = false;
|
||||
block->obstacle = false;
|
||||
block->selectable = false;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_SAND, 12);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_BEDROCK, 13);
|
||||
block->breakable = false;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_GRASS, 14);
|
||||
block->drawGroup = 5;
|
||||
block->lightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->model = 2;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_FLOWER, 16);
|
||||
block->drawGroup = 5;
|
||||
block->lightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->model = 2;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_BRICK, 17);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_METAL, 18);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
block = new Block(BLOCK_RUST, 19);
|
||||
Block::blocks[block->id] = block;
|
||||
}
|
||||
@ -2,164 +2,29 @@
|
||||
#define DECLARATIONS_H
|
||||
|
||||
#include <iostream>
|
||||
#include "Assets.h"
|
||||
#include "graphics/Shader.h"
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/Font.h"
|
||||
#include "window/Window.h"
|
||||
|
||||
#include "voxels/Block.h"
|
||||
#define BLOCK_AIR 0
|
||||
#define BLOCK_DIRT 1
|
||||
#define BLOCK_GRASS_BLOCK 2
|
||||
#define BLOCK_LAMP 3
|
||||
#define BLOCK_GLASS 4
|
||||
#define BLOCK_PLANKS 5
|
||||
#define BLOCK_WOOD 6
|
||||
#define BLOCK_LEAVES 7
|
||||
#define BLOCK_STONE 8
|
||||
#define BLOCK_WATER 9
|
||||
#define BLOCK_SAND 10
|
||||
#define BLOCK_BEDROCK 11
|
||||
#define BLOCK_GRASS 12
|
||||
#define BLOCK_FLOWER 13
|
||||
#define BLOCK_BRICK 14
|
||||
#define BLOCK_METAL 15
|
||||
#define BLOCK_RUST 16
|
||||
|
||||
class Assets;
|
||||
|
||||
// Shaders, textures, renderers
|
||||
int initialize_assets(Assets* assets);
|
||||
void setup_definitions();
|
||||
|
||||
bool _load_shader(Assets* assets, std::string vertex_file, std::string fragment_file, std::string name){
|
||||
Shader* shader = load_shader(vertex_file, fragment_file);
|
||||
if (shader == nullptr){
|
||||
std::cerr << "failed to load shader '" << name << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
assets->store(shader, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _load_texture(Assets* assets, std::string filename, std::string name){
|
||||
Texture* texture = load_texture(filename);
|
||||
if (texture == nullptr){
|
||||
std::cerr << "failed to load texture '" << name << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
assets->store(texture, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _load_font(Assets* assets, std::string filename, std::string name){
|
||||
std::vector<Texture*> 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(pages);
|
||||
assets->store(font, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
int initialize_assets(Assets* assets) {
|
||||
#define LOAD_SHADER(VERTEX, FRAGMENT, NAME) \
|
||||
if (!_load_shader(assets, VERTEX, FRAGMENT, NAME))\
|
||||
return 1;
|
||||
#define LOAD_TEXTURE(FILENAME, NAME) \
|
||||
if (!_load_texture(assets, FILENAME, NAME))\
|
||||
return 1;
|
||||
#define LOAD_FONT(FILENAME, NAME) \
|
||||
if (!_load_font(assets, FILENAME, NAME))\
|
||||
return 1;
|
||||
|
||||
LOAD_SHADER("res/main.glslv", "res/main.glslf", "main");
|
||||
LOAD_SHADER("res/crosshair.glslv", "res/crosshair.glslf", "crosshair");
|
||||
LOAD_SHADER("res/lines.glslv", "res/lines.glslf", "lines");
|
||||
LOAD_SHADER("res/ui.glslv", "res/ui.glslf", "ui");
|
||||
|
||||
LOAD_TEXTURE("res/block.png", "block");
|
||||
LOAD_TEXTURE("res/sprite.png", "sprite");
|
||||
|
||||
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;
|
||||
block->lightPassing = true;
|
||||
block->skyLightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->selectable = false;
|
||||
block->model = 0;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// DIRT 1
|
||||
block = new Block(1,2);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// GRASS BLOCK2
|
||||
block = new Block(2,4);
|
||||
block->textureFaces[2] = 2;
|
||||
block->textureFaces[3] = 1;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// LAMP 3
|
||||
block = new Block(3,3);
|
||||
block->emission[0] = 15;
|
||||
block->emission[1] = 14;
|
||||
block->emission[2] = 13;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// GLASS 4
|
||||
block = new Block(4,5);
|
||||
block->drawGroup = 2;
|
||||
block->lightPassing = true;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// PLANKS 5
|
||||
block = new Block(5,6);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// WOOD 6
|
||||
block = new Block(6,7);
|
||||
block->textureFaces[2] = 8;
|
||||
block->textureFaces[3] = 8;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// LEAVES 7
|
||||
block = new Block(7,9);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// STONE 8
|
||||
block = new Block(8,10);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// WATER 9
|
||||
block = new Block(9,11);
|
||||
block->drawGroup = 4;
|
||||
block->lightPassing = true;
|
||||
block->skyLightPassing = false;
|
||||
block->obstacle = false;
|
||||
block->selectable = false;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// SAND 10
|
||||
block = new Block(10,12);
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// BEDROCK 11
|
||||
block = new Block(11,13);
|
||||
block->breakable = false;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// GRASS 12
|
||||
block = new Block(12,14);
|
||||
block->drawGroup = 5;
|
||||
block->lightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->model = 2;
|
||||
Block::blocks[block->id] = block;
|
||||
|
||||
// FLOWER 13
|
||||
block = new Block(13,16);
|
||||
block->drawGroup = 5;
|
||||
block->lightPassing = true;
|
||||
block->obstacle = false;
|
||||
block->model = 2;
|
||||
Block::blocks[block->id] = block;
|
||||
}
|
||||
#endif // DECLARATIONS_H
|
||||
|
||||
|
||||
@ -19,6 +19,9 @@ union {
|
||||
|
||||
#define SECTION_POSITION 1
|
||||
#define SECTION_ROTATION 2
|
||||
#define SECTION_FLAGS 3
|
||||
#define PLAYER_FLAG_FLIGHT 0x1
|
||||
#define PLAYER_FLAG_NOCLIP 0x2
|
||||
|
||||
unsigned long WorldFiles::totalCompressed = 0;
|
||||
|
||||
@ -33,7 +36,7 @@ void int2Bytes(int value, char* dest, unsigned int offset){
|
||||
dest[offset+3] = (char) (value >> 0 & 255);
|
||||
}
|
||||
|
||||
void float2Bytes(float fvalue, char* dest, unsigned int offset){
|
||||
void floatToBytes(float fvalue, char* dest, unsigned int offset){
|
||||
uint32_t value = *((uint32_t*)&fvalue);
|
||||
dest[offset] = (char) (value >> 24 & 255);
|
||||
dest[offset+1] = (char) (value >> 16 & 255);
|
||||
@ -58,15 +61,15 @@ WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity) : direc
|
||||
WorldFiles::~WorldFiles(){
|
||||
delete[] mainBufferIn;
|
||||
delete[] mainBufferOut;
|
||||
std::unordered_map<long, char**>::iterator it;
|
||||
std::unordered_map<long, WorldRegion>::iterator it;
|
||||
for (it = regions.begin(); it != regions.end(); it++){
|
||||
char** region = it->second;
|
||||
if (region == nullptr)
|
||||
WorldRegion region = it->second;
|
||||
if (region.chunksData == nullptr)
|
||||
continue;
|
||||
for (unsigned int i = 0; i < REGION_VOL; i++){
|
||||
delete[] region[i];
|
||||
delete[] region.chunksData[i];
|
||||
}
|
||||
delete[] region;
|
||||
delete[] region.chunksData;
|
||||
}
|
||||
regions.clear();
|
||||
}
|
||||
@ -82,17 +85,17 @@ void WorldFiles::put(const char* chunkData, int x, int y){
|
||||
|
||||
_tempcoords._coords[0] = regionX;
|
||||
_tempcoords._coords[1] = regionY;
|
||||
char** region = regions[_tempcoords._key];
|
||||
if (region == nullptr){
|
||||
region = new char*[REGION_VOL];
|
||||
WorldRegion& region = regions[_tempcoords._key];
|
||||
region.unsaved = true;
|
||||
if (region.chunksData == nullptr){
|
||||
region.chunksData = new char*[REGION_VOL];
|
||||
for (unsigned int i = 0; i < REGION_VOL; i++)
|
||||
region[i] = nullptr;
|
||||
regions[_tempcoords._key] = region;
|
||||
region.chunksData[i] = nullptr;
|
||||
}
|
||||
char* targetChunk = region[localY * REGION_SIZE + localX];
|
||||
char* targetChunk = region.chunksData[localY * REGION_SIZE + localX];
|
||||
if (targetChunk == nullptr){
|
||||
targetChunk = new char[CHUNK_VOL];
|
||||
region[localY * REGION_SIZE + localX] = targetChunk;
|
||||
region.chunksData[localY * REGION_SIZE + localX] = targetChunk;
|
||||
totalCompressed += CHUNK_VOL;
|
||||
}
|
||||
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
||||
@ -122,11 +125,11 @@ bool WorldFiles::getChunk(int x, int y, char* out){
|
||||
_tempcoords._coords[0] = regionX;
|
||||
_tempcoords._coords[1] = regionY;
|
||||
|
||||
char** region = regions[_tempcoords._key];
|
||||
if (region == nullptr)
|
||||
WorldRegion& region = regions[_tempcoords._key];
|
||||
if (region.chunksData == nullptr)
|
||||
return readChunk(x,y,out);
|
||||
|
||||
char* chunk = region[chunkIndex];
|
||||
char* chunk = region.chunksData[chunkIndex];
|
||||
if (chunk == nullptr)
|
||||
return readChunk(x,y,out);
|
||||
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
||||
@ -174,34 +177,38 @@ bool WorldFiles::readChunk(int x, int y, char* out){
|
||||
}
|
||||
|
||||
void WorldFiles::write(){
|
||||
std::unordered_map<long, char**>::iterator it;
|
||||
std::unordered_map<long, WorldRegion>::iterator it;
|
||||
for (it = regions.begin(); it != regions.end(); it++){
|
||||
if (it->second == nullptr)
|
||||
if (it->second.chunksData == nullptr || !it->second.unsaved)
|
||||
continue;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
longToCoords(x,y, it->first);
|
||||
|
||||
unsigned int size = writeRegion(mainBufferOut, x,y, it->second);
|
||||
unsigned int size = writeRegion(mainBufferOut, x,y, it->second.chunksData);
|
||||
write_binary_file(getRegionFile(x,y), mainBufferOut, size);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldFiles::writePlayer(Player* player){
|
||||
char dst[1+3*4 + 1+2*4];
|
||||
char dst[1+3*4 + 1+2*4 + 1+1];
|
||||
|
||||
glm::vec3 position = player->hitbox->position;
|
||||
|
||||
size_t offset = 0;
|
||||
dst[offset++] = SECTION_POSITION;
|
||||
float2Bytes(position.x, dst, offset); offset += 4;
|
||||
float2Bytes(position.y, dst, offset); offset += 4;
|
||||
float2Bytes(position.z, dst, offset); offset += 4;
|
||||
floatToBytes(position.x, dst, offset); offset += 4;
|
||||
floatToBytes(position.y, dst, offset); offset += 4;
|
||||
floatToBytes(position.z, dst, offset); offset += 4;
|
||||
|
||||
dst[offset++] = SECTION_ROTATION;
|
||||
float2Bytes(player->camX, dst, offset); offset += 4;
|
||||
float2Bytes(player->camY, dst, offset); offset += 4;
|
||||
floatToBytes(player->camX, dst, offset); offset += 4;
|
||||
floatToBytes(player->camY, dst, offset); offset += 4;
|
||||
|
||||
dst[offset++] = SECTION_FLAGS;
|
||||
dst[offset++] = player->flight * PLAYER_FLAG_FLIGHT |
|
||||
player->noclip * PLAYER_FLAG_NOCLIP;
|
||||
|
||||
write_binary_file(getPlayerFile(), (const char*)dst, sizeof(dst));
|
||||
}
|
||||
@ -227,6 +234,13 @@ bool WorldFiles::readPlayer(Player* player) {
|
||||
player->camX = bytes2Float(data, offset); offset += 4;
|
||||
player->camY = bytes2Float(data, offset); offset += 4;
|
||||
break;
|
||||
case SECTION_FLAGS:
|
||||
{
|
||||
unsigned char flags = data[offset++];
|
||||
player->flight = flags & PLAYER_FLAG_FLIGHT;
|
||||
player->noclip = flags & PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
player->hitbox->position = position;
|
||||
|
||||
@ -12,15 +12,15 @@ class Player;
|
||||
#define REGION_SIZE (1 << (REGION_SIZE_BIT))
|
||||
#define REGION_VOL ((REGION_SIZE) * (REGION_SIZE))
|
||||
|
||||
/* Требование:
|
||||
* - высота мира = 1 чанк (любых размеров)
|
||||
* Пример:
|
||||
* - CHUNK_W = 16, CHUNK_H = 128, CHUNK_D = 16
|
||||
* */
|
||||
struct WorldRegion {
|
||||
char** chunksData;
|
||||
bool unsaved;
|
||||
};
|
||||
|
||||
class WorldFiles {
|
||||
public:
|
||||
static unsigned long totalCompressed;
|
||||
std::unordered_map<long, char**> regions;
|
||||
std::unordered_map<long, WorldRegion> regions;
|
||||
std::string directory;
|
||||
char* mainBufferIn;
|
||||
char* mainBufferOut;
|
||||
|
||||
@ -69,16 +69,17 @@ unsigned int decompressRLE(const char* src, unsigned int length, char* dst, unsi
|
||||
|
||||
unsigned int calcRLE(const char* src, unsigned int length) {
|
||||
unsigned int offset = 0;
|
||||
unsigned int counter = 1;
|
||||
unsigned int counter = 0;
|
||||
char c = src[0];
|
||||
for (unsigned int i = 0; i < length; i++){
|
||||
char cnext = src[i];
|
||||
if (cnext != c || counter == 256){
|
||||
if (cnext != c || counter == 255){
|
||||
offset += 2;
|
||||
c = cnext;
|
||||
counter = 0;
|
||||
} else {
|
||||
counter++;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
return offset + 2;
|
||||
}
|
||||
@ -86,19 +87,20 @@ unsigned int calcRLE(const char* src, unsigned int length) {
|
||||
// max result size = length * 2; returns compressed length
|
||||
unsigned int compressRLE(const char* src, unsigned int length, char* dst) {
|
||||
unsigned int offset = 0;
|
||||
unsigned int counter = 1;
|
||||
unsigned int counter = 0;
|
||||
char c = src[0];
|
||||
for (unsigned int i = 1; i < length; i++){
|
||||
char cnext = src[i];
|
||||
if (cnext != c || counter == 256){
|
||||
dst[offset++] = counter-1;
|
||||
if (cnext != c || counter == 255){
|
||||
dst[offset++] = counter;
|
||||
dst[offset++] = c;
|
||||
c = cnext;
|
||||
counter = 0;
|
||||
} else {
|
||||
counter++;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
dst[offset++] = counter-1;
|
||||
dst[offset++] = counter;
|
||||
dst[offset++] = c;
|
||||
return offset;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "Batch2D.h"
|
||||
#include "Mesh.h"
|
||||
#include "Texture.h"
|
||||
#include "Sprite.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
@ -86,6 +87,116 @@ void Batch2D::rect(float x, float y, float w, float h){
|
||||
vertex(x+w, y+h, 1, 1, r,g,b,a);
|
||||
}
|
||||
|
||||
void Batch2D::rect(
|
||||
float x, float y,
|
||||
float w, float h,
|
||||
float ox, float oy,
|
||||
float angle,
|
||||
UVRegion region,
|
||||
bool flippedX,
|
||||
bool flippedY,
|
||||
vec4 tint) {
|
||||
if (index + 6*VERTEX_SIZE >= capacity)
|
||||
render();
|
||||
|
||||
float centerX = w*ox;
|
||||
float centerY = h*oy;
|
||||
float acenterX = w-centerX;
|
||||
float acenterY = h-centerY;
|
||||
|
||||
float _x1 = -centerX;
|
||||
float _y1 = -centerY;
|
||||
|
||||
float _x2 = -centerX;
|
||||
float _y2 = +acenterY;
|
||||
|
||||
float _x3 = +acenterX;
|
||||
float _y3 = +acenterY;
|
||||
|
||||
float _x4 = +acenterX;
|
||||
float _y4 = -centerY;
|
||||
|
||||
float x1,y1,x2,y2,x3,y3,x4,y4;
|
||||
|
||||
if (angle != 0) {
|
||||
float s = sin(angle);
|
||||
float c = cos(angle);
|
||||
|
||||
x1 = c * _x1 - s * _y1;
|
||||
y1 = s * _x1 + c * _y1;
|
||||
|
||||
x2 = c * _x2 - s * _y2;
|
||||
y2 = s * _x2 + c * _y2;
|
||||
|
||||
x3 = c * _x3 - s * _y3;
|
||||
y3 = s * _x3 + c * _y3;
|
||||
|
||||
x4 = x1 + (x3 - x2);
|
||||
y4 = y3 - (y2 - y1);
|
||||
} else {
|
||||
x1 = _x1;
|
||||
y1 = _y1;
|
||||
x2 = _x2;
|
||||
y2 = _y2;
|
||||
x3 = _x3;
|
||||
y3 = _y3;
|
||||
x4 = _x4;
|
||||
y4 = _y4;
|
||||
}
|
||||
|
||||
x1 += x; x2 += x; x3 += x; x4 += x;
|
||||
y1 += y; y2 += y; y3 += y; y4 += y;
|
||||
|
||||
float u1 = region.u1;
|
||||
float v1 = region.v1;
|
||||
float u2 = region.u1;
|
||||
float v2 = region.v2;
|
||||
float u3 = region.u2;
|
||||
float v3 = region.v2;
|
||||
float u4 = region.u2;
|
||||
float v4 = region.v1;
|
||||
|
||||
if (flippedX) {
|
||||
float temp = u1;
|
||||
u1 = u3;
|
||||
u4 = temp;
|
||||
u2 = u3;
|
||||
u3 = temp;
|
||||
}
|
||||
if (flippedY) {
|
||||
float temp = v1;
|
||||
v1 = v2;
|
||||
v4 = v2;
|
||||
v2 = temp;
|
||||
v3 = temp;
|
||||
}
|
||||
|
||||
vertex(x1, y1, u1, v1, tint.r, tint.g, tint.b, tint.a);
|
||||
vertex(x2, y2, u2, v2, tint.r, tint.g, tint.b, tint.a);
|
||||
vertex(x3, y3, u3, v3, tint.r, tint.g, tint.b, tint.a);
|
||||
|
||||
/* Right down triangle */
|
||||
vertex(x1, y1, u1, v1, tint.r, tint.g, tint.b, tint.a);
|
||||
vertex(x3, y3, u3, v3, tint.r, tint.g, tint.b, tint.a);
|
||||
vertex(x4, y4, u4, v4, tint.r, tint.g, tint.b, tint.a);
|
||||
}
|
||||
|
||||
void Batch2D::sprite(Sprite* sprite) {
|
||||
vec2 position = sprite->position;
|
||||
vec2 size = sprite->size;
|
||||
vec2 origin = sprite->origin;
|
||||
texture(sprite->texture);
|
||||
rect(
|
||||
position.x, position.y,
|
||||
size.x, size.y,
|
||||
origin.x, origin.y,
|
||||
sprite->angle,
|
||||
sprite->region,
|
||||
sprite->flippedX,
|
||||
sprite->flippedY,
|
||||
sprite->color);
|
||||
}
|
||||
|
||||
void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint){
|
||||
float scale = 1.0f / (float)atlasRes;
|
||||
float u = (index % atlasRes) * scale;
|
||||
@ -99,16 +210,19 @@ void Batch2D::blockSprite(float x, float y, float w, float h, int atlasRes, int
|
||||
float vu = 1.0f - ((index[3] / atlasRes) * scale) - scale;
|
||||
float uf = (index[0] % atlasRes) * scale;
|
||||
float vf = 1.0f - ((index[0] / atlasRes) * scale) - scale;
|
||||
if (index[0] + 6*VERTEX_SIZE >= capacity)
|
||||
if (this->index + 18*VERTEX_SIZE >= capacity)
|
||||
render();
|
||||
|
||||
vec2 points[7] = {vec2(x+(w*0.5f), y+(h*0.5f)),
|
||||
vec2(x, y+(h*0.25f)),
|
||||
vec2(x+(w*0.5f), y),
|
||||
vec2(x+w, y+(h*0.25f)),
|
||||
vec2(x+w, y+(h*0.75f)),
|
||||
vec2(x+(w*0.5f), y+h),
|
||||
vec2(x, y+(h*0.75f))};
|
||||
float ar = 0.88f;
|
||||
float ox = x + (w * 0.5f);
|
||||
float sx = w * 0.5f * ar;
|
||||
vec2 points[7] = {vec2(ox, y+(h*0.5f)),
|
||||
vec2(ox-sx, y+(h*0.25f)),
|
||||
vec2(ox, y),
|
||||
vec2(ox+sx, y+(h*0.25f)),
|
||||
vec2(ox+sx, y+(h*0.75f)),
|
||||
vec2(ox, y+h),
|
||||
vec2(ox-sx, y+(h*0.75f))};
|
||||
|
||||
vec2 uvpoints[8] = {vec2(uu, vu),
|
||||
vec2(uu+scale, vu),
|
||||
|
||||
@ -4,16 +4,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "UVRegion.h"
|
||||
|
||||
using namespace glm;
|
||||
|
||||
class Mesh;
|
||||
class Texture;
|
||||
class Sprite;
|
||||
|
||||
class Batch2D {
|
||||
float* buffer;
|
||||
size_t capacity;
|
||||
size_t offset;
|
||||
glm::vec4 color;
|
||||
Mesh* mesh;
|
||||
size_t index;
|
||||
|
||||
@ -28,13 +30,23 @@ class Batch2D {
|
||||
float r, float g, float b, float a);
|
||||
|
||||
public:
|
||||
glm::vec4 color;
|
||||
|
||||
Batch2D(size_t capacity);
|
||||
~Batch2D();
|
||||
|
||||
void begin();
|
||||
void texture(Texture* texture);
|
||||
void sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint);
|
||||
void sprite(Sprite* sprite);
|
||||
void blockSprite(float x, float y, float w, float h, int atlasRes, int index[6], vec4 tint);
|
||||
void rect(float x, float y,
|
||||
float w, float h,
|
||||
float ox, float oy,
|
||||
float angle, UVRegion region,
|
||||
bool flippedX, bool flippedY,
|
||||
vec4 tint);
|
||||
|
||||
void rect(float x, float y, float w, float h);
|
||||
void rect(float x, float y, float w, float h,
|
||||
float u, float v, float tx, float ty,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#define VERTEX_SIZE 9
|
||||
|
||||
Batch3D::Batch3D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){
|
||||
Batch3D::Batch3D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 0.0f){
|
||||
const int attrs[] = {
|
||||
3, 2, 4, 0 //null terminator
|
||||
};
|
||||
|
||||
@ -19,9 +19,9 @@ int Font::getGlyphWidth(char c) {
|
||||
case '.':
|
||||
case ',':
|
||||
case ':':
|
||||
case ';': return 3;
|
||||
case 't': return 5;
|
||||
case ' ': return 3;
|
||||
case ';': return 7;
|
||||
case 't': return 8;
|
||||
case ' ': return 7;
|
||||
}
|
||||
return 7;
|
||||
}
|
||||
@ -75,7 +75,7 @@ void Font::draw(Batch2D* batch, std::wstring text, int x, int y, int style) {
|
||||
break;
|
||||
}
|
||||
|
||||
batch->sprite(x, y, RES, RES, 16, c, vec4(1.0f));
|
||||
batch->sprite(x, y, RES, RES, 16, c, batch->color);
|
||||
}
|
||||
else if (charpage > page && charpage < next){
|
||||
next = charpage;
|
||||
|
||||
37
src/graphics/Framebuffer.cpp
Normal file
37
src/graphics/Framebuffer.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "Framebuffer.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include "Texture.h"
|
||||
|
||||
Framebuffer::Framebuffer(int width, int height) : width(width), height(height) {
|
||||
glGenFramebuffers(1, &fbo);
|
||||
bind();
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
||||
texture = new Texture(tex, width, height);
|
||||
glGenRenderbuffers(1, &depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
|
||||
unbind();
|
||||
}
|
||||
|
||||
Framebuffer::~Framebuffer() {
|
||||
delete texture;
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
void Framebuffer::bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
}
|
||||
|
||||
void Framebuffer::unbind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
20
src/graphics/Framebuffer.h
Normal file
20
src/graphics/Framebuffer.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef SRC_GRAPHICS_FRAMEBUFFER_H_
|
||||
#define SRC_GRAPHICS_FRAMEBUFFER_H_
|
||||
|
||||
class Texture;
|
||||
|
||||
class Framebuffer {
|
||||
unsigned int fbo;
|
||||
unsigned int depth;
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
Texture* texture;
|
||||
Framebuffer(int width, int height);
|
||||
~Framebuffer();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
};
|
||||
|
||||
#endif /* SRC_GRAPHICS_FRAMEBUFFER_H_ */
|
||||
17
src/graphics/Sprite.cpp
Normal file
17
src/graphics/Sprite.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "Sprite.h"
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
Sprite::Sprite(glm::vec2 position, glm::vec2 size, Texture* texture)
|
||||
: position(position),
|
||||
size(size),
|
||||
origin(0.5f, 0.5f),
|
||||
color(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
angle(0.0f),
|
||||
texture(texture),
|
||||
region() {
|
||||
}
|
||||
|
||||
Sprite::~Sprite() {
|
||||
}
|
||||
|
||||
29
src/graphics/Sprite.h
Normal file
29
src/graphics/Sprite.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef SRC_GRAPHICS_SPRITE_H_
|
||||
#define SRC_GRAPHICS_SPRITE_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include "UVRegion.h"
|
||||
|
||||
class Texture;
|
||||
|
||||
class Sprite {
|
||||
public:
|
||||
glm::vec2 position;
|
||||
glm::vec2 size;
|
||||
glm::vec2 origin;
|
||||
glm::vec4 color;
|
||||
float angle;
|
||||
bool flippedX = false;
|
||||
bool flippedY = false;
|
||||
Texture* texture;
|
||||
UVRegion region;
|
||||
|
||||
Sprite(glm::vec2 position, glm::vec2 size, Texture* texture);
|
||||
virtual ~Sprite();
|
||||
|
||||
void setTexture(Texture* texture) {
|
||||
this->texture = texture;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* SRC_GRAPHICS_SPRITE_H_ */
|
||||
1
src/graphics/UVRegion.cpp
Normal file
1
src/graphics/UVRegion.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "UVRegion.h"
|
||||
17
src/graphics/UVRegion.h
Normal file
17
src/graphics/UVRegion.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef SRC_GRAPHICS_UVREGION_H_
|
||||
#define SRC_GRAPHICS_UVREGION_H_
|
||||
|
||||
class UVRegion {
|
||||
public:
|
||||
float u1;
|
||||
float v1;
|
||||
float u2;
|
||||
float v2;
|
||||
|
||||
UVRegion(float u1, float v1, float u2, float v2)
|
||||
: u1(u1), v1(v1), u2(u2), v2(v2){}
|
||||
|
||||
UVRegion() : u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f){}
|
||||
};
|
||||
|
||||
#endif /* SRC_GRAPHICS_UVREGION_H_ */
|
||||
@ -12,7 +12,7 @@
|
||||
#define LOCAL_NEG(X, SIZE) (((X) < 0) ? ((SIZE)+(X)) : (X))
|
||||
#define LOCAL(X, SIZE) ((X) >= (SIZE) ? ((X) - (SIZE)) : LOCAL_NEG(X, SIZE))
|
||||
#define IS_CHUNK(X,Y,Z) (GET_CHUNK(X,Y,Z) != nullptr)
|
||||
#define GET_CHUNK(X,Y,Z) (chunks[((CDIV(Y, CHUNK_H)+1) * 3 + CDIV(Z, CHUNK_D) + 1) * 3 + CDIV(X, CHUNK_W) + 1])
|
||||
#define GET_CHUNK(X,Y,Z) (chunks[(CDIV(Z, CHUNK_D) + 1) * 3 + CDIV(X, CHUNK_W) + 1])
|
||||
|
||||
#define LIGHT(X,Y,Z, CHANNEL) (IS_CHUNK(X,Y,Z) ? GET_CHUNK(X,Y,Z)->lightmap->get(LOCAL(X, CHUNK_W), LOCAL(Y, CHUNK_H), LOCAL(Z, CHUNK_D), (CHANNEL)) : 0)
|
||||
#define VOXEL(X,Y,Z) (GET_CHUNK(X,Y,Z)->voxels[(LOCAL(Y, CHUNK_H) * CHUNK_D + LOCAL(Z, CHUNK_D)) * CHUNK_W + LOCAL(X, CHUNK_W)])
|
||||
@ -43,13 +43,7 @@ VoxelRenderer::VoxelRenderer() {
|
||||
VoxelRenderer::~VoxelRenderer(){
|
||||
}
|
||||
|
||||
inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){
|
||||
unsigned int id = vox.id;
|
||||
|
||||
if (!id){
|
||||
return;
|
||||
}
|
||||
|
||||
inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const Chunk** chunks, unsigned int id, size_t& index){
|
||||
float l;
|
||||
float uvsize = 1.0f/16.0f;
|
||||
|
||||
@ -61,10 +55,10 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
|
||||
SETUP_UV(block->textureFaces[3]);
|
||||
|
||||
float lr = LIGHT(x,y+1,z, 0) / 15.0f;
|
||||
float lg = LIGHT(x,y+1,z, 1) / 15.0f;
|
||||
float lb = LIGHT(x,y+1,z, 2) / 15.0f;
|
||||
float ls = LIGHT(x,y+1,z, 3) / 15.0f;
|
||||
const float lr = LIGHT(x,y+1,z, 0) / 15.0f;
|
||||
const float lg = LIGHT(x,y+1,z, 1) / 15.0f;
|
||||
const float lb = LIGHT(x,y+1,z, 2) / 15.0f;
|
||||
const float ls = LIGHT(x,y+1,z, 3) / 15.0f;
|
||||
|
||||
float lr0 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z-1,0) + LIGHT(x,y+1,z-1,0)) / 75.0f;
|
||||
float lr1 = (LIGHT(x-1,y+1,z,0) + lr*30 + LIGHT(x-1,y+1,z+1,0) + LIGHT(x,y+1,z+1,0)) / 75.0f;
|
||||
@ -99,10 +93,10 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
|
||||
SETUP_UV(block->textureFaces[2]);
|
||||
|
||||
float lr = LIGHT(x,y-1,z, 0) / 15.0f;
|
||||
float lg = LIGHT(x,y-1,z, 1) / 15.0f;
|
||||
float lb = LIGHT(x,y-1,z, 2) / 15.0f;
|
||||
float ls = LIGHT(x,y-1,z, 3) / 15.0f;
|
||||
const float lr = LIGHT(x,y-1,z, 0) / 15.0f;
|
||||
const float lg = LIGHT(x,y-1,z, 1) / 15.0f;
|
||||
const float lb = LIGHT(x,y-1,z, 2) / 15.0f;
|
||||
const float ls = LIGHT(x,y-1,z, 3) / 15.0f;
|
||||
|
||||
float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y-1,z,0) + LIGHT(x,y-1,z-1,0)) / 75.0f;
|
||||
float lr1 = (LIGHT(x+1,y-1,z+1,0) + lr*30 + LIGHT(x+1,y-1,z,0) + LIGHT(x,y-1,z+1,0)) / 75.0f;
|
||||
@ -138,10 +132,10 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
|
||||
SETUP_UV(block->textureFaces[1]);
|
||||
|
||||
float lr = LIGHT(x+1,y,z, 0) / 15.0f;
|
||||
float lg = LIGHT(x+1,y,z, 1) / 15.0f;
|
||||
float lb = LIGHT(x+1,y,z, 2) / 15.0f;
|
||||
float ls = LIGHT(x+1,y,z, 3) / 15.0f;
|
||||
const float lr = LIGHT(x+1,y,z, 0) / 15.0f;
|
||||
const float lg = LIGHT(x+1,y,z, 1) / 15.0f;
|
||||
const float lb = LIGHT(x+1,y,z, 2) / 15.0f;
|
||||
const float ls = LIGHT(x+1,y,z, 3) / 15.0f;
|
||||
|
||||
float lr0 = (LIGHT(x+1,y-1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y-1,z,0)) / 75.0f;
|
||||
float lr1 = (LIGHT(x+1,y+1,z-1,0) + lr*30 + LIGHT(x+1,y,z-1,0) + LIGHT(x+1,y+1,z,0)) / 75.0f;
|
||||
@ -176,10 +170,10 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
|
||||
SETUP_UV(block->textureFaces[0]);
|
||||
|
||||
float lr = LIGHT(x-1,y,z, 0) / 15.0f;
|
||||
float lg = LIGHT(x-1,y,z, 1) / 15.0f;
|
||||
float lb = LIGHT(x-1,y,z, 2) / 15.0f;
|
||||
float ls = LIGHT(x-1,y,z, 3) / 15.0f;
|
||||
const float lr = LIGHT(x-1,y,z, 0) / 15.0f;
|
||||
const float lg = LIGHT(x-1,y,z, 1) / 15.0f;
|
||||
const float lb = LIGHT(x-1,y,z, 2) / 15.0f;
|
||||
const float ls = LIGHT(x-1,y,z, 3) / 15.0f;
|
||||
|
||||
float lr0 = (LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x-1,y,z-1,0) + LIGHT(x-1,y-1,z,0)) / 75.0f;
|
||||
float lr1 = (LIGHT(x-1,y+1,z+1,0) + lr*30 + LIGHT(x-1,y,z+1,0) + LIGHT(x-1,y+1,z,0)) / 75.0f;
|
||||
@ -215,10 +209,10 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
|
||||
SETUP_UV(block->textureFaces[5]);
|
||||
|
||||
float lr = LIGHT(x,y,z+1, 0) / 15.0f;
|
||||
float lg = LIGHT(x,y,z+1, 1) / 15.0f;
|
||||
float lb = LIGHT(x,y,z+1, 2) / 15.0f;
|
||||
float ls = LIGHT(x,y,z+1, 3) / 15.0f;
|
||||
const float lr = LIGHT(x,y,z+1, 0) / 15.0f;
|
||||
const float lg = LIGHT(x,y,z+1, 1) / 15.0f;
|
||||
const float lb = LIGHT(x,y,z+1, 2) / 15.0f;
|
||||
const float ls = LIGHT(x,y,z+1, 3) / 15.0f;
|
||||
|
||||
float lr0 = l*(LIGHT(x-1,y-1,z+1,0) + lr*30 + LIGHT(x,y-1,z+1,0) + LIGHT(x-1,y,z+1,0)) / 75.0f;
|
||||
float lr1 = l*(LIGHT(x+1,y+1,z+1,0) + lr*30 + LIGHT(x,y+1,z+1,0) + LIGHT(x+1,y,z+1,0)) / 75.0f;
|
||||
@ -253,10 +247,10 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
|
||||
SETUP_UV(block->textureFaces[4]);
|
||||
|
||||
float lr = LIGHT(x,y,z-1, 0) / 15.0f;
|
||||
float lg = LIGHT(x,y,z-1, 1) / 15.0f;
|
||||
float lb = LIGHT(x,y,z-1, 2) / 15.0f;
|
||||
float ls = LIGHT(x,y,z-1, 3) / 15.0f;
|
||||
const float lr = LIGHT(x,y,z-1, 0) / 15.0f;
|
||||
const float lg = LIGHT(x,y,z-1, 1) / 15.0f;
|
||||
const float lb = LIGHT(x,y,z-1, 2) / 15.0f;
|
||||
const float ls = LIGHT(x,y,z-1, 3) / 15.0f;
|
||||
|
||||
float lr0 = l*(LIGHT(x-1,y-1,z-1,0) + lr*30 + LIGHT(x,y-1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 75.0f;
|
||||
float lr1 = l*(LIGHT(x-1,y+1,z-1,0) + lr*30 + LIGHT(x,y+1,z-1,0) + LIGHT(x-1,y,z-1,0)) / 75.0f;
|
||||
@ -288,8 +282,82 @@ inline void _renderBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
}
|
||||
}
|
||||
|
||||
inline void _renderBlockShadeless(std::vector<float>& buffer, int x, int y, int z, const Chunk** chunks, unsigned int id, size_t& index){
|
||||
float l;
|
||||
float uvsize = 1.0f/16.0f;
|
||||
|
||||
Block* block = Block::blocks[id];
|
||||
unsigned char group = block->drawGroup;
|
||||
|
||||
if (!IS_BLOCKED(x,y+1,z,group)){
|
||||
SETUP_UV(block->textureFaces[3]);
|
||||
|
||||
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0);
|
||||
|
||||
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v1, 1,1,1,0);
|
||||
}
|
||||
if (!IS_BLOCKED(x,y-1,z,group)){
|
||||
SETUP_UV(block->textureFaces[2]);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v2, 1,1,1,0);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
}
|
||||
|
||||
if (!IS_BLOCKED(x+1,y,z,group)){
|
||||
SETUP_UV(block->textureFaces[1]);
|
||||
|
||||
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u2,v2, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0);
|
||||
|
||||
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u1,v1, 1,1,1,0);
|
||||
}
|
||||
if (!IS_BLOCKED(x-1,y,z,group)){
|
||||
SETUP_UV(block->textureFaces[0]);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u1,v2, 1,1,1,0);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
}
|
||||
|
||||
if (!IS_BLOCKED(x,y,z+1,group)){
|
||||
SETUP_UV(block->textureFaces[5]);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y+0.5f, z+0.5f, u1,v2, 1,1,1,0);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z+0.5f, u1,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y-0.5f, z+0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z+0.5f, u2,v2, 1,1,1,0);
|
||||
}
|
||||
if (!IS_BLOCKED(x,y,z-1,group)){
|
||||
SETUP_UV(block->textureFaces[4]);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x-0.5f, y+0.5f, z-0.5f, u2,v2, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, 1,1,1,0);
|
||||
|
||||
VERTEX(index, x-0.5f, y-0.5f, z-0.5f, u2,v1, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y+0.5f, z-0.5f, u1,v2, 1,1,1,0);
|
||||
VERTEX(index, x+0.5f, y-0.5f, z-0.5f, u1,v1, 1,1,1,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void _renderXBlock(std::vector<float>& buffer, int x, int y, int z, const Chunk** chunks, voxel vox, size_t& index){
|
||||
@ -304,101 +372,88 @@ inline void _renderXBlock(std::vector<float>& buffer, int x, int y, int z, const
|
||||
return;
|
||||
}
|
||||
|
||||
float l;
|
||||
float uvsize = 1.0f/16.0f;
|
||||
|
||||
float lr = LIGHT(x,y,z, 0) / 15.0f;
|
||||
float lg = LIGHT(x,y,z, 1) / 15.0f;
|
||||
float lb = LIGHT(x,y,z, 2) / 15.0f;
|
||||
float ls = LIGHT(x,y,z, 3) / 15.0f;
|
||||
float lr = LIGHT(x,y,z, 0) / 15.0f;
|
||||
float lg = LIGHT(x,y,z, 1) / 15.0f;
|
||||
float lb = LIGHT(x,y,z, 2) / 15.0f;
|
||||
float ls = LIGHT(x,y,z, 3) / 15.0f;
|
||||
|
||||
float lr0 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr1 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr2 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr3 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr4 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr5 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr6 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr7 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr0 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr1 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr2 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr3 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr4 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
float lr5 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr6 = (LIGHT(x,y+1,z,0) + lr*30) / 45.0f;
|
||||
float lr7 = (LIGHT(x,y-1,z,0) + lr*30) / 45.0f;
|
||||
|
||||
float lg0 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg1 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg2 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg3 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg4 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg5 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg6 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg7 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg0 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg1 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg2 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg3 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg4 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
float lg5 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg6 = (LIGHT(x,y+1,z,1) + lg*30) / 45.0f;
|
||||
float lg7 = (LIGHT(x,y-1,z,1) + lg*30) / 45.0f;
|
||||
|
||||
float lb0 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb1 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb2 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb3 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb4 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb5 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb6 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb7 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb0 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb1 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb2 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb3 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb4 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
float lb5 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb6 = (LIGHT(x,y+1,z,2) + lb*30) / 45.0f;
|
||||
float lb7 = (LIGHT(x,y-1,z,2) + lb*30) / 45.0f;
|
||||
|
||||
float ls0 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls1 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls2 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls3 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls4 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls5 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls6 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls7 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls0 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls1 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls2 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls3 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls4 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
float ls5 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls6 = (LIGHT(x,y+1,z,3) + ls*30) / 45.0f;
|
||||
float ls7 = (LIGHT(x,y-1,z,3) + ls*30) / 45.0f;
|
||||
|
||||
{SETUP_UV(block->textureFaces[1]);
|
||||
|
||||
l = 0.95f;
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2);
|
||||
|
||||
{SETUP_UV(block->textureFaces[1]);
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr3,lg3,lb3,ls3);}
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2);
|
||||
{SETUP_UV(block->textureFaces[0]);
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr2,lg2,lb2,ls2);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr3,lg3,lb3,ls3);}
|
||||
|
||||
|
||||
l = 0.85f;
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr2,lg2,lb2,ls2);
|
||||
|
||||
{SETUP_UV(block->textureFaces[0]);
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr3,lg3,lb3,ls3);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);}
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr2,lg2,lb2,ls2);
|
||||
{SETUP_UV(block->textureFaces[5]);
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr0,lg0,lb0,ls0);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr3,lg3,lb3,ls3);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr1,lg1,lb1,ls1);}
|
||||
|
||||
|
||||
l = 0.9f;
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr6,lg6,lb6,ls6);
|
||||
|
||||
{SETUP_UV(block->textureFaces[5]);
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr7,lg7,lb7,ls7);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);}
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u1,v2, lr6,lg6,lb6,ls6);
|
||||
{SETUP_UV(block->textureFaces[4]);
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u1,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u2,v1, lr7,lg7,lb7,ls7);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);}
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6);
|
||||
|
||||
|
||||
l = 0.8f;
|
||||
|
||||
{SETUP_UV(block->textureFaces[4]);
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x-0.5f+xs, y+0.5f, z+0.5f+zs, u2,v2, lr5,lg5,lb5,ls5);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6);
|
||||
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr7,lg7,lb7,ls7);}
|
||||
VERTEX(index, x-0.5f+xs, y-0.5f, z+0.5f+zs, u2,v1, lr4,lg4,lb4,ls4);
|
||||
VERTEX(index, x+0.5f+xs, y+0.5f, z-0.5f+zs, u1,v2, lr6,lg6,lb6,ls6);
|
||||
VERTEX(index, x+0.5f+xs, y-0.5f, z-0.5f+zs, u1,v1, lr7,lg7,lb7,ls7);}
|
||||
}
|
||||
|
||||
const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& size){
|
||||
@ -408,9 +463,15 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
|
||||
if (vox.id == 0)
|
||||
continue;
|
||||
if (vox.id == 9 || vox.id == 4 || vox.id == 12 || vox.id == 13)
|
||||
continue;
|
||||
_renderBlock(buffer, x, y, z, chunks, vox, index);
|
||||
Block* block = Block::blocks[vox.id];
|
||||
if (block->emission[0] || block->emission[1] || block->emission[2]){
|
||||
continue;
|
||||
}
|
||||
_renderBlock(buffer, x, y, z, chunks, vox.id, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -419,9 +480,25 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
|
||||
if (vox.id == 0)
|
||||
continue;
|
||||
Block* block = Block::blocks[vox.id];
|
||||
if (block->emission[0] || block->emission[1] || block->emission[2]){
|
||||
_renderBlockShadeless(buffer, x, y, z, chunks, vox.id, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < CHUNK_H; y++){
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
|
||||
if (vox.id == 0)
|
||||
continue;
|
||||
if (vox.id != 9)
|
||||
continue;
|
||||
_renderBlock(buffer, x, y, z, chunks, vox, index);
|
||||
_renderBlock(buffer, x, y, z, chunks, vox.id, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,7 +507,9 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
|
||||
if (vox.id != 12 && vox.id != 13)
|
||||
if (vox.id == 0)
|
||||
continue;
|
||||
if (Block::blocks[vox.id]->model != BLOCK_MODEL_GRASS)
|
||||
continue;
|
||||
_renderXBlock(buffer, x, y, z, chunks, vox, index);
|
||||
}
|
||||
@ -441,9 +520,11 @@ const float* VoxelRenderer::render(Chunk* chunk, const Chunk** chunks, size_t& s
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
|
||||
if (vox.id == 0)
|
||||
continue;
|
||||
if (vox.id != 4)
|
||||
continue;
|
||||
_renderBlock(buffer, x, y, z, chunks, vox, index);
|
||||
_renderBlock(buffer, x, y, z, chunks, vox.id, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ class Chunk;
|
||||
class VoxelRenderer {
|
||||
public:
|
||||
std::vector<float> buffer;
|
||||
unsigned char lights[27 * 4];
|
||||
VoxelRenderer();
|
||||
~VoxelRenderer();
|
||||
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
#include "hud_render.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "Assets.h"
|
||||
#include "graphics/Shader.h"
|
||||
#include "graphics/Batch2D.h"
|
||||
#include "graphics/Font.h"
|
||||
#include "graphics/Mesh.h"
|
||||
#include "window/Camera.h"
|
||||
#include "window/Window.h"
|
||||
#include "window/Events.h"
|
||||
#include "voxels/Chunks.h"
|
||||
#include "voxels/Block.h"
|
||||
#include "world/World.h"
|
||||
@ -15,6 +18,19 @@
|
||||
|
||||
|
||||
HudRenderer::HudRenderer() {
|
||||
float vertices[] = {
|
||||
// x y
|
||||
-0.01f,-0.01f,
|
||||
0.01f, 0.01f,
|
||||
|
||||
-0.01f, 0.01f,
|
||||
0.01f,-0.01f,
|
||||
};
|
||||
int attrs[] = {
|
||||
2, 0 //null terminator
|
||||
};
|
||||
crosshair = new Mesh(vertices, 4, attrs);
|
||||
|
||||
batch = new Batch2D(1024);
|
||||
uicamera = new Camera(glm::vec3(), Window::height / 1.0f);
|
||||
uicamera->perspective = false;
|
||||
@ -22,48 +38,103 @@ HudRenderer::HudRenderer() {
|
||||
}
|
||||
|
||||
HudRenderer::~HudRenderer() {
|
||||
delete crosshair;
|
||||
delete batch;
|
||||
delete uicamera;
|
||||
}
|
||||
|
||||
|
||||
void HudRenderer::draw(World* world, Level* level, Assets* assets, bool devdata, int fps){
|
||||
void HudRenderer::drawDebug(Level* level, Assets* assets, int fps, bool occlusion){
|
||||
Chunks* chunks = level->chunks;
|
||||
Player* player = level->player;
|
||||
|
||||
Font* font = assets->getFont("normal");
|
||||
|
||||
Shader* uishader = assets->getShader("ui");
|
||||
uishader->use();
|
||||
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
||||
batch->color = vec4(1.0f);
|
||||
batch->begin();
|
||||
font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE);
|
||||
font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring(fps), 44, 42, STYLE_OUTLINE);
|
||||
font->draw(batch, L"occlusion: "+std::to_wstring(occlusion), 16, 54, STYLE_OUTLINE);
|
||||
batch->render();
|
||||
}
|
||||
|
||||
|
||||
void HudRenderer::draw(Level* level, Assets* assets){
|
||||
uicamera->fov = Window::height;
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
Shader* uishader = assets->getShader("ui");
|
||||
uishader->use();
|
||||
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
||||
|
||||
// Draw debug info
|
||||
Font* font = assets->getFont("normal");
|
||||
batch->begin();
|
||||
if (devdata){
|
||||
font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring((int)player->camera->position.y), 50, 30, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring((int)player->camera->position.z), 90, 30, STYLE_OUTLINE);
|
||||
font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE);
|
||||
font->draw(batch, std::to_wstring(fps), 40, 42, STYLE_OUTLINE);
|
||||
}
|
||||
batch->render();
|
||||
|
||||
// Chosen block preview
|
||||
Texture* blocks = assets->getTexture("block");
|
||||
Texture* sprite = assets->getTexture("sprite");
|
||||
Texture* sprite = assets->getTexture("slot");
|
||||
|
||||
if (!Events::_cursor_locked) {
|
||||
batch->texture(nullptr);
|
||||
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
batch->rect(0, 0, Window::width, Window::height);
|
||||
}
|
||||
|
||||
batch->color = vec4(1.0f);
|
||||
batch->texture(sprite);
|
||||
batch->sprite(16, 640, 64, 64, 16, 0, vec4(1.0f));
|
||||
batch->sprite(16, uicamera->fov - 80, 64, 64, 16, 0, vec4(1.0f));
|
||||
|
||||
batch->texture(blocks);
|
||||
Block* cblock = Block::blocks[player->choosenBlock];
|
||||
if (cblock->model == BLOCK_MODEL_CUBE){
|
||||
batch->blockSprite(24, 648, 48, 48, 16, cblock->textureFaces, vec4(1.0f));
|
||||
} else if (cblock->model == BLOCK_MODEL_GRASS){
|
||||
batch->sprite(24, 648, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f));
|
||||
Player* player = level->player;
|
||||
{
|
||||
Block* cblock = Block::blocks[player->choosenBlock];
|
||||
if (cblock->model == BLOCK_MODEL_CUBE){
|
||||
batch->blockSprite(24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces, vec4(1.0f));
|
||||
} else if (cblock->model == BLOCK_MODEL_GRASS){
|
||||
batch->sprite(24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (!Events::_cursor_locked) {
|
||||
for (unsigned i = 1; i < 256; i++) {
|
||||
Block* cblock = Block::blocks[i];
|
||||
if (cblock == nullptr)
|
||||
break;
|
||||
int size = 48;
|
||||
int step = 70;
|
||||
int x = 24 + (i-1) * step;
|
||||
int y = uicamera->fov - 72 - 70;
|
||||
y -= 72 * (x / (Window::width - step));
|
||||
x %= (Window::width - step);
|
||||
vec4 tint(1.0f);
|
||||
int mx = Events::x;
|
||||
int my = Events::y;
|
||||
if (mx > x && mx < x + size && my > y && my < y + size) {
|
||||
tint.r *= 2.0f;
|
||||
tint.g *= 2.0f;
|
||||
tint.b *= 2.0f;
|
||||
if (Events::jclicked(GLFW_MOUSE_BUTTON_LEFT)) {
|
||||
player->choosenBlock = i;
|
||||
}
|
||||
}
|
||||
if (cblock->model == BLOCK_MODEL_CUBE){
|
||||
batch->blockSprite(x, y, size, size, 16, cblock->textureFaces, tint);
|
||||
} else if (cblock->model == BLOCK_MODEL_GRASS){
|
||||
batch->sprite(x, y, size, size, 16, cblock->textureFaces[3], tint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
batch->render();
|
||||
|
||||
Shader* crosshairShader = assets->getShader("crosshair");
|
||||
crosshairShader->use();
|
||||
crosshairShader->uniform1f("u_ar", (float)Window::height / (float)Window::width);
|
||||
crosshairShader->uniform1f("u_scale", 1.0f / ((float)Window::height / 1000.0f));
|
||||
crosshair->draw(GL_LINES);
|
||||
}
|
||||
|
||||
@ -3,17 +3,19 @@
|
||||
|
||||
class Batch2D;
|
||||
class Camera;
|
||||
class World;
|
||||
class Level;
|
||||
class Assets;
|
||||
class Mesh;
|
||||
|
||||
class HudRenderer {
|
||||
Batch2D *batch;
|
||||
Camera *uicamera;
|
||||
Batch2D* batch;
|
||||
Camera* uicamera;
|
||||
Mesh* crosshair;
|
||||
public:
|
||||
HudRenderer();
|
||||
~HudRenderer();
|
||||
void draw(World* world, Level* level, Assets* assets, bool devdata, int fps);
|
||||
void draw(Level* level, Assets* assets);
|
||||
void drawDebug(Level* level, Assets* assets, int fps, bool occlusion);
|
||||
};
|
||||
|
||||
#endif /* SRC_HUD_RENDER_H_ */
|
||||
|
||||
@ -21,8 +21,8 @@ void LightSolver::add(int x, int y, int z, int emission) {
|
||||
addqueue.push(entry);
|
||||
|
||||
Chunk* chunk = chunks->getChunkByVoxel(entry.x, entry.y, entry.z);
|
||||
chunk->modified = true;
|
||||
chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y-chunk->y*CHUNK_H, entry.z-chunk->z*CHUNK_D, channel, entry.light);
|
||||
chunk->setModified(true);
|
||||
chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y, entry.z-chunk->z*CHUNK_D, channel, entry.light);
|
||||
}
|
||||
|
||||
void LightSolver::add(int x, int y, int z) {
|
||||
@ -35,7 +35,7 @@ void LightSolver::remove(int x, int y, int z) {
|
||||
if (chunk == nullptr)
|
||||
return;
|
||||
|
||||
int light = chunk->lightmap->get(x-chunk->x*CHUNK_W, y-chunk->y*CHUNK_H, z-chunk->z*CHUNK_D, channel);
|
||||
int light = chunk->lightmap->get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||
if (light == 0){
|
||||
return;
|
||||
}
|
||||
@ -47,7 +47,7 @@ void LightSolver::remove(int x, int y, int z) {
|
||||
entry.light = light;
|
||||
remqueue.push(entry);
|
||||
|
||||
chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y-chunk->y*CHUNK_H, entry.z-chunk->z*CHUNK_D, channel, 0);
|
||||
chunk->lightmap->set(entry.x-chunk->x*CHUNK_W, entry.y, entry.z-chunk->z*CHUNK_D, channel, 0);
|
||||
}
|
||||
|
||||
void LightSolver::solve(){
|
||||
@ -78,8 +78,8 @@ void LightSolver::solve(){
|
||||
nentry.z = z;
|
||||
nentry.light = light;
|
||||
remqueue.push(nentry);
|
||||
chunk->lightmap->set(x-chunk->x*CHUNK_W, y-chunk->y*CHUNK_H, z-chunk->z*CHUNK_D, channel, 0);
|
||||
chunk->modified = true;
|
||||
chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0);
|
||||
chunk->setModified(true);
|
||||
}
|
||||
else if (light >= entry.light){
|
||||
lightentry nentry;
|
||||
@ -94,7 +94,7 @@ void LightSolver::solve(){
|
||||
}
|
||||
|
||||
while (!addqueue.empty()){
|
||||
lightentry entry = addqueue.front();
|
||||
const lightentry entry = addqueue.front();
|
||||
addqueue.pop();
|
||||
|
||||
if (entry.light <= 1)
|
||||
@ -110,8 +110,8 @@ void LightSolver::solve(){
|
||||
voxel* v = chunks->get(x,y,z);
|
||||
Block* block = Block::blocks[v->id];
|
||||
if (block->lightPassing && light+2 <= entry.light){
|
||||
chunk->lightmap->set(x-chunk->x*CHUNK_W, y-chunk->y*CHUNK_H, z-chunk->z*CHUNK_D, channel, entry.light-1);
|
||||
chunk->modified = true;
|
||||
chunk->lightmap->set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, entry.light-1);
|
||||
chunk->setModified(true);
|
||||
lightentry nentry;
|
||||
nentry.x = x;
|
||||
nentry.y = y;
|
||||
|
||||
@ -35,154 +35,94 @@ void Lighting::clear(){
|
||||
}
|
||||
}
|
||||
|
||||
void Lighting::onChunkLoaded(int cx, int cy, int cz, bool sky){
|
||||
Chunk* chunk = chunks->getChunk(cx, cy, cz);
|
||||
Chunk* chunkUpper = chunks->getChunk(cx, cy+1, cz);
|
||||
Chunk* chunkLower = chunks->getChunk(cx, cy-1, cz);
|
||||
if (chunkLower && sky){
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
void Lighting::prebuildSkyLight(int cx, int cz){
|
||||
Chunk* chunk = chunks->getChunk(cx, cz);
|
||||
int highestPoint = 0;
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
for (int y = CHUNK_H-1;;y--){
|
||||
if (y < 0)
|
||||
break;
|
||||
voxel* vox = &(chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);
|
||||
Block* block = Block::blocks[vox->id];
|
||||
if (!block->skyLightPassing) {
|
||||
if (highestPoint < y)
|
||||
highestPoint = y;
|
||||
break;
|
||||
}
|
||||
chunk->lightmap->setS(x,y,z, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (highestPoint < CHUNK_H-1)
|
||||
highestPoint++;
|
||||
chunk->lightmap->highestPoint = highestPoint;
|
||||
}
|
||||
|
||||
void Lighting::buildSkyLight(int cx, int cz){
|
||||
Chunk* chunk = chunks->getChunk(cx, cz);
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
for (int y = chunk->lightmap->highestPoint; y >= 0; y--){
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
|
||||
int light = chunk->lightmap->getS(x,0,z);
|
||||
int ncy = cy-1;
|
||||
if (light < 15){
|
||||
Chunk* current = chunkLower;
|
||||
if (chunkLower->lightmap->getS(x,15,z) == 0)
|
||||
continue;
|
||||
for (int y = 15;;y--){
|
||||
if (y < 0){
|
||||
ncy--;
|
||||
y += CHUNK_H;
|
||||
}
|
||||
if (ncy != current->y)
|
||||
current = chunks->getChunk(cx,ncy,cz);
|
||||
if (!current)
|
||||
break;
|
||||
voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz);
|
||||
Block* block = Block::blocks[vox->id];
|
||||
if (!block->skyLightPassing)
|
||||
break;
|
||||
//current->lightmap->setS(x,y,z, 0);
|
||||
current->modified = true;
|
||||
solverS->remove(gx,y+ncy*CHUNK_H,gz);
|
||||
current->lightmap->setS(x,y,z, 0);
|
||||
while (y > 0 && !Block::blocks[chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x].id]->lightPassing) {
|
||||
y--;
|
||||
}
|
||||
if (chunk->lightmap->getS(x, y, z) != 15) {
|
||||
solverS->add(gx,y+1,gz);
|
||||
for (; y >= 0; y--){
|
||||
solverS->add(gx+1,y,gz);
|
||||
solverS->add(gx-1,y,gz);
|
||||
solverS->add(gx,y,gz+1);
|
||||
solverS->add(gx,y,gz-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunkUpper && sky){
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gy = cy * CHUNK_H;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
int ncy = cy;
|
||||
solverS->solve();
|
||||
}
|
||||
|
||||
int light = chunkUpper->lightmap->getS(x,0,z);
|
||||
void Lighting::onChunkLoaded(int cx, int cz){
|
||||
const Chunk* chunk = chunks->getChunk(cx, cz);
|
||||
|
||||
Chunk* current = chunk;
|
||||
if (light == 15){
|
||||
for (int y = CHUNK_H-1;;y--){
|
||||
if (y < 0){
|
||||
ncy--;
|
||||
y += CHUNK_H;
|
||||
}
|
||||
if (ncy != current->y)
|
||||
current = chunks->getChunk(cx,ncy,cz);
|
||||
if (!current)
|
||||
break;
|
||||
voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz);
|
||||
Block* block = Block::blocks[vox->id];
|
||||
if (!block->skyLightPassing)
|
||||
break;
|
||||
current->lightmap->setS(x,y,z, 15);
|
||||
current->modified = true;
|
||||
solverS->add(gx,y+ncy*CHUNK_H,gz);
|
||||
}
|
||||
} else if (light){
|
||||
solverS->add(gx,gy+CHUNK_H,gz);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sky){
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
int ncy = cy;
|
||||
|
||||
Chunk* current = chunk;
|
||||
for (int y = CHUNK_H-1;;y--){
|
||||
if (y < 0){
|
||||
ncy--;
|
||||
y += CHUNK_H;
|
||||
}
|
||||
if (ncy != current->y)
|
||||
current = chunks->getChunk(cx,ncy,cz);
|
||||
if (!current)
|
||||
break;
|
||||
voxel* vox = &(current->voxels[(y * CHUNK_D + z) * CHUNK_W + x]);//chunks->get(gx,gy+y,gz);
|
||||
Block* block = Block::blocks[vox->id];
|
||||
if (!block->skyLightPassing)
|
||||
break;
|
||||
current->lightmap->setS(x,y,z, 15);
|
||||
current->modified = true;
|
||||
solverS->add(gx,y+ncy*CHUNK_H,gz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//std::cout << "DONE" << std::endl;
|
||||
for (unsigned int y = 0; y < CHUNK_H; y++){
|
||||
for (unsigned int z = 0; z < CHUNK_D; z++){
|
||||
for (unsigned int x = 0; x < CHUNK_W; x++){
|
||||
voxel vox = chunk->voxels[(y * CHUNK_D + z) * CHUNK_W + x];
|
||||
Block* block = Block::blocks[vox.id];
|
||||
if (block->emission[0] || block->emission[1] || block->emission[2]){
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gy = y + cy * CHUNK_H;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
solverR->add(gx,gy,gz,block->emission[0]);
|
||||
solverG->add(gx,gy,gz,block->emission[1]);
|
||||
solverB->add(gx,gy,gz,block->emission[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int y = -1; y <= CHUNK_H; y++){
|
||||
for (int z = -1; z <= CHUNK_D; z++){
|
||||
for (int x = -1; x <= CHUNK_W; x++){
|
||||
if (!(x == -1 || x == CHUNK_W || y == -1 || y == CHUNK_H || z == -1 || z == CHUNK_D))
|
||||
continue;
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gy = y + cy * CHUNK_H;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
if (chunks->getLight(x,y,z)){
|
||||
solverR->add(gx,gy,gz);
|
||||
solverG->add(gx,gy,gz);
|
||||
solverB->add(gx,gy,gz);
|
||||
if (sky)
|
||||
solverS->add(gx,gy,gz);
|
||||
if (block->emission[0] || block->emission[1] || block->emission[2]){
|
||||
solverR->add(gx,y,gz,block->emission[0]);
|
||||
solverG->add(gx,y,gz,block->emission[1]);
|
||||
solverB->add(gx,y,gz,block->emission[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = -1; y <= CHUNK_H; y++){
|
||||
for (int z = -1; z <= CHUNK_D; z++){
|
||||
for (int x = -1; x <= CHUNK_W; x++){
|
||||
if (!(x == -1 || x == CHUNK_W || z == -1 || z == CHUNK_D))
|
||||
continue;
|
||||
int gx = x + cx * CHUNK_W;
|
||||
int gz = z + cz * CHUNK_D;
|
||||
if (chunks->getLight(x,y,z)){
|
||||
solverR->add(gx,y,gz);
|
||||
solverG->add(gx,y,gz);
|
||||
solverB->add(gx,y,gz);
|
||||
solverS->add(gx,y,gz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
solverR->solve();
|
||||
solverG->solve();
|
||||
solverB->solve();
|
||||
solverS->solve();
|
||||
|
||||
Chunk* other;
|
||||
other = chunks->getChunk(cx-1,cy,cz); if (other) other->modified = true;
|
||||
other = chunks->getChunk(cx+1,cy,cz); if (other) other->modified = true;
|
||||
other = chunks->getChunk(cx,cy-1,cz); if (other) other->modified = true;
|
||||
other = chunks->getChunk(cx,cy+1,cz); if (other) other->modified = true;
|
||||
other = chunks->getChunk(cx,cy,cz-1); if (other) other->modified = true;
|
||||
other = chunks->getChunk(cx,cy,cz+1); if (other) other->modified = true;
|
||||
}
|
||||
|
||||
void Lighting::onBlockSet(int x, int y, int z, int id){
|
||||
@ -191,11 +131,9 @@ void Lighting::onBlockSet(int x, int y, int z, int id){
|
||||
solverR->remove(x,y,z);
|
||||
solverG->remove(x,y,z);
|
||||
solverB->remove(x,y,z);
|
||||
|
||||
solverR->solve();
|
||||
solverG->solve();
|
||||
solverB->solve();
|
||||
|
||||
if (chunks->getLight(x,y+1,z, 3) == 0xF){
|
||||
for (int i = y; i >= 0; i--){
|
||||
voxel* vox = chunks->get(x,i,z);
|
||||
@ -204,14 +142,12 @@ void Lighting::onBlockSet(int x, int y, int z, int id){
|
||||
solverS->add(x,i,z, 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
solverR->add(x,y+1,z); solverG->add(x,y+1,z); solverB->add(x,y+1,z); solverS->add(x,y+1,z);
|
||||
solverR->add(x,y-1,z); solverG->add(x,y-1,z); solverB->add(x,y-1,z); solverS->add(x,y-1,z);
|
||||
solverR->add(x+1,y,z); solverG->add(x+1,y,z); solverB->add(x+1,y,z); solverS->add(x+1,y,z);
|
||||
solverR->add(x-1,y,z); solverG->add(x-1,y,z); solverB->add(x-1,y,z); solverS->add(x-1,y,z);
|
||||
solverR->add(x,y,z+1); solverG->add(x,y,z+1); solverB->add(x,y,z+1); solverS->add(x,y,z+1);
|
||||
solverR->add(x,y,z-1); solverG->add(x,y,z-1); solverB->add(x,y,z-1); solverS->add(x,y,z-1);
|
||||
|
||||
solverR->solve();
|
||||
solverG->solve();
|
||||
solverB->solve();
|
||||
|
||||
@ -15,7 +15,9 @@ public:
|
||||
~Lighting();
|
||||
|
||||
void clear();
|
||||
void onChunkLoaded(int cx, int cy, int cz, bool sky);
|
||||
void prebuildSkyLight(int cx, int cz);
|
||||
void buildSkyLight(int cx, int cz);
|
||||
void onChunkLoaded(int cx, int cz);
|
||||
void onBlockSet(int x, int y, int z, int id);
|
||||
};
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
class Lightmap {
|
||||
public:
|
||||
unsigned short* map;
|
||||
int highestPoint = 0;
|
||||
Lightmap();
|
||||
~Lightmap();
|
||||
|
||||
|
||||
@ -102,6 +102,8 @@ int _png_load(const char* file, int* width, int* height){
|
||||
alpha, GL_UNSIGNED_BYTE, (GLvoid *) image_data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
@ -210,6 +212,8 @@ int _png_load(const char* file, int* pwidth, int* pheight){
|
||||
alpha, GL_UNSIGNED_BYTE, (GLvoid *) flipped);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
pwidth[0] = ihdr.width;
|
||||
|
||||
@ -14,6 +14,7 @@ public:
|
||||
Camera* camera;
|
||||
Hitbox* hitbox;
|
||||
bool flight = false;
|
||||
bool noclip = false;
|
||||
int choosenBlock;
|
||||
float camX, camY;
|
||||
float cameraShaking = 0.0f;
|
||||
|
||||
@ -10,7 +10,9 @@
|
||||
PhysicsSolver::PhysicsSolver(vec3 gravity) : gravity(gravity) {
|
||||
}
|
||||
|
||||
void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting, float gravityScale) {
|
||||
void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting,
|
||||
float gravityScale,
|
||||
bool collisions) {
|
||||
hitbox->grounded = false;
|
||||
for (unsigned i = 0; i < substeps; i++){
|
||||
float dt = delta / (float)substeps;
|
||||
@ -25,85 +27,87 @@ void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned s
|
||||
float px = pos.x;
|
||||
float pz = pos.z;
|
||||
|
||||
if (vel.x < 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int x = floor(pos.x-half.x-E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.x *= 0.0;
|
||||
pos.x = x + 1 + half.x + E;
|
||||
break;
|
||||
if (collisions) {
|
||||
if (vel.x < 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int x = floor(pos.x-half.x-E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.x *= 0.0;
|
||||
pos.x = x + 1 + half.x + E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vel.x > 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int x = floor(pos.x+half.x+E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.x *= 0.0;
|
||||
pos.x = x - half.x - E;
|
||||
break;
|
||||
if (vel.x > 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int x = floor(pos.x+half.x+E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.x *= 0.0;
|
||||
pos.x = x - half.x - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel.z < 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
if (vel.z < 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||
int z = floor(pos.z-half.z-E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.z *= 0.0;
|
||||
pos.z = z + 1 + half.z + E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel.z > 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||
int z = floor(pos.z+half.z+E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.z *= 0.0;
|
||||
pos.z = z - half.z - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel.y < 0.0){
|
||||
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||
int z = floor(pos.z-half.z-E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.z *= 0.0;
|
||||
pos.z = z + 1 + half.z + E;
|
||||
break;
|
||||
bool broken = false;
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int y = floor(pos.y-half.y-E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.y *= 0.0;
|
||||
pos.y = y + 1 + half.y;
|
||||
int f = DEFAULT_FRICTION;
|
||||
vel.x *= max(0.0, 1.0 - dt * f);
|
||||
vel.z *= max(0.0, 1.0 - dt * f);
|
||||
hitbox->grounded = true;
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (broken)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel.z > 0.0){
|
||||
for (int y = floor(pos.y-half.y+E); y <= floor(pos.y+half.y-E); y++){
|
||||
if (vel.y > 0.0){
|
||||
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||
int z = floor(pos.z+half.z+E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.z *= 0.0;
|
||||
pos.z = z - half.z - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vel.y < 0.0){
|
||||
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||
bool broken = false;
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int y = floor(pos.y-half.y-E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.y *= 0.0;
|
||||
pos.y = y + 1 + half.y;
|
||||
int f = DEFAULT_FRICTION;
|
||||
vel.x *= max(0.0, 1.0 - dt * f);
|
||||
vel.z *= max(0.0, 1.0 - dt * f);
|
||||
hitbox->grounded = true;
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (broken)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vel.y > 0.0){
|
||||
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int y = floor(pos.y+half.y+E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.y *= 0.0;
|
||||
pos.y = y - half.y - E;
|
||||
break;
|
||||
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||
int y = floor(pos.y+half.y+E);
|
||||
if (chunks->isObstacle(x,y,z)){
|
||||
vel.y *= 0.0;
|
||||
pos.y = y - half.y - E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,13 @@ class PhysicsSolver {
|
||||
vec3 gravity;
|
||||
public:
|
||||
PhysicsSolver(vec3 gravity);
|
||||
void step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting, float gravityScale);
|
||||
void step(Chunks* chunks,
|
||||
Hitbox* hitbox,
|
||||
float delta,
|
||||
unsigned substeps,
|
||||
bool shifting,
|
||||
float gravityScale,
|
||||
bool collisions);
|
||||
bool isBlockInside(int x, int y, int z, Hitbox* hitbox);
|
||||
};
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#define CAMERA_SHAKING_OFFSET_Y 0.031f
|
||||
#define CAMERA_SHAKING_SPEED 1.6f
|
||||
#define CAMERA_SHAKING_DELTA_K 10.0f
|
||||
#define FLIGHT_SPEED_MUL 8.0f
|
||||
#define FLIGHT_SPEED_MUL 4.0f
|
||||
#define CHEAT_SPEED_MUL 5.0f
|
||||
#define JUMP_FORCE 7.0f
|
||||
|
||||
@ -35,13 +35,6 @@ PlayerController::PlayerController(Level* level) : level(level) {
|
||||
void PlayerController::update_controls(float delta){
|
||||
Player* player = level->player;
|
||||
|
||||
if (Events::jpressed(GLFW_KEY_ESCAPE)){
|
||||
Window::setShouldClose(true);
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_TAB)){
|
||||
Events::toogleCursor();
|
||||
}
|
||||
|
||||
for (int i = 1; i < 10; i++){
|
||||
if (Events::jpressed(GLFW_KEY_0+i)){
|
||||
player->choosenBlock = i;
|
||||
@ -65,7 +58,7 @@ void PlayerController::update_controls(float delta){
|
||||
}
|
||||
int substeps = (int)(delta * 1000);
|
||||
substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps));
|
||||
level->physics->step(level->chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f);
|
||||
level->physics->step(level->chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f, !player->noclip);
|
||||
camera->position.x = hitbox->position.x;
|
||||
camera->position.y = hitbox->position.y + 0.7f;
|
||||
camera->position.z = hitbox->position.z;
|
||||
@ -85,18 +78,20 @@ void PlayerController::update_controls(float delta){
|
||||
camera->position += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking;
|
||||
camera->position -= min(player->interpVel * 0.05f, 1.0f);
|
||||
|
||||
if (Events::jpressed(GLFW_KEY_F)){
|
||||
if ((Events::jpressed(GLFW_KEY_F) && !player->noclip) ||
|
||||
(Events::jpressed(GLFW_KEY_N) && player->flight == player->noclip)){
|
||||
player->flight = !player->flight;
|
||||
if (player->flight){
|
||||
hitbox->velocity.y += 1;
|
||||
hitbox->grounded = false;
|
||||
}
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_N)) {
|
||||
player->noclip = !player->noclip;
|
||||
}
|
||||
|
||||
// Field of view manipulations
|
||||
float dt = min(1.0f, delta * ZOOM_SPEED);
|
||||
if (dt > 1.0f)
|
||||
dt = 1.0f;
|
||||
float zoomValue = 1.0f;
|
||||
if (shift){
|
||||
speed *= CROUCH_SPEED_MUL;
|
||||
@ -182,7 +177,8 @@ void PlayerController::update_interaction(){
|
||||
selectedBlockId = vox->id;
|
||||
selectedBlockPosition = iend;
|
||||
|
||||
if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && Block::blocks[vox->id]->breakable){
|
||||
Block* block = Block::blocks[vox->id];
|
||||
if (Events::jclicked(GLFW_MOUSE_BUTTON_1) && block->breakable){
|
||||
int x = (int)iend.x;
|
||||
int y = (int)iend.y;
|
||||
int z = (int)iend.z;
|
||||
@ -193,6 +189,11 @@ void PlayerController::update_interaction(){
|
||||
int x = (int)(iend.x)+(int)(norm.x);
|
||||
int y = (int)(iend.y)+(int)(norm.y);
|
||||
int z = (int)(iend.z)+(int)(norm.z);
|
||||
if (block->model == BLOCK_MODEL_GRASS){
|
||||
x = (int)iend.x;
|
||||
y = (int)iend.y;
|
||||
z = (int)iend.z;
|
||||
}
|
||||
if (!level->physics->isBlockInside(x,y,z, player->hitbox)){
|
||||
chunks->set(x, y, z, player->choosenBlock);
|
||||
lighting->onBlockSet(x,y,z, player->choosenBlock);
|
||||
|
||||
@ -24,6 +24,7 @@ using namespace glm;
|
||||
#include "graphics/VoxelRenderer.h"
|
||||
#include "graphics/LineBatch.h"
|
||||
#include "graphics/Batch2D.h"
|
||||
#include "graphics/Framebuffer.h"
|
||||
#include "window/Window.h"
|
||||
#include "window/Events.h"
|
||||
#include "window/Camera.h"
|
||||
@ -54,13 +55,9 @@ using namespace glm;
|
||||
#include "hud_render.h"
|
||||
#include "player_control.h"
|
||||
|
||||
|
||||
float gravity = 19.6f;
|
||||
|
||||
int WIDTH = 1280;
|
||||
int HEIGHT = 720;
|
||||
|
||||
|
||||
// Save all world data to files
|
||||
void write_world(World* world, Level* level){
|
||||
WorldFiles* wfile = world->wfile;
|
||||
@ -68,7 +65,7 @@ void write_world(World* world, Level* level){
|
||||
|
||||
for (unsigned int i = 0; i < chunks->volume; i++){
|
||||
Chunk* chunk = chunks->chunks[i];
|
||||
if (chunk == nullptr)
|
||||
if (chunk == nullptr || !chunk->isUnsaved())
|
||||
continue;
|
||||
wfile->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||
}
|
||||
@ -78,16 +75,17 @@ void write_world(World* world, Level* level){
|
||||
world->wfile->writePlayer(level->player);
|
||||
}
|
||||
|
||||
void update_level(World* world, Level* level, float delta, long frame, VoxelRenderer* renderer){
|
||||
void update_level(World* world, Level* level, float delta, long frame, VoxelRenderer* renderer) {
|
||||
level->playerController->update_controls(delta);
|
||||
level->playerController->update_interaction();
|
||||
if (Events::_cursor_locked)
|
||||
level->playerController->update_interaction();
|
||||
|
||||
vec3 position = level->player->hitbox->position;
|
||||
level->chunks->setCenter(world->wfile, position.x, 0, position.z);
|
||||
level->chunks->setCenter(world->wfile, position.x, position.z);
|
||||
}
|
||||
|
||||
Level* load_level(World* world, Player* player) {
|
||||
Level* level = new Level(world, player, new Chunks(34,1,34, 0,0,0), new PhysicsSolver(vec3(0, -gravity, 0)));
|
||||
Level* level = new Level(world, player, new Chunks(56, 56, 0, 0), new PhysicsSolver(vec3(0, -19.6f, 0)));
|
||||
world->wfile->readPlayer(player);
|
||||
|
||||
Camera* camera = player->camera;
|
||||
@ -96,10 +94,8 @@ Level* load_level(World* world, Player* player) {
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
int initialize(Assets*& assets){
|
||||
Audio::initialize();
|
||||
Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v.12");
|
||||
int initialize(Assets*& assets) {
|
||||
Window::initialize(WIDTH, HEIGHT, "VoxelEngine-Cpp v12");
|
||||
Events::initialize();
|
||||
|
||||
assets = new Assets();
|
||||
@ -113,6 +109,66 @@ int initialize(Assets*& assets){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mainloop(Level* level, Assets* assets) {
|
||||
Camera* camera = level->player->camera;
|
||||
std::cout << "-- preparing systems" << std::endl;
|
||||
World* world = level->world;
|
||||
WorldRenderer worldRenderer(level, assets);
|
||||
HudRenderer hud;
|
||||
long frame = 0;
|
||||
float lastTime = glfwGetTime();
|
||||
float delta = 0.0f;
|
||||
bool occlusion = true;
|
||||
bool devdata = false;
|
||||
Window::swapInterval(1);
|
||||
while (!Window::isShouldClose()){
|
||||
frame++;
|
||||
float currentTime = glfwGetTime();
|
||||
delta = currentTime - lastTime;
|
||||
lastTime = currentTime;
|
||||
int fps = 1 / delta;
|
||||
if (Events::jpressed(GLFW_KEY_ESCAPE)){
|
||||
Window::setShouldClose(true);
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_TAB)){
|
||||
Events::toogleCursor();
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_O)){
|
||||
occlusion = !occlusion;
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_F3)){
|
||||
devdata = !devdata;
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_F5)){
|
||||
for (unsigned i = 0; i < level->chunks->volume; i++) {
|
||||
Chunk* chunk = level->chunks->chunks[i];
|
||||
if (chunk != nullptr && chunk->isReady()){
|
||||
chunk->setModified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_level(world, level, delta, frame, worldRenderer.renderer);
|
||||
int freeLoaders = level->chunksController->countFreeLoaders();
|
||||
for (int i = 0; i < freeLoaders; i++)
|
||||
level->chunksController->_buildMeshes(worldRenderer.renderer, frame);
|
||||
freeLoaders = level->chunksController->countFreeLoaders();
|
||||
for (int i = 0; i < freeLoaders; i++)
|
||||
level->chunksController->calculateLights();
|
||||
freeLoaders = level->chunksController->countFreeLoaders();
|
||||
for (int i = 0; i < freeLoaders; i++)
|
||||
level->chunksController->loadVisible(world->wfile);
|
||||
|
||||
worldRenderer.draw(world, camera, occlusion);
|
||||
hud.draw(level, assets);
|
||||
if (devdata) {
|
||||
hud.drawDebug(level, assets, fps, occlusion);
|
||||
}
|
||||
|
||||
Window::swapBuffers();
|
||||
Events::pullEvents();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
setup_definitions();
|
||||
@ -128,57 +184,12 @@ int main() {
|
||||
Player* player = new Player(playerPosition, 4.0f, camera);
|
||||
Level* level = load_level(world, player);
|
||||
|
||||
std::cout << "-- preparing systems" << std::endl;
|
||||
HudRenderer hud;
|
||||
WorldRenderer worldRenderer(level);
|
||||
|
||||
float lastTime = glfwGetTime();
|
||||
float delta = 0.0f;
|
||||
long frame = 0;
|
||||
bool occlusion = false;
|
||||
bool devdata = false;
|
||||
|
||||
Window::swapInterval(1);
|
||||
|
||||
std::cout << "-- initializing finished" << std::endl;
|
||||
while (!Window::isShouldClose()){
|
||||
frame++;
|
||||
float currentTime = glfwGetTime();
|
||||
delta = currentTime - lastTime;
|
||||
lastTime = currentTime;
|
||||
int fps = 1 / delta;
|
||||
|
||||
if (Events::jpressed(GLFW_KEY_O)){
|
||||
occlusion = !occlusion;
|
||||
}
|
||||
if (Events::jpressed(GLFW_KEY_F3)){
|
||||
devdata = !devdata;
|
||||
}
|
||||
Audio::initialize();
|
||||
mainloop(level, assets);
|
||||
Audio::finalize();
|
||||
|
||||
update_level(world, level, delta, frame, worldRenderer.renderer);
|
||||
int freeLoaders = level->chunksController->countFreeLoaders();
|
||||
for (int i = 0; i < freeLoaders; i++)
|
||||
level->chunksController->_buildMeshes(worldRenderer.renderer, frame);
|
||||
freeLoaders = level->chunksController->countFreeLoaders();
|
||||
for (int i = 0; i < freeLoaders; i++)
|
||||
level->chunksController->loadVisible(world->wfile);
|
||||
|
||||
worldRenderer.draw(world, camera, assets, occlusion);
|
||||
if (level->playerController->selectedBlockId != -1){
|
||||
Block* selectedBlock = Block::blocks[level->playerController->selectedBlockId];
|
||||
LineBatch* lineBatch = worldRenderer.lineBatch;
|
||||
vec3 pos = level->playerController->selectedBlockPosition;
|
||||
if (selectedBlock->model == 1){
|
||||
lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f);
|
||||
} else if (selectedBlock->model == 2){
|
||||
lineBatch->box(pos.x+0.4f, pos.y+0.3f, pos.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f);
|
||||
}
|
||||
}
|
||||
hud.draw(world, level, assets, devdata, fps);
|
||||
|
||||
Window::swapBuffers();
|
||||
Events::pullEvents();
|
||||
}
|
||||
std::cout << "-- saving world" << std::endl;
|
||||
write_world(world, level);
|
||||
|
||||
@ -187,7 +198,6 @@ int main() {
|
||||
|
||||
std::cout << "-- shutting down" << std::endl;
|
||||
delete assets;
|
||||
Audio::finalize();
|
||||
Events::finalize();
|
||||
Window::terminate();
|
||||
return 0;
|
||||
|
||||
@ -2,8 +2,7 @@
|
||||
#include "voxel.h"
|
||||
#include "../lighting/Lightmap.h"
|
||||
|
||||
|
||||
Chunk::Chunk(int xpos, int ypos, int zpos) : x(xpos), y(ypos), z(zpos){
|
||||
Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos){
|
||||
voxels = new voxel[CHUNK_VOL];
|
||||
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
||||
voxels[i].id = 1;
|
||||
@ -30,7 +29,7 @@ bool Chunk::isEmpty(){
|
||||
}
|
||||
|
||||
Chunk* Chunk::clone() const {
|
||||
Chunk* other = new Chunk(x,y,z);
|
||||
Chunk* other = new Chunk(x,z);
|
||||
for (int i = 0; i < CHUNK_VOL; i++)
|
||||
other->voxels[i] = voxels[i];
|
||||
other->lightmap->set(lightmap);
|
||||
|
||||
@ -8,6 +8,12 @@
|
||||
#define CHUNK_D 16
|
||||
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D)
|
||||
|
||||
#define CHUNK_MODIFIED 0x1
|
||||
#define CHUNK_READY 0x2
|
||||
#define CHUNK_LOADED 0x4
|
||||
#define CHUNK_LIGHTED 0x8
|
||||
#define CHUNK_UNSAVED 0x10
|
||||
|
||||
class voxel;
|
||||
class Lightmap;
|
||||
|
||||
@ -16,19 +22,21 @@ struct RenderData {
|
||||
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 {
|
||||
public:
|
||||
int x,y,z;
|
||||
int x, z;
|
||||
voxel* voxels;
|
||||
Lightmap* lightmap;
|
||||
bool modified = true;
|
||||
bool ready = false;
|
||||
bool loaded = false;
|
||||
int flags = 0;
|
||||
int surrounding = 0;
|
||||
int references = 1;
|
||||
RenderData renderData;
|
||||
|
||||
Chunk(int x, int y, int z);
|
||||
Chunk(int x, int z);
|
||||
~Chunk();
|
||||
|
||||
bool isEmpty();
|
||||
@ -36,6 +44,28 @@ public:
|
||||
Chunk* clone() const;
|
||||
void incref();
|
||||
void decref();
|
||||
|
||||
// flags getters/setters below
|
||||
|
||||
inline bool isUnsaved() const {return flags & CHUNK_UNSAVED;}
|
||||
|
||||
inline bool isModified() const {return flags & CHUNK_MODIFIED;}
|
||||
|
||||
inline bool isLighted() const {return flags & CHUNK_LIGHTED;}
|
||||
|
||||
inline bool isLoaded() const {return flags & CHUNK_LOADED;}
|
||||
|
||||
inline bool isReady() const {return flags & CHUNK_READY;}
|
||||
|
||||
inline void setUnsaved(bool flag) {BITSET(flags, CHUNK_UNSAVED, flag);}
|
||||
|
||||
inline void setModified(bool flag) {BITSET(flags, CHUNK_MODIFIED, flag);}
|
||||
|
||||
inline void setLoaded(bool flag) {BITSET(flags, CHUNK_LOADED, flag);}
|
||||
|
||||
inline void setLighted(bool flag) {BITSET(flags, CHUNK_LIGHTED, flag);}
|
||||
|
||||
inline void setReady(bool flag) {BITSET(flags, CHUNK_READY, flag);}
|
||||
};
|
||||
|
||||
#endif /* VOXELS_CHUNK_H_ */
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
Chunks::Chunks(int w, int h, int d, int ox, int oy, int oz) : w(w), h(h), d(d), ox(ox), oy(oy), oz(oz){
|
||||
volume = w*h*d;
|
||||
Chunks::Chunks(int w, int d, int ox, int oz) : w(w), d(d), ox(ox), oz(oz){
|
||||
volume = w*d;
|
||||
chunks = new Chunk*[volume];
|
||||
chunksSecond = new Chunk*[volume];
|
||||
|
||||
@ -36,7 +36,6 @@ Chunks::~Chunks(){
|
||||
|
||||
voxel* Chunks::get(int x, int y, int z){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@ -44,7 +43,7 @@ voxel* Chunks::get(int x, int y, int z){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return nullptr;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
if (chunk == nullptr)
|
||||
@ -64,7 +63,6 @@ bool Chunks::isObstacle(int x, int y, int z){
|
||||
|
||||
unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@ -72,7 +70,7 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return 0;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
if (chunk == nullptr)
|
||||
@ -85,7 +83,6 @@ unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||
|
||||
unsigned short Chunks::getLight(int x, int y, int z){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@ -93,7 +90,7 @@ unsigned short Chunks::getLight(int x, int y, int z){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return 0;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
if (chunk == nullptr)
|
||||
@ -106,7 +103,6 @@ unsigned short Chunks::getLight(int x, int y, int z){
|
||||
|
||||
Chunk* Chunks::getChunkByVoxel(int x, int y, int z){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
@ -114,48 +110,44 @@ Chunk* Chunks::getChunkByVoxel(int x, int y, int z){
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= 1 || cz >= d)
|
||||
return nullptr;
|
||||
return chunks[(cy * d + cz) * w + cx];
|
||||
}
|
||||
|
||||
Chunk* Chunks::getChunk(int x, int y, int z){
|
||||
Chunk* Chunks::getChunk(int x, int z){
|
||||
x -= ox;
|
||||
y -= oy;
|
||||
z -= oz;
|
||||
if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d)
|
||||
if (x < 0 || z < 0 || x >= w || z >= d)
|
||||
return nullptr;
|
||||
return chunks[(y * d + z) * w + x];
|
||||
return chunks[z * w + x];
|
||||
}
|
||||
|
||||
void Chunks::set(int x, int y, int z, int id){
|
||||
x -= ox * CHUNK_W;
|
||||
y -= oy * CHUNK_H;
|
||||
z -= oz * CHUNK_D;
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
if (y < 0 || y >= CHUNK_H)
|
||||
return;
|
||||
int cz = z / CHUNK_D;
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
if (cx < 0 || cy < 0 || cz < 0 || cx >= w || cy >= h || cz >= d)
|
||||
if (cx < 0 || cz < 0 || cx >= w || cz >= d)
|
||||
return;
|
||||
Chunk* chunk = chunks[(cy * d + cz) * w + cx];
|
||||
Chunk* chunk = chunks[cz * w + cx];
|
||||
if (chunk == nullptr)
|
||||
return;
|
||||
int lx = x - cx * CHUNK_W;
|
||||
int ly = y - cy * CHUNK_H;
|
||||
int lz = z - cz * CHUNK_D;
|
||||
chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx].id = id;
|
||||
chunk->modified = true;
|
||||
chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx].id = id;
|
||||
chunk->setUnsaved(true);
|
||||
chunk->setModified(true);
|
||||
|
||||
if (lx == 0 && (chunk = getChunk(cx+ox-1, cy+oy, cz+oz))) chunk->modified = true;
|
||||
if (ly == 0 && (chunk = getChunk(cx+ox, cy+oy-1, cz+oz))) chunk->modified = true;
|
||||
if (lz == 0 && (chunk = getChunk(cx+ox, cy+oy, cz+oz-1))) chunk->modified = true;
|
||||
if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz))) chunk->setModified(true);
|
||||
if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1))) chunk->setModified(true);
|
||||
|
||||
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cy+oy, cz+oz))) chunk->modified = true;
|
||||
if (ly == CHUNK_H-1 && (chunk = getChunk(cx+ox, cy+oy+1, cz+oz))) chunk->modified = true;
|
||||
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cy+oy, cz+oz+1))) chunk->modified = true;
|
||||
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz))) chunk->setModified(true);
|
||||
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1))) chunk->setModified(true);
|
||||
}
|
||||
|
||||
voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, vec3& iend) {
|
||||
@ -246,48 +238,42 @@ voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, v
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Chunks::setCenter(WorldFiles* worldFiles, int x, int y, int z) {
|
||||
void Chunks::setCenter(WorldFiles* worldFiles, int x, int z) {
|
||||
int cx = x / CHUNK_W;
|
||||
int cy = y / CHUNK_H;
|
||||
int cz = z / CHUNK_D;
|
||||
cx -= ox;
|
||||
cy -= oy;
|
||||
cz -= oz;
|
||||
if (x < 0) cx--;
|
||||
if (y < 0) cy--;
|
||||
if (z < 0) cz--;
|
||||
cx -= w/2;
|
||||
cy -= h/2;
|
||||
cz -= d/2;
|
||||
if (cx != 0 || cy != 0 || cz != 0)
|
||||
translate(worldFiles, cx,cy,cz);
|
||||
if (cx | cz) {
|
||||
translate(worldFiles, cx,cz);
|
||||
}
|
||||
}
|
||||
|
||||
void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
|
||||
void Chunks::translate(WorldFiles* worldFiles, int dx, int dz){
|
||||
for (unsigned int i = 0; i < volume; i++){
|
||||
chunksSecond[i] = nullptr;
|
||||
meshesSecond[i] = nullptr;
|
||||
}
|
||||
for (unsigned int y = 0; y < h; y++){
|
||||
for (unsigned int z = 0; z < d; z++){
|
||||
for (unsigned int x = 0; x < w; x++){
|
||||
Chunk* chunk = chunks[(y * d + z) * w + x];
|
||||
int nx = x - dx;
|
||||
int ny = y - dy;
|
||||
int nz = z - dz;
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = meshes[(y * d + z) * w + x];
|
||||
if (nx < 0 || ny < 0 || nz < 0 || nx >= w || ny >= h || nz >= d){
|
||||
worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||
chunk->decref();
|
||||
delete mesh;
|
||||
chunksCount--;
|
||||
continue;
|
||||
}
|
||||
meshesSecond[(ny * d + nz) * w + nx] = mesh;
|
||||
chunksSecond[(ny * d + nz) * w + nx] = chunk;
|
||||
for (int z = 0; z < d; z++){
|
||||
for (int x = 0; x < w; x++){
|
||||
Chunk* chunk = chunks[z * w + x];
|
||||
int nx = x - dx;
|
||||
int nz = z - dz;
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = meshes[z * w + x];
|
||||
if (nx < 0 || nz < 0 || nx >= w || nz >= d){
|
||||
worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||
chunk->decref();
|
||||
delete mesh;
|
||||
chunksCount--;
|
||||
continue;
|
||||
}
|
||||
meshesSecond[nz * w + nx] = mesh;
|
||||
chunksSecond[nz * w + nx] = chunk;
|
||||
}
|
||||
}
|
||||
Chunk** ctemp = chunks;
|
||||
@ -299,26 +285,22 @@ void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
|
||||
meshesSecond = mtemp;
|
||||
|
||||
ox += dx;
|
||||
oy += dy;
|
||||
oz += dz;
|
||||
}
|
||||
|
||||
void Chunks::_setOffset(int x, int y, int z){
|
||||
void Chunks::_setOffset(int x, int z){
|
||||
ox = x;
|
||||
oy = y;
|
||||
oz = z;
|
||||
}
|
||||
|
||||
bool Chunks::putChunk(Chunk* chunk) {
|
||||
int x = chunk->x;
|
||||
int y = chunk->y;
|
||||
int z = chunk->z;
|
||||
x -= ox;
|
||||
y -= oy;
|
||||
z -= oz;
|
||||
if (x < 0 || y < 0 || z < 0 || x >= w || y >= h || z >= d)
|
||||
if (x < 0 || z < 0 || x >= w || z >= d)
|
||||
return false;
|
||||
chunks[(y * d + z) * w + x] = chunk;
|
||||
chunks[z * w + x] = chunk;
|
||||
chunksCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -21,15 +21,15 @@ public:
|
||||
Mesh** meshesSecond;
|
||||
size_t volume;
|
||||
size_t chunksCount;
|
||||
unsigned int w,h,d;
|
||||
int ox,oy,oz;
|
||||
int w,d;
|
||||
int ox,oz;
|
||||
|
||||
Chunks(int w, int h, int d, int ox, int oy, int oz);
|
||||
Chunks(int w, int d, int ox, int oz);
|
||||
~Chunks();
|
||||
|
||||
bool putChunk(Chunk* chunk);
|
||||
|
||||
Chunk* getChunk(int x, int y, int z);
|
||||
Chunk* getChunk(int x, int z);
|
||||
Chunk* getChunkByVoxel(int x, int y, int z);
|
||||
voxel* get(int x, int y, int z);
|
||||
unsigned short getLight(int x, int y, int z);
|
||||
@ -40,10 +40,10 @@ public:
|
||||
bool isObstacle(int x, int y, int z);
|
||||
|
||||
// does not move chunks inside
|
||||
void _setOffset(int x, int y, int z);
|
||||
void _setOffset(int x, int z);
|
||||
|
||||
void setCenter(WorldFiles* worldFiles, int x, int y, int z);
|
||||
void translate(WorldFiles* worldFiles, int x, int y, int z);
|
||||
void setCenter(WorldFiles* worldFiles, int x, int z);
|
||||
void translate(WorldFiles* worldFiles, int x, int z);
|
||||
|
||||
void clear(bool freeMemory);
|
||||
};
|
||||
|
||||
@ -48,117 +48,78 @@ int ChunksController::countFreeLoaders(){
|
||||
|
||||
bool ChunksController::loadVisible(WorldFiles* worldFiles){
|
||||
const int w = chunks->w;
|
||||
const int h = chunks->h;
|
||||
const int d = chunks->d;
|
||||
const int ox = chunks->ox;
|
||||
const int oy = chunks->oy;
|
||||
const int oz = chunks->oz;
|
||||
int nearX = 0;
|
||||
int nearY = 0;
|
||||
int nearZ = 0;
|
||||
int minDistance = (w/2)*(w/2);
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 2; z < d-2; z++){
|
||||
for (int x = 2; x < w-2; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk != nullptr){
|
||||
int surrounding = 0;
|
||||
for (int oz = -1; oz <= 1; oz++){
|
||||
for (int ox = -1; ox <= 1; ox++){
|
||||
Chunk* other = chunks->getChunk(chunk->x+ox, chunk->y, chunk->z+oz);
|
||||
if (other != nullptr && other->ready) surrounding++;
|
||||
}
|
||||
for (int z = 2; z < d-2; z++){
|
||||
for (int x = 2; x < w-2; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk != nullptr){
|
||||
int surrounding = 0;
|
||||
for (int oz = -1; oz <= 1; oz++){
|
||||
for (int ox = -1; ox <= 1; ox++){
|
||||
Chunk* other = chunks->getChunk(chunk->x+ox, chunk->z+oz);
|
||||
if (other != nullptr && other->isReady()) surrounding++;
|
||||
}
|
||||
chunk->surrounding = surrounding;
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int ly = y - h / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + ly * ly + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearY = y;
|
||||
nearZ = z;
|
||||
}
|
||||
chunk->surrounding = surrounding;
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearZ = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int index = (nearY * d + nearZ) * w + nearX;
|
||||
int index = nearZ * w + nearX;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk != nullptr)
|
||||
return false;
|
||||
|
||||
ChunksLoader* freeLoader = nullptr;
|
||||
for (int i = 0; i < loadersCount; i++){
|
||||
ChunksLoader* loader = loaders[i];
|
||||
if (loader->isBusy()){
|
||||
continue;
|
||||
}
|
||||
freeLoader = loader;
|
||||
break;
|
||||
}
|
||||
ChunksLoader* freeLoader = getFreeLoader();
|
||||
if (freeLoader == nullptr)
|
||||
return false;
|
||||
chunk = new Chunk(nearX+ox,nearY+oy,nearZ+oz);
|
||||
|
||||
chunk = new Chunk(nearX+ox, nearZ+oz);
|
||||
if (worldFiles->getChunk(chunk->x, chunk->z, (char*)chunk->voxels))
|
||||
chunk->loaded = true;
|
||||
chunk->setLoaded(true);
|
||||
|
||||
chunks->putChunk(chunk);
|
||||
|
||||
Chunk* closes[27];
|
||||
for (int i = 0; i < 27; i++)
|
||||
Chunk* closes[9];
|
||||
for (int i = 0; i < 9; i++)
|
||||
closes[i] = nullptr;
|
||||
for (size_t j = 0; j < chunks->volume; j++){
|
||||
Chunk* other = chunks->chunks[j];
|
||||
if (other == nullptr)
|
||||
continue;
|
||||
if (!other->ready)
|
||||
if (!other->isReady())
|
||||
continue;
|
||||
|
||||
int ox = other->x - chunk->x;
|
||||
int oy = other->y - chunk->y;
|
||||
int oz = other->z - chunk->z;
|
||||
|
||||
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
|
||||
if (abs(ox) > 1 || abs(oz) > 1)
|
||||
continue;
|
||||
|
||||
ox += 1;
|
||||
oy += 1;
|
||||
oz += 1;
|
||||
closes[(oy * 3 + oz) * 3 + ox] = other;
|
||||
closes[oz * 3 + ox] = other;
|
||||
}
|
||||
freeLoader->load(chunk, (Chunk**)closes);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
const int w = chunks->w;
|
||||
const int h = chunks->h;
|
||||
const int d = chunks->d;
|
||||
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->renderData.vertices > (void*)1){
|
||||
const int chunk_attrs[] = {3,2,4, 0};
|
||||
Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs);
|
||||
if (chunks->meshes[index])
|
||||
delete chunks->meshes[index];
|
||||
chunks->meshes[index] = mesh;
|
||||
delete[] chunk->renderData.vertices;
|
||||
chunk->renderData.vertices = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChunksLoader* ChunksController::getFreeLoader() {
|
||||
ChunksLoader* freeLoader = nullptr;
|
||||
for (int i = 0; i < loadersCount; i++){
|
||||
ChunksLoader* loader = loaders[i];
|
||||
@ -168,85 +129,152 @@ bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
freeLoader = loader;
|
||||
break;
|
||||
}
|
||||
return freeLoader;
|
||||
}
|
||||
|
||||
void ChunksController::calculateLights() {
|
||||
ChunksLoader* freeLoader = getFreeLoader();
|
||||
if (freeLoader == nullptr)
|
||||
return;
|
||||
const int w = chunks->w;
|
||||
const int d = chunks->d;
|
||||
int nearX = 0;
|
||||
int nearZ = 0;
|
||||
int minDistance = INT_MAX;
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->isLighted() || chunk->surrounding < MIN_SURROUNDING){
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearZ = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
int index = nearZ * w + nearX;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
return;
|
||||
Chunk* closes[9];
|
||||
for (int i = 0; i < 9; i++)
|
||||
closes[i] = nullptr;
|
||||
for (size_t j = 0; j < chunks->volume; j++){
|
||||
Chunk* other = chunks->chunks[j];
|
||||
if (other == nullptr)
|
||||
continue;
|
||||
|
||||
int ox = other->x - chunk->x;
|
||||
int oz = other->z - chunk->z;
|
||||
|
||||
if (abs(ox) > 1|| abs(oz) > 1)
|
||||
continue;
|
||||
|
||||
ox += 1;
|
||||
oz += 1;
|
||||
closes[oz * 3 + ox] = other;
|
||||
}
|
||||
freeLoader->lights(chunk, (Chunk**)closes);
|
||||
}
|
||||
|
||||
bool ChunksController::_buildMeshes(VoxelRenderer* renderer, int tick) {
|
||||
const int w = chunks->w;
|
||||
const int d = chunks->d;
|
||||
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
if (chunk->renderData.vertices > (void*)1){
|
||||
const int chunk_attrs[] = {3,2,4, 0};
|
||||
Mesh* mesh = new Mesh(chunk->renderData.vertices, chunk->renderData.size / CHUNK_VERTEX_SIZE, chunk_attrs);
|
||||
if (chunks->meshes[index])
|
||||
delete chunks->meshes[index];
|
||||
chunks->meshes[index] = mesh;
|
||||
delete[] chunk->renderData.vertices;
|
||||
chunk->renderData.vertices = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
ChunksLoader* freeLoader = getFreeLoader();
|
||||
if (freeLoader == nullptr)
|
||||
return false;
|
||||
|
||||
int nearX = 0;
|
||||
int nearY = 0;
|
||||
int nearZ = 0;
|
||||
int minDistance = INT_MAX;
|
||||
for (int y = 0; y < h; y++){
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = (y * d + z) * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = chunks->meshes[index];
|
||||
if (mesh != nullptr && !chunk->modified)
|
||||
continue;
|
||||
if (!chunk->ready || chunk->surrounding < MIN_SURROUNDING){
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int ly = y - h / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + ly * ly + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearY = y;
|
||||
nearZ = z;
|
||||
}
|
||||
for (int z = 1; z < d-1; z++){
|
||||
for (int x = 1; x < w-1; x++){
|
||||
int index = z * w + x;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
Mesh* mesh = chunks->meshes[index];
|
||||
if (mesh != nullptr && !chunk->isModified())
|
||||
continue;
|
||||
if (!chunk->isReady() || !chunk->isLighted() || chunk->surrounding < MIN_SURROUNDING){
|
||||
continue;
|
||||
}
|
||||
int lx = x - w / 2;
|
||||
int lz = z - d / 2;
|
||||
int distance = (lx * lx + lz * lz);
|
||||
if (distance < minDistance){
|
||||
minDistance = distance;
|
||||
nearX = x;
|
||||
nearZ = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int index = (nearY * d + nearZ) * w + nearX;
|
||||
|
||||
|
||||
int index = nearZ * w + nearX;
|
||||
Chunk* chunk = chunks->chunks[index];
|
||||
if (chunk == nullptr){
|
||||
return false;
|
||||
}
|
||||
Mesh* mesh = chunks->meshes[index];
|
||||
if (mesh == nullptr || chunk->modified){
|
||||
Chunk* closes[27];
|
||||
if (mesh == nullptr || chunk->isModified()){
|
||||
if (chunk->renderData.vertices != nullptr) {
|
||||
return false;
|
||||
}
|
||||
Chunk* closes[9];
|
||||
if (chunk->isEmpty()){
|
||||
chunks->meshes[index] = nullptr;
|
||||
return false;
|
||||
}
|
||||
chunk->modified = false;
|
||||
for (int i = 0; i < 27; i++)
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
closes[i] = nullptr;
|
||||
for (size_t j = 0; j < chunks->volume; j++){
|
||||
Chunk* other = chunks->chunks[j];
|
||||
if (other == nullptr)
|
||||
continue;
|
||||
if (!other->ready)
|
||||
continue;
|
||||
|
||||
int ox = other->x - chunk->x;
|
||||
int oy = other->y - chunk->y;
|
||||
int oz = other->z - chunk->z;
|
||||
|
||||
if (abs(ox) > 1 || abs(oy) > 1 || abs(oz) > 1)
|
||||
if (abs(ox) > 1 || abs(oz) > 1)
|
||||
continue;
|
||||
|
||||
ox += 1;
|
||||
oy += 1;
|
||||
oz += 1;
|
||||
closes[(oy * 3 + oz) * 3 + ox] = other;
|
||||
if ((!other->isReady() || !other->isLighted()) && other != chunk)
|
||||
return false;
|
||||
closes[oz * 3 + ox] = other;
|
||||
}
|
||||
if (chunk->renderData.vertices == nullptr){
|
||||
chunk->renderData.vertices = (float*)1;
|
||||
freeLoader->render(chunk, (Chunk**)closes);
|
||||
|
||||
return true;
|
||||
}
|
||||
//mesh = renderer->render(chunk, (const Chunk**)closes);
|
||||
//chunks->meshes[index] = mesh;
|
||||
chunk->setModified(false);
|
||||
chunk->renderData.vertices = (float*)1;
|
||||
freeLoader->render(chunk, (Chunk**)closes);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -18,8 +18,10 @@ public:
|
||||
ChunksController(World* world, Chunks* chunks, Lighting* lighting);
|
||||
~ChunksController();
|
||||
|
||||
ChunksLoader* getFreeLoader();
|
||||
int countFreeLoaders();
|
||||
bool loadVisible(WorldFiles* worldFiles);
|
||||
void calculateLights();
|
||||
bool _buildMeshes(VoxelRenderer* renderer, int tick);
|
||||
};
|
||||
|
||||
|
||||
@ -12,10 +12,10 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define CLOSES_C 27
|
||||
#define SURROUNDINGS_C 9
|
||||
|
||||
void ChunksLoader::_thread(){
|
||||
Chunks chunks(3,3,3, -1,-1,-1);
|
||||
Chunks chunks(3, 3, -1, -1);
|
||||
Lighting lighting(&chunks);
|
||||
VoxelRenderer renderer;
|
||||
while (state != OFF){
|
||||
@ -24,9 +24,9 @@ void ChunksLoader::_thread(){
|
||||
continue;
|
||||
}
|
||||
Chunk* chunk = current;
|
||||
chunks._setOffset(chunk->x-1, chunk->y-1, chunk->z-1);
|
||||
for (size_t i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes[i];
|
||||
chunks._setOffset(chunk->x-1, chunk->z-1);
|
||||
for (size_t i = 0; i < SURROUNDINGS_C; i++){
|
||||
Chunk* other = surroundings[i];
|
||||
if (other){
|
||||
chunks.putChunk(other);
|
||||
}
|
||||
@ -34,8 +34,9 @@ void ChunksLoader::_thread(){
|
||||
|
||||
if (state == LOAD){
|
||||
chunks.putChunk(chunk);
|
||||
if (!chunk->loaded){
|
||||
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->y, chunk->z, world->seed);
|
||||
if (!chunk->isLoaded()){
|
||||
WorldGenerator::generate(chunk->voxels, chunk->x, chunk->z, world->seed);
|
||||
chunk->setUnsaved(true);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < CHUNK_VOL; i++){
|
||||
@ -44,11 +45,17 @@ void ChunksLoader::_thread(){
|
||||
chunk->voxels[i].id = 11;
|
||||
}
|
||||
}
|
||||
lighting.onChunkLoaded(chunk->x, chunk->y, chunk->z, true);
|
||||
lighting.prebuildSkyLight(chunk->x, chunk->z);
|
||||
}
|
||||
else if (state == LIGHTS) {
|
||||
lighting.buildSkyLight(chunk->x, chunk->z);
|
||||
lighting.onChunkLoaded(chunk->x, chunk->z);
|
||||
chunk->setLighted(true);
|
||||
}
|
||||
else if (state == RENDER){
|
||||
chunk->setModified(false);
|
||||
size_t size;
|
||||
renderer.render(chunk, (const Chunk**)(closes.load()), size);
|
||||
renderer.render(chunk, (const Chunk**)(surroundings.load()), size);
|
||||
float* vertices = new float[size];
|
||||
for (size_t i = 0; i < size; i++)
|
||||
vertices[i] = renderer.buffer[i];
|
||||
@ -57,33 +64,33 @@ void ChunksLoader::_thread(){
|
||||
}
|
||||
|
||||
chunks.clear(false);
|
||||
for (int i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes[i];
|
||||
for (int i = 0; i < SURROUNDINGS_C; i++){
|
||||
Chunk* other = surroundings[i];
|
||||
if (other)
|
||||
other->decref();
|
||||
}
|
||||
chunk->ready = true;
|
||||
chunk->setReady(true);
|
||||
current = nullptr;
|
||||
chunk->decref();
|
||||
}
|
||||
}
|
||||
|
||||
void ChunksLoader::perform(Chunk* chunk, Chunk** closes_passed, LoaderMode mode){
|
||||
void ChunksLoader::perform(Chunk* chunk, Chunk** surroundings_passed, LoaderMode mode){
|
||||
if (isBusy()){
|
||||
std::cerr << "performing while busy" << std::endl;
|
||||
return;
|
||||
}
|
||||
chunk->incref();
|
||||
if (closes == nullptr){
|
||||
closes = new Chunk*[CLOSES_C];
|
||||
if (surroundings == nullptr){
|
||||
surroundings = new Chunk*[SURROUNDINGS_C];
|
||||
}
|
||||
for (int i = 0; i < CLOSES_C; i++){
|
||||
Chunk* other = closes_passed[i];
|
||||
for (int i = 0; i < SURROUNDINGS_C; i++){
|
||||
Chunk* other = surroundings_passed[i];
|
||||
if (other == nullptr)
|
||||
closes[i] = nullptr;
|
||||
surroundings[i] = nullptr;
|
||||
else {
|
||||
other->incref();
|
||||
closes[i] = other;
|
||||
surroundings[i] = other;
|
||||
}
|
||||
}
|
||||
current = chunk;
|
||||
@ -94,6 +101,10 @@ void ChunksLoader::load(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, LOAD);
|
||||
}
|
||||
|
||||
void ChunksLoader::lights(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, LIGHTS);
|
||||
}
|
||||
|
||||
void ChunksLoader::render(Chunk* chunk, Chunk** closes_passed){
|
||||
perform(chunk, closes_passed, RENDER);
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ class Chunk;
|
||||
class World;
|
||||
|
||||
enum LoaderMode {
|
||||
OFF, IDLE, LOAD, RENDER,
|
||||
OFF, IDLE, LOAD, LIGHTS, RENDER,
|
||||
};
|
||||
|
||||
class ChunksLoader final {
|
||||
@ -22,7 +22,7 @@ private:
|
||||
std::thread loaderThread;
|
||||
void _thread();
|
||||
std::atomic<Chunk*> current {nullptr};
|
||||
std::atomic<Chunk**> closes {nullptr};
|
||||
std::atomic<Chunk**> surroundings {nullptr};
|
||||
std::atomic<LoaderMode> state {IDLE};
|
||||
World* world;
|
||||
|
||||
@ -41,6 +41,7 @@ public:
|
||||
}
|
||||
|
||||
void load(Chunk* chunk, Chunk** closes_passed);
|
||||
void lights(Chunk* chunk, Chunk** closes_passed);
|
||||
void render(Chunk* chunk, Chunk** closes_passed);
|
||||
|
||||
void stop(){
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "voxel.h"
|
||||
#include "Chunk.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/noise.hpp>
|
||||
@ -9,6 +10,8 @@
|
||||
#include "../maths/FastNoiseLite.h"
|
||||
#include <time.h>
|
||||
|
||||
#include "../declarations.h"
|
||||
|
||||
class PseudoRandom {
|
||||
unsigned short seed;
|
||||
public:
|
||||
@ -64,7 +67,7 @@ float calc_height_faster(fnl_state *noise, int real_x, int real_z){
|
||||
height *= 64.0f;
|
||||
return height;
|
||||
}
|
||||
#include <iostream>
|
||||
|
||||
int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights, int real_x, int real_y, int real_z, int tileSize){
|
||||
const int tileX = floor((double)real_x/(double)tileSize);
|
||||
const int tileY = floor((double)real_z/(double)tileSize);
|
||||
@ -92,18 +95,14 @@ int generate_tree(fnl_state *noise, PseudoRandom* random, const float* heights,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){
|
||||
void WorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
|
||||
fnl_state noise = fnlCreateState();
|
||||
noise.noise_type = FNL_NOISE_OPENSIMPLEX2;
|
||||
noise.seed = seed * 60617077 % 25896307;
|
||||
|
||||
PseudoRandom randomtree;
|
||||
// PseudoRandom random;
|
||||
|
||||
float heights[CHUNK_VOL];
|
||||
|
||||
// std::cout << calc_height(&noise, cx, cy) << "\n";
|
||||
|
||||
for (int z = 0; z < CHUNK_D; z++){
|
||||
for (int x = 0; x < CHUNK_W; x++){
|
||||
int real_x = x + cx * CHUNK_W;
|
||||
@ -120,14 +119,14 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){
|
||||
float height = heights[z*CHUNK_W+x];
|
||||
|
||||
for (int y = 0; y < CHUNK_H; y++){
|
||||
int real_y = y + cy * CHUNK_H;
|
||||
int id = real_y < 55 ? 9 : 0;
|
||||
if ((real_y == (int)height) && (54 < real_y))
|
||||
id = 2;
|
||||
else if (real_y < (height - 6)){
|
||||
id = 8;
|
||||
int real_y = y;
|
||||
int id = real_y < 55 ? BLOCK_WATER : BLOCK_AIR;
|
||||
if ((real_y == (int)height) && (54 < real_y)) {
|
||||
id = BLOCK_GRASS_BLOCK;
|
||||
} else if (real_y < (height - 6)){
|
||||
id = BLOCK_STONE;
|
||||
} else if (real_y < height){
|
||||
id = 1;
|
||||
id = BLOCK_DIRT;
|
||||
} else {
|
||||
int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 16);
|
||||
if (tree) {
|
||||
@ -139,15 +138,15 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz, int seed){
|
||||
}
|
||||
}
|
||||
if ( ((height - (1.5 - 0.2 * pow(height - 54, 4))) < real_y) && (real_y < height)){
|
||||
id = 10;
|
||||
id = BLOCK_SAND;
|
||||
}
|
||||
if (real_y <= 2)
|
||||
id = 11;
|
||||
id = BLOCK_BEDROCK;
|
||||
if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 56000)){
|
||||
id = 12;
|
||||
id = BLOCK_GRASS;
|
||||
}
|
||||
if ((id == 0) && (real_y > 55) && ((int)height + 1 == real_y) && ((unsigned short)random() > 64000)){
|
||||
id = 13;
|
||||
id = BLOCK_FLOWER;
|
||||
}
|
||||
voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ class voxel;
|
||||
|
||||
class WorldGenerator {
|
||||
public:
|
||||
static void generate(voxel* voxels, int x, int y, int z, int seed);
|
||||
static void generate(voxel* voxels, int x, int z, int seed);
|
||||
};
|
||||
|
||||
#endif /* VOXELS_WORLDGENERATOR_H_ */
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* Camera.cpp
|
||||
*
|
||||
* Created on: Feb 11, 2020
|
||||
* Author: MihailRis
|
||||
*/
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Window.h"
|
||||
|
||||
@ -36,7 +29,10 @@ void Camera::rotate(float x, float y, float z){
|
||||
}
|
||||
|
||||
mat4 Camera::getProjection(){
|
||||
float aspect = (float)Window::width / (float)Window::height;
|
||||
float aspect = this->aspect;
|
||||
if (aspect == 0.0f){
|
||||
aspect = (float)Window::width / (float)Window::height;
|
||||
}
|
||||
if (perspective)
|
||||
return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f);
|
||||
else
|
||||
@ -50,5 +46,5 @@ mat4 Camera::getView(){
|
||||
if (perspective)
|
||||
return glm::lookAt(position, position+front, up);
|
||||
else
|
||||
return glm::mat4(1.0f);
|
||||
return glm::translate(glm::mat4(1.0f), position);
|
||||
}
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* Camera.h
|
||||
*
|
||||
* Created on: Feb 11, 2020
|
||||
* Author: MihailRis
|
||||
*/
|
||||
|
||||
#ifndef WINDOW_CAMERA_H_
|
||||
#define WINDOW_CAMERA_H_
|
||||
|
||||
@ -25,6 +18,7 @@ public:
|
||||
mat4 rotation;
|
||||
bool perspective = true;
|
||||
bool flipped = false;
|
||||
float aspect = 0.0f;
|
||||
Camera(vec3 position, float fov);
|
||||
|
||||
void rotate(float x, float y, float z);
|
||||
|
||||
@ -41,6 +41,10 @@ int Window::initialize(int width, int height, const char* title){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Window::viewport(int x, int y, int width, int height){
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
void Window::setCursorMode(int mode){
|
||||
glfwSetInputMode(window, GLFW_CURSOR, mode);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ public:
|
||||
static int initialize(int width, int height, const char* title);
|
||||
static void terminate();
|
||||
|
||||
static void viewport(int x, int y, int width, int height);
|
||||
static void setCursorMode(int mode);
|
||||
static bool isShouldClose();
|
||||
static void setShouldClose(bool flag);
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "../player_control.h"
|
||||
|
||||
Level::Level(World* world, Player* player, Chunks* chunks, PhysicsSolver* physics) :
|
||||
world(world),
|
||||
player(player),
|
||||
chunks(chunks),
|
||||
physics(physics) {
|
||||
|
||||
@ -11,6 +11,7 @@ class PlayerController;
|
||||
|
||||
class Level {
|
||||
public:
|
||||
World* world;
|
||||
Player* player;
|
||||
Chunks* chunks;
|
||||
PhysicsSolver* physics;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "world_render.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "graphics/VoxelRenderer.h"
|
||||
|
||||
#include "window/Window.h"
|
||||
@ -11,38 +12,24 @@
|
||||
#include "graphics/Batch3D.h"
|
||||
#include "voxels/Chunks.h"
|
||||
#include "voxels/Chunk.h"
|
||||
#include "voxels/Block.h"
|
||||
#include "world/World.h"
|
||||
#include "world/Level.h"
|
||||
#include "objects/Player.h"
|
||||
#include "Assets.h"
|
||||
#include "player_control.h"
|
||||
|
||||
float _camera_cx;
|
||||
float _camera_cz;
|
||||
|
||||
Mesh *crosshair;
|
||||
|
||||
float vertices[] = {
|
||||
// x y
|
||||
-0.01f,-0.01f,
|
||||
0.01f, 0.01f,
|
||||
|
||||
-0.01f, 0.01f,
|
||||
0.01f,-0.01f,
|
||||
};
|
||||
|
||||
int attrs[] = {
|
||||
2, 0 //null terminator
|
||||
};
|
||||
|
||||
WorldRenderer::WorldRenderer(Level* level) {
|
||||
this->level = level;
|
||||
crosshair = new Mesh(vertices, 4, attrs);
|
||||
WorldRenderer::WorldRenderer(Level* level, Assets* assets) : assets(assets), level(level) {
|
||||
lineBatch = new LineBatch(4096);
|
||||
batch3d = new Batch3D(1024);
|
||||
renderer = new VoxelRenderer();
|
||||
}
|
||||
|
||||
WorldRenderer::~WorldRenderer() {
|
||||
delete crosshair;
|
||||
delete batch3d;
|
||||
delete lineBatch;
|
||||
delete renderer;
|
||||
}
|
||||
@ -50,71 +37,71 @@ WorldRenderer::~WorldRenderer() {
|
||||
Chunks* _chunks = nullptr;
|
||||
|
||||
bool chunks_distance_compare(size_t i, size_t j) {
|
||||
Chunks* chunks = _chunks;
|
||||
Chunk* a = chunks->chunks[i];
|
||||
Chunk* b = chunks->chunks[j];
|
||||
return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz)
|
||||
>
|
||||
Chunk* a = _chunks->chunks[i];
|
||||
Chunk* b = _chunks->chunks[j];
|
||||
return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz) >
|
||||
(b->x + 0.5f - _camera_cx)*(b->x + 0.5f - _camera_cx) + (b->z + 0.5f - _camera_cz)*(b->z + 0.5f - _camera_cz));
|
||||
}
|
||||
|
||||
void WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){
|
||||
bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){
|
||||
Chunk* chunk = level->chunks->chunks[index];
|
||||
Mesh* mesh = level->chunks->meshes[index];
|
||||
if (mesh == nullptr)
|
||||
return;
|
||||
return false;
|
||||
|
||||
// Simple frustum culling (culling chunks behind the camera in 2D - XZ)
|
||||
// Simple frustum culling
|
||||
if (occlusion){
|
||||
const float cameraX = camera->position.x;
|
||||
const float cameraZ = camera->position.z;
|
||||
const float camDirX = camera->dir.x;
|
||||
const float camDirZ = camera->dir.z;
|
||||
|
||||
bool unoccluded = false;
|
||||
do {
|
||||
if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
|
||||
unoccluded = true; break;
|
||||
float y = camera->position.y+camera->front.y * CHUNK_H * 0.5f;
|
||||
if (y < 0.0f)
|
||||
y = 0.0f;
|
||||
if (y > CHUNK_H)
|
||||
y = CHUNK_H;
|
||||
vec3 v = vec3(chunk->x*CHUNK_W, y, chunk->z*CHUNK_D)-camera->position;
|
||||
if (v.x*v.x+v.z*v.z > (CHUNK_W*3)*(CHUNK_W*3)) {
|
||||
if (dot(camera->front, v) < 0.0f){
|
||||
return true;
|
||||
}
|
||||
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
|
||||
unoccluded = true; break;
|
||||
}
|
||||
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
|
||||
unoccluded = true; break;
|
||||
}
|
||||
if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
|
||||
unoccluded = true; break;
|
||||
}
|
||||
} while (false);
|
||||
if (!unoccluded)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f));
|
||||
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f));
|
||||
shader->uniformMatrix("u_model", model);
|
||||
mesh->draw(GL_TRIANGLES);
|
||||
return false;
|
||||
}
|
||||
|
||||
void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occlusion){
|
||||
|
||||
void WorldRenderer::draw(World* world, Camera* camera, bool occlusion){
|
||||
Chunks* chunks = level->chunks;
|
||||
|
||||
glClearColor(0.7f,0.81f,1.0f,1);
|
||||
vec4 skyColor(0.7f, 0.81f, 1.0f, 1.0f);
|
||||
glClearColor(skyColor.r, skyColor.g, skyColor.b, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Window::viewport(0, 0, Window::width, Window::height);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
Texture* texture = assets->getTexture("block");
|
||||
Shader* shader = assets->getShader("main");
|
||||
Shader* crosshairShader = assets->getShader("crosshair");
|
||||
Shader* linesShader = assets->getShader("lines");
|
||||
shader->use();
|
||||
shader->uniformMatrix("u_proj", camera->getProjection());
|
||||
shader->uniformMatrix("u_view", camera->getView());
|
||||
shader->uniform1f("u_gamma", 1.6f);
|
||||
shader->uniform3f("u_skyLightColor", 2.2f,2.2f,2.2f);
|
||||
shader->uniform3f("u_fogColor", 0.7f,0.81f,1.0f);
|
||||
shader->uniform1f("u_fogFactor", 0.03f);
|
||||
shader->uniform3f("u_skyLightColor", 1.1f,1.1f,1.1f);
|
||||
shader->uniform3f("u_fogColor", skyColor.r,skyColor.g,skyColor.b);
|
||||
shader->uniform1f("u_fogFactor", 0.025f);
|
||||
shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z);
|
||||
|
||||
Block* cblock = Block::blocks[level->player->choosenBlock];
|
||||
shader->uniform3f("u_torchlightColor",
|
||||
cblock->emission[0] / 15.0f,
|
||||
cblock->emission[1] / 15.0f,
|
||||
cblock->emission[2] / 15.0f);
|
||||
shader->uniform1f("u_torchlightDistance", 6.0f);
|
||||
shader->uniform1f("u_fogFactor", 0.025f);
|
||||
texture->bind();
|
||||
|
||||
std::vector<size_t> indices;
|
||||
@ -136,8 +123,9 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl
|
||||
std::sort(indices.begin(), indices.end(), chunks_distance_compare);
|
||||
|
||||
|
||||
int occludedChunks = 0;
|
||||
for (size_t i = 0; i < indices.size(); i++){
|
||||
drawChunk(indices[i], camera, shader, occlusion);
|
||||
occludedChunks += drawChunk(indices[i], camera, shader, occlusion);
|
||||
}
|
||||
|
||||
shader->uniformMatrix("u_model", mat4(1.0f));
|
||||
@ -145,11 +133,6 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl
|
||||
// draw 3D stuff here
|
||||
batch3d->render();
|
||||
|
||||
crosshairShader->use();
|
||||
crosshairShader->uniform1f("u_ar", (float)Window::height / (float)Window::width);
|
||||
crosshairShader->uniform1f("u_scale", 1.0f / ((float)Window::height / 1000.0f));
|
||||
crosshair->draw(GL_LINES);
|
||||
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
||||
glLineWidth(2.0f);
|
||||
@ -157,4 +140,14 @@ void WorldRenderer::draw(World* world, Camera* camera, Assets* assets, bool occl
|
||||
lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f, camera->position.z+0.01f, 0, 0, 1, 1);
|
||||
lineBatch->line(camera->position.x, camera->position.y-0.1f, camera->position.z, camera->position.x, camera->position.y-0.1f+0.01f, camera->position.z, 0, 1, 0, 1);
|
||||
lineBatch->render();
|
||||
|
||||
if (level->playerController->selectedBlockId != -1){
|
||||
Block* selectedBlock = Block::blocks[level->playerController->selectedBlockId];
|
||||
vec3 pos = level->playerController->selectedBlockPosition;
|
||||
if (selectedBlock->model == 1){
|
||||
lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f);
|
||||
} else if (selectedBlock->model == 2){
|
||||
lineBatch->box(pos.x+0.4f, pos.y+0.3f, pos.z+0.4f, 0.805f,0.805f,0.805f, 0,0,0,0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,21 +21,23 @@ class LineBatch;
|
||||
class Batch3D;
|
||||
class VoxelRenderer;
|
||||
class Shader;
|
||||
class Texture;
|
||||
class Framebuffer;
|
||||
|
||||
|
||||
class WorldRenderer {
|
||||
Batch3D *batch3d;
|
||||
Assets* assets;
|
||||
Level* level;
|
||||
|
||||
void drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
||||
public:
|
||||
VoxelRenderer *renderer;
|
||||
LineBatch *lineBatch;
|
||||
|
||||
WorldRenderer(Level* level);
|
||||
WorldRenderer(Level* level, Assets* assets);
|
||||
~WorldRenderer();
|
||||
|
||||
void draw(World* world, Camera* camera, Assets* assets, bool occlusion);
|
||||
void draw(World* world, Camera* camera, bool occlusion);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user