Refactor and fixes
This commit is contained in:
parent
b4a3608302
commit
63b5f4bc6b
@ -106,7 +106,7 @@ int _png_load(const char* file, int* width, int* height){
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
|||||||
@ -30,40 +30,12 @@ using std::shared_ptr;
|
|||||||
using glm::vec3;
|
using glm::vec3;
|
||||||
using gui::GUI;
|
using gui::GUI;
|
||||||
|
|
||||||
void load_settings(EngineSettings& settings, std::string filename) {
|
|
||||||
std::string source = files::read_string(filename);
|
|
||||||
std::unique_ptr<json::JObject> obj(json::parse(filename, source));
|
|
||||||
obj->num("display-width", settings.displayWidth);
|
|
||||||
obj->num("display-height", settings.displayHeight);
|
|
||||||
obj->num("display-samples", settings.displaySamples);
|
|
||||||
obj->num("display-swap-interval", settings.displaySwapInterval);
|
|
||||||
obj->num("chunks-load-distance", settings.chunksLoadDistance);
|
|
||||||
obj->num("chunks-load-speed", settings.chunksLoadSpeed);
|
|
||||||
obj->num("chunks-padding", settings.chunksPadding);
|
|
||||||
obj->num("fog-curve", settings.fogCurve);
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_settings(EngineSettings& settings, std::string filename) {
|
|
||||||
json::JObject obj;
|
|
||||||
obj.put("display-width", settings.displayWidth);
|
|
||||||
obj.put("display-height", settings.displayHeight);
|
|
||||||
obj.put("display-samples", settings.displaySamples);
|
|
||||||
obj.put("display-swap-interval", settings.displaySwapInterval);
|
|
||||||
obj.put("chunks-load-distance", settings.chunksLoadDistance);
|
|
||||||
obj.put("chunks-load-speed", settings.chunksLoadSpeed);
|
|
||||||
obj.put("chunks-padding", settings.chunksPadding);
|
|
||||||
obj.put("fog-curve", settings.fogCurve);
|
|
||||||
files::write_string(filename, json::stringify(&obj, true, " "));
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine::Engine(const EngineSettings& settings) {
|
Engine::Engine(const EngineSettings& settings_) {
|
||||||
this->settings = settings;
|
this->settings = settings_;
|
||||||
|
|
||||||
Window::initialize(settings.displayWidth,
|
Window::initialize(settings.display);
|
||||||
settings.displayHeight,
|
|
||||||
settings.displayTitle,
|
|
||||||
settings.displaySamples);
|
|
||||||
Window::swapInterval(settings.displaySwapInterval);
|
|
||||||
|
|
||||||
assets = new Assets();
|
assets = new Assets();
|
||||||
std::cout << "-- loading assets" << std::endl;
|
std::cout << "-- loading assets" << std::endl;
|
||||||
@ -82,7 +54,7 @@ Engine::Engine(const EngineSettings& settings) {
|
|||||||
Camera* camera = new Camera(playerPosition, radians(90.0f));
|
Camera* camera = new Camera(playerPosition, radians(90.0f));
|
||||||
World* world = new World("world-1", "world/", 42);
|
World* world = new World("world-1", "world/", 42);
|
||||||
Player* player = new Player(playerPosition, 4.0f, camera);
|
Player* player = new Player(playerPosition, 4.0f, camera);
|
||||||
level = world->loadLevel(player, settings.chunksLoadDistance, settings.chunksPadding);
|
level = world->loadLevel(player, settings);
|
||||||
|
|
||||||
std::cout << "-- initializing finished" << std::endl;
|
std::cout << "-- initializing finished" << std::endl;
|
||||||
|
|
||||||
@ -116,8 +88,9 @@ void Engine::updateHotkeys() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Engine::mainloop() {
|
void Engine::mainloop() {
|
||||||
Camera* camera = level->player->camera;
|
|
||||||
std::cout << "-- preparing systems" << std::endl;
|
std::cout << "-- preparing systems" << std::endl;
|
||||||
|
|
||||||
|
Camera* camera = level->player->camera;
|
||||||
WorldRenderer worldRenderer(level, assets);
|
WorldRenderer worldRenderer(level, assets);
|
||||||
HudRenderer hud(gui, level, assets);
|
HudRenderer hud(gui, level, assets);
|
||||||
Batch2D batch(1024);
|
Batch2D batch(1024);
|
||||||
@ -127,15 +100,18 @@ void Engine::mainloop() {
|
|||||||
updateTimers();
|
updateTimers();
|
||||||
updateHotkeys();
|
updateHotkeys();
|
||||||
|
|
||||||
level->update(delta, Events::_cursor_locked, Events::_cursor_locked);
|
bool inputLocked = hud.isPause() || hud.isInventoryOpen() || gui->isFocusCaught();
|
||||||
level->chunksController->update(settings.chunksLoadSpeed);
|
level->updatePlayer(delta, !inputLocked, hud.isPause(), !inputLocked);
|
||||||
|
level->update();
|
||||||
|
level->chunksController->update(settings.chunks.loadSpeed);
|
||||||
|
|
||||||
worldRenderer.draw(camera, occlusion, 1.6f / (float)settings.chunksLoadDistance, settings.fogCurve);
|
float fovFactor = 1.6f / (float)settings.chunks.loadDistance;
|
||||||
|
worldRenderer.draw(camera, occlusion, fovFactor, settings.fogCurve);
|
||||||
hud.draw();
|
hud.draw();
|
||||||
if (level->player->debug) {
|
if (level->player->debug) {
|
||||||
hud.drawDebug( 1 / delta, occlusion);
|
hud.drawDebug( 1 / delta, occlusion);
|
||||||
}
|
}
|
||||||
gui->act();
|
gui->act(delta);
|
||||||
gui->draw(&batch, assets);
|
gui->draw(&batch, assets);
|
||||||
|
|
||||||
Window::swapBuffers();
|
Window::swapBuffers();
|
||||||
|
|||||||
27
src/engine.h
27
src/engine.h
@ -5,6 +5,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
class Assets;
|
class Assets;
|
||||||
class Level;
|
class Level;
|
||||||
@ -13,32 +14,6 @@ namespace gui {
|
|||||||
class GUI;
|
class GUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EngineSettings {
|
|
||||||
/* Window width (pixels) */
|
|
||||||
int displayWidth;
|
|
||||||
/* Window height (pixels) */
|
|
||||||
int displayHeight;
|
|
||||||
/* Anti-aliasing samples */
|
|
||||||
int displaySamples;
|
|
||||||
/* GLFW swap interval value, 0 - unlimited fps, 1 - vsync*/
|
|
||||||
int displaySwapInterval;
|
|
||||||
/* Window title */
|
|
||||||
const char* displayTitle;
|
|
||||||
/* Max milliseconds that engine uses for chunks loading only */
|
|
||||||
uint chunksLoadSpeed;
|
|
||||||
/* Radius of chunks loading zone (chunk is unit) */
|
|
||||||
uint chunksLoadDistance;
|
|
||||||
/* Buffer zone where chunks are not unloading (chunk is unit)*/
|
|
||||||
uint chunksPadding;
|
|
||||||
/* Fog opacity is calculated as `pow(depth*k, fogCurve)` where k depends on chunksLoadDistance.
|
|
||||||
Use values in range [1.0 - 2.0] where 1.0 is linear, 2.0 is quadratic
|
|
||||||
*/
|
|
||||||
float fogCurve;
|
|
||||||
};
|
|
||||||
|
|
||||||
void load_settings(EngineSettings& settings, std::string filename);
|
|
||||||
void save_settings(EngineSettings& settings, std::string filename);
|
|
||||||
|
|
||||||
class initialize_error : public std::runtime_error {
|
class initialize_error : public std::runtime_error {
|
||||||
public:
|
public:
|
||||||
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
||||||
|
|||||||
@ -20,7 +20,15 @@ GUI::~GUI() {
|
|||||||
delete container;
|
delete container;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::act() {
|
void GUI::act(float delta) {
|
||||||
|
for (IntervalEvent& event : intervalEvents) {
|
||||||
|
event.timer += delta;
|
||||||
|
if (event.timer > event.interval) {
|
||||||
|
event.callback();
|
||||||
|
event.timer = fmod(event.timer, event.interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
container->size(vec2(Window::width, Window::height));
|
container->size(vec2(Window::width, Window::height));
|
||||||
int mx = Events::x;
|
int mx = Events::x;
|
||||||
int my = Events::y;
|
int my = Events::y;
|
||||||
@ -83,3 +91,7 @@ bool GUI::isFocusCaught() const {
|
|||||||
void GUI::add(shared_ptr<UINode> panel) {
|
void GUI::add(shared_ptr<UINode> panel) {
|
||||||
container->add(panel);
|
container->add(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUI::interval(float interval, ontimeout callback) {
|
||||||
|
intervalEvents.push_back({callback, interval, 0.0f});
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
class Batch2D;
|
class Batch2D;
|
||||||
class Assets;
|
class Assets;
|
||||||
@ -43,11 +44,19 @@ namespace gui {
|
|||||||
class UINode;
|
class UINode;
|
||||||
class Container;
|
class Container;
|
||||||
|
|
||||||
|
typedef std::function<void()> ontimeout;
|
||||||
|
struct IntervalEvent {
|
||||||
|
ontimeout callback;
|
||||||
|
float interval;
|
||||||
|
float timer;
|
||||||
|
};
|
||||||
|
|
||||||
class GUI {
|
class GUI {
|
||||||
Container* container;
|
Container* container;
|
||||||
std::shared_ptr<UINode> hover = nullptr;
|
std::shared_ptr<UINode> hover = nullptr;
|
||||||
std::shared_ptr<UINode> pressed = nullptr;
|
std::shared_ptr<UINode> pressed = nullptr;
|
||||||
std::shared_ptr<UINode> focus = nullptr;
|
std::shared_ptr<UINode> focus = nullptr;
|
||||||
|
std::vector<IntervalEvent> intervalEvents;
|
||||||
public:
|
public:
|
||||||
GUI();
|
GUI();
|
||||||
~GUI();
|
~GUI();
|
||||||
@ -55,9 +64,11 @@ namespace gui {
|
|||||||
std::shared_ptr<UINode> getFocused() const;
|
std::shared_ptr<UINode> getFocused() const;
|
||||||
bool isFocusCaught() const;
|
bool isFocusCaught() const;
|
||||||
|
|
||||||
void act();
|
void act(float delta);
|
||||||
void draw(Batch2D* batch, Assets* assets);
|
void draw(Batch2D* batch, Assets* assets);
|
||||||
void add(std::shared_ptr<UINode> panel);
|
void add(std::shared_ptr<UINode> panel);
|
||||||
|
|
||||||
|
void interval(float interval, ontimeout callback);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
#include "Panel.h"
|
|
||||||
|
|
||||||
#include "../../graphics/Batch2D.h"
|
|
||||||
|
|
||||||
using gui::Panel;
|
|
||||||
|
|
||||||
Panel::Panel(glm::vec2 coord, glm::vec2 size, glm::vec4 color)
|
|
||||||
: coord(coord), size(size), color(color) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::draw(Batch2D* batch) {
|
|
||||||
batch->texture(nullptr);
|
|
||||||
batch->color = color;
|
|
||||||
batch->rect(coord.x, coord.y, size.x, size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Panel::isVisible() const {
|
|
||||||
return visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::setVisible(bool flag) {
|
|
||||||
visible = flag;
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
#ifndef FRONTEND_GUI_PANEL_H_
|
|
||||||
#define FRONTEND_GUI_PANEL_H_
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
class Batch2D;
|
|
||||||
|
|
||||||
namespace gui {
|
|
||||||
class Panel {
|
|
||||||
glm::vec2 coord;
|
|
||||||
glm::vec2 size;
|
|
||||||
glm::vec4 color;
|
|
||||||
bool visible = true;
|
|
||||||
public:
|
|
||||||
Panel(glm::vec2 coord, glm::vec2 size, glm::vec4 color);
|
|
||||||
|
|
||||||
void draw(Batch2D* batch);
|
|
||||||
|
|
||||||
void setVisible(bool flag);
|
|
||||||
bool isVisible() const;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FRONTEND_GUI_PANEL_H_
|
|
||||||
@ -34,12 +34,7 @@ using std::shared_ptr;
|
|||||||
using glm::vec2;
|
using glm::vec2;
|
||||||
using glm::vec3;
|
using glm::vec3;
|
||||||
using glm::vec4;
|
using glm::vec4;
|
||||||
using gui::GUI;
|
using namespace gui;
|
||||||
using gui::UINode;
|
|
||||||
using gui::Panel;
|
|
||||||
using gui::Label;
|
|
||||||
using gui::Button;
|
|
||||||
using gui::TextBox;
|
|
||||||
|
|
||||||
inline Label* create_label(gui::wstringsupplier supplier) {
|
inline Label* create_label(gui::wstringsupplier supplier) {
|
||||||
Label* label = new Label(L"-");
|
Label* label = new Label(L"-");
|
||||||
@ -49,10 +44,15 @@ inline Label* create_label(gui::wstringsupplier supplier) {
|
|||||||
|
|
||||||
HudRenderer::HudRenderer(GUI* gui, Level* level, Assets* assets) : level(level), assets(assets), guiController(gui) {
|
HudRenderer::HudRenderer(GUI* gui, Level* level, Assets* assets) : level(level), assets(assets), guiController(gui) {
|
||||||
batch = new Batch2D(1024);
|
batch = new Batch2D(1024);
|
||||||
uicamera = new Camera(glm::vec3(), Window::height);
|
uicamera = new Camera(vec3(), Window::height);
|
||||||
uicamera->perspective = false;
|
uicamera->perspective = false;
|
||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
|
|
||||||
|
gui->interval(1.0f, [this]() {
|
||||||
|
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
|
||||||
|
fpsMin = fps;
|
||||||
|
fpsMax = fps;
|
||||||
|
});
|
||||||
Panel* panel = new Panel(vec2(200, 200), vec4(5.0f), 1.0f);
|
Panel* panel = new Panel(vec2(200, 200), vec4(5.0f), 1.0f);
|
||||||
panel->setCoord(vec2(10, 10));
|
panel->setCoord(vec2(10, 10));
|
||||||
panel->add(shared_ptr<Label>(create_label([this](){
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
@ -74,11 +74,14 @@ HudRenderer::HudRenderer(GUI* gui, Level* level, Assets* assets) : level(level),
|
|||||||
})));
|
})));
|
||||||
for (int ax = 0; ax < 3; ax++){
|
for (int ax = 0; ax < 3; ax++){
|
||||||
Panel* sub = new Panel(vec2(10, 27), vec4(0.0f));
|
Panel* sub = new Panel(vec2(10, 27), vec4(0.0f));
|
||||||
sub->orientation(gui::Orientation::horizontal);
|
sub->orientation(Orientation::horizontal);
|
||||||
|
|
||||||
Label* label = new Label(wstring({L'x'+ax})+L": ");
|
Label* label = new Label(wstring({L'x'+ax})+L": ");
|
||||||
label->margin(vec4(2, 3, 2, 3));
|
label->margin(vec4(2, 3, 2, 3));
|
||||||
sub->add(shared_ptr<UINode>(label));
|
sub->add(shared_ptr<UINode>(label));
|
||||||
sub->color(vec4(0.0f));
|
sub->color(vec4(0.0f));
|
||||||
|
|
||||||
|
// Coordinate input
|
||||||
TextBox* box = new TextBox(L"");
|
TextBox* box = new TextBox(L"");
|
||||||
box->textSupplier([this, ax]() {
|
box->textSupplier([this, ax]() {
|
||||||
Hitbox* hitbox = this->level->player->hitbox;
|
Hitbox* hitbox = this->level->player->hitbox;
|
||||||
@ -86,7 +89,9 @@ HudRenderer::HudRenderer(GUI* gui, Level* level, Assets* assets) : level(level),
|
|||||||
});
|
});
|
||||||
box->textConsumer([this, ax](wstring text) {
|
box->textConsumer([this, ax](wstring text) {
|
||||||
try {
|
try {
|
||||||
this->level->player->hitbox->position[ax] = std::stoi(text);
|
vec3 position = this->level->player->hitbox->position;
|
||||||
|
position[ax] = std::stoi(text);
|
||||||
|
this->level->player->teleport(position);
|
||||||
} catch (std::invalid_argument& _){
|
} catch (std::invalid_argument& _){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -125,12 +130,7 @@ HudRenderer::~HudRenderer() {
|
|||||||
|
|
||||||
void HudRenderer::drawDebug(int fps, bool occlusion){
|
void HudRenderer::drawDebug(int fps, bool occlusion){
|
||||||
this->occlusion = occlusion;
|
this->occlusion = occlusion;
|
||||||
if (fpsFrame % 60 == 0) {
|
this->fps = fps;
|
||||||
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
|
|
||||||
fpsMin = fps;
|
|
||||||
fpsMax = fps;
|
|
||||||
}
|
|
||||||
fpsFrame++;
|
|
||||||
fpsMin = min(fps, fpsMin);
|
fpsMin = min(fps, fpsMin);
|
||||||
fpsMax = max(fps, fpsMax);
|
fpsMax = max(fps, fpsMax);
|
||||||
}
|
}
|
||||||
@ -240,6 +240,7 @@ void HudRenderer::draw(){
|
|||||||
batch->line(width/2-5, height/2-5, width/2+5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
|
batch->line(width/2-5, height/2-5, width/2+5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
|
||||||
batch->line(width/2+5, height/2-5, width/2-5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
|
batch->line(width/2+5, height/2-5, width/2-5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
|
||||||
}
|
}
|
||||||
|
Player* player = level->player;
|
||||||
|
|
||||||
batch->rect(Window::width/2-128-4, Window::height-80-4, 256+8, 64+8,
|
batch->rect(Window::width/2-128-4, Window::height-80-4, 256+8, 64+8,
|
||||||
0.95f, 0.95f, 0.95f, 0.85f, 0.85f, 0.85f,
|
0.95f, 0.95f, 0.95f, 0.85f, 0.85f, 0.85f,
|
||||||
@ -259,7 +260,7 @@ void HudRenderer::draw(){
|
|||||||
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 2);
|
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 2);
|
||||||
|
|
||||||
batch->texture(blocks);
|
batch->texture(blocks);
|
||||||
Player* player = level->player;
|
|
||||||
{
|
{
|
||||||
Block* cblock = Block::blocks[player->choosenBlock];
|
Block* cblock = Block::blocks[player->choosenBlock];
|
||||||
if (cblock->model == BLOCK_MODEL_CUBE){
|
if (cblock->model == BLOCK_MODEL_CUBE){
|
||||||
@ -296,3 +297,11 @@ void HudRenderer::draw(){
|
|||||||
}
|
}
|
||||||
batch->render();
|
batch->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HudRenderer::isInventoryOpen() const {
|
||||||
|
return inventoryOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HudRenderer::isPause() const {
|
||||||
|
return pause;
|
||||||
|
}
|
||||||
@ -21,9 +21,9 @@ class HudRenderer {
|
|||||||
Batch2D* batch;
|
Batch2D* batch;
|
||||||
Camera* uicamera;
|
Camera* uicamera;
|
||||||
|
|
||||||
|
int fps = 60;
|
||||||
int fpsMin = 60;
|
int fpsMin = 60;
|
||||||
int fpsMax = 60;
|
int fpsMax = 60;
|
||||||
int fpsFrame = 0;
|
|
||||||
std::wstring fpsString;
|
std::wstring fpsString;
|
||||||
bool occlusion;
|
bool occlusion;
|
||||||
bool inventoryOpen = false;
|
bool inventoryOpen = false;
|
||||||
@ -38,6 +38,9 @@ public:
|
|||||||
void drawInventory(Player* player);
|
void drawInventory(Player* player);
|
||||||
void draw();
|
void draw();
|
||||||
void drawDebug(int fps, bool occlusion);
|
void drawDebug(int fps, bool occlusion);
|
||||||
|
|
||||||
|
bool isInventoryOpen() const;
|
||||||
|
bool isPause() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SRC_HUD_H_ */
|
#endif /* SRC_HUD_H_ */
|
||||||
|
|||||||
@ -7,17 +7,12 @@ Texture::Texture(unsigned int id, int width, int height) : id(id), width(width),
|
|||||||
Texture::Texture(unsigned char* data, int width, int height) : width(width), height(height) {
|
Texture::Texture(unsigned char* data, int width, int height) : width(width), height(height) {
|
||||||
glGenTextures(1, &id);
|
glGenTextures(1, &id);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
// glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, id);
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) data);
|
GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) data);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
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_MAG_FILTER, GL_NEAREST);
|
||||||
// glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, width, height, GL_TRUE);
|
|
||||||
// glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
// glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
// glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
@ -31,10 +26,7 @@ void Texture::bind(){
|
|||||||
|
|
||||||
void Texture::reload(unsigned char* data){
|
void Texture::reload(unsigned char* data){
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
// glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, id);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) data);
|
GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) data);
|
||||||
// glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, width, height, GL_TRUE);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
// glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,3 +17,7 @@ Player::Player(glm::vec3 position, float speed, Camera* camera) :
|
|||||||
Player::~Player(){
|
Player::~Player(){
|
||||||
delete hitbox;
|
delete hitbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::teleport(glm::vec3 position) {
|
||||||
|
hitbox->position = position;
|
||||||
|
}
|
||||||
|
|||||||
@ -26,6 +26,8 @@ public:
|
|||||||
voxel selectedVoxel {0, 0};
|
voxel selectedVoxel {0, 0};
|
||||||
Player(glm::vec3 position, float speed, Camera* camera);
|
Player(glm::vec3 position, float speed, Camera* camera);
|
||||||
~Player();
|
~Player();
|
||||||
|
|
||||||
|
void teleport(glm::vec3 position);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SRC_OBJECTS_PLAYER_H_ */
|
#endif /* SRC_OBJECTS_PLAYER_H_ */
|
||||||
|
|||||||
@ -29,46 +29,100 @@
|
|||||||
#define CHEAT_SPEED_MUL 5.0f
|
#define CHEAT_SPEED_MUL 5.0f
|
||||||
#define JUMP_FORCE 7.0f
|
#define JUMP_FORCE 7.0f
|
||||||
|
|
||||||
PlayerController::PlayerController(Level* level) : level(level) {
|
PlayerController::PlayerController(Level* level, const EngineSettings& settings)
|
||||||
|
: level(level), player(level->player), camSettings(settings.camera) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::update_controls(float delta, bool movement){
|
void PlayerController::refreshCamera() {
|
||||||
Player* player = level->player;
|
level->player->camera->position = level->player->hitbox->position + cameraOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/*block choose*/{
|
void PlayerController::updateKeyboard() {
|
||||||
|
input.zoom = Events::pressed(keycode::C);
|
||||||
|
input.moveForward = Events::pressed(keycode::W);
|
||||||
|
input.moveBack = Events::pressed(keycode::S);
|
||||||
|
input.moveLeft = Events::pressed(keycode::A);
|
||||||
|
input.moveRight = Events::pressed(keycode::D);
|
||||||
|
input.sprint = Events::pressed(keycode::LEFT_CONTROL);
|
||||||
|
input.shift = Events::pressed(keycode::LEFT_SHIFT);
|
||||||
|
input.cheat = Events::pressed(keycode::R);
|
||||||
|
input.jump = Events::pressed(keycode::SPACE);
|
||||||
|
|
||||||
|
input.noclip = Events::jpressed(keycode::N);
|
||||||
|
input.flight = Events::jpressed(keycode::F);
|
||||||
|
|
||||||
|
// block choice
|
||||||
for (int i = 1; i < 10; i++){
|
for (int i = 1; i < 10; i++){
|
||||||
if (Events::jpressed(keycode::NUM_0+i)){
|
if (Events::jpressed(keycode::NUM_0+i)){
|
||||||
player->choosenBlock = i;
|
player->choosenBlock = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}//end
|
}
|
||||||
|
|
||||||
|
void PlayerController::resetKeyboard() {
|
||||||
|
input.zoom = false;
|
||||||
|
input.moveForward = false;
|
||||||
|
input.moveBack = false;
|
||||||
|
input.moveLeft = false;
|
||||||
|
input.moveRight = false;
|
||||||
|
input.sprint = false;
|
||||||
|
input.shift = false;
|
||||||
|
input.cheat = false;
|
||||||
|
input.jump = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerController::updateControls(float delta){
|
||||||
|
Player* player = level->player;
|
||||||
Camera* camera = player->camera;
|
Camera* camera = player->camera;
|
||||||
Hitbox* hitbox = player->hitbox;
|
Hitbox* hitbox = player->hitbox;
|
||||||
bool sprint = Events::pressed(keycode::LEFT_CONTROL) && movement;
|
|
||||||
bool shift = Events::pressed(keycode::LEFT_SHIFT) && hitbox->grounded && !sprint && movement;
|
|
||||||
bool zoom = Events::pressed(keycode::C) && movement;
|
|
||||||
bool cheat = Events::pressed(keycode::R) && movement;
|
|
||||||
|
|
||||||
|
bool crouch = input.shift && hitbox->grounded && !input.sprint;
|
||||||
float speed = player->speed;
|
float speed = player->speed;
|
||||||
|
|
||||||
if (player->flight){
|
if (player->flight){
|
||||||
speed *= FLIGHT_SPEED_MUL;
|
speed *= FLIGHT_SPEED_MUL;
|
||||||
}
|
}
|
||||||
if (cheat){
|
if (input.cheat){
|
||||||
speed *= CHEAT_SPEED_MUL;
|
speed *= CHEAT_SPEED_MUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 dir(0,0,0);
|
||||||
|
if (input.moveForward){
|
||||||
|
dir.x += camera->dir.x;
|
||||||
|
dir.z += camera->dir.z;
|
||||||
|
}
|
||||||
|
if (input.moveBack){
|
||||||
|
dir.x -= camera->dir.x;
|
||||||
|
dir.z -= camera->dir.z;
|
||||||
|
}
|
||||||
|
if (input.moveRight){
|
||||||
|
dir.x += camera->right.x;
|
||||||
|
dir.z += camera->right.z;
|
||||||
|
}
|
||||||
|
if (input.moveLeft){
|
||||||
|
dir.x -= camera->right.x;
|
||||||
|
dir.z -= camera->right.z;
|
||||||
|
}
|
||||||
|
if (length(dir) > 0.0f){
|
||||||
|
dir = normalize(dir);
|
||||||
|
hitbox->velocity.x += dir.x * speed * delta * 9;
|
||||||
|
hitbox->velocity.z += dir.z * speed * delta * 9;
|
||||||
|
}
|
||||||
|
|
||||||
int substeps = (int)(delta * 1000);
|
int substeps = (int)(delta * 1000);
|
||||||
substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps));
|
substeps = (substeps <= 0 ? 1 : (substeps > 100 ? 100 : substeps));
|
||||||
if (movement)
|
level->physics->step(level->chunks, hitbox, delta, substeps, crouch, player->flight ? 0.0f : 1.0f, !player->noclip);
|
||||||
level->physics->step(level->chunks, hitbox, delta, substeps, shift, player->flight ? 0.0f : 1.0f, !player->noclip);
|
if (player->flight && hitbox->grounded) {
|
||||||
camera->position.x = hitbox->position.x;
|
|
||||||
camera->position.y = hitbox->position.y + 0.7f;
|
|
||||||
camera->position.z = hitbox->position.z;
|
|
||||||
|
|
||||||
if (player->flight && hitbox->grounded)
|
|
||||||
player->flight = false;
|
player->flight = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*camera shaking*/{
|
if (input.jump && hitbox->grounded){
|
||||||
|
hitbox->velocity.y = JUMP_FORCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cameraOffset = vec3(0.0f, 0.7f, 0.0f);
|
||||||
|
|
||||||
|
if (camSettings.shaking) {
|
||||||
player->interpVel = player->interpVel * (1.0f - delta * 5) + hitbox->velocity * delta * 0.1f;
|
player->interpVel = player->interpVel * (1.0f - delta * 5) + hitbox->velocity * delta * 0.1f;
|
||||||
if (hitbox->grounded && player->interpVel.y < 0.0f){
|
if (hitbox->grounded && player->interpVel.y < 0.0f){
|
||||||
player->interpVel.y *= -30.0f;
|
player->interpVel.y *= -30.0f;
|
||||||
@ -77,84 +131,62 @@ void PlayerController::update_controls(float delta, bool movement){
|
|||||||
player->cameraShakingTimer += delta * factor * CAMERA_SHAKING_SPEED;
|
player->cameraShakingTimer += delta * factor * CAMERA_SHAKING_SPEED;
|
||||||
float shakeTimer = player->cameraShakingTimer;
|
float shakeTimer = player->cameraShakingTimer;
|
||||||
player->cameraShaking = player->cameraShaking * (1.0f - delta * CAMERA_SHAKING_DELTA_K) + factor * delta * CAMERA_SHAKING_DELTA_K;
|
player->cameraShaking = player->cameraShaking * (1.0f - delta * CAMERA_SHAKING_DELTA_K) + factor * delta * CAMERA_SHAKING_DELTA_K;
|
||||||
camera->position += camera->right * sin(shakeTimer) * CAMERA_SHAKING_OFFSET * player->cameraShaking;
|
cameraOffset += camera->right * sin(shakeTimer) * CAMERA_SHAKING_OFFSET * player->cameraShaking;
|
||||||
camera->position += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking;
|
cameraOffset += camera->up * abs(cos(shakeTimer)) * CAMERA_SHAKING_OFFSET_Y * player->cameraShaking;
|
||||||
camera->position -= min(player->interpVel * 0.05f, 1.0f);
|
cameraOffset -= min(player->interpVel * 0.05f, 1.0f);
|
||||||
}//end
|
}
|
||||||
|
|
||||||
if ((Events::jpressed(keycode::F) && movement && !player->noclip) ||
|
if ((input.flight && !player->noclip) ||
|
||||||
(Events::jpressed(keycode::N) && movement && player->flight == player->noclip)){
|
(input.noclip && player->flight == player->noclip)){
|
||||||
player->flight = !player->flight;
|
player->flight = !player->flight;
|
||||||
if (player->flight){
|
if (player->flight){
|
||||||
hitbox->grounded = false;
|
hitbox->grounded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Events::jpressed(keycode::N) && movement) {
|
if (input.noclip) {
|
||||||
player->noclip = !player->noclip;
|
player->noclip = !player->noclip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*field of view manipulations*/{
|
if (camSettings.fovEvents){
|
||||||
float dt = min(1.0f, delta * ZOOM_SPEED);
|
float dt = min(1.0f, delta * ZOOM_SPEED);
|
||||||
float zoomValue = 1.0f;
|
float zoomValue = 1.0f;
|
||||||
if (shift){
|
if (crouch){
|
||||||
speed *= CROUCH_SPEED_MUL;
|
speed *= CROUCH_SPEED_MUL;
|
||||||
camera->position.y += CROUCH_SHIFT_Y;
|
cameraOffset += CROUCH_SHIFT_Y;
|
||||||
zoomValue = CROUCH_ZOOM;
|
zoomValue = CROUCH_ZOOM;
|
||||||
} else if (sprint){
|
} else if (input.sprint){
|
||||||
speed *= RUN_SPEED_MUL;
|
speed *= RUN_SPEED_MUL;
|
||||||
zoomValue = RUN_ZOOM;
|
zoomValue = RUN_ZOOM;
|
||||||
}
|
}
|
||||||
if (zoom)
|
if (input.zoom)
|
||||||
zoomValue *= C_ZOOM;
|
zoomValue *= C_ZOOM;
|
||||||
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
|
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
|
||||||
}//end
|
|
||||||
|
|
||||||
if (Events::pressed(keycode::SPACE) && movement && hitbox->grounded){
|
|
||||||
hitbox->velocity.y = JUMP_FORCE;
|
|
||||||
}
|
|
||||||
vec3 dir(0,0,0);
|
|
||||||
if (Events::pressed(keycode::W) && movement){
|
|
||||||
dir.x += camera->dir.x;
|
|
||||||
dir.z += camera->dir.z;
|
|
||||||
}
|
|
||||||
if (Events::pressed(keycode::S) && movement){
|
|
||||||
dir.x -= camera->dir.x;
|
|
||||||
dir.z -= camera->dir.z;
|
|
||||||
}
|
|
||||||
if (Events::pressed(keycode::D) && movement){
|
|
||||||
dir.x += camera->right.x;
|
|
||||||
dir.z += camera->right.z;
|
|
||||||
}
|
|
||||||
if (Events::pressed(keycode::A) && movement){
|
|
||||||
dir.x -= camera->right.x;
|
|
||||||
dir.z -= camera->right.z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hitbox->linear_damping = PLAYER_GROUND_DAMPING;
|
hitbox->linear_damping = PLAYER_GROUND_DAMPING;
|
||||||
if (player->flight){
|
if (player->flight){
|
||||||
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
||||||
hitbox->velocity.y *= 1.0f - delta * 9;
|
hitbox->velocity.y *= 1.0f - delta * 9;
|
||||||
if (Events::pressed(keycode::SPACE) && movement){
|
if (input.jump){
|
||||||
hitbox->velocity.y += speed * delta * 9;
|
hitbox->velocity.y += speed * delta * 9;
|
||||||
}
|
}
|
||||||
if (Events::pressed(keycode::LEFT_SHIFT) && movement){
|
if (input.shift){
|
||||||
hitbox->velocity.y -= speed * delta * 9;
|
hitbox->velocity.y -= speed * delta * 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hitbox->grounded)
|
if (!hitbox->grounded) {
|
||||||
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
hitbox->linear_damping = PLAYER_AIR_DAMPING;
|
||||||
if (length(dir) > 0.0f){
|
|
||||||
dir = normalize(dir);
|
|
||||||
hitbox->velocity.x += dir.x * speed * delta * 9;
|
|
||||||
hitbox->velocity.z += dir.z * speed * delta * 9;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.noclip = false;
|
||||||
|
input.flight = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*camera rotate*/{
|
void PlayerController::updateCameraControl() {
|
||||||
if (Events::_cursor_locked){
|
Camera* camera = player->camera;
|
||||||
float rotX = -Events::deltaX / Window::height * 2;
|
float rotX = -Events::deltaX / Window::height * 2;
|
||||||
float rotY = -Events::deltaY / Window::height * 2;
|
float rotY = -Events::deltaY / Window::height * 2;
|
||||||
if (zoom){
|
if (input.zoom){
|
||||||
rotX /= 4;
|
rotX /= 4;
|
||||||
rotY /= 4;
|
rotY /= 4;
|
||||||
}
|
}
|
||||||
@ -171,10 +203,8 @@ void PlayerController::update_controls(float delta, bool movement){
|
|||||||
camera->rotation = mat4(1.0f);
|
camera->rotation = mat4(1.0f);
|
||||||
camera->rotate(player->camY, player->camX, 0);
|
camera->rotate(player->camY, player->camX, 0);
|
||||||
}
|
}
|
||||||
}//end
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerController::update_interaction(){
|
void PlayerController::updateInteraction(){
|
||||||
Chunks* chunks = level->chunks;
|
Chunks* chunks = level->chunks;
|
||||||
Player* player = level->player;
|
Player* player = level->player;
|
||||||
Lighting* lighting = level->lighting;
|
Lighting* lighting = level->lighting;
|
||||||
@ -193,22 +223,13 @@ void PlayerController::update_interaction(){
|
|||||||
uint8_t states = 0;
|
uint8_t states = 0;
|
||||||
|
|
||||||
if (Block::blocks[player->choosenBlock]->rotatable){
|
if (Block::blocks[player->choosenBlock]->rotatable){
|
||||||
// states = states & 0b11111100;
|
|
||||||
// if (abs(norm.x) > abs(norm.z)){
|
|
||||||
// if (abs(norm.x) > abs(norm.y)) states = states | 0b00000001;
|
|
||||||
// if (abs(norm.x) < abs(norm.y)) states = states | 0b00000010;
|
|
||||||
// }
|
|
||||||
// if (abs(norm.x) < abs(norm.z)){
|
|
||||||
// if (abs(norm.z) > abs(norm.y)) states = states | 0b00000011;
|
|
||||||
// if (abs(norm.z) < abs(norm.y)) states = states | 0b00000010;
|
|
||||||
// }
|
|
||||||
if (abs(norm.x) > abs(norm.z)){
|
if (abs(norm.x) > abs(norm.z)){
|
||||||
if (abs(norm.x) > abs(norm.y)) states = 0x31;
|
if (abs(norm.x) > abs(norm.y)) states = BLOCK_DIR_X;
|
||||||
if (abs(norm.x) < abs(norm.y)) states = 0x32;
|
if (abs(norm.x) < abs(norm.y)) states = BLOCK_DIR_Y;
|
||||||
}
|
}
|
||||||
if (abs(norm.x) < abs(norm.z)){
|
if (abs(norm.x) < abs(norm.z)){
|
||||||
if (abs(norm.z) > abs(norm.y)) states = 0x33;
|
if (abs(norm.z) > abs(norm.y)) states = BLOCK_DIR_Z;
|
||||||
if (abs(norm.z) < abs(norm.y)) states = 0x32;
|
if (abs(norm.z) < abs(norm.y)) states = BLOCK_DIR_Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,19 +3,45 @@
|
|||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "../settings.h"
|
||||||
|
|
||||||
class PhysicsSolver;
|
class PhysicsSolver;
|
||||||
class Chunks;
|
class Chunks;
|
||||||
class Player;
|
class Player;
|
||||||
class Level;
|
class Level;
|
||||||
|
|
||||||
|
struct PlayerInput {
|
||||||
|
bool zoom;
|
||||||
|
bool moveForward;
|
||||||
|
bool moveBack;
|
||||||
|
bool moveRight;
|
||||||
|
bool moveLeft;
|
||||||
|
bool sprint;
|
||||||
|
bool shift;
|
||||||
|
bool cheat;
|
||||||
|
bool jump;
|
||||||
|
bool noclip;
|
||||||
|
bool flight;
|
||||||
|
};
|
||||||
|
|
||||||
class PlayerController {
|
class PlayerController {
|
||||||
Level* level;
|
Level* level;
|
||||||
|
Player* player;
|
||||||
|
|
||||||
|
PlayerInput input;
|
||||||
|
|
||||||
|
const CameraSettings& camSettings;
|
||||||
public:
|
public:
|
||||||
glm::vec3 selectedBlockPosition;
|
glm::vec3 selectedBlockPosition;
|
||||||
|
glm::vec3 cameraOffset {0.0f, 0.7f, 0.0f};
|
||||||
int selectedBlockId = -1;
|
int selectedBlockId = -1;
|
||||||
PlayerController(Level* level);
|
PlayerController(Level* level, const EngineSettings& settings);
|
||||||
void update_controls(float delta, bool movement);
|
void updateKeyboard();
|
||||||
void update_interaction();
|
void resetKeyboard();
|
||||||
|
void updateCameraControl();
|
||||||
|
void updateControls(float delta);
|
||||||
|
void updateInteraction();
|
||||||
|
void refreshCamera();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PLAYER_CONTROL_H_ */
|
#endif /* PLAYER_CONTROL_H_ */
|
||||||
|
|||||||
61
src/settings.cpp
Normal file
61
src/settings.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "files/files.h"
|
||||||
|
#include "coders/json.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::unique_ptr;
|
||||||
|
|
||||||
|
void load_settings(EngineSettings& settings, string filename) {
|
||||||
|
string source = files::read_string(filename);
|
||||||
|
unique_ptr<json::JObject> obj(json::parse(filename, source));
|
||||||
|
{
|
||||||
|
auto& display = settings.display;
|
||||||
|
obj->num("display-width", display.width);
|
||||||
|
obj->num("display-height", display.height);
|
||||||
|
obj->num("display-samples", display.samples);
|
||||||
|
obj->num("display-swap-interval", display.swapInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& chunks = settings.chunks;
|
||||||
|
obj->num("chunks-load-distance", chunks.loadDistance);
|
||||||
|
obj->num("chunks-load-speed", chunks.loadSpeed);
|
||||||
|
obj->num("chunks-padding", chunks.padding);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto& camera = settings.camera;
|
||||||
|
obj->flag("camera-fov-effects", camera.fovEvents);
|
||||||
|
obj->flag("camera-shaking", camera.shaking);
|
||||||
|
}
|
||||||
|
obj->num("fog-curve", settings.fogCurve);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_settings(EngineSettings& settings, string filename) {
|
||||||
|
json::JObject obj;
|
||||||
|
{
|
||||||
|
auto& display = settings.display;
|
||||||
|
obj.put("display-width", display.width);
|
||||||
|
obj.put("display-height", display.height);
|
||||||
|
obj.put("display-samples", display.samples);
|
||||||
|
obj.put("display-swap-interval", display.swapInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& chunks = settings.chunks;
|
||||||
|
obj.put("chunks-load-distance", chunks.loadDistance);
|
||||||
|
obj.put("chunks-load-speed", chunks.loadSpeed);
|
||||||
|
obj.put("chunks-padding", chunks.padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& camera = settings.camera;
|
||||||
|
obj.put("camera-fov-effects", camera.fovEvents);
|
||||||
|
obj.put("camera-shaking", camera.shaking);
|
||||||
|
}
|
||||||
|
obj.put("fog-curve", settings.fogCurve);
|
||||||
|
files::write_string(filename, json::stringify(&obj, true, " "));
|
||||||
|
}
|
||||||
51
src/settings.h
Normal file
51
src/settings.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef SRC_SETTINGS_H_
|
||||||
|
#define SRC_SETTINGS_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "typedefs.h"
|
||||||
|
|
||||||
|
struct DisplaySettings {
|
||||||
|
/* Window width (pixels) */
|
||||||
|
int width = 1280;
|
||||||
|
/* Window height (pixels) */
|
||||||
|
int height = 720;
|
||||||
|
/* Anti-aliasing samples */
|
||||||
|
int samples = 0;
|
||||||
|
/* GLFW swap interval value, 0 - unlimited fps, 1 - vsync*/
|
||||||
|
int swapInterval = 1;
|
||||||
|
/* Window title */
|
||||||
|
const char* title = "VoxelEngine-Cpp v0.13";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChunksSettings {
|
||||||
|
/* Max milliseconds that engine uses for chunks loading only */
|
||||||
|
uint loadSpeed = 10;
|
||||||
|
/* Radius of chunks loading zone (chunk is unit) */
|
||||||
|
uint loadDistance = 22;
|
||||||
|
/* Buffer zone where chunks are not unloading (chunk is unit)*/
|
||||||
|
uint padding = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CameraSettings {
|
||||||
|
/* Camera dynamic field of view effects */
|
||||||
|
bool fovEvents = true;
|
||||||
|
/* Camera movement shake */
|
||||||
|
bool shaking = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EngineSettings {
|
||||||
|
DisplaySettings display;
|
||||||
|
ChunksSettings chunks;
|
||||||
|
CameraSettings camera;
|
||||||
|
|
||||||
|
/* Fog opacity is calculated as `pow(depth*k, fogCurve)` where k depends on chunksLoadDistance.
|
||||||
|
Use values in range [1.0 - 2.0] where 1.0 is linear, 2.0 is quadratic
|
||||||
|
*/
|
||||||
|
float fogCurve = 1.6f;
|
||||||
|
};
|
||||||
|
|
||||||
|
void load_settings(EngineSettings& settings, std::string filename);
|
||||||
|
void save_settings(EngineSettings& settings, std::string filename);
|
||||||
|
|
||||||
|
#endif // SRC_SETTINGS_H_
|
||||||
@ -15,16 +15,6 @@ int main() {
|
|||||||
setup_definitions();
|
setup_definitions();
|
||||||
try {
|
try {
|
||||||
EngineSettings settings;
|
EngineSettings settings;
|
||||||
settings.displayWidth = 1280;
|
|
||||||
settings.displayHeight = 720;
|
|
||||||
settings.displaySamples = 0; // верну мультисемплинг позже
|
|
||||||
settings.displayTitle = "VoxelEngine-Cpp v0.13";
|
|
||||||
settings.chunksLoadSpeed = 10;
|
|
||||||
settings.chunksLoadDistance = 12;
|
|
||||||
settings.chunksPadding = 2;
|
|
||||||
settings.displaySwapInterval = 1;
|
|
||||||
settings.fogCurve = 1.6f;
|
|
||||||
|
|
||||||
std::string settings_file = platform::get_settings_file();
|
std::string settings_file = platform::get_settings_file();
|
||||||
if (std::filesystem::is_regular_file(settings_file)) {
|
if (std::filesystem::is_regular_file(settings_file)) {
|
||||||
std::cout << "-- loading settings" << std::endl;
|
std::cout << "-- loading settings" << std::endl;
|
||||||
|
|||||||
@ -140,7 +140,7 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
|
|||||||
int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 12);
|
int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 12);
|
||||||
if (tree) {
|
if (tree) {
|
||||||
id = tree;
|
id = tree;
|
||||||
states = 0x32;
|
states = BLOCK_DIR_Y;
|
||||||
// } else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 19))){
|
// } else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 19))){
|
||||||
// id = tree;
|
// id = tree;
|
||||||
// } else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 23))){
|
// } else if ((tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 23))){
|
||||||
@ -162,7 +162,7 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
|
|||||||
}
|
}
|
||||||
if ((height > 56) && ((int)(height + 1) == real_y) && ((unsigned short)randomgrass.rand() > 65533)){
|
if ((height > 56) && ((int)(height + 1) == real_y) && ((unsigned short)randomgrass.rand() > 65533)){
|
||||||
id = BLOCK_WOOD;
|
id = BLOCK_WOOD;
|
||||||
states = 0x32;
|
states = BLOCK_DIR_Y;
|
||||||
}
|
}
|
||||||
voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id;
|
voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id;
|
||||||
voxels[(y * CHUNK_D + z) * CHUNK_W + x].states = states;
|
voxels[(y * CHUNK_D + z) * CHUNK_W + x].states = states;
|
||||||
|
|||||||
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
#define BLOCK_DIR_X 0x1
|
||||||
|
#define BLOCK_DIR_Y 0x2
|
||||||
|
#define BLOCK_DIR_Z 0x3
|
||||||
|
|
||||||
struct voxel {
|
struct voxel {
|
||||||
blockid_t id;
|
blockid_t id;
|
||||||
uint8_t states;
|
uint8_t states;
|
||||||
|
|||||||
@ -64,15 +64,18 @@ void character_callback(GLFWwindow* window, unsigned int codepoint){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Window::initialize(uint width, uint height, const char* title, int samples){
|
int Window::initialize(DisplaySettings& settings){
|
||||||
|
Window::width = settings.width;
|
||||||
|
Window::height = settings.height;
|
||||||
|
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
|
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
|
||||||
glfwWindowHint(GLFW_SAMPLES, samples);
|
glfwWindowHint(GLFW_SAMPLES, settings.samples);
|
||||||
|
|
||||||
window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
window = glfwCreateWindow(width, height, settings.title, nullptr, nullptr);
|
||||||
if (window == nullptr){
|
if (window == nullptr){
|
||||||
std::cerr << "Failed to create GLFW Window" << std::endl;
|
std::cerr << "Failed to create GLFW Window" << std::endl;
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
@ -95,15 +98,14 @@ int Window::initialize(uint width, uint height, const char* title, int samples){
|
|||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
Window::width = width;
|
|
||||||
Window::height = height;
|
|
||||||
|
|
||||||
Events::initialize();
|
Events::initialize();
|
||||||
glfwSetKeyCallback(window, key_callback);
|
glfwSetKeyCallback(window, key_callback);
|
||||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
glfwSetCursorPosCallback(window, cursor_position_callback);
|
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||||
glfwSetWindowSizeCallback(window, window_size_callback);
|
glfwSetWindowSizeCallback(window, window_size_callback);
|
||||||
glfwSetCharCallback(window, character_callback);
|
glfwSetCharCallback(window, character_callback);
|
||||||
|
|
||||||
|
glfwSwapInterval(settings.swapInterval);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
#define WINDOW_WINDOW_H_
|
#define WINDOW_WINDOW_H_
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
#include "../settings.h"
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ class Window {
|
|||||||
public:
|
public:
|
||||||
static uint width;
|
static uint width;
|
||||||
static uint height;
|
static uint height;
|
||||||
static int initialize(uint width, uint height, const char* title, int samples);
|
static int initialize(DisplaySettings& settings);
|
||||||
static void terminate();
|
static void terminate();
|
||||||
|
|
||||||
static void viewport(int x, int y, int width, int height);
|
static void viewport(int x, int y, int width, int height);
|
||||||
|
|||||||
@ -11,17 +11,20 @@
|
|||||||
#include "../objects/Player.h"
|
#include "../objects/Player.h"
|
||||||
#include "../objects/player_control.h"
|
#include "../objects/player_control.h"
|
||||||
|
|
||||||
Level::Level(World* world, Player* player, ChunksStorage* chunksStorage, LevelEvents* events, uint loadDistance, uint chunksPadding) :
|
Level::Level(World* world, Player* player, ChunksStorage* chunksStorage, LevelEvents* events, EngineSettings& settings) :
|
||||||
world(world),
|
world(world),
|
||||||
player(player),
|
player(player),
|
||||||
chunksStorage(chunksStorage),
|
chunksStorage(chunksStorage),
|
||||||
events(events) {
|
events(events) {
|
||||||
physics = new PhysicsSolver(vec3(0, -19.6f, 0));
|
physics = new PhysicsSolver(vec3(0, -19.6f, 0));
|
||||||
uint matrixSize = (loadDistance+chunksPadding) * 2;
|
|
||||||
|
uint matrixSize = (settings.chunks.loadDistance+
|
||||||
|
settings.chunks.padding) * 2;
|
||||||
chunks = new Chunks(matrixSize, matrixSize, 0, 0, world->wfile, events);
|
chunks = new Chunks(matrixSize, matrixSize, 0, 0, world->wfile, events);
|
||||||
lighting = new Lighting(chunks);
|
lighting = new Lighting(chunks);
|
||||||
chunksController = new ChunksController(this, chunks, lighting, chunksPadding);
|
chunksController = new ChunksController(this, chunks, lighting, settings.chunks.padding);
|
||||||
playerController = new PlayerController(this);
|
playerController = new PlayerController(this, settings);
|
||||||
|
|
||||||
events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
||||||
this->chunksStorage->remove(chunk->x, chunk->z);
|
this->chunksStorage->remove(chunk->x, chunk->z);
|
||||||
});
|
});
|
||||||
@ -38,16 +41,29 @@ Level::~Level(){
|
|||||||
delete playerController;
|
delete playerController;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::update(float delta, bool updatePlayer, bool interactions) {
|
void Level::updatePlayer(float delta,
|
||||||
if (updatePlayer)
|
bool input,
|
||||||
playerController->update_controls(delta, updatePlayer);
|
bool pause,
|
||||||
if (interactions) {
|
bool interactions) {
|
||||||
playerController->update_interaction();
|
if (!pause) {
|
||||||
|
if (input) {
|
||||||
|
playerController->updateKeyboard();
|
||||||
|
playerController->updateCameraControl();
|
||||||
|
} else {
|
||||||
|
playerController->resetKeyboard();
|
||||||
}
|
}
|
||||||
else
|
playerController->updateControls(delta);
|
||||||
{
|
|
||||||
|
}
|
||||||
|
playerController->refreshCamera();
|
||||||
|
if (interactions) {
|
||||||
|
playerController->updateInteraction();
|
||||||
|
} else {
|
||||||
playerController->selectedBlockId = -1;
|
playerController->selectedBlockId = -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::update() {
|
||||||
vec3 position = player->hitbox->position;
|
vec3 position = player->hitbox->position;
|
||||||
chunks->setCenter(position.x, position.z);
|
chunks->setCenter(position.x, position.z);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#define WORLD_LEVEL_H_
|
#define WORLD_LEVEL_H_
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
#include "../settings.h"
|
||||||
|
|
||||||
class World;
|
class World;
|
||||||
class Player;
|
class Player;
|
||||||
@ -24,15 +25,20 @@ public:
|
|||||||
ChunksController* chunksController;
|
ChunksController* chunksController;
|
||||||
PlayerController* playerController;
|
PlayerController* playerController;
|
||||||
LevelEvents* events;
|
LevelEvents* events;
|
||||||
|
|
||||||
Level(World* world,
|
Level(World* world,
|
||||||
Player* player,
|
Player* player,
|
||||||
ChunksStorage* chunksStorage,
|
ChunksStorage* chunksStorage,
|
||||||
LevelEvents* events,
|
LevelEvents* events,
|
||||||
uint loadDistance,
|
EngineSettings& settings);
|
||||||
uint chunksPadding);
|
|
||||||
~Level();
|
~Level();
|
||||||
|
|
||||||
void update(float delta, bool updatePlayer, bool interactions);
|
void updatePlayer(float delta,
|
||||||
|
bool input,
|
||||||
|
bool pause,
|
||||||
|
bool interactions);
|
||||||
|
|
||||||
|
void update();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* WORLD_LEVEL_H_ */
|
#endif /* WORLD_LEVEL_H_ */
|
||||||
|
|||||||
@ -36,10 +36,10 @@ void World::write(Level* level) {
|
|||||||
wfile->writePlayer(level->player);
|
wfile->writePlayer(level->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
Level* World::loadLevel(Player* player, uint loadDistance, uint chunksPadding) {
|
Level* World::loadLevel(Player* player, EngineSettings& settings) {
|
||||||
ChunksStorage* storage = new ChunksStorage();
|
ChunksStorage* storage = new ChunksStorage();
|
||||||
LevelEvents* events = new LevelEvents();
|
LevelEvents* events = new LevelEvents();
|
||||||
Level* level = new Level(this, player, storage, events, loadDistance, chunksPadding);
|
Level* level = new Level(this, player, storage, events, settings);
|
||||||
wfile->readPlayer(player);
|
wfile->readPlayer(player);
|
||||||
|
|
||||||
Camera* camera = player->camera;
|
Camera* camera = player->camera;
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
#include "../settings.h"
|
||||||
|
|
||||||
class WorldFiles;
|
class WorldFiles;
|
||||||
class Chunks;
|
class Chunks;
|
||||||
@ -19,7 +20,7 @@ public:
|
|||||||
~World();
|
~World();
|
||||||
|
|
||||||
void write(Level* level);
|
void write(Level* level);
|
||||||
Level* loadLevel(Player* player, uint loadDistance, uint chunksPadding);
|
Level* loadLevel(Player* player, EngineSettings& settings);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* WORLD_WORLD_H_ */
|
#endif /* WORLD_WORLD_H_ */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user