-
-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added pause menu, new F3 debug panel, fogCurve setting
- Loading branch information
Showing
28 changed files
with
1,267 additions
and
324 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
#include "engine.h" | ||
|
||
#include <memory> | ||
#include <iostream> | ||
#include <glm/glm.hpp> | ||
|
||
#include "audio/Audio.h" | ||
#include "assets/Assets.h" | ||
#include "assets/AssetsLoader.h" | ||
#include "window/Window.h" | ||
#include "window/Events.h" | ||
#include "window/Camera.h" | ||
#include "window/input.h" | ||
#include "graphics/Batch2D.h" | ||
#include "world/World.h" | ||
#include "world/Level.h" | ||
#include "voxels/Chunk.h" | ||
#include "voxels/Chunks.h" | ||
#include "voxels/ChunksController.h" | ||
#include "voxels/ChunksStorage.h" | ||
#include "objects/Player.h" | ||
#include "frontend/world_render.h" | ||
#include "frontend/hud.h" | ||
#include "frontend/gui/GUI.h" | ||
|
||
#include "coders/json.h" | ||
#include "files/files.h" | ||
|
||
using std::shared_ptr; | ||
using glm::vec3; | ||
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) { | ||
this->settings = settings; | ||
|
||
Window::initialize(settings.displayWidth, | ||
settings.displayHeight, | ||
settings.displayTitle, | ||
settings.displaySamples); | ||
Window::swapInterval(settings.displaySwapInterval); | ||
|
||
assets = new Assets(); | ||
std::cout << "-- loading assets" << std::endl; | ||
AssetsLoader loader(assets); | ||
AssetsLoader::createDefaults(loader); | ||
AssetsLoader::addDefaults(loader); | ||
while (loader.hasNext()) { | ||
if (!loader.loadNext()) { | ||
delete assets; | ||
Window::terminate(); | ||
throw initialize_error("could not to initialize assets"); | ||
} | ||
} | ||
std::cout << "-- loading world" << std::endl; | ||
vec3 playerPosition = vec3(0, 64, 0); | ||
Camera* camera = new Camera(playerPosition, radians(90.0f)); | ||
World* world = new World("world-1", "world/", 42); | ||
Player* player = new Player(playerPosition, 4.0f, camera); | ||
level = world->loadLevel(player, settings.chunksLoadDistance, settings.chunksPadding); | ||
|
||
std::cout << "-- initializing finished" << std::endl; | ||
|
||
Audio::initialize(); | ||
|
||
gui = new GUI(); | ||
} | ||
|
||
void Engine::updateTimers() { | ||
frame++; | ||
double currentTime = Window::time(); | ||
delta = currentTime - lastTime; | ||
lastTime = currentTime; | ||
} | ||
|
||
void Engine::updateHotkeys() { | ||
if (Events::jpressed(keycode::O)) { | ||
occlusion = !occlusion; | ||
} | ||
if (Events::jpressed(keycode::F3)) { | ||
level->player->debug = !level->player->debug; | ||
} | ||
if (Events::jpressed(keycode::F5)) { | ||
for (uint i = 0; i < level->chunks->volume; i++) { | ||
shared_ptr<Chunk> chunk = level->chunks->chunks[i]; | ||
if (chunk != nullptr && chunk->isReady()) { | ||
chunk->setModified(true); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void Engine::mainloop() { | ||
Camera* camera = level->player->camera; | ||
std::cout << "-- preparing systems" << std::endl; | ||
WorldRenderer worldRenderer(level, assets); | ||
HudRenderer hud(gui, level, assets); | ||
Batch2D batch(1024); | ||
lastTime = Window::time(); | ||
|
||
while (!Window::isShouldClose()){ | ||
updateTimers(); | ||
updateHotkeys(); | ||
|
||
level->update(delta, Events::_cursor_locked, Events::_cursor_locked); | ||
level->chunksController->update(settings.chunksLoadSpeed); | ||
|
||
worldRenderer.draw(camera, occlusion, 1.6f / (float)settings.chunksLoadDistance, settings.fogCurve); | ||
hud.draw(); | ||
if (level->player->debug) { | ||
hud.drawDebug( 1 / delta, occlusion); | ||
} | ||
gui->act(); | ||
gui->draw(&batch, assets); | ||
|
||
Window::swapBuffers(); | ||
Events::pullEvents(); | ||
} | ||
} | ||
|
||
Engine::~Engine() { | ||
Audio::finalize(); | ||
|
||
World* world = level->world; | ||
|
||
std::cout << "-- saving world" << std::endl; | ||
world->write(level); | ||
|
||
delete level; | ||
delete world; | ||
|
||
std::cout << "-- shutting down" << std::endl; | ||
delete assets; | ||
Window::terminate(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#ifndef SRC_ENGINE_H_ | ||
#define SRC_ENGINE_H_ | ||
|
||
#include <string> | ||
#include <memory> | ||
#include <stdexcept> | ||
#include "typedefs.h" | ||
|
||
class Assets; | ||
class Level; | ||
|
||
namespace 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 { | ||
public: | ||
initialize_error(const std::string& message) : std::runtime_error(message) {} | ||
}; | ||
|
||
class Engine { | ||
Assets* assets; | ||
Level* level; | ||
EngineSettings settings; | ||
|
||
uint64_t frame = 0; | ||
double lastTime = 0.0; | ||
double delta = 0.0; | ||
bool occlusion = true; | ||
|
||
gui::GUI* gui; | ||
public: | ||
Engine(const EngineSettings& settings); | ||
~Engine(); | ||
|
||
void updateTimers(); | ||
void updateHotkeys(); | ||
void mainloop(); | ||
}; | ||
|
||
#endif // SRC_ENGINE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include "GUI.h" | ||
#include "UINode.h" | ||
#include "panels.h" | ||
|
||
#include <iostream> | ||
|
||
#include "../../assets/Assets.h" | ||
#include "../../graphics/Batch2D.h" | ||
#include "../../window/Events.h" | ||
#include "../../window/input.h" | ||
|
||
using std::shared_ptr; | ||
using namespace gui; | ||
|
||
GUI::GUI() { | ||
container = new Container(vec2(0, 0), vec2(Window::width, Window::height)); | ||
} | ||
|
||
GUI::~GUI() { | ||
delete container; | ||
} | ||
|
||
void GUI::act() { | ||
container->size(vec2(Window::width, Window::height)); | ||
int mx = Events::x; | ||
int my = Events::y; | ||
|
||
auto hover = container->getAt(vec2(mx, my), nullptr); | ||
if (this->hover && this->hover != hover) { | ||
this->hover->hover(false); | ||
} | ||
if (hover) { | ||
hover->hover(true); | ||
} | ||
this->hover = hover; | ||
|
||
if (Events::clicked(0)) { | ||
if (pressed == nullptr && this->hover) { | ||
pressed = hover; | ||
pressed->click(this, mx, my); | ||
if (focus) { | ||
focus->defocus(); | ||
} | ||
focus = pressed; | ||
} | ||
if (this->hover == nullptr && focus) { | ||
focus->defocus(); | ||
focus = nullptr; | ||
} | ||
} else if (pressed) { | ||
pressed->mouseRelease(this, mx, my); | ||
pressed = nullptr; | ||
} | ||
if (focus) { | ||
if (!focus->isfocused()){ | ||
focus = nullptr; | ||
} else if (Events::jpressed(keycode::ESCAPE)) { | ||
focus->defocus(); | ||
focus = nullptr; | ||
} else { | ||
for (auto codepoint : Events::codepoints) { | ||
focus->typed(codepoint); | ||
} | ||
for (auto key : Events::pressedKeys) { | ||
focus->keyPressed(key); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void GUI::draw(Batch2D* batch, Assets* assets) { | ||
container->draw(batch, assets); | ||
} | ||
|
||
shared_ptr<UINode> GUI::getFocused() const { | ||
return focus; | ||
} | ||
|
||
bool GUI::isFocusCaught() const { | ||
return focus && focus->isfocuskeeper(); | ||
} | ||
|
||
void GUI::add(shared_ptr<UINode> panel) { | ||
container->add(panel); | ||
} |
Oops, something went wrong.