All changes made for 10th part of tutorial
voxel_engine.cpp - changed structure, added character controls, physics almost all files are modified (including shaders) + new source directory - physics
This commit is contained in:
parent
e1cdcf01e9
commit
1a00a11917
BIN
res/block_.png
Normal file
BIN
res/block_.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
res/block_white.png
Normal file
BIN
res/block_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@ -7,15 +7,16 @@ layout (location = 2) in vec4 v_light;
|
|||||||
out vec4 a_color;
|
out vec4 a_color;
|
||||||
out vec2 a_texCoord;
|
out vec2 a_texCoord;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 u_model;
|
||||||
uniform mat4 projview;
|
uniform mat4 u_projview;
|
||||||
|
uniform vec3 u_skyLightColor;
|
||||||
|
uniform float u_gamma;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec4 position = projview * model * vec4(v_position, 1.0);
|
vec4 position = u_projview * u_model * vec4(v_position, 1.0);
|
||||||
a_color = vec4(v_light.r,v_light.g,v_light.b,1.0f);
|
a_color = vec4(pow(v_light.rgb, vec3(u_gamma)),1.0f);
|
||||||
a_texCoord = v_texCoord;
|
a_texCoord = v_texCoord;
|
||||||
a_color.rgb += v_light.a;
|
a_color.rgb += u_skyLightColor * v_light.a*0.5;
|
||||||
a_color.rgb *= 1.0-position.z*0.0025;
|
a_color.rgb *= 1.0-position.z*0.0025;
|
||||||
//a_color.rgb = pow(a_color.rgb, vec3(1.0/0.7));
|
|
||||||
gl_Position = position;
|
gl_Position = position;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,8 @@ union {
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
unsigned long WorldFiles::totalCompressed = 0;
|
||||||
|
|
||||||
int bytes2Int(const unsigned char* src, unsigned int offset){
|
int bytes2Int(const unsigned char* src, unsigned int offset){
|
||||||
return (src[offset] << 24) | (src[offset+1] << 16) | (src[offset+2] << 8) | (src[offset+3]);
|
return (src[offset] << 24) | (src[offset+1] << 16) | (src[offset+2] << 8) | (src[offset+3]);
|
||||||
}
|
}
|
||||||
@ -26,11 +28,13 @@ void int2Bytes(int value, char* dest, unsigned int offset){
|
|||||||
}
|
}
|
||||||
|
|
||||||
WorldFiles::WorldFiles(const char* directory, size_t mainBufferCapacity) : directory(directory){
|
WorldFiles::WorldFiles(const char* directory, size_t mainBufferCapacity) : directory(directory){
|
||||||
mainBuffer = new char[mainBufferCapacity];
|
mainBufferIn = new char[CHUNK_VOL*2];
|
||||||
|
mainBufferOut = new char[mainBufferCapacity];
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldFiles::~WorldFiles(){
|
WorldFiles::~WorldFiles(){
|
||||||
delete[] mainBuffer;
|
delete[] mainBufferIn;
|
||||||
|
delete[] mainBufferOut;
|
||||||
std::unordered_map<long, char**>::iterator it;
|
std::unordered_map<long, char**>::iterator it;
|
||||||
for (it = regions.begin(); it != regions.end(); it++){
|
for (it = regions.begin(); it != regions.end(); it++){
|
||||||
char** region = it->second;
|
char** region = it->second;
|
||||||
@ -66,9 +70,11 @@ void WorldFiles::put(const char* chunkData, int x, int y){
|
|||||||
if (targetChunk == nullptr){
|
if (targetChunk == nullptr){
|
||||||
targetChunk = new char[CHUNK_VOL];
|
targetChunk = new char[CHUNK_VOL];
|
||||||
region[localY * REGION_SIZE + localX] = targetChunk;
|
region[localY * REGION_SIZE + localX] = targetChunk;
|
||||||
|
totalCompressed += CHUNK_VOL;
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
for (unsigned int i = 0; i < CHUNK_VOL; i++)
|
||||||
targetChunk[i] = chunkData[i];
|
targetChunk[i] = chunkData[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WorldFiles::getRegionFile(int x, int y) {
|
std::string WorldFiles::getRegionFile(int x, int y) {
|
||||||
@ -123,19 +129,19 @@ bool WorldFiles::readChunk(int x, int y, char* out){
|
|||||||
input.read((char*)(&offset), 4);
|
input.read((char*)(&offset), 4);
|
||||||
// Ordering bytes from big-endian to machine order (any, just reading)
|
// Ordering bytes from big-endian to machine order (any, just reading)
|
||||||
offset = bytes2Int((const unsigned char*)(&offset), 0);
|
offset = bytes2Int((const unsigned char*)(&offset), 0);
|
||||||
|
assert (offset < 1000000);
|
||||||
if (offset == 0){
|
if (offset == 0){
|
||||||
input.close();
|
input.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.seekg(offset);
|
input.seekg(offset);
|
||||||
input.read((char*)(&offset), 4);
|
input.read((char*)(&offset), 4);
|
||||||
size_t compressedSize = bytes2Int((const unsigned char*)(&offset), 0);
|
size_t compressedSize = bytes2Int((const unsigned char*)(&offset), 0);
|
||||||
|
|
||||||
input.read(mainBuffer, compressedSize);
|
input.read(mainBufferIn, compressedSize);
|
||||||
input.close();
|
input.close();
|
||||||
|
|
||||||
decompressRLE(mainBuffer, compressedSize, out, CHUNK_VOL);
|
decompressRLE(mainBufferIn, compressedSize, out, CHUNK_VOL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -150,8 +156,8 @@ void WorldFiles::write(){
|
|||||||
int y;
|
int y;
|
||||||
longToCoords(x,y, it->first);
|
longToCoords(x,y, it->first);
|
||||||
|
|
||||||
unsigned int size = writeRegion(mainBuffer, x,y, it->second);
|
unsigned int size = writeRegion(mainBufferOut, x,y, it->second);
|
||||||
write_binary_file(getRegionFile(x,y), mainBuffer, size);
|
write_binary_file(getRegionFile(x,y), mainBufferOut, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +171,11 @@ unsigned int WorldFiles::writeRegion(char* out, int x, int y, char** region){
|
|||||||
char* chunk = region[i];
|
char* chunk = region[i];
|
||||||
if (chunk == nullptr){
|
if (chunk == nullptr){
|
||||||
chunk = new char[CHUNK_VOL];
|
chunk = new char[CHUNK_VOL];
|
||||||
|
assert((((i % REGION_SIZE) + x * REGION_SIZE) >> REGION_SIZE_BIT) == x);
|
||||||
|
assert((((i / REGION_SIZE) + y * REGION_SIZE) >> REGION_SIZE_BIT) == y);
|
||||||
if (readChunk((i % REGION_SIZE) + x * REGION_SIZE, (i / REGION_SIZE) + y * REGION_SIZE, chunk)){
|
if (readChunk((i % REGION_SIZE) + x * REGION_SIZE, (i / REGION_SIZE) + y * REGION_SIZE, chunk)){
|
||||||
region[i] = chunk;
|
region[i] = chunk;
|
||||||
|
totalCompressed += CHUNK_VOL;
|
||||||
} else {
|
} else {
|
||||||
delete[] chunk;
|
delete[] chunk;
|
||||||
chunk = nullptr;
|
chunk = nullptr;
|
||||||
|
|||||||
@ -15,9 +15,11 @@
|
|||||||
* */
|
* */
|
||||||
class WorldFiles {
|
class WorldFiles {
|
||||||
public:
|
public:
|
||||||
|
static unsigned long totalCompressed;
|
||||||
std::unordered_map<long, char**> regions;
|
std::unordered_map<long, char**> regions;
|
||||||
std::string directory;
|
std::string directory;
|
||||||
char* mainBuffer;
|
char* mainBufferIn;
|
||||||
|
char* mainBufferOut;
|
||||||
|
|
||||||
WorldFiles(const char* directory, size_t mainBufferCapacity);
|
WorldFiles(const char* directory, size_t mainBufferCapacity);
|
||||||
~WorldFiles();
|
~WorldFiles();
|
||||||
|
|||||||
@ -26,6 +26,27 @@ void Shader::uniformMatrix(std::string name, glm::mat4 matrix){
|
|||||||
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(matrix));
|
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shader::uniform1i(std::string name, int x){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform1i(transformLoc, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform1f(std::string name, float x){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform1f(transformLoc, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform2f(std::string name, float x, float y){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform2f(transformLoc, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::uniform3f(std::string name, float x, float y, float z){
|
||||||
|
GLuint transformLoc = glGetUniformLocation(id, name.c_str());
|
||||||
|
glUniform3f(transformLoc, x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Shader* load_shader(std::string vertexFile, std::string fragmentFile) {
|
Shader* load_shader(std::string vertexFile, std::string fragmentFile) {
|
||||||
// Reading Files
|
// Reading Files
|
||||||
|
|||||||
@ -13,6 +13,10 @@ public:
|
|||||||
|
|
||||||
void use();
|
void use();
|
||||||
void uniformMatrix(std::string name, glm::mat4 matrix);
|
void uniformMatrix(std::string name, glm::mat4 matrix);
|
||||||
|
void uniform1i(std::string name, int x);
|
||||||
|
void uniform1f(std::string name, float x);
|
||||||
|
void uniform2f(std::string name, float x, float y);
|
||||||
|
void uniform3f(std::string name, float x, float y, float z);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Shader* load_shader(std::string vertexFile, std::string fragmentFile);
|
extern Shader* load_shader(std::string vertexFile, std::string fragmentFile);
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include "LightSolver.h"
|
#include "LightSolver.h"
|
||||||
#include "Lightmap.h"
|
#include "Lightmap.h"
|
||||||
#include "../voxels/Chunks.h"
|
#include "../voxels/Chunks.h"
|
||||||
@ -24,6 +25,7 @@ void LightSolver::add(int x, int y, int z, int emission) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LightSolver::add(int x, int y, int z) {
|
void LightSolver::add(int x, int y, int z) {
|
||||||
|
assert (chunks != nullptr);
|
||||||
add(x,y,z, chunks->getLight(x,y,z, channel));
|
add(x,y,z, chunks->getLight(x,y,z, channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
/*
|
|
||||||
* png_loading.cpp
|
|
||||||
*
|
|
||||||
* Created on: Feb 10, 2020
|
|
||||||
* Author: MihailRis
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "png_loading.h"
|
#include "png_loading.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <png.h>
|
|
||||||
#include "../graphics/Texture.h"
|
#include "../graphics/Texture.h"
|
||||||
|
|
||||||
|
// comment line below for use spng instead of libpng
|
||||||
|
#define LIBPNG
|
||||||
|
|
||||||
|
#ifdef LIBPNG
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
int _png_load(const char* file, int* width, int* height){
|
int _png_load(const char* file, int* width, int* height){
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int is_png, bit_depth, color_type, row_bytes;
|
int is_png, bit_depth, color_type, row_bytes;
|
||||||
@ -113,6 +111,116 @@ int _png_load(const char* file, int* width, int* height){
|
|||||||
fclose( f );
|
fclose( f );
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#include <spng.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
int _png_load(const char* file, int* pwidth, int* pheight){
|
||||||
|
int r = 0;
|
||||||
|
FILE *png;
|
||||||
|
char *pngbuf = nullptr;
|
||||||
|
spng_ctx *ctx = nullptr;
|
||||||
|
unsigned char *out = nullptr;
|
||||||
|
|
||||||
|
png = fopen(file, "rb");
|
||||||
|
if (png == nullptr){
|
||||||
|
std::cerr << "could not to open file " << file << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(png, 0, SEEK_END);
|
||||||
|
long siz_pngbuf = ftell(png);
|
||||||
|
rewind(png);
|
||||||
|
if(siz_pngbuf < 1) {
|
||||||
|
std::cerr << "could not to read file " << file << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pngbuf = new char[siz_pngbuf];
|
||||||
|
if(fread(pngbuf, siz_pngbuf, 1, png) != 1){
|
||||||
|
std::cerr << "fread() failed" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ctx = spng_ctx_new(0);
|
||||||
|
if (ctx == nullptr){
|
||||||
|
std::cerr << "spng_ctx_new() failed" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
r = spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
|
||||||
|
if (r){
|
||||||
|
std::cerr << "spng_set_crc_action() error: " << spng_strerror(r) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
r = spng_set_png_buffer(ctx, pngbuf, siz_pngbuf);
|
||||||
|
if (r){
|
||||||
|
std::cerr << "spng_set_png_buffer() error: " << spng_strerror(r) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spng_ihdr ihdr;
|
||||||
|
r = spng_get_ihdr(ctx, &ihdr);
|
||||||
|
if (r){
|
||||||
|
std::cerr << "spng_get_ihdr() error: " << spng_strerror(r) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *clr_type_str;
|
||||||
|
if(ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE)
|
||||||
|
clr_type_str = "grayscale";
|
||||||
|
else if(ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR)
|
||||||
|
clr_type_str = "truecolor";
|
||||||
|
else if(ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
|
||||||
|
clr_type_str = "indexed color";
|
||||||
|
else if(ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA)
|
||||||
|
clr_type_str = "grayscale with alpha";
|
||||||
|
else
|
||||||
|
clr_type_str = "truecolor with alpha";
|
||||||
|
|
||||||
|
size_t out_size;
|
||||||
|
r = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &out_size);
|
||||||
|
if (r){
|
||||||
|
std::cerr << "spng_decoded_image_size() error: " << spng_strerror(r) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
out = new unsigned char[out_size];
|
||||||
|
r = spng_decode_image(ctx, out, out_size, SPNG_FMT_RGBA8, 0);
|
||||||
|
if (r){
|
||||||
|
std::cerr << "spng_decode_image() error: " << spng_strerror(r) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* flipped = new unsigned char[out_size];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ihdr.height; i+=1){
|
||||||
|
size_t rowsize = ihdr.width*4;
|
||||||
|
for (size_t j = 0; j < rowsize; j++){
|
||||||
|
flipped[(ihdr.height-i-1)*rowsize+j] = out[i*rowsize+j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] out;
|
||||||
|
|
||||||
|
unsigned int texture;
|
||||||
|
int alpha = GL_RGBA;
|
||||||
|
|
||||||
|
glGenTextures(1, &texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ihdr.width, ihdr.height, 0,
|
||||||
|
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);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
pwidth[0] = ihdr.width;
|
||||||
|
pheight[0] = ihdr.height;
|
||||||
|
|
||||||
|
spng_ctx_free(ctx);
|
||||||
|
delete[] pngbuf;
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Texture* load_texture(std::string filename){
|
Texture* load_texture(std::string filename){
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|||||||
@ -1,10 +1,3 @@
|
|||||||
/*
|
|
||||||
* png_loading.h
|
|
||||||
*
|
|
||||||
* Created on: Feb 10, 2020
|
|
||||||
* Author: MihailRis
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LOADERS_PNG_LOADING_H_
|
#ifndef LOADERS_PNG_LOADING_H_
|
||||||
#define LOADERS_PNG_LOADING_H_
|
#define LOADERS_PNG_LOADING_H_
|
||||||
|
|
||||||
|
|||||||
4
src/physics/Hitbox.cpp
Normal file
4
src/physics/Hitbox.cpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "Hitbox.h"
|
||||||
|
|
||||||
|
Hitbox::Hitbox(vec3 position, vec3 halfsize) : position(position), halfsize(halfsize), velocity(0.0f,0.0f,0.0f) {
|
||||||
|
}
|
||||||
20
src/physics/Hitbox.h
Normal file
20
src/physics/Hitbox.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef PHYSICS_HITBOX_H_
|
||||||
|
#define PHYSICS_HITBOX_H_
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
class Hitbox {
|
||||||
|
public:
|
||||||
|
vec3 position;
|
||||||
|
vec3 halfsize;
|
||||||
|
vec3 velocity;
|
||||||
|
bool grounded = false;
|
||||||
|
|
||||||
|
Hitbox(vec3 position, vec3 halfsize);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PHYSICS_HITBOX_H_ */
|
||||||
148
src/physics/PhysicsSolver.cpp
Normal file
148
src/physics/PhysicsSolver.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#include "PhysicsSolver.h"
|
||||||
|
#include "Hitbox.h"
|
||||||
|
#include "../voxels/Chunks.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define E 0.01
|
||||||
|
|
||||||
|
PhysicsSolver::PhysicsSolver(vec3 gravity) : gravity(gravity) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSolver::step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting) {
|
||||||
|
for (unsigned i = 0; i < substeps; i++){
|
||||||
|
float dt = delta / (float)substeps;
|
||||||
|
vec3& pos = hitbox->position;
|
||||||
|
vec3& half = hitbox->halfsize;
|
||||||
|
vec3& vel = hitbox->velocity;
|
||||||
|
vel.x += gravity.x*dt;
|
||||||
|
vel.y += gravity.y*dt;
|
||||||
|
vel.z += gravity.z*dt;
|
||||||
|
|
||||||
|
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 (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++){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hitbox->grounded = false;
|
||||||
|
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 + 1 + half.y;
|
||||||
|
int f = 18.0;
|
||||||
|
vel.x *= max(0.0, 1.0 - dt * f);
|
||||||
|
vel.z *= max(0.0, 1.0 - dt * f);
|
||||||
|
hitbox->grounded = true;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.x += vel.x * dt;
|
||||||
|
pos.y += vel.y * dt;
|
||||||
|
pos.z += vel.z * dt;
|
||||||
|
|
||||||
|
if (shifting && hitbox->grounded){
|
||||||
|
int y = floor(pos.y-half.y-E);
|
||||||
|
|
||||||
|
hitbox->grounded = false;
|
||||||
|
for (int x = floor(px-half.x+E); x <= floor(px+half.x-E); x++){
|
||||||
|
for (int z = floor(pos.z-half.z+E); z <= floor(pos.z+half.z-E); z++){
|
||||||
|
if (chunks->isObstacle(x,y,z)){
|
||||||
|
hitbox->grounded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hitbox->grounded)
|
||||||
|
pos.z = pz;
|
||||||
|
hitbox->grounded = false;
|
||||||
|
|
||||||
|
for (int x = floor(pos.x-half.x+E); x <= floor(pos.x+half.x-E); x++){
|
||||||
|
for (int z = floor(pz-half.z+E); z <= floor(pz+half.z-E); z++){
|
||||||
|
if (chunks->isObstacle(x,y,z)){
|
||||||
|
hitbox->grounded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hitbox->grounded)
|
||||||
|
pos.x = px;
|
||||||
|
|
||||||
|
hitbox->grounded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) {
|
||||||
|
vec3& pos = hitbox->position;
|
||||||
|
vec3& half = hitbox->halfsize;
|
||||||
|
return x >= floor(pos.x-half.x) && x <= floor(pos.x+half.x) &&
|
||||||
|
z >= floor(pos.z-half.z) && z <= floor(pos.z+half.z) &&
|
||||||
|
y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y);
|
||||||
|
}
|
||||||
21
src/physics/PhysicsSolver.h
Normal file
21
src/physics/PhysicsSolver.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef PHYSICS_PHYSICSSOLVER_H_
|
||||||
|
#define PHYSICS_PHYSICSSOLVER_H_
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
class Hitbox;
|
||||||
|
class Chunks;
|
||||||
|
|
||||||
|
class PhysicsSolver {
|
||||||
|
vec3 gravity;
|
||||||
|
public:
|
||||||
|
PhysicsSolver(vec3 gravity);
|
||||||
|
void step(Chunks* chunks, Hitbox* hitbox, float delta, unsigned substeps, bool shifting);
|
||||||
|
bool isBlockInside(int x, int y, int z, Hitbox* hitbox);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PHYSICS_PHYSICSSOLVER_H_ */
|
||||||
@ -32,6 +32,8 @@ using namespace glm;
|
|||||||
#include "lighting/LightSolver.h"
|
#include "lighting/LightSolver.h"
|
||||||
#include "lighting/Lightmap.h"
|
#include "lighting/Lightmap.h"
|
||||||
#include "lighting/Lighting.h"
|
#include "lighting/Lighting.h"
|
||||||
|
#include "physics/Hitbox.h"
|
||||||
|
#include "physics/PhysicsSolver.h"
|
||||||
|
|
||||||
int WIDTH = 1280;
|
int WIDTH = 1280;
|
||||||
int HEIGHT = 720;
|
int HEIGHT = 720;
|
||||||
@ -49,90 +51,166 @@ int attrs[] = {
|
|||||||
2, 0 //null terminator
|
2, 0 //null terminator
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
Mesh *crosshair;
|
||||||
Window::initialize(WIDTH, HEIGHT, "Window 2.0");
|
Shader *shader, *linesShader, *crosshairShader;
|
||||||
Events::initialize();
|
Texture *texture;
|
||||||
|
LineBatch *lineBatch;
|
||||||
|
|
||||||
Shader* shader = load_shader("res/main.glslv", "res/main.glslf");
|
Chunks* chunks;
|
||||||
|
WorldFiles* wfile;
|
||||||
|
|
||||||
|
// All in-game definitions (blocks, items, etc..)
|
||||||
|
void setup_definitions() {
|
||||||
|
// AIR
|
||||||
|
Block* block = new Block(0,0);
|
||||||
|
block->drawGroup = 1;
|
||||||
|
block->lightPassing = true;
|
||||||
|
block->obstacle = false;
|
||||||
|
Block::blocks[block->id] = block;
|
||||||
|
|
||||||
|
// STONE
|
||||||
|
block = new Block(1,2);
|
||||||
|
Block::blocks[block->id] = block;
|
||||||
|
|
||||||
|
// GRASS
|
||||||
|
block = new Block(2,4);
|
||||||
|
block->textureFaces[2] = 2;
|
||||||
|
block->textureFaces[3] = 1;
|
||||||
|
Block::blocks[block->id] = block;
|
||||||
|
|
||||||
|
// LAMP
|
||||||
|
block = new Block(3,3);
|
||||||
|
block->emission[0] = 15;
|
||||||
|
block->emission[1] = 14;
|
||||||
|
block->emission[2] = 13;
|
||||||
|
Block::blocks[block->id] = block;
|
||||||
|
|
||||||
|
// GLASS
|
||||||
|
block = new Block(4,5);
|
||||||
|
block->drawGroup = 2;
|
||||||
|
block->lightPassing = true;
|
||||||
|
Block::blocks[block->id] = block;
|
||||||
|
|
||||||
|
// PLANKS
|
||||||
|
block = new Block(5,6);
|
||||||
|
Block::blocks[block->id] = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shaders, textures, renderers
|
||||||
|
int initialize_assets() {
|
||||||
|
shader = load_shader("res/main.glslv", "res/main.glslf");
|
||||||
if (shader == nullptr){
|
if (shader == nullptr){
|
||||||
std::cerr << "failed to load shader" << std::endl;
|
std::cerr << "failed to load shader" << std::endl;
|
||||||
Window::terminate();
|
Window::terminate();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* crosshairShader = load_shader("res/crosshair.glslv", "res/crosshair.glslf");
|
crosshairShader = load_shader("res/crosshair.glslv", "res/crosshair.glslf");
|
||||||
if (crosshairShader == nullptr){
|
if (crosshairShader == nullptr){
|
||||||
std::cerr << "failed to load crosshair shader" << std::endl;
|
std::cerr << "failed to load crosshair shader" << std::endl;
|
||||||
Window::terminate();
|
Window::terminate();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* linesShader = load_shader("res/lines.glslv", "res/lines.glslf");
|
linesShader = load_shader("res/lines.glslv", "res/lines.glslf");
|
||||||
if (linesShader == nullptr){
|
if (linesShader == nullptr){
|
||||||
std::cerr << "failed to load lines shader" << std::endl;
|
std::cerr << "failed to load lines shader" << std::endl;
|
||||||
Window::terminate();
|
Window::terminate();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture* texture = load_texture("res/block.png");
|
texture = load_texture("res/block.png");
|
||||||
if (texture == nullptr){
|
if (texture == nullptr){
|
||||||
std::cerr << "failed to load texture" << std::endl;
|
std::cerr << "failed to load texture" << std::endl;
|
||||||
delete shader;
|
delete shader;
|
||||||
Window::terminate();
|
Window::terminate();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
void draw_world(Camera* camera){
|
||||||
// AIR
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
Block* block = new Block(0,0);
|
|
||||||
block->drawGroup = 1;
|
|
||||||
block->lightPassing = true;
|
|
||||||
Block::blocks[block->id] = block;
|
|
||||||
|
|
||||||
// STONE
|
// Draw VAO
|
||||||
block = new Block(1,2);
|
shader->use();
|
||||||
Block::blocks[block->id] = block;
|
shader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
||||||
|
shader->uniform1f("u_gamma", 1.6f);
|
||||||
// GRASS
|
shader->uniform3f("u_skyLightColor", 0.1*2,0.15*2,0.2*2);
|
||||||
block = new Block(2,4);
|
texture->bind();
|
||||||
block->textureFaces[2] = 2;
|
mat4 model(1.0f);
|
||||||
block->textureFaces[3] = 1;
|
for (size_t i = 0; i < chunks->volume; i++){
|
||||||
Block::blocks[block->id] = block;
|
Chunk* chunk = chunks->chunks[i];
|
||||||
|
if (chunk == nullptr)
|
||||||
// LAMP
|
continue;
|
||||||
block = new Block(3,3);
|
Mesh* mesh = chunks->meshes[i];
|
||||||
block->emission[0] = 10;
|
if (mesh == nullptr)
|
||||||
block->emission[1] = 0;
|
continue;
|
||||||
block->emission[2] = 0;
|
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));
|
||||||
Block::blocks[block->id] = block;
|
shader->uniformMatrix("u_model", model);
|
||||||
|
mesh->draw(GL_TRIANGLES);
|
||||||
// GLASS
|
|
||||||
block = new Block(4,5);
|
|
||||||
block->drawGroup = 2;
|
|
||||||
block->lightPassing = true;
|
|
||||||
Block::blocks[block->id] = block;
|
|
||||||
|
|
||||||
// PLANKS
|
|
||||||
block = new Block(5,6);
|
|
||||||
Block::blocks[block->id] = block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldFiles wfile = WorldFiles("world/", 24*1024*1024);
|
crosshairShader->use();
|
||||||
Chunks* chunks = new Chunks(16*4,1,16*4, 0,0,0);
|
crosshair->draw(GL_LINES);
|
||||||
VoxelRenderer renderer(1024*1024*8);
|
|
||||||
LineBatch* lineBatch = new LineBatch(4096);
|
linesShader->use();
|
||||||
|
linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
||||||
|
glLineWidth(2.0f);
|
||||||
|
lineBatch->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deleting GL objects like shaders, textures
|
||||||
|
void finalize_assets(){
|
||||||
|
delete shader;
|
||||||
|
delete texture;
|
||||||
|
delete crosshair;
|
||||||
|
delete crosshairShader;
|
||||||
|
delete linesShader;
|
||||||
|
delete lineBatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save all world data to files
|
||||||
|
void write_world(){
|
||||||
|
for (unsigned int i = 0; i < chunks->volume; i++){
|
||||||
|
Chunk* chunk = chunks->chunks[i];
|
||||||
|
if (chunk == nullptr)
|
||||||
|
continue;
|
||||||
|
wfile->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
wfile->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deleting world data from memory
|
||||||
|
void close_world(){
|
||||||
|
delete chunks;
|
||||||
|
delete wfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
setup_definitions();
|
||||||
|
|
||||||
|
Window::initialize(WIDTH, HEIGHT, "Window 2.0");
|
||||||
|
Events::initialize();
|
||||||
|
|
||||||
|
int result = initialize_assets();
|
||||||
|
if (result){
|
||||||
|
Window::terminate();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
wfile = new WorldFiles("world/", REGION_VOL * (CHUNK_VOL * 2 + 8));
|
||||||
|
chunks = new Chunks(32,1,32, 0,0,0);
|
||||||
|
VoxelRenderer renderer(1024*1024);
|
||||||
|
lineBatch = new LineBatch(4096);
|
||||||
|
PhysicsSolver physics(vec3(0,-16.0f,0));
|
||||||
|
|
||||||
Lighting::initialize(chunks);
|
Lighting::initialize(chunks);
|
||||||
|
|
||||||
glClearColor(0.0f,0.0f,0.0f,1);
|
crosshair = new Mesh(vertices, 4, attrs);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
Mesh* crosshair = new Mesh(vertices, 4, attrs);
|
|
||||||
Camera* camera = new Camera(vec3(32,32,32), radians(90.0f));
|
Camera* camera = new Camera(vec3(32,32,32), radians(90.0f));
|
||||||
|
Hitbox* hitbox = new Hitbox(vec3(32,32,32), vec3(0.2f,0.9f,0.2f));
|
||||||
|
|
||||||
float lastTime = glfwGetTime();
|
float lastTime = glfwGetTime();
|
||||||
float delta = 0.0f;
|
float delta = 0.0f;
|
||||||
@ -140,13 +218,15 @@ int main() {
|
|||||||
float camX = 0.0f;
|
float camX = 0.0f;
|
||||||
float camY = 0.0f;
|
float camY = 0.0f;
|
||||||
|
|
||||||
float speed = 15;
|
float playerSpeed = 4.0f;
|
||||||
|
|
||||||
int choosenBlock = 1;
|
int choosenBlock = 1;
|
||||||
|
long frame = 0;
|
||||||
|
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(1);
|
||||||
|
|
||||||
while (!Window::isShouldClose()){
|
while (!Window::isShouldClose()){
|
||||||
|
frame++;
|
||||||
float currentTime = glfwGetTime();
|
float currentTime = glfwGetTime();
|
||||||
delta = currentTime - lastTime;
|
delta = currentTime - lastTime;
|
||||||
lastTime = currentTime;
|
lastTime = currentTime;
|
||||||
@ -164,22 +244,58 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Events::pressed(GLFW_KEY_W)){
|
// Controls
|
||||||
camera->position += camera->front * delta * speed;
|
bool sprint = Events::pressed(GLFW_KEY_LEFT_CONTROL);
|
||||||
|
bool shift = Events::pressed(GLFW_KEY_LEFT_SHIFT) && hitbox->grounded && !sprint;
|
||||||
|
|
||||||
|
float speed = playerSpeed;
|
||||||
|
int substeps = (int)(delta * 1000);
|
||||||
|
substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps));
|
||||||
|
physics.step(chunks, hitbox, delta, substeps, shift);
|
||||||
|
camera->position.x = hitbox->position.x;
|
||||||
|
camera->position.y = hitbox->position.y + 0.5f;
|
||||||
|
camera->position.z = hitbox->position.z;
|
||||||
|
|
||||||
|
float dt = min(1.0f, delta * 16);
|
||||||
|
if (shift){
|
||||||
|
speed *= 0.25f;
|
||||||
|
camera->position.y -= 0.2f;
|
||||||
|
camera->zoom = 0.9f * dt + camera->zoom * (1.0f - dt);
|
||||||
|
} else if (sprint){
|
||||||
|
speed *= 1.5f;
|
||||||
|
camera->zoom = 1.1f * dt + camera->zoom * (1.0f - dt);
|
||||||
|
} else {
|
||||||
|
camera->zoom = dt + camera->zoom * (1.0f - dt);
|
||||||
}
|
}
|
||||||
if (Events::pressed(GLFW_KEY_S)){
|
if (Events::pressed(GLFW_KEY_SPACE) && hitbox->grounded){
|
||||||
camera->position -= camera->front * delta * speed;
|
hitbox->velocity.y = 6.0f;
|
||||||
}
|
|
||||||
if (Events::pressed(GLFW_KEY_D)){
|
|
||||||
camera->position += camera->right * delta * speed;
|
|
||||||
}
|
|
||||||
if (Events::pressed(GLFW_KEY_A)){
|
|
||||||
camera->position -= camera->right * delta * speed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chunks->setCenter(camera->position.x,0,camera->position.z);
|
vec3 dir(0,0,0);
|
||||||
|
if (Events::pressed(GLFW_KEY_W)){
|
||||||
|
dir.x += camera->dir.x;
|
||||||
|
dir.z += camera->dir.z;
|
||||||
|
}
|
||||||
|
if (Events::pressed(GLFW_KEY_S)){
|
||||||
|
dir.x -= camera->dir.x;
|
||||||
|
dir.z -= camera->dir.z;
|
||||||
|
}
|
||||||
|
if (Events::pressed(GLFW_KEY_D)){
|
||||||
|
dir.x += camera->right.x;
|
||||||
|
dir.z += camera->right.z;
|
||||||
|
}
|
||||||
|
if (Events::pressed(GLFW_KEY_A)){
|
||||||
|
dir.x -= camera->right.x;
|
||||||
|
dir.z -= camera->right.z;
|
||||||
|
}
|
||||||
|
if (length(dir) > 0.0f)
|
||||||
|
dir = normalize(dir);
|
||||||
|
hitbox->velocity.x = dir.x * speed;
|
||||||
|
hitbox->velocity.z = dir.z * speed;
|
||||||
|
|
||||||
|
chunks->setCenter(wfile, camera->position.x,0,camera->position.z);
|
||||||
chunks->_buildMeshes(&renderer);
|
chunks->_buildMeshes(&renderer);
|
||||||
chunks->loadVisible(&wfile);
|
chunks->loadVisible(wfile);
|
||||||
|
|
||||||
if (Events::_cursor_locked){
|
if (Events::_cursor_locked){
|
||||||
camY += -Events::deltaY / Window::height * 2;
|
camY += -Events::deltaY / Window::height * 2;
|
||||||
@ -215,62 +331,24 @@ int main() {
|
|||||||
int x = (int)(iend.x)+(int)(norm.x);
|
int x = (int)(iend.x)+(int)(norm.x);
|
||||||
int y = (int)(iend.y)+(int)(norm.y);
|
int y = (int)(iend.y)+(int)(norm.y);
|
||||||
int z = (int)(iend.z)+(int)(norm.z);
|
int z = (int)(iend.z)+(int)(norm.z);
|
||||||
chunks->set(x, y, z, choosenBlock);
|
if (!physics.isBlockInside(x,y,z, hitbox)){
|
||||||
Lighting::onBlockSet(x,y,z, choosenBlock);
|
chunks->set(x, y, z, choosenBlock);
|
||||||
|
Lighting::onBlockSet(x,y,z, choosenBlock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
draw_world(camera);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
// Draw VAO
|
|
||||||
shader->use();
|
|
||||||
shader->uniformMatrix("projview", camera->getProjection()*camera->getView());
|
|
||||||
texture->bind();
|
|
||||||
mat4 model(1.0f);
|
|
||||||
for (size_t i = 0; i < chunks->volume; i++){
|
|
||||||
Chunk* chunk = chunks->chunks[i];
|
|
||||||
if (chunk == nullptr)
|
|
||||||
continue;
|
|
||||||
Mesh* mesh = chunks->meshes[i];
|
|
||||||
if (mesh == nullptr)
|
|
||||||
continue;
|
|
||||||
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));
|
|
||||||
shader->uniformMatrix("model", model);
|
|
||||||
mesh->draw(GL_TRIANGLES);
|
|
||||||
}
|
|
||||||
|
|
||||||
crosshairShader->use();
|
|
||||||
crosshair->draw(GL_LINES);
|
|
||||||
|
|
||||||
linesShader->use();
|
|
||||||
linesShader->uniformMatrix("projview", camera->getProjection()*camera->getView());
|
|
||||||
glLineWidth(2.0f);
|
|
||||||
lineBatch->render();
|
|
||||||
|
|
||||||
Window::swapBuffers();
|
Window::swapBuffers();
|
||||||
Events::pullEvents();
|
Events::pullEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_world();
|
||||||
|
close_world();
|
||||||
|
|
||||||
Lighting::finalize();
|
Lighting::finalize();
|
||||||
|
finalize_assets();
|
||||||
for (unsigned int i = 0; i < chunks->volume; i++){
|
|
||||||
Chunk* chunk = chunks->chunks[i];
|
|
||||||
if (chunk == nullptr)
|
|
||||||
continue;
|
|
||||||
wfile.put((const char*)chunk->voxels, chunk->x, chunk->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
wfile.write();
|
|
||||||
|
|
||||||
delete shader;
|
|
||||||
delete texture;
|
|
||||||
delete chunks;
|
|
||||||
delete crosshair;
|
|
||||||
delete crosshairShader;
|
|
||||||
delete linesShader;
|
|
||||||
delete lineBatch;
|
|
||||||
|
|
||||||
Window::terminate();
|
Window::terminate();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ public:
|
|||||||
unsigned char emission[3];
|
unsigned char emission[3];
|
||||||
unsigned char drawGroup = 0;
|
unsigned char drawGroup = 0;
|
||||||
bool lightPassing = false;
|
bool lightPassing = false;
|
||||||
|
bool obstacle = true;
|
||||||
|
|
||||||
Block(unsigned int id, int texture);
|
Block(unsigned int id, int texture);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#define VOXELS_CHUNK_H_
|
#define VOXELS_CHUNK_H_
|
||||||
|
|
||||||
#define CHUNK_W 16
|
#define CHUNK_W 16
|
||||||
#define CHUNK_H 128
|
#define CHUNK_H 64
|
||||||
#define CHUNK_D 16
|
#define CHUNK_D 16
|
||||||
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D)
|
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D)
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "Chunks.h"
|
#include "Chunks.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
|
#include "Block.h"
|
||||||
#include "WorldGenerator.h"
|
#include "WorldGenerator.h"
|
||||||
#include "../lighting/Lightmap.h"
|
#include "../lighting/Lightmap.h"
|
||||||
#include "../files/WorldFiles.h"
|
#include "../files/WorldFiles.h"
|
||||||
@ -129,6 +130,13 @@ voxel* Chunks::get(int x, int y, int z){
|
|||||||
return &chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx];
|
return &chunk->voxels[(ly * CHUNK_D + lz) * CHUNK_W + lx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Chunks::isObstacle(int x, int y, int z){
|
||||||
|
voxel* v = get(x,y,z);
|
||||||
|
if (v == nullptr)
|
||||||
|
return true; // void - is obstacle
|
||||||
|
return Block::blocks[v->id]->obstacle;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
unsigned char Chunks::getLight(int x, int y, int z, int channel){
|
||||||
x -= ox * CHUNK_W;
|
x -= ox * CHUNK_W;
|
||||||
y -= oy * CHUNK_H;
|
y -= oy * CHUNK_H;
|
||||||
@ -292,7 +300,7 @@ voxel* Chunks::rayCast(vec3 a, vec3 dir, float maxDist, vec3& end, vec3& norm, v
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunks::setCenter(int x, int y, int z) {
|
void Chunks::setCenter(WorldFiles* worldFiles, int x, int y, int z) {
|
||||||
int cx = x / CHUNK_W;
|
int cx = x / CHUNK_W;
|
||||||
int cy = y / CHUNK_H;
|
int cy = y / CHUNK_H;
|
||||||
int cz = z / CHUNK_D;
|
int cz = z / CHUNK_D;
|
||||||
@ -306,7 +314,7 @@ void Chunks::setCenter(int x, int y, int z) {
|
|||||||
cy -= h/2;
|
cy -= h/2;
|
||||||
cz -= d/2;
|
cz -= d/2;
|
||||||
if (cx != 0 || cy != 0 || cz != 0)
|
if (cx != 0 || cy != 0 || cz != 0)
|
||||||
translate(cx,cy,cz);
|
translate(worldFiles, cx,cy,cz);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Chunks::loadVisible(WorldFiles* worldFiles){
|
bool Chunks::loadVisible(WorldFiles* worldFiles){
|
||||||
@ -349,7 +357,7 @@ bool Chunks::loadVisible(WorldFiles* worldFiles){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunks::translate(int dx, int dy, int dz){
|
void Chunks::translate(WorldFiles* worldFiles, int dx, int dy, int dz){
|
||||||
for (unsigned int i = 0; i < volume; i++){
|
for (unsigned int i = 0; i < volume; i++){
|
||||||
chunksSecond[i] = nullptr;
|
chunksSecond[i] = nullptr;
|
||||||
meshesSecond[i] = nullptr;
|
meshesSecond[i] = nullptr;
|
||||||
@ -365,6 +373,7 @@ void Chunks::translate(int dx, int dy, int dz){
|
|||||||
continue;
|
continue;
|
||||||
Mesh* mesh = meshes[(y * d + z) * w + x];
|
Mesh* mesh = meshes[(y * d + z) * w + x];
|
||||||
if (nx < 0 || ny < 0 || nz < 0 || nx >= w || ny >= h || nz >= d){
|
if (nx < 0 || ny < 0 || nz < 0 || nx >= w || ny >= h || nz >= d){
|
||||||
|
worldFiles->put((const char*)chunk->voxels, chunk->x, chunk->z);
|
||||||
delete chunk;
|
delete chunk;
|
||||||
delete mesh;
|
delete mesh;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -33,8 +33,10 @@ public:
|
|||||||
void set(int x, int y, int z, int id);
|
void set(int x, int y, int z, int id);
|
||||||
voxel* rayCast(vec3 start, vec3 dir, float maxLength, vec3& end, vec3& norm, vec3& iend);
|
voxel* rayCast(vec3 start, vec3 dir, float maxLength, vec3& end, vec3& norm, vec3& iend);
|
||||||
|
|
||||||
void setCenter(int x, int y, int z);
|
bool isObstacle(int x, int y, int z);
|
||||||
void translate(int x, int y, int z);
|
|
||||||
|
void setCenter(WorldFiles* worldFiles, int x, int y, int z);
|
||||||
|
void translate(WorldFiles* worldFiles, int x, int y, int z);
|
||||||
|
|
||||||
bool loadVisible(WorldFiles* worldFiles);
|
bool loadVisible(WorldFiles* worldFiles);
|
||||||
bool _buildMeshes(VoxelRenderer* renderer);
|
bool _buildMeshes(VoxelRenderer* renderer);
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
Camera::Camera(vec3 position, float fov) : position(position), fov(fov), rotation(1.0f) {
|
Camera::Camera(vec3 position, float fov) : position(position), fov(fov), zoom(1.0f), rotation(1.0f) {
|
||||||
updateVectors();
|
updateVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,6 +18,13 @@ void Camera::updateVectors(){
|
|||||||
front = vec3(rotation * vec4(0,0,-1,1));
|
front = vec3(rotation * vec4(0,0,-1,1));
|
||||||
right = vec3(rotation * vec4(1,0,0,1));
|
right = vec3(rotation * vec4(1,0,0,1));
|
||||||
up = vec3(rotation * vec4(0,1,0,1));
|
up = vec3(rotation * vec4(0,1,0,1));
|
||||||
|
dir = vec3(rotation * vec4(0,0,-1,1));
|
||||||
|
dir.y = 0;
|
||||||
|
float len = length(dir);
|
||||||
|
if (len > 0.0f){
|
||||||
|
dir.x /= len;
|
||||||
|
dir.z /= len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::rotate(float x, float y, float z){
|
void Camera::rotate(float x, float y, float z){
|
||||||
@ -30,7 +37,7 @@ void Camera::rotate(float x, float y, float z){
|
|||||||
|
|
||||||
mat4 Camera::getProjection(){
|
mat4 Camera::getProjection(){
|
||||||
float aspect = (float)Window::width / (float)Window::height;
|
float aspect = (float)Window::width / (float)Window::height;
|
||||||
return glm::perspective(fov, aspect, 0.1f, 1500.0f);
|
return glm::perspective(fov*zoom, aspect, 0.05f, 1500.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
mat4 Camera::getView(){
|
mat4 Camera::getView(){
|
||||||
|
|||||||
@ -17,9 +17,11 @@ public:
|
|||||||
vec3 front;
|
vec3 front;
|
||||||
vec3 up;
|
vec3 up;
|
||||||
vec3 right;
|
vec3 right;
|
||||||
|
vec3 dir;
|
||||||
|
|
||||||
vec3 position;
|
vec3 position;
|
||||||
float fov;
|
float fov;
|
||||||
|
float zoom;
|
||||||
mat4 rotation;
|
mat4 rotation;
|
||||||
Camera(vec3 position, float fov);
|
Camera(vec3 position, float fov);
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,12 @@ int Window::initialize(int width, int height, const char* title){
|
|||||||
}
|
}
|
||||||
glViewport(0,0, width, height);
|
glViewport(0,0, width, height);
|
||||||
|
|
||||||
|
glClearColor(0.0f,0.0f,0.0f,1);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
Window::width = width;
|
Window::width = width;
|
||||||
Window::height = height;
|
Window::height = height;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user