Added pause menu, new F3 debug panel, fogCurve setting
This commit is contained in:
parent
b9ed7a2b28
commit
e48e41c99a
@ -8,6 +8,7 @@ out vec4 f_color;
|
|||||||
uniform sampler2D u_texture0;
|
uniform sampler2D u_texture0;
|
||||||
uniform vec3 u_fogColor;
|
uniform vec3 u_fogColor;
|
||||||
uniform float u_fogFactor;
|
uniform float u_fogFactor;
|
||||||
|
uniform float u_fogCurve;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec4 tex_color = texture(u_texture0, a_texCoord);
|
vec4 tex_color = texture(u_texture0, a_texCoord);
|
||||||
@ -16,6 +17,6 @@ void main(){
|
|||||||
// anyway it's any alpha-test alternative required
|
// anyway it's any alpha-test alternative required
|
||||||
if (alpha < 0.1f)
|
if (alpha < 0.1f)
|
||||||
discard;
|
discard;
|
||||||
f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, depth*u_fogFactor));
|
f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, pow(depth*u_fogFactor, u_fogCurve)));
|
||||||
f_color.a = alpha;
|
f_color.a = alpha;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,7 @@ void setup_definitions() {
|
|||||||
block->lightPassing = true;
|
block->lightPassing = true;
|
||||||
block->obstacle = false;
|
block->obstacle = false;
|
||||||
block->model = 2;
|
block->model = 2;
|
||||||
|
block->hitboxScale = 0.5f;
|
||||||
Block::blocks[block->id] = block;
|
Block::blocks[block->id] = block;
|
||||||
|
|
||||||
block = new Block(BLOCK_FLOWER, 16);
|
block = new Block(BLOCK_FLOWER, 16);
|
||||||
|
|||||||
160
src/engine.cpp
Normal file
160
src/engine.cpp
Normal file
@ -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();
|
||||||
|
}
|
||||||
67
src/engine.h
Normal file
67
src/engine.h
Normal file
@ -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_
|
||||||
85
src/frontend/gui/GUI.cpp
Normal file
85
src/frontend/gui/GUI.cpp
Normal file
@ -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);
|
||||||
|
}
|
||||||
64
src/frontend/gui/GUI.h
Normal file
64
src/frontend/gui/GUI.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef FRONTEND_GUI_GUI_H_
|
||||||
|
#define FRONTEND_GUI_GUI_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Batch2D;
|
||||||
|
class Assets;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some info about padding and margin.
|
||||||
|
Padding is element inner space, margin is outer
|
||||||
|
glm::vec4 usage:
|
||||||
|
x - left
|
||||||
|
y - top
|
||||||
|
z - right
|
||||||
|
w - bottom
|
||||||
|
|
||||||
|
Outer element
|
||||||
|
+======================================================================+
|
||||||
|
| . . . . |
|
||||||
|
| .padding.y . . . |
|
||||||
|
| padding.x . . . . padding.z |
|
||||||
|
|- - - - - - + - - - - - + - - - - - - - - - -+- - - - - + - - - - - - |
|
||||||
|
| . . . . |
|
||||||
|
| . .margin.y . . |
|
||||||
|
| .margin.x . . margin.z. |
|
||||||
|
|- - - - - - + - - - - - +====================+- - - - - + - - - - - - |
|
||||||
|
| . | Inner element | . |
|
||||||
|
|- - - - - - + - - - - - +====================+- - - - - + - - - - - - |
|
||||||
|
| . . . . |
|
||||||
|
| . .margin.w . . |
|
||||||
|
| . . . . |
|
||||||
|
|- - - - - - + - - - - - + - - - - - - - - - -+- - - - - + - - - - - - |
|
||||||
|
| . . . . |
|
||||||
|
| .padding.w . . . |
|
||||||
|
| . . . . |
|
||||||
|
+======================================================================+
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class UINode;
|
||||||
|
class Container;
|
||||||
|
|
||||||
|
class GUI {
|
||||||
|
Container* container;
|
||||||
|
std::shared_ptr<UINode> hover = nullptr;
|
||||||
|
std::shared_ptr<UINode> pressed = nullptr;
|
||||||
|
std::shared_ptr<UINode> focus = nullptr;
|
||||||
|
public:
|
||||||
|
GUI();
|
||||||
|
~GUI();
|
||||||
|
|
||||||
|
std::shared_ptr<UINode> getFocused() const;
|
||||||
|
bool isFocusCaught() const;
|
||||||
|
|
||||||
|
void act();
|
||||||
|
void draw(Batch2D* batch, Assets* assets);
|
||||||
|
void add(std::shared_ptr<UINode> panel);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRONTEND_GUI_GUI_H_
|
||||||
24
src/frontend/gui/Panel.cpp
Normal file
24
src/frontend/gui/Panel.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
24
src/frontend/gui/Panel.h
Normal file
24
src/frontend/gui/Panel.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#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_
|
||||||
134
src/frontend/gui/UINode.cpp
Normal file
134
src/frontend/gui/UINode.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "UINode.h"
|
||||||
|
|
||||||
|
#include "../../graphics/Batch2D.h"
|
||||||
|
|
||||||
|
using std::shared_ptr;
|
||||||
|
|
||||||
|
using gui::UINode;
|
||||||
|
using gui::Align;
|
||||||
|
|
||||||
|
using glm::vec2;
|
||||||
|
using glm::vec4;
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
UINode::UINode(vec2 coord, vec2 size) : coord(coord), size_(size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
UINode::~UINode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UINode::visible() const {
|
||||||
|
return isvisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::visible(bool flag) {
|
||||||
|
isvisible = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
Align UINode::align() const {
|
||||||
|
return align_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::align(Align align) {
|
||||||
|
align_ = align;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::hover(bool flag) {
|
||||||
|
hover_ = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UINode::hover() const {
|
||||||
|
return hover_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::setParent(UINode* node) {
|
||||||
|
parent = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINode* UINode::getParent() const {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::click(GUI*, int x, int y) {
|
||||||
|
pressed_ = true;
|
||||||
|
focused_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::mouseRelease(GUI*, int x, int y) {
|
||||||
|
pressed_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UINode::ispressed() const {
|
||||||
|
return pressed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::defocus() {
|
||||||
|
focused_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UINode::isfocused() const {
|
||||||
|
return focused_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UINode::isInside(glm::vec2 pos) {
|
||||||
|
vec2 coord = calcCoord();
|
||||||
|
vec2 size = this->size();
|
||||||
|
return (pos.x >= coord.x && pos.y >= coord.y &&
|
||||||
|
pos.x < coord.x + size.x && pos.y < coord.y + size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<UINode> UINode::getAt(vec2 pos, shared_ptr<UINode> self) {
|
||||||
|
return isInside(pos) ? self : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 UINode::calcCoord() const {
|
||||||
|
if (parent) {
|
||||||
|
return coord + parent->calcCoord();
|
||||||
|
}
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::setCoord(vec2 coord) {
|
||||||
|
this->coord = coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 UINode::size() const {
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::size(vec2 size) {
|
||||||
|
if (sizelock)
|
||||||
|
return;
|
||||||
|
this->size_ = size;
|
||||||
|
if (parent) {
|
||||||
|
sizelock = true;
|
||||||
|
parent->refresh();
|
||||||
|
sizelock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::_size(vec2 size) {
|
||||||
|
if (sizelock)
|
||||||
|
return;
|
||||||
|
this->size_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::color(vec4 color) {
|
||||||
|
this->color_ = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 UINode::color() const {
|
||||||
|
return color_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::margin(vec4 margin) {
|
||||||
|
this->margin_ = margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 UINode::margin() const {
|
||||||
|
return margin_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UINode::lock() {
|
||||||
|
}
|
||||||
82
src/frontend/gui/UINode.h
Normal file
82
src/frontend/gui/UINode.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#ifndef FRONTEND_GUI_UINODE_H_
|
||||||
|
#define FRONTEND_GUI_UINODE_H_
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class Batch2D;
|
||||||
|
class Assets;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class UINode;
|
||||||
|
class GUI;
|
||||||
|
|
||||||
|
typedef std::function<void(GUI*)> onaction;
|
||||||
|
typedef std::function<void(GUI*, double)> onnumberchange;
|
||||||
|
|
||||||
|
enum class Align {
|
||||||
|
left, center, right
|
||||||
|
};
|
||||||
|
class UINode {
|
||||||
|
protected:
|
||||||
|
glm::vec2 coord;
|
||||||
|
glm::vec2 size_;
|
||||||
|
glm::vec4 color_ {1.0f};
|
||||||
|
glm::vec4 margin_ {1.0f};
|
||||||
|
bool isvisible = true;
|
||||||
|
bool sizelock = false;
|
||||||
|
bool hover_ = false;
|
||||||
|
bool pressed_ = false;
|
||||||
|
bool focused_ = false;
|
||||||
|
Align align_ = Align::left;
|
||||||
|
UINode* parent = nullptr;
|
||||||
|
UINode(glm::vec2 coord, glm::vec2 size);
|
||||||
|
public:
|
||||||
|
virtual ~UINode();
|
||||||
|
virtual void draw(Batch2D* batch, Assets* assets) = 0;
|
||||||
|
|
||||||
|
virtual void visible(bool flag);
|
||||||
|
bool visible() const;
|
||||||
|
|
||||||
|
virtual void align(Align align);
|
||||||
|
Align align() const;
|
||||||
|
|
||||||
|
virtual void hover(bool flag);
|
||||||
|
bool hover() const;
|
||||||
|
|
||||||
|
virtual void setParent(UINode* node);
|
||||||
|
UINode* getParent() const;
|
||||||
|
|
||||||
|
virtual void color(glm::vec4 newColor);
|
||||||
|
glm::vec4 color() const;
|
||||||
|
|
||||||
|
virtual void margin(glm::vec4 margin);
|
||||||
|
glm::vec4 margin() const;
|
||||||
|
|
||||||
|
virtual void click(GUI*, int x, int y);
|
||||||
|
virtual void mouseRelease(GUI*, int x, int y);
|
||||||
|
|
||||||
|
bool ispressed() const;
|
||||||
|
void defocus();
|
||||||
|
bool isfocused() const;
|
||||||
|
virtual bool isfocuskeeper() const {return false;}
|
||||||
|
|
||||||
|
virtual void typed(unsigned int codepoint) {};
|
||||||
|
virtual void keyPressed(int key) {};
|
||||||
|
|
||||||
|
virtual bool isInside(glm::vec2 pos);
|
||||||
|
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self);
|
||||||
|
|
||||||
|
glm::vec2 calcCoord() const;
|
||||||
|
void setCoord(glm::vec2 coord);
|
||||||
|
glm::vec2 size() const;
|
||||||
|
virtual void size(glm::vec2 size);
|
||||||
|
void _size(glm::vec2 size);
|
||||||
|
virtual void refresh() {};
|
||||||
|
virtual void lock();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRONTEND_GUI_UINODE_H_
|
||||||
133
src/frontend/gui/controls.cpp
Normal file
133
src/frontend/gui/controls.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#include "controls.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "../../assets/Assets.h"
|
||||||
|
#include "../../graphics/Batch2D.h"
|
||||||
|
#include "../../graphics/Font.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::wstring;
|
||||||
|
using std::shared_ptr;
|
||||||
|
using glm::vec2;
|
||||||
|
|
||||||
|
#define KEY_ESCAPE 256
|
||||||
|
#define KEY_ENTER 257
|
||||||
|
#define KEY_BACKSPACE 259
|
||||||
|
|
||||||
|
using namespace gui;
|
||||||
|
|
||||||
|
Label::Label(wstring text, string fontName)
|
||||||
|
: UINode(vec2(), vec2(text.length() * 8, 15)), text_(text), fontName_(fontName) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Label& Label::text(wstring text) {
|
||||||
|
this->text_ = text;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
wstring Label::text() const {
|
||||||
|
return text_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::draw(Batch2D* batch, Assets* assets) {
|
||||||
|
if (supplier) {
|
||||||
|
text(supplier());
|
||||||
|
}
|
||||||
|
batch->color = color_;
|
||||||
|
Font* font = assets->getFont(fontName_);
|
||||||
|
vec2 size = this->size();
|
||||||
|
vec2 newsize = vec2(font->calcWidth(text_), font->lineHeight());
|
||||||
|
if (newsize.x > size.x) {
|
||||||
|
this->size(newsize);
|
||||||
|
size = newsize;
|
||||||
|
}
|
||||||
|
vec2 coord = calcCoord();
|
||||||
|
font->draw(batch, text_, coord.x, coord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::textSupplier(wstringsupplier supplier) {
|
||||||
|
this->supplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
Button::Button(shared_ptr<UINode> content, glm::vec4 padding) : Panel(vec2(32,32), padding, 0) {
|
||||||
|
add(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
Button::Button(wstring text, glm::vec4 padding) : Panel(vec2(32,32), padding, 0) {
|
||||||
|
Label* label = new Label(text);
|
||||||
|
label->align(Align::center);
|
||||||
|
add(shared_ptr<UINode>(label));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::drawBackground(Batch2D* batch, Assets* assets) {
|
||||||
|
vec2 coord = calcCoord();
|
||||||
|
batch->texture(nullptr);
|
||||||
|
batch->color = (ispressed() ? pressedColor : (hover_ ? hoverColor : color_));
|
||||||
|
batch->rect(coord.x, coord.y, size_.x, size_.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<UINode> Button::getAt(vec2 pos, shared_ptr<UINode> self) {
|
||||||
|
return UINode::getAt(pos, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::mouseRelease(GUI* gui, int x, int y) {
|
||||||
|
UINode::mouseRelease(gui, x, y);
|
||||||
|
if (isInside(vec2(x, y))) {
|
||||||
|
for (auto callback : actions) {
|
||||||
|
callback(gui);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::listenAction(onaction action) {
|
||||||
|
actions.push_back(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBox::TextBox(wstring text, vec4 padding) : Panel(vec2(200,32), padding, 0, false) {
|
||||||
|
label = new Label(text);
|
||||||
|
label->align(Align::center);
|
||||||
|
add(shared_ptr<UINode>(label));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::drawBackground(Batch2D* batch, Assets* assets) {
|
||||||
|
vec2 coord = calcCoord();
|
||||||
|
batch->texture(nullptr);
|
||||||
|
batch->color = (isfocused() ? focusedColor : (hover_ ? hoverColor : color_));
|
||||||
|
batch->rect(coord.x, coord.y, size_.x, size_.y);
|
||||||
|
if (!focused_ && supplier) {
|
||||||
|
label->text(supplier());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::typed(unsigned int codepoint) {
|
||||||
|
label->text(label->text() + wstring({(wchar_t)codepoint}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::keyPressed(int key) {
|
||||||
|
wstring src = label->text();
|
||||||
|
switch (key) {
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
if (src.length())
|
||||||
|
label->text(src.substr(0, src.length()-1));
|
||||||
|
break;
|
||||||
|
case KEY_ENTER:
|
||||||
|
if (consumer) {
|
||||||
|
consumer(label->text());
|
||||||
|
}
|
||||||
|
defocus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<UINode> TextBox::getAt(vec2 pos, shared_ptr<UINode> self) {
|
||||||
|
return UINode::getAt(pos, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::textSupplier(wstringsupplier supplier) {
|
||||||
|
this->supplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextBox::textConsumer(wstringconsumer consumer) {
|
||||||
|
this->consumer = consumer;
|
||||||
|
}
|
||||||
72
src/frontend/gui/controls.h
Normal file
72
src/frontend/gui/controls.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#ifndef FRONTEND_GUI_CONTROLS_H_
|
||||||
|
#define FRONTEND_GUI_CONTROLS_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "UINode.h"
|
||||||
|
#include "panels.h"
|
||||||
|
|
||||||
|
class Batch2D;
|
||||||
|
class Assets;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
typedef std::function<std::wstring()> wstringsupplier;
|
||||||
|
typedef std::function<void(std::wstring)> wstringconsumer;
|
||||||
|
|
||||||
|
class Label : public UINode {
|
||||||
|
protected:
|
||||||
|
std::wstring text_;
|
||||||
|
std::string fontName_;
|
||||||
|
wstringsupplier supplier = nullptr;
|
||||||
|
public:
|
||||||
|
Label(std::wstring text, std::string fontName="normal");
|
||||||
|
|
||||||
|
virtual Label& text(std::wstring text);
|
||||||
|
std::wstring text() const;
|
||||||
|
|
||||||
|
virtual void draw(Batch2D* batch, Assets* assets);
|
||||||
|
|
||||||
|
virtual void textSupplier(wstringsupplier supplier);
|
||||||
|
};
|
||||||
|
class Button : public Panel {
|
||||||
|
protected:
|
||||||
|
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
|
||||||
|
glm::vec4 pressedColor {0.0f, 0.0f, 0.0f, 0.95f};
|
||||||
|
std::vector<onaction> actions;
|
||||||
|
public:
|
||||||
|
Button(std::shared_ptr<UINode> content, glm::vec4 padding=glm::vec4(2.0f));
|
||||||
|
Button(std::wstring text, glm::vec4 padding=glm::vec4(2.0f));
|
||||||
|
|
||||||
|
virtual void drawBackground(Batch2D* batch, Assets* assets);
|
||||||
|
|
||||||
|
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
||||||
|
|
||||||
|
virtual void mouseRelease(GUI*, int x, int y) override;
|
||||||
|
virtual void listenAction(onaction action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextBox : public Panel {
|
||||||
|
protected:
|
||||||
|
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
|
||||||
|
glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
Label* label;
|
||||||
|
wstringsupplier supplier = nullptr;
|
||||||
|
wstringconsumer consumer = nullptr;
|
||||||
|
public:
|
||||||
|
TextBox(std::wstring text, glm::vec4 padding=glm::vec4(2.0f));
|
||||||
|
|
||||||
|
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
||||||
|
|
||||||
|
virtual void drawBackground(Batch2D* batch, Assets* assets) override;
|
||||||
|
virtual void typed(unsigned int codepoint) override;
|
||||||
|
virtual void keyPressed(int key) override;
|
||||||
|
virtual void textSupplier(wstringsupplier supplier);
|
||||||
|
virtual void textConsumer(wstringconsumer consumer);
|
||||||
|
virtual bool isfocuskeeper() const override {return true;}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FRONTEND_GUI_CONTROLS_H_
|
||||||
130
src/frontend/gui/panels.cpp
Normal file
130
src/frontend/gui/panels.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include "panels.h"
|
||||||
|
|
||||||
|
#include "../../window/Window.h"
|
||||||
|
#include "../../assets/Assets.h"
|
||||||
|
#include "../../graphics/Batch2D.h"
|
||||||
|
|
||||||
|
using std::shared_ptr;
|
||||||
|
|
||||||
|
using gui::UINode;
|
||||||
|
using gui::Container;
|
||||||
|
using gui::Panel;
|
||||||
|
using gui::Orientation;
|
||||||
|
|
||||||
|
using glm::vec2;
|
||||||
|
using glm::vec4;
|
||||||
|
|
||||||
|
Container::Container(vec2 coord, vec2 size) : UINode(coord, size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<UINode> Container::getAt(vec2 pos, shared_ptr<UINode> self) {
|
||||||
|
for (auto node : nodes) {
|
||||||
|
if (!node->visible())
|
||||||
|
continue;
|
||||||
|
auto hover = node->getAt(pos, node);
|
||||||
|
if (hover != nullptr) {
|
||||||
|
return hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UINode::getAt(pos, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Container::draw(Batch2D* batch, Assets* assets) {
|
||||||
|
vec2 coord = calcCoord();
|
||||||
|
vec2 size = this->size();
|
||||||
|
drawBackground(batch, assets);
|
||||||
|
batch->texture(nullptr);
|
||||||
|
batch->render();
|
||||||
|
Window::pushScissor(vec4(coord.x, coord.y, size.x, size.y));
|
||||||
|
for (auto node : nodes) {
|
||||||
|
if (node->visible())
|
||||||
|
node->draw(batch, assets);
|
||||||
|
}
|
||||||
|
batch->render();
|
||||||
|
Window::popScissor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Container::add(shared_ptr<UINode> node) {
|
||||||
|
nodes.push_back(node);
|
||||||
|
node->setParent(this);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel::Panel(vec2 size, glm::vec4 padding, float interval, bool resizing)
|
||||||
|
: Container(vec2(), size), padding(padding), interval(interval), resizing_(resizing) {
|
||||||
|
color_ = vec4(0.0f, 0.0f, 0.0f, 0.75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel::~Panel() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::drawBackground(Batch2D* batch, Assets* assets) {
|
||||||
|
vec2 coord = calcCoord();
|
||||||
|
batch->texture(nullptr);
|
||||||
|
batch->color = color_;
|
||||||
|
batch->rect(coord.x, coord.y, size_.x, size_.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::refresh() {
|
||||||
|
float x = padding.x;
|
||||||
|
float y = padding.y;
|
||||||
|
vec2 size = this->size();
|
||||||
|
if (orientation_ == Orientation::vertical) {
|
||||||
|
float maxw = size.x;
|
||||||
|
for (auto node : nodes) {
|
||||||
|
vec2 nodesize = node->size();
|
||||||
|
const vec4 margin = node->margin();
|
||||||
|
y += margin.y;
|
||||||
|
|
||||||
|
float ex;
|
||||||
|
|
||||||
|
switch (node->align()) {
|
||||||
|
case Align::center:
|
||||||
|
ex = x + fmax(0.0f, (size.x - margin.z - padding.z) - node->size().x) / 2.0f;
|
||||||
|
break;
|
||||||
|
case Align::right:
|
||||||
|
ex = x + size.x - margin.z - padding.z - node->size().x;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ex = x + margin.x;
|
||||||
|
}
|
||||||
|
node->setCoord(vec2(ex, y));
|
||||||
|
y += nodesize.y + margin.w + interval;
|
||||||
|
node->size(vec2(size.x - padding.x - padding.z - margin.x - margin.z, nodesize.y));
|
||||||
|
maxw = fmax(maxw, ex+node->size().x+margin.z+padding.z);
|
||||||
|
}
|
||||||
|
if (resizing_)
|
||||||
|
this->size(vec2(maxw, y+padding.w));
|
||||||
|
} else {
|
||||||
|
float maxh = size.y;
|
||||||
|
for (auto node : nodes) {
|
||||||
|
vec2 nodesize = node->size();
|
||||||
|
const vec4 margin = node->margin();
|
||||||
|
x += margin.x;
|
||||||
|
node->setCoord(vec2(x, y+margin.y));
|
||||||
|
x += nodesize.x + margin.z + interval;
|
||||||
|
node->size(vec2(nodesize.x, size.y - padding.y - padding.w - margin.y - margin.w));
|
||||||
|
maxh = fmax(maxh, y+margin.y+node->size().y+margin.w+padding.w);
|
||||||
|
}
|
||||||
|
bool increased = maxh > size.y;
|
||||||
|
if (resizing_)
|
||||||
|
this->size(vec2(x+padding.z, maxh));
|
||||||
|
if (increased)
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::orientation(Orientation orientation) {
|
||||||
|
this->orientation_ = orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Orientation Panel::orientation() const {
|
||||||
|
return orientation_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::lock(){
|
||||||
|
for (auto node : nodes) {
|
||||||
|
node->lock();
|
||||||
|
}
|
||||||
|
resizing_ = false;
|
||||||
|
}
|
||||||
46
src/frontend/gui/panels.h
Normal file
46
src/frontend/gui/panels.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef FRONTEND_GUI_PANELS_H_
|
||||||
|
#define FRONTEND_GUI_PANELS_H_
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include "UINode.h"
|
||||||
|
|
||||||
|
class Batch2D;
|
||||||
|
class Assets;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
enum class Orientation { vertical, horizontal };
|
||||||
|
|
||||||
|
class Container : public UINode {
|
||||||
|
protected:
|
||||||
|
std::vector<std::shared_ptr<UINode>> nodes;
|
||||||
|
public:
|
||||||
|
Container(glm::vec2 coord, glm::vec2 size);
|
||||||
|
|
||||||
|
virtual void drawBackground(Batch2D* batch, Assets* assets) {};
|
||||||
|
virtual void draw(Batch2D* batch, Assets* assets);
|
||||||
|
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
||||||
|
virtual void add(std::shared_ptr<UINode> node);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Panel : public Container {
|
||||||
|
protected:
|
||||||
|
Orientation orientation_ = Orientation::vertical;
|
||||||
|
glm::vec4 padding {2.0f};
|
||||||
|
float interval = 2.0f;
|
||||||
|
bool resizing_;
|
||||||
|
public:
|
||||||
|
Panel(glm::vec2 size, glm::vec4 padding=glm::vec4(2.0f), float interval=2.0f, bool resizing=true);
|
||||||
|
virtual ~Panel();
|
||||||
|
|
||||||
|
virtual void drawBackground(Batch2D* batch, Assets* assets) override;
|
||||||
|
|
||||||
|
virtual void orientation(Orientation orientation);
|
||||||
|
Orientation orientation() const;
|
||||||
|
|
||||||
|
virtual void refresh() override;
|
||||||
|
virtual void lock() override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // FRONTEND_GUI_PANELS_H_
|
||||||
@ -1,10 +1,14 @@
|
|||||||
#include "hud_render.h"
|
#include "hud.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
#include "../util/stringutil.h"
|
||||||
#include "../assets/Assets.h"
|
#include "../assets/Assets.h"
|
||||||
#include "../graphics/Shader.h"
|
#include "../graphics/Shader.h"
|
||||||
#include "../graphics/Batch2D.h"
|
#include "../graphics/Batch2D.h"
|
||||||
@ -13,59 +17,132 @@
|
|||||||
#include "../window/Camera.h"
|
#include "../window/Camera.h"
|
||||||
#include "../window/Window.h"
|
#include "../window/Window.h"
|
||||||
#include "../window/Events.h"
|
#include "../window/Events.h"
|
||||||
|
#include "../window/input.h"
|
||||||
#include "../voxels/Chunks.h"
|
#include "../voxels/Chunks.h"
|
||||||
#include "../voxels/Block.h"
|
#include "../voxels/Block.h"
|
||||||
#include "../world/World.h"
|
#include "../world/World.h"
|
||||||
#include "../world/Level.h"
|
#include "../world/Level.h"
|
||||||
#include "../objects/Player.h"
|
#include "../objects/Player.h"
|
||||||
|
#include "../physics/Hitbox.h"
|
||||||
|
#include "gui/controls.h"
|
||||||
|
#include "gui/panels.h"
|
||||||
|
#include "gui/UINode.h"
|
||||||
|
#include "gui/GUI.h"
|
||||||
|
|
||||||
|
using std::wstring;
|
||||||
|
using std::shared_ptr;
|
||||||
|
using glm::vec2;
|
||||||
|
using glm::vec3;
|
||||||
|
using glm::vec4;
|
||||||
|
using gui::GUI;
|
||||||
|
using gui::UINode;
|
||||||
|
using gui::Panel;
|
||||||
|
using gui::Label;
|
||||||
|
using gui::Button;
|
||||||
|
using gui::TextBox;
|
||||||
|
|
||||||
HudRenderer::HudRenderer(Assets* assets) : assets(assets) {
|
inline Label* create_label(gui::wstringsupplier supplier) {
|
||||||
|
Label* label = new Label(L"-");
|
||||||
|
label->textSupplier(supplier);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(glm::vec3(), Window::height);
|
||||||
uicamera->perspective = false;
|
uicamera->perspective = false;
|
||||||
uicamera->flipped = true;
|
uicamera->flipped = true;
|
||||||
|
|
||||||
|
Panel* panel = new Panel(vec2(200, 200), vec4(5.0f), 1.0f);
|
||||||
|
panel->setCoord(vec2(10, 10));
|
||||||
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
|
return L"chunks: "+std::to_wstring(this->level->chunks->chunksCount);
|
||||||
|
})));
|
||||||
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
|
return L"fps: "+this->fpsString;
|
||||||
|
})));
|
||||||
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
|
return L"occlusion: "+wstring(this->occlusion ? L"on" : L"off");
|
||||||
|
})));
|
||||||
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
|
std::wstringstream stream;
|
||||||
|
stream << std::hex << this->level->player->selectedVoxel.states;
|
||||||
|
return L"block-selected: "+std::to_wstring(this->level->player->selectedVoxel.id)+L" "+stream.str();
|
||||||
|
})));
|
||||||
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
|
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
||||||
|
})));
|
||||||
|
for (int ax = 0; ax < 3; ax++){
|
||||||
|
Panel* sub = new Panel(vec2(10, 27), vec4(0.0f));
|
||||||
|
sub->orientation(gui::Orientation::horizontal);
|
||||||
|
Label* label = new Label(wstring({L'x'+ax})+L": ");
|
||||||
|
label->margin(vec4(2, 3, 2, 3));
|
||||||
|
sub->add(shared_ptr<UINode>(label));
|
||||||
|
sub->color(vec4(0.0f));
|
||||||
|
TextBox* box = new TextBox(L"");
|
||||||
|
box->textSupplier([this, ax]() {
|
||||||
|
Hitbox* hitbox = this->level->player->hitbox;
|
||||||
|
return std::to_wstring((int)hitbox->position[ax]);
|
||||||
|
});
|
||||||
|
box->textConsumer([this, ax](wstring text) {
|
||||||
|
try {
|
||||||
|
this->level->player->hitbox->position[ax] = std::stoi(text);
|
||||||
|
} catch (std::invalid_argument& _){
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sub->add(shared_ptr<UINode>(box));
|
||||||
|
panel->add(shared_ptr<UINode>(sub));
|
||||||
|
}
|
||||||
|
panel->refresh();
|
||||||
|
debugPanel = panel;
|
||||||
|
|
||||||
|
pauseMenu = new Panel(vec2(350, 200));
|
||||||
|
pauseMenu->color(vec4(0.0f));
|
||||||
|
{
|
||||||
|
Button* button = new Button(L"Continue", vec4(12.0f, 10.0f, 12.0f, 12.0f));
|
||||||
|
button->listenAction([this](GUI*){
|
||||||
|
this->pause = false;
|
||||||
|
});
|
||||||
|
pauseMenu->add(shared_ptr<UINode>(button));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Button* button = new Button(L"Save and Quit", vec4(12.0f, 10.0f, 12.0f, 12.0f));
|
||||||
|
button->listenAction([this](GUI*){
|
||||||
|
Window::setShouldClose(true);
|
||||||
|
});
|
||||||
|
pauseMenu->add(shared_ptr<UINode>(button));
|
||||||
|
}
|
||||||
|
guiController->add(shared_ptr<UINode>(debugPanel));
|
||||||
|
guiController->add(shared_ptr<UINode>(pauseMenu));
|
||||||
}
|
}
|
||||||
|
|
||||||
HudRenderer::~HudRenderer() {
|
HudRenderer::~HudRenderer() {
|
||||||
delete batch;
|
delete batch;
|
||||||
delete uicamera;
|
delete uicamera;
|
||||||
|
delete guiController;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HudRenderer::drawDebug(Level* level, int fps, bool occlusion){
|
void HudRenderer::drawDebug(int fps, bool occlusion){
|
||||||
Chunks* chunks = level->chunks;
|
this->occlusion = occlusion;
|
||||||
Player* player = level->player;
|
if (fpsFrame % 60 == 0) {
|
||||||
|
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
|
||||||
Font* font = assets->getFont("normal");
|
fpsMin = fps;
|
||||||
|
fpsMax = fps;
|
||||||
Shader* uishader = assets->getShader("ui");
|
}
|
||||||
uishader->use();
|
fpsFrame++;
|
||||||
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
fpsMin = min(fps, fpsMin);
|
||||||
batch->color = vec4(1.0f);
|
fpsMax = max(fps, fpsMax);
|
||||||
batch->begin();
|
|
||||||
font->draw(batch, L"chunks: "+std::to_wstring(chunks->chunksCount), 16, 16, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, std::to_wstring((int)player->camera->position.x), 10, 30, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, std::to_wstring((int)player->camera->position.y), 90, 30, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, std::to_wstring((int)player->camera->position.z), 170, 30, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, L"fps:", 16, 42, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, std::to_wstring(fps), 44, 42, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, L"occlusion: "+std::to_wstring(occlusion), 16, 54, STYLE_OUTLINE);
|
|
||||||
|
|
||||||
std::wstringstream stream;
|
|
||||||
stream << std::hex << player->selectedVoxel.states;
|
|
||||||
font->draw(batch, L"block-selected: "+std::to_wstring(player->selectedVoxel.id)+L" "+stream.str(), 16, 78, STYLE_OUTLINE);
|
|
||||||
font->draw(batch, L"meshes: " + std::to_wstring(Mesh::meshesCount), 16, 102, STYLE_OUTLINE);
|
|
||||||
batch->render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HudRenderer::drawInventory(Player* player) {
|
void HudRenderer::drawInventory(Player* player) {
|
||||||
Texture* blocks = assets->getTexture("block");
|
Texture* blocks = assets->getTexture("block");
|
||||||
uint size = 48;
|
uint size = 48;
|
||||||
uint step = 64;
|
uint step = 64;
|
||||||
uint inv_wm = step*10;
|
uint inv_cols = 10;
|
||||||
uint inv_hm = step*8;
|
uint inv_rows = 8;
|
||||||
uint inv_w = inv_wm - (step - size);
|
uint inv_w = step*inv_cols + size;
|
||||||
uint inv_h = inv_hm - (step - size);
|
uint inv_h = step*inv_rows + size;
|
||||||
int inv_x = (Window::width - (inv_w)) / 2;
|
int inv_x = (Window::width - (inv_w)) / 2;
|
||||||
int inv_y = (Window::height - (inv_h)) / 2;
|
int inv_y = (Window::height - (inv_h)) / 2;
|
||||||
int xs = (Window::width - inv_w + step)/2;
|
int xs = (Window::width - inv_w + step)/2;
|
||||||
@ -76,17 +153,14 @@ void HudRenderer::drawInventory(Player* player) {
|
|||||||
xs = (Window::width + inv_w + step)/2;
|
xs = (Window::width + inv_w + step)/2;
|
||||||
ys = (Window::height - inv_h + step)/2;
|
ys = (Window::height - inv_h + step)/2;
|
||||||
}
|
}
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
vec4 tint = vec4(1.0f);
|
vec4 tint = vec4(1.0f);
|
||||||
int mx = Events::x;
|
int mx = Events::x;
|
||||||
int my = Events::y;
|
int my = Events::y;
|
||||||
uint count = (inv_w / step) * (inv_h / step) + 1;
|
uint count = inv_cols * inv_rows;
|
||||||
|
|
||||||
//back
|
// back
|
||||||
batch->texture(nullptr);
|
batch->texture(nullptr);
|
||||||
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.3f);
|
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.3f);
|
||||||
batch->rect(0, 0, Window::width, Window::height);
|
|
||||||
batch->rect(inv_x - 4, inv_y - 4, inv_w+8, inv_h+8,
|
batch->rect(inv_x - 4, inv_y - 4, inv_w+8, inv_h+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,
|
||||||
0.7f, 0.7f, 0.7f,
|
0.7f, 0.7f, 0.7f,
|
||||||
@ -97,9 +171,9 @@ void HudRenderer::drawInventory(Player* player) {
|
|||||||
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 4);
|
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 4);
|
||||||
|
|
||||||
batch->color = vec4(0.35f, 0.35f, 0.35f, 1.0f);
|
batch->color = vec4(0.35f, 0.35f, 0.35f, 1.0f);
|
||||||
for (uint i = 1; i < count; i++) {
|
for (uint i = 0; i < count; i++) {
|
||||||
x = xs + step * ((i-1) % (inv_w / step));
|
int x = xs + step * (i % (inv_cols));
|
||||||
y = ys + step * ((i-1) / (inv_w / step));
|
int y = ys + step * (i / (inv_cols));
|
||||||
batch->rect(x-2, y-2, size+4, size+4,
|
batch->rect(x-2, y-2, size+4, size+4,
|
||||||
0.45f, 0.45f, 0.45f, 0.55f, 0.55f, 0.55f,
|
0.45f, 0.45f, 0.45f, 0.55f, 0.55f, 0.55f,
|
||||||
0.7f, 0.7f, 0.7f,
|
0.7f, 0.7f, 0.7f,
|
||||||
@ -110,20 +184,20 @@ void HudRenderer::drawInventory(Player* player) {
|
|||||||
0.65f, 0.65f, 0.65f, 0.65f, 0.65f, 0.65f, 2);
|
0.65f, 0.65f, 0.65f, 0.65f, 0.65f, 0.65f, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//front
|
// front
|
||||||
batch->texture(blocks);
|
batch->texture(blocks);
|
||||||
for (uint i = 1; i < count; i++) {
|
for (uint i = 0; i < count; i++) {
|
||||||
Block* cblock = Block::blocks[i];
|
Block* cblock = Block::blocks[i+1];
|
||||||
if (cblock == nullptr)
|
if (cblock == nullptr)
|
||||||
break;
|
break;
|
||||||
x = xs + step * ((i-1) % (inv_w / step));
|
int x = xs + step * (i % inv_cols);
|
||||||
y = ys + step * ((i-1) / (inv_w / step));
|
int y = ys + step * (i / inv_cols);
|
||||||
if (mx > x && mx < x + (int)size && my > y && my < y + (int)size) {
|
if (mx > x && mx < x + (int)size && my > y && my < y + (int)size) {
|
||||||
tint.r *= 1.2f;
|
tint.r *= 1.2f;
|
||||||
tint.g *= 1.2f;
|
tint.g *= 1.2f;
|
||||||
tint.b *= 1.2f;
|
tint.b *= 1.2f;
|
||||||
if (Events::jclicked(GLFW_MOUSE_BUTTON_LEFT)) {
|
if (Events::jclicked(GLFW_MOUSE_BUTTON_LEFT)) {
|
||||||
player->choosenBlock = i;
|
player->choosenBlock = i+1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@ -138,13 +212,16 @@ void HudRenderer::drawInventory(Player* player) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HudRenderer::draw(Level* level){
|
void HudRenderer::draw(){
|
||||||
glDisable(GL_MULTISAMPLE);
|
debugPanel->visible(level->player->debug);
|
||||||
uicamera->fov = Window::height;
|
pauseMenu->visible(pause);
|
||||||
|
pauseMenu->setCoord(vec2(Window::width/2.0f, Window::height/2.0f) - pauseMenu->size() / 2.0f);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
uicamera->fov = Window::height;
|
||||||
|
|
||||||
Shader* uishader = assets->getShader("ui");
|
Shader* uishader = assets->getShader("ui");
|
||||||
uishader->use();
|
uishader->use();
|
||||||
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView());
|
||||||
@ -181,7 +258,6 @@ void HudRenderer::draw(Level* level){
|
|||||||
0.75f, 0.75f, 0.75f,
|
0.75f, 0.75f, 0.75f,
|
||||||
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;
|
Player* player = level->player;
|
||||||
{
|
{
|
||||||
@ -193,9 +269,30 @@ void HudRenderer::draw(Level* level){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Events::_cursor_locked) {
|
if (Events::jpressed(keycode::ESCAPE) && !guiController->isFocusCaught()) {
|
||||||
|
if (pause) {
|
||||||
|
pause = false;
|
||||||
|
} else if (inventoryOpen) {
|
||||||
|
inventoryOpen = false;
|
||||||
|
} else {
|
||||||
|
pause = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Events::jpressed(keycode::TAB)) {
|
||||||
|
if (!pause) {
|
||||||
|
inventoryOpen = !inventoryOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((pause || inventoryOpen) == Events::_cursor_locked)
|
||||||
|
Events::toggleCursor();
|
||||||
|
|
||||||
|
if (pause || inventoryOpen) {
|
||||||
|
batch->texture(nullptr);
|
||||||
|
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f);
|
||||||
|
batch->rect(0, 0, Window::width, Window::height);
|
||||||
|
}
|
||||||
|
if (inventoryOpen) {
|
||||||
drawInventory(player);
|
drawInventory(player);
|
||||||
}
|
}
|
||||||
batch->render();
|
batch->render();
|
||||||
glEnable(GL_MULTISAMPLE);
|
|
||||||
}
|
}
|
||||||
43
src/frontend/hud.h
Normal file
43
src/frontend/hud.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef SRC_HUD_H_
|
||||||
|
#define SRC_HUD_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Batch2D;
|
||||||
|
class Camera;
|
||||||
|
class Level;
|
||||||
|
class Assets;
|
||||||
|
class Player;
|
||||||
|
class Level;
|
||||||
|
|
||||||
|
namespace gui {
|
||||||
|
class GUI;
|
||||||
|
class Panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
class HudRenderer {
|
||||||
|
Level* level;
|
||||||
|
Assets* assets;
|
||||||
|
Batch2D* batch;
|
||||||
|
Camera* uicamera;
|
||||||
|
|
||||||
|
int fpsMin = 60;
|
||||||
|
int fpsMax = 60;
|
||||||
|
int fpsFrame = 0;
|
||||||
|
std::wstring fpsString;
|
||||||
|
bool occlusion;
|
||||||
|
bool inventoryOpen = false;
|
||||||
|
bool pause = true;
|
||||||
|
|
||||||
|
gui::Panel* debugPanel;
|
||||||
|
gui::Panel* pauseMenu;
|
||||||
|
gui::GUI* guiController;
|
||||||
|
public:
|
||||||
|
HudRenderer(gui::GUI* gui, Level* level, Assets* assets);
|
||||||
|
~HudRenderer();
|
||||||
|
void drawInventory(Player* player);
|
||||||
|
void draw();
|
||||||
|
void drawDebug(int fps, bool occlusion);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SRC_HUD_H_ */
|
||||||
@ -1,22 +0,0 @@
|
|||||||
#ifndef SRC_HUD_RENDER_H_
|
|
||||||
#define SRC_HUD_RENDER_H_
|
|
||||||
|
|
||||||
class Batch2D;
|
|
||||||
class Camera;
|
|
||||||
class Level;
|
|
||||||
class Assets;
|
|
||||||
class Player;
|
|
||||||
|
|
||||||
class HudRenderer {
|
|
||||||
Assets* assets;
|
|
||||||
Batch2D* batch;
|
|
||||||
Camera* uicamera;
|
|
||||||
public:
|
|
||||||
HudRenderer(Assets* assets);
|
|
||||||
~HudRenderer();
|
|
||||||
void drawInventory(Player* player);
|
|
||||||
void draw(Level* level);
|
|
||||||
void drawDebug(Level* level, int fps, bool occlusion);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* SRC_HUD_RENDER_H_ */
|
|
||||||
@ -24,9 +24,6 @@
|
|||||||
|
|
||||||
using std::shared_ptr;
|
using std::shared_ptr;
|
||||||
|
|
||||||
float _camera_cx;
|
|
||||||
float _camera_cz;
|
|
||||||
|
|
||||||
WorldRenderer::WorldRenderer(Level* level, Assets* assets) : assets(assets), level(level) {
|
WorldRenderer::WorldRenderer(Level* level, Assets* assets) : assets(assets), level(level) {
|
||||||
lineBatch = new LineBatch(4096);
|
lineBatch = new LineBatch(4096);
|
||||||
batch3d = new Batch3D(1024);
|
batch3d = new Batch3D(1024);
|
||||||
@ -42,15 +39,6 @@ WorldRenderer::~WorldRenderer() {
|
|||||||
delete renderer;
|
delete renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunks* _chunks = nullptr;
|
|
||||||
|
|
||||||
bool chunks_distance_compare(size_t i, size_t j) {
|
|
||||||
shared_ptr<Chunk> a = _chunks->chunks[i];
|
|
||||||
shared_ptr<Chunk> b = _chunks->chunks[j];
|
|
||||||
return ((a->x + 0.5f - _camera_cx)*(a->x + 0.5f - _camera_cx) + (a->z + 0.5f - _camera_cz)*(a->z + 0.5f - _camera_cz) >
|
|
||||||
(b->x + 0.5f - _camera_cx)*(b->x + 0.5f - _camera_cx) + (b->z + 0.5f - _camera_cz)*(b->z + 0.5f - _camera_cz));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){
|
bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion){
|
||||||
shared_ptr<Chunk> chunk = level->chunks->chunks[index];
|
shared_ptr<Chunk> chunk = level->chunks->chunks[index];
|
||||||
if (!chunk->isLighted())
|
if (!chunk->isLighted())
|
||||||
@ -75,14 +63,12 @@ bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool
|
|||||||
}
|
}
|
||||||
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W, 0.0f, chunk->z*CHUNK_D+1));
|
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W, 0.0f, chunk->z*CHUNK_D+1));
|
||||||
shader->uniformMatrix("u_model", model);
|
shader->uniformMatrix("u_model", model);
|
||||||
glDisable(GL_MULTISAMPLE);
|
|
||||||
mesh->draw(GL_TRIANGLES);
|
mesh->draw(GL_TRIANGLES);
|
||||||
glEnable(GL_MULTISAMPLE);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WorldRenderer::draw(Camera* camera, bool occlusion){
|
void WorldRenderer::draw(Camera* camera, bool occlusion, float fogFactor, float fogCurve){
|
||||||
Chunks* chunks = level->chunks;
|
Chunks* chunks = level->chunks;
|
||||||
|
|
||||||
vec4 skyColor(0.7f, 0.81f, 1.0f, 1.0f);
|
vec4 skyColor(0.7f, 0.81f, 1.0f, 1.0f);
|
||||||
@ -103,7 +89,8 @@ void WorldRenderer::draw(Camera* camera, bool occlusion){
|
|||||||
shader->uniform1f("u_gamma", 1.6f);
|
shader->uniform1f("u_gamma", 1.6f);
|
||||||
shader->uniform3f("u_skyLightColor", 1.1f,1.1f,1.1f);
|
shader->uniform3f("u_skyLightColor", 1.1f,1.1f,1.1f);
|
||||||
shader->uniform3f("u_fogColor", skyColor.r,skyColor.g,skyColor.b);
|
shader->uniform3f("u_fogColor", skyColor.r,skyColor.g,skyColor.b);
|
||||||
shader->uniform1f("u_fogFactor", 0.025f);
|
shader->uniform1f("u_fogFactor", fogFactor);
|
||||||
|
shader->uniform1f("u_fogCurve", fogCurve);
|
||||||
shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z);
|
shader->uniform3f("u_cameraPos", camera->position.x,camera->position.y,camera->position.z);
|
||||||
|
|
||||||
Block* cblock = Block::blocks[level->player->choosenBlock];
|
Block* cblock = Block::blocks[level->player->choosenBlock];
|
||||||
@ -112,7 +99,6 @@ void WorldRenderer::draw(Camera* camera, bool occlusion){
|
|||||||
cblock->emission[1] / 15.0f,
|
cblock->emission[1] / 15.0f,
|
||||||
cblock->emission[2] / 15.0f);
|
cblock->emission[2] / 15.0f);
|
||||||
shader->uniform1f("u_torchlightDistance", 6.0f);
|
shader->uniform1f("u_torchlightDistance", 6.0f);
|
||||||
shader->uniform1f("u_fogFactor", 0.025f);
|
|
||||||
texture->bind();
|
texture->bind();
|
||||||
|
|
||||||
std::vector<size_t> indices;
|
std::vector<size_t> indices;
|
||||||
@ -126,11 +112,12 @@ void WorldRenderer::draw(Camera* camera, bool occlusion){
|
|||||||
|
|
||||||
float px = camera->position.x / (float)CHUNK_W;
|
float px = camera->position.x / (float)CHUNK_W;
|
||||||
float pz = camera->position.z / (float)CHUNK_D;
|
float pz = camera->position.z / (float)CHUNK_D;
|
||||||
|
std::sort(indices.begin(), indices.end(), [this, chunks, px, pz](size_t i, size_t j) {
|
||||||
_camera_cx = px;
|
shared_ptr<Chunk> a = chunks->chunks[i];
|
||||||
_camera_cz = pz;
|
shared_ptr<Chunk> b = chunks->chunks[j];
|
||||||
_chunks = chunks;
|
return ((a->x + 0.5f - px)*(a->x + 0.5f - px) + (a->z + 0.5f - pz)*(a->z + 0.5f - pz) >
|
||||||
std::sort(indices.begin(), indices.end(), chunks_distance_compare);
|
(b->x + 0.5f - px)*(b->x + 0.5f - px) + (b->z + 0.5f - pz)*(b->z + 0.5f - pz));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
int occludedChunks = 0;
|
int occludedChunks = 0;
|
||||||
@ -161,9 +148,9 @@ void WorldRenderer::draw(Camera* camera, bool occlusion){
|
|||||||
linesShader->use();
|
linesShader->use();
|
||||||
linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
||||||
|
|
||||||
vec3 point = vec3(camera->position.x+camera->front.x/1,
|
vec3 point = vec3(camera->position.x+camera->front.x,
|
||||||
camera->position.y+camera->front.y/1,
|
camera->position.y+camera->front.y,
|
||||||
camera->position.z+camera->front.z/1);
|
camera->position.z+camera->front.z);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class Framebuffer;
|
|||||||
|
|
||||||
|
|
||||||
class WorldRenderer {
|
class WorldRenderer {
|
||||||
Batch3D *batch3d;
|
Batch3D* batch3d;
|
||||||
Assets* assets;
|
Assets* assets;
|
||||||
Level* level;
|
Level* level;
|
||||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
||||||
@ -34,7 +34,7 @@ public:
|
|||||||
WorldRenderer(Level* level, Assets* assets);
|
WorldRenderer(Level* level, Assets* assets);
|
||||||
~WorldRenderer();
|
~WorldRenderer();
|
||||||
|
|
||||||
void draw(Camera* camera, bool occlusion);
|
void draw(Camera* camera, bool occlusion, float fogFactor, float fogCurve);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
PlayerController::PlayerController(Level* level) : level(level) {
|
PlayerController::PlayerController(Level* level) : level(level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerController::update_controls(float delta){
|
void PlayerController::update_controls(float delta, bool movement){
|
||||||
Player* player = level->player;
|
Player* player = level->player;
|
||||||
|
|
||||||
/*block choose*/{
|
/*block choose*/{
|
||||||
@ -45,10 +45,10 @@ void PlayerController::update_controls(float delta){
|
|||||||
|
|
||||||
Camera* camera = player->camera;
|
Camera* camera = player->camera;
|
||||||
Hitbox* hitbox = player->hitbox;
|
Hitbox* hitbox = player->hitbox;
|
||||||
bool sprint = Events::pressed(keycode::LEFT_CONTROL);
|
bool sprint = Events::pressed(keycode::LEFT_CONTROL) && movement;
|
||||||
bool shift = Events::pressed(keycode::LEFT_SHIFT) && hitbox->grounded && !sprint;
|
bool shift = Events::pressed(keycode::LEFT_SHIFT) && hitbox->grounded && !sprint && movement;
|
||||||
bool zoom = Events::pressed(keycode::C);
|
bool zoom = Events::pressed(keycode::C) && movement;
|
||||||
bool cheat = Events::pressed(keycode::R);
|
bool cheat = Events::pressed(keycode::R) && movement;
|
||||||
|
|
||||||
float speed = player->speed;
|
float speed = player->speed;
|
||||||
if (player->flight){
|
if (player->flight){
|
||||||
@ -59,6 +59,7 @@ void PlayerController::update_controls(float delta){
|
|||||||
}
|
}
|
||||||
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, shift, 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);
|
||||||
camera->position.x = hitbox->position.x;
|
camera->position.x = hitbox->position.x;
|
||||||
camera->position.y = hitbox->position.y + 0.7f;
|
camera->position.y = hitbox->position.y + 0.7f;
|
||||||
@ -81,14 +82,14 @@ void PlayerController::update_controls(float delta){
|
|||||||
camera->position -= min(player->interpVel * 0.05f, 1.0f);
|
camera->position -= min(player->interpVel * 0.05f, 1.0f);
|
||||||
}//end
|
}//end
|
||||||
|
|
||||||
if ((Events::jpressed(keycode::F) && !player->noclip) ||
|
if ((Events::jpressed(keycode::F) && movement && !player->noclip) ||
|
||||||
(Events::jpressed(keycode::N) && player->flight == player->noclip)){
|
(Events::jpressed(keycode::N) && movement && 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)) {
|
if (Events::jpressed(keycode::N) && movement) {
|
||||||
player->noclip = !player->noclip;
|
player->noclip = !player->noclip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,23 +109,23 @@ void PlayerController::update_controls(float delta){
|
|||||||
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
|
camera->zoom = zoomValue * dt + camera->zoom * (1.0f - dt);
|
||||||
}//end
|
}//end
|
||||||
|
|
||||||
if (Events::pressed(keycode::SPACE) && hitbox->grounded){
|
if (Events::pressed(keycode::SPACE) && movement && hitbox->grounded){
|
||||||
hitbox->velocity.y = JUMP_FORCE;
|
hitbox->velocity.y = JUMP_FORCE;
|
||||||
}
|
}
|
||||||
vec3 dir(0,0,0);
|
vec3 dir(0,0,0);
|
||||||
if (Events::pressed(keycode::W)){
|
if (Events::pressed(keycode::W) && movement){
|
||||||
dir.x += camera->dir.x;
|
dir.x += camera->dir.x;
|
||||||
dir.z += camera->dir.z;
|
dir.z += camera->dir.z;
|
||||||
}
|
}
|
||||||
if (Events::pressed(keycode::S)){
|
if (Events::pressed(keycode::S) && movement){
|
||||||
dir.x -= camera->dir.x;
|
dir.x -= camera->dir.x;
|
||||||
dir.z -= camera->dir.z;
|
dir.z -= camera->dir.z;
|
||||||
}
|
}
|
||||||
if (Events::pressed(keycode::D)){
|
if (Events::pressed(keycode::D) && movement){
|
||||||
dir.x += camera->right.x;
|
dir.x += camera->right.x;
|
||||||
dir.z += camera->right.z;
|
dir.z += camera->right.z;
|
||||||
}
|
}
|
||||||
if (Events::pressed(keycode::A)){
|
if (Events::pressed(keycode::A) && movement){
|
||||||
dir.x -= camera->right.x;
|
dir.x -= camera->right.x;
|
||||||
dir.z -= camera->right.z;
|
dir.z -= camera->right.z;
|
||||||
}
|
}
|
||||||
@ -133,10 +134,10 @@ void PlayerController::update_controls(float delta){
|
|||||||
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)){
|
if (Events::pressed(keycode::SPACE) && movement){
|
||||||
hitbox->velocity.y += speed * delta * 9;
|
hitbox->velocity.y += speed * delta * 9;
|
||||||
}
|
}
|
||||||
if (Events::pressed(keycode::LEFT_SHIFT)){
|
if (Events::pressed(keycode::LEFT_SHIFT) && movement){
|
||||||
hitbox->velocity.y -= speed * delta * 9;
|
hitbox->velocity.y -= speed * delta * 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public:
|
|||||||
glm::vec3 selectedBlockPosition;
|
glm::vec3 selectedBlockPosition;
|
||||||
int selectedBlockId = -1;
|
int selectedBlockId = -1;
|
||||||
PlayerController(Level* level);
|
PlayerController(Level* level);
|
||||||
void update_controls(float delta);
|
void update_controls(float delta, bool movement);
|
||||||
void update_interaction();
|
void update_interaction();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -3,211 +3,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
|
||||||
#include <ctime>
|
|
||||||
#include <exception>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
// GLM
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/ext.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
|
|
||||||
#include "coders/json.h"
|
|
||||||
#include "files/files.h"
|
|
||||||
#include "window/Window.h"
|
|
||||||
#include "window/Events.h"
|
|
||||||
#include "window/Camera.h"
|
|
||||||
#include "window/input.h"
|
|
||||||
#include "audio/Audio.h"
|
|
||||||
#include "voxels/Chunk.h"
|
|
||||||
#include "voxels/Chunks.h"
|
|
||||||
#include "voxels/ChunksController.h"
|
|
||||||
#include "voxels/ChunksStorage.h"
|
|
||||||
#include "objects/Player.h"
|
|
||||||
#include "world/Level.h"
|
|
||||||
#include "world/World.h"
|
|
||||||
#include "definitions.h"
|
#include "definitions.h"
|
||||||
#include "assets/Assets.h"
|
|
||||||
#include "assets/AssetsLoader.h"
|
|
||||||
#include "frontend/world_render.h"
|
|
||||||
#include "frontend/hud_render.h"
|
|
||||||
|
|
||||||
#define SETTINGS_FILE "settings.json"
|
#include "util/platform.h"
|
||||||
|
#include "engine.h"
|
||||||
using std::shared_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
class initialize_error : public std::runtime_error {
|
|
||||||
public:
|
|
||||||
initialize_error(const std::string& message) : std::runtime_error(message) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
void save_settings(EngineSettings& settings, std::string filename);
|
|
||||||
|
|
||||||
class Engine {
|
|
||||||
Assets* assets;
|
|
||||||
Level* level;
|
|
||||||
EngineSettings settings;
|
|
||||||
|
|
||||||
uint64_t frame = 0;
|
|
||||||
double lastTime = 0.0;
|
|
||||||
double delta = 0.0;
|
|
||||||
bool occlusion = true;
|
|
||||||
public:
|
|
||||||
Engine(const EngineSettings& settings);
|
|
||||||
~Engine();
|
|
||||||
|
|
||||||
void updateTimers();
|
|
||||||
void updateHotkeys();
|
|
||||||
void mainloop();
|
|
||||||
};
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::updateTimers() {
|
|
||||||
frame++;
|
|
||||||
double currentTime = Window::time();
|
|
||||||
delta = currentTime - lastTime;
|
|
||||||
lastTime = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::updateHotkeys() {
|
|
||||||
if (Events::jpressed(keycode::TAB)) {
|
|
||||||
Events::toggleCursor();
|
|
||||||
}
|
|
||||||
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(assets);
|
|
||||||
lastTime = Window::time();
|
|
||||||
|
|
||||||
while (!Window::isShouldClose()){
|
|
||||||
updateTimers();
|
|
||||||
updateHotkeys();
|
|
||||||
|
|
||||||
level->update(delta, Events::_cursor_locked);
|
|
||||||
level->chunksController->update(settings.chunksLoadSpeed);
|
|
||||||
|
|
||||||
worldRenderer.draw(camera, occlusion);
|
|
||||||
hud.draw(level);
|
|
||||||
if (level->player->debug) {
|
|
||||||
hud.drawDebug(level, 1 / delta, occlusion);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
files::write_string(filename, json::stringify(&obj, true, " "));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
platform::configure_encoding();
|
||||||
setup_definitions();
|
setup_definitions();
|
||||||
try {
|
try {
|
||||||
EngineSettings settings;
|
EngineSettings settings;
|
||||||
@ -219,12 +23,15 @@ int main() {
|
|||||||
settings.chunksLoadDistance = 12;
|
settings.chunksLoadDistance = 12;
|
||||||
settings.chunksPadding = 2;
|
settings.chunksPadding = 2;
|
||||||
settings.displaySwapInterval = 1;
|
settings.displaySwapInterval = 1;
|
||||||
|
settings.fogCurve = 1.6f;
|
||||||
|
|
||||||
if (std::filesystem::is_regular_file(SETTINGS_FILE)) {
|
std::string settings_file = platform::get_settings_file();
|
||||||
|
if (std::filesystem::is_regular_file(settings_file)) {
|
||||||
std::cout << "-- loading settings" << std::endl;
|
std::cout << "-- loading settings" << std::endl;
|
||||||
load_settings(settings, SETTINGS_FILE);
|
load_settings(settings, settings_file);
|
||||||
} else {
|
} else {
|
||||||
save_settings(settings, SETTINGS_FILE);
|
std::cout << "-- creating settings file " << settings_file << std::endl;
|
||||||
|
save_settings(settings, settings_file);
|
||||||
}
|
}
|
||||||
Engine engine(settings);
|
Engine engine(settings);
|
||||||
engine.mainloop();
|
engine.mainloop();
|
||||||
|
|||||||
@ -28,7 +28,6 @@ public:
|
|||||||
bool breakable = true;
|
bool breakable = true;
|
||||||
bool rotatable = false;
|
bool rotatable = false;
|
||||||
float hitboxScale = 1;
|
float hitboxScale = 1;
|
||||||
float hitboxY = 1;
|
|
||||||
|
|
||||||
Block(unsigned int id, int texture);
|
Block(unsigned int id, int texture);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -137,7 +137,7 @@ void WorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){
|
|||||||
} else if (real_y < height){
|
} else if (real_y < height){
|
||||||
id = BLOCK_DIRT;
|
id = BLOCK_DIRT;
|
||||||
} else {
|
} else {
|
||||||
int tree = generate_tree(&noise, &randomtree, heights, real_x, real_y, real_z, 23);
|
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 = 0x32;
|
||||||
|
|||||||
@ -91,6 +91,8 @@ int Window::initialize(uint width, uint height, const char* title, int samples){
|
|||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
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::width = width;
|
||||||
@ -105,6 +107,10 @@ int Window::initialize(uint width, uint height, const char* title, int samples){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::clear() {
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::viewport(int x, int y, int width, int height){
|
void Window::viewport(int x, int y, int width, int height){
|
||||||
glViewport(x, y, width, height);
|
glViewport(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,8 @@ public:
|
|||||||
static void popScissor();
|
static void popScissor();
|
||||||
static void resetScissor();
|
static void resetScissor();
|
||||||
|
|
||||||
|
static void clear();
|
||||||
|
|
||||||
static double time();
|
static double time();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -38,8 +38,8 @@ Level::~Level(){
|
|||||||
delete playerController;
|
delete playerController;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::update(float delta, bool interactions) {
|
void Level::update(float delta, bool updatePlayer, bool interactions) {
|
||||||
playerController->update_controls(delta);
|
playerController->update_controls(delta, updatePlayer);
|
||||||
if (interactions) {
|
if (interactions) {
|
||||||
playerController->update_interaction();
|
playerController->update_interaction();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ public:
|
|||||||
uint chunksPadding);
|
uint chunksPadding);
|
||||||
~Level();
|
~Level();
|
||||||
|
|
||||||
void update(float delta, bool interactions);
|
void update(float delta, bool updatePlayer, bool interactions);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* WORLD_LEVEL_H_ */
|
#endif /* WORLD_LEVEL_H_ */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user