UDP Networking first commit + Bugfixes & Cleanup
New stuff: * Client will fork and exec a given path with the "server" argument if supplied. * Packet class to help transfer data between client and server. * New Server class which accepts handshake from client * GameScene now attempts to connect to a server and ends if it fails. Fixes: * Changed deltaTime to double on Player class * SceneManager defaults Scene to nullptr to fix seg fault. * Moved some code to DebugGui and out of GameScene. * World class stores per-frame updates for chunks and meshes. * Scene emits warning if a derived class doesn't override all methods. * GameScene overrides cleanup * Created MenuScene to test having multiple scenes. * Moved commented code out of Mainmaster
parent
a681301ac6
commit
c608e2336d
|
@ -84,6 +84,12 @@ add_executable(zeus
|
|||
zeus/client/SceneManager.cpp
|
||||
zeus/client/SceneManager.h
|
||||
zeus/client/Scene.h
|
||||
zeus/client/ClientState.h)
|
||||
zeus/client/ClientState.h
|
||||
zeus/game/MenuScene.cpp
|
||||
zeus/game/MenuScene.h
|
||||
zeus/server/Server.cpp
|
||||
zeus/server/Server.h
|
||||
zeus/client/ClientPacket.cpp
|
||||
zeus/client/ClientPacket.h zeus/server/ClientConnection.cpp zeus/server/ClientConnection.h zeus/server/Packet.cpp zeus/server/Packet.h)
|
||||
|
||||
target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl)
|
||||
|
|
44
lua/file.lua
44
lua/file.lua
|
@ -151,7 +151,7 @@ zeus.register_blockmodel("default:plantlike", {
|
|||
zeus.register_blockmodel("default:block_poof", {
|
||||
{
|
||||
face = "left",
|
||||
tex = 0,
|
||||
tex = 1,
|
||||
points = {
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 1, 1, 1,
|
||||
|
@ -160,7 +160,7 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
}
|
||||
}, {
|
||||
face = "right",
|
||||
tex = 0,
|
||||
tex = 1,
|
||||
points = {
|
||||
1, 1, 1, 1, 0,
|
||||
1, 0, 1, 1, 1,
|
||||
|
@ -169,7 +169,7 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
}
|
||||
}, {
|
||||
face = "top",
|
||||
tex = 0,
|
||||
tex = 1,
|
||||
points = {
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 1, 0, 1,
|
||||
|
@ -178,7 +178,7 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
}
|
||||
}, {
|
||||
face = "bottom",
|
||||
tex = 0,
|
||||
tex = 1,
|
||||
points = {
|
||||
0, 0, 0, 0, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
|
@ -187,7 +187,7 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
}
|
||||
}, {
|
||||
face = "front",
|
||||
tex = 0,
|
||||
tex = 1,
|
||||
points = {
|
||||
0, 0, 1, 0, 1,
|
||||
1, 0, 1, 1, 1,
|
||||
|
@ -196,7 +196,7 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
}
|
||||
}, {
|
||||
face = "back",
|
||||
tex = 0,
|
||||
tex = 1,
|
||||
points = {
|
||||
0, 0, 0, 0, 1,
|
||||
0, 1, 0, 0, 0,
|
||||
|
@ -205,16 +205,16 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
}
|
||||
}, {
|
||||
face = "nocull",
|
||||
tex = 0,
|
||||
tex = 2,
|
||||
points = {
|
||||
-0.31, 1.30, -0.3, 0, 0,
|
||||
-0.31, -0.30, -0.31, 0, 1,
|
||||
1.3, -0.30, 1.3, 1, 1,
|
||||
1.3, 1.30, 1.29, 1, 0,
|
||||
|
||||
-0.31, 1.30, -0.3, 0, 0,
|
||||
-0.31, -0.30, -0.31, 0, 1,
|
||||
1.3, -0.30, 1.3, 1, 1,
|
||||
-0.31, -0.30, -0.31, 0, 1,
|
||||
-0.31, 1.30, -0.3, 0, 0,
|
||||
1.3, 1.30, 1.29, 1, 0,
|
||||
|
||||
-0.31, 1.30, 1.29, 0, 0,
|
||||
|
@ -222,9 +222,9 @@ zeus.register_blockmodel("default:block_poof", {
|
|||
1.3, -0.30, -0.31, 1, 1,
|
||||
1.3, 1.30, -0.3, 1, 0,
|
||||
|
||||
-0.31, 1.30, 1.29, 0, 0,
|
||||
-0.31, -0.30, 1.3, 0, 1,
|
||||
1.3, -0.30, -0.31, 1, 1,
|
||||
-0.31, -0.30, 1.3, 0, 1,
|
||||
-0.31, 1.30, 1.29, 0, 0,
|
||||
1.3, 1.30, -0.3, 1, 0
|
||||
}
|
||||
}
|
||||
|
@ -379,3 +379,25 @@ zeus.register_block('default:stone', {
|
|||
model = "default:block",
|
||||
textures = {"default_stone_dark"}
|
||||
})
|
||||
|
||||
-- Leaves
|
||||
zeus.register_block('default:leaves', {
|
||||
name = "Log",
|
||||
model = "default:block_poof",
|
||||
textures = {
|
||||
"default_leaves",
|
||||
"default_leaves_puff"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- Wood
|
||||
zeus.register_block('default:wood', {
|
||||
name = "Log",
|
||||
model = "default:block",
|
||||
textures = {
|
||||
"default_log_top",
|
||||
"default_log_top",
|
||||
"default_log_side"
|
||||
}
|
||||
})
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
textureAtlas.png
BIN
textureAtlas.png
Binary file not shown.
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
@ -5,70 +5,26 @@
|
|||
|
||||
#include "client/Client.h"
|
||||
|
||||
//std::string make_daytime_string() {
|
||||
// std::time_t now = std::time(nullptr);
|
||||
// return "HIfhjdsfjhglfgkhkdfjhbhnjgdsk,jfgbhdksijfghgjfkwaslodfjgbhfdsklofjghnbgkmdsk,lfkgbna";
|
||||
//// return std::ctime(&now);
|
||||
//}
|
||||
|
||||
//void server() {
|
||||
// try {
|
||||
// asio::io_context io_context;
|
||||
// udp::socket socket(io_context, udp::endpoint(udp::v4(), 12345));
|
||||
//
|
||||
// for (;;) {
|
||||
// char recv_buf[128];
|
||||
// udp::endpoint remote_endpoint; //Populated by the next line
|
||||
//
|
||||
// Timer t("owo");
|
||||
// socket.receive_from(asio::buffer(recv_buf), remote_endpoint);
|
||||
// t.printElapsedSeconds();
|
||||
// std::cout << recv_buf << std::endl;
|
||||
//
|
||||
// std::string message = make_daytime_string();
|
||||
//
|
||||
// asio::error_code ignored_error;
|
||||
// socket.send_to(asio::buffer(message), remote_endpoint, 0, ignored_error);
|
||||
//
|
||||
// //Socket is garbage collected here, so like, don't do that?
|
||||
// }
|
||||
// }
|
||||
// catch (std::exception& e) {
|
||||
// std::cerr << e.what() << std::endl;
|
||||
// }
|
||||
//}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// auto serverThread = new std::thread(server);
|
||||
// this_thread::sleep_for(0.2s);
|
||||
//
|
||||
// try {
|
||||
// asio::io_context io_context;
|
||||
// udp::resolver resolver(io_context);
|
||||
// udp::endpoint receiver_endpoint = *resolver.resolve(udp::v4(), "127.0.0.1", "12345").begin();
|
||||
//
|
||||
// udp::socket socket(io_context);
|
||||
// socket.open(udp::v4());
|
||||
//
|
||||
// char send_buf[3] = {'a', 'b', 'c'};
|
||||
// socket.send_to(asio::buffer(send_buf), receiver_endpoint);
|
||||
//
|
||||
// char recv_buf[20];
|
||||
//
|
||||
// udp::endpoint sender_endpoint; //Populated by the next line
|
||||
// size_t len = socket.receive_from(asio::buffer(recv_buf), sender_endpoint);
|
||||
//
|
||||
// sender_endpoint.
|
||||
//
|
||||
// std::cout.write(recv_buf, len);
|
||||
//// std::cout << "Done " << len << std::endl;
|
||||
// }
|
||||
// catch (std::exception& e) {
|
||||
// std::cout << e.what() << std::endl;
|
||||
// }
|
||||
std::string start = "client";
|
||||
if (argc >= 2) {
|
||||
start = argv[1];
|
||||
}
|
||||
|
||||
if (start == "client") {
|
||||
Client c(1366, 768);
|
||||
c.start(nullptr);
|
||||
}
|
||||
|
||||
else if (start == "local") {
|
||||
Client c(1366, 768);
|
||||
c.start(argv[0]); //TODO: Get this to client some other way
|
||||
}
|
||||
|
||||
else if (start == "server") {
|
||||
Server s(12345);
|
||||
s.start();
|
||||
}
|
||||
|
||||
Client c(1366, 768);
|
||||
c.start();
|
||||
return 0;
|
||||
}
|
|
@ -2,8 +2,13 @@
|
|||
// Created by aurailus on 06/01/19.
|
||||
//
|
||||
|
||||
#include <zconf.h>
|
||||
#include <signal.h>
|
||||
#include "Client.h"
|
||||
#include "../game/GameScene.h"
|
||||
#include "../server/Packet.h"
|
||||
#include <asio.hpp>
|
||||
|
||||
using asio::ip::udp;
|
||||
|
||||
Client::Client() = default;
|
||||
|
||||
|
@ -11,15 +16,87 @@ Client::Client(int width, int height) {
|
|||
renderer = new Renderer(width, height);
|
||||
}
|
||||
|
||||
void Client::start() {
|
||||
void Client::start(char* path) {
|
||||
// Start Local Server
|
||||
if (path != nullptr) {
|
||||
int pid = fork();
|
||||
if (pid == 0) {
|
||||
char *arr[] = {
|
||||
(char *) "xterm",
|
||||
(char *) "-iconic",
|
||||
(char *) "-e",
|
||||
path,
|
||||
(char *) "server",
|
||||
(char *) nullptr};
|
||||
|
||||
execvp("xterm", arr);
|
||||
} else {
|
||||
local_server_pid = pid;
|
||||
}
|
||||
}
|
||||
|
||||
//Create ClientState struct
|
||||
state = new ClientState {
|
||||
.renderer = renderer,
|
||||
.fps = 0,
|
||||
.deltaTime = 0
|
||||
};
|
||||
|
||||
Scene* s = new GameScene(state);
|
||||
sceneManager.setScene(s); //Main Menu Scene here eventually
|
||||
//Start the Main Menu
|
||||
Scene* m = new MenuScene(state);
|
||||
sceneManager.setScene(m);
|
||||
|
||||
//Try to connect to a server
|
||||
try {
|
||||
asio::io_context io_context;
|
||||
udp::resolver resolver(io_context);
|
||||
udp::endpoint receiver_endpoint = *resolver.resolve(udp::v4(), "127.0.0.1", "12346").begin();
|
||||
|
||||
udp::socket socket(io_context);
|
||||
socket.open(udp::v4());
|
||||
|
||||
int attempts = 0;
|
||||
bool connected = false;
|
||||
while (!connected) {
|
||||
if (attempts > 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
Packet p(Packet::HANDSHAKE);
|
||||
p.addInt(attempts);
|
||||
auto send_buf = p.serialize();
|
||||
|
||||
socket.send_to(asio::buffer(send_buf, send_buf.size()), receiver_endpoint);
|
||||
attempts++;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
|
||||
if (socket.available() > 0) {
|
||||
std::cout << "Connected" << std::endl;
|
||||
connected = true;
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed to connect..." << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((attempts < 3 ? 50 : 700)));
|
||||
}
|
||||
}
|
||||
if (!connected) {
|
||||
std::cout << "Connection timed out!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
char recv_buf[20];
|
||||
|
||||
udp::endpoint sender_endpoint; //Populated by the next line
|
||||
size_t len = socket.receive_from(asio::buffer(recv_buf), sender_endpoint);
|
||||
|
||||
std::cout.write(recv_buf, len);
|
||||
std::cout << "Done " << len << std::endl;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
while (!renderer->getWindow()->getShouldClose()) loop();
|
||||
}
|
||||
|
@ -31,6 +108,12 @@ void Client::loop() {
|
|||
state->deltaTime = now - timeElapsed;
|
||||
timeElapsed = now;
|
||||
|
||||
count ++;
|
||||
if (count == 20) {
|
||||
Scene* g = new GameScene(state);
|
||||
sceneManager.setScene(g); //Main Menu Scene here eventually
|
||||
}
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
sceneManager.update();
|
||||
|
@ -40,6 +123,9 @@ void Client::loop() {
|
|||
}
|
||||
|
||||
void Client::cleanup() {
|
||||
if (local_server_pid != 0) {
|
||||
kill(local_server_pid, SIGKILL);
|
||||
}
|
||||
sceneManager.cleanupScene();
|
||||
delete state;
|
||||
delete renderer;
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
#include "../engine/Timer.h"
|
||||
#include "SceneManager.h"
|
||||
#include "ClientState.h"
|
||||
#include "../game/GameScene.h"
|
||||
#include "../game/MenuScene.h"
|
||||
|
||||
class Client {
|
||||
public:
|
||||
Client();
|
||||
Client(int width, int height);
|
||||
|
||||
void start();
|
||||
void start(char* path);
|
||||
|
||||
~Client();
|
||||
|
||||
|
@ -29,6 +31,9 @@ private:
|
|||
ClientState* state;
|
||||
SceneManager sceneManager;
|
||||
|
||||
int local_server_pid = 0;
|
||||
int count = 0;
|
||||
|
||||
double timeElapsed = 0.0f;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,11 +13,17 @@ public:
|
|||
this->state = state;
|
||||
};
|
||||
|
||||
virtual void update() {};
|
||||
virtual void update() {
|
||||
std::cerr << "State doesn't define update method!" << std::endl;
|
||||
};
|
||||
|
||||
virtual void draw() {};
|
||||
virtual void draw() {
|
||||
std::cerr << "State doesn't define draw method!" << std::endl;
|
||||
};
|
||||
|
||||
virtual void cleanup() {};
|
||||
virtual void cleanup() {
|
||||
std::cerr << "State doesn't define cleanup method!" << std::endl;
|
||||
};
|
||||
|
||||
ClientState* state;
|
||||
};
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
#include "SceneManager.h"
|
||||
|
||||
SceneManager::SceneManager() = default;
|
||||
SceneManager::SceneManager() {
|
||||
scene = nullptr;
|
||||
};
|
||||
|
||||
void SceneManager::update() {
|
||||
scene->update();
|
||||
|
|
|
@ -44,10 +44,10 @@ int Window::initialize() {
|
|||
// glEnable(GL_MULTISAMPLE);
|
||||
|
||||
//VSync 1 = On, 0 = Off
|
||||
glfwSwapInterval(1);
|
||||
glfwSwapInterval(0);
|
||||
|
||||
//Create the window
|
||||
mainWindow = glfwCreateWindow(width, height, "Zeus_cpp OPENGL Linux x64", nullptr, nullptr);
|
||||
mainWindow = glfwCreateWindow(width, height, "Zeus Alpha", nullptr, nullptr);
|
||||
|
||||
if (!mainWindow) {
|
||||
printf("GLFW window failed");
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "../lua_api/l_register_blockmodel.h"
|
||||
|
||||
GameScene::GameScene(ClientState* state) : Scene(state) {
|
||||
|
||||
textureAtlas = new TextureAtlas("../tex");
|
||||
blockAtlas = new BlockAtlas(textureAtlas);
|
||||
|
||||
|
@ -40,7 +39,6 @@ GameScene::GameScene(ClientState* state) : Scene(state) {
|
|||
|
||||
gui.pushGuiObjects(guiEntities);
|
||||
|
||||
|
||||
auto crosshairTexture = new Texture((char*)"../tex/gui/crosshair.png");
|
||||
crosshairTexture->load();
|
||||
auto crosshair = new Entity();
|
||||
|
@ -74,58 +72,25 @@ GameScene::GameScene(ClientState* state) : Scene(state) {
|
|||
|
||||
|
||||
void GameScene::update() {
|
||||
|
||||
auto camera = state->renderer->getCamera();
|
||||
auto window = state->renderer->getWindow();
|
||||
|
||||
player->update(window->getKeysArray(), (GLfloat)state->deltaTime, window->getDeltaX(), window->getDeltaY());
|
||||
|
||||
glm::vec3 round = World::roundVec(*camera->getPosition());
|
||||
round.y -= 2;
|
||||
|
||||
int block = world->getBlock(round);
|
||||
std::string on = "Null";
|
||||
if (block >= 0) {
|
||||
on = blockAtlas->getBlock(block)->getIdentifier();
|
||||
}
|
||||
|
||||
block = 0;
|
||||
for (Ray ray(player); ray.getLength() < 5; ray.step(0.01)) {
|
||||
auto found = world->getBlock(*ray.getEnd());
|
||||
if (found > 0) {
|
||||
block = found;
|
||||
if (state->renderer->getWindow()->mouseIsDown()) {
|
||||
world->setBlock(*ray.getEnd(), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string look = "Null";
|
||||
if (block >= 0) {
|
||||
look = blockAtlas->getBlock(block)->getIdentifier();
|
||||
}
|
||||
|
||||
gui.update(player->getPos(), player->getVel(), player->getYaw(), player->getPitch(), on, look, state->fps);
|
||||
player->update(window->getKeysArray(), state->deltaTime, window->getDeltaX(), window->getDeltaY());
|
||||
|
||||
gui.update(player, world, window, blockAtlas, state->fps);
|
||||
world->update();
|
||||
}
|
||||
|
||||
void GameScene::draw() {
|
||||
Timer t("Drawing");
|
||||
|
||||
state->renderer->begin();
|
||||
|
||||
state->renderer->enableWorldShader();
|
||||
|
||||
textureAtlas->getTexture()->use();
|
||||
|
||||
for (auto &chunk : *world->getMeshChunks()) {
|
||||
for (auto &chunk : *world->getMeshChunks())
|
||||
state->renderer->draw(chunk.second);
|
||||
}
|
||||
|
||||
for (auto &entity : entities) {
|
||||
for (auto &entity : entities)
|
||||
state->renderer->draw(entity);
|
||||
}
|
||||
|
||||
state->renderer->enableGuiShader();
|
||||
|
||||
|
@ -136,9 +101,12 @@ void GameScene::draw() {
|
|||
prevTexture = gui->getTexture();
|
||||
gui->getTexture()->use();
|
||||
}
|
||||
|
||||
state->renderer->drawGui(gui);
|
||||
}
|
||||
|
||||
state->renderer->end();
|
||||
}
|
||||
|
||||
void GameScene::cleanup() {
|
||||
//TODO: Clean up
|
||||
}
|
|
@ -18,14 +18,17 @@
|
|||
#include "world/Player.h"
|
||||
#include "../engine/Ray.h"
|
||||
#include "../client/Scene.h"
|
||||
#include "../server/Server.h"
|
||||
|
||||
class GameScene : public Scene {
|
||||
public:
|
||||
GameScene(ClientState* state);
|
||||
explicit GameScene(ClientState* state);
|
||||
|
||||
void update() override;
|
||||
|
||||
void draw() override;
|
||||
|
||||
void cleanup() override;
|
||||
public:
|
||||
Player* player;
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Created by aurailus on 08/01/19.
|
||||
//
|
||||
|
||||
#include "MenuScene.h"
|
||||
#include "../engine/graphics/HudText.h"
|
||||
|
||||
MenuScene::MenuScene(ClientState *state) : Scene(state) {
|
||||
fontTexture = new Texture((char*)"../tex/gui/font.png");
|
||||
fontTexture->load();
|
||||
|
||||
auto alphaText = new HudText(fontTexture);
|
||||
alphaText->set("Zeus Alpha 0.01");
|
||||
alphaText->setScale(3);
|
||||
alphaText->setPosition(glm::vec3(8, 4, 0));
|
||||
entities.push_back(alphaText);
|
||||
|
||||
auto titleText = new HudText(fontTexture);
|
||||
titleText->set("Zeus");
|
||||
titleText->setScale(12);
|
||||
titleText->setPosition(glm::vec3(490, 120, 0));
|
||||
entities.push_back(titleText);
|
||||
|
||||
auto mainMenuText = new HudText(fontTexture);
|
||||
mainMenuText->set("MAIN MENU");
|
||||
mainMenuText->setScale(4);
|
||||
mainMenuText->setPosition(glm::vec3(530, 230, 0));
|
||||
entities.push_back(mainMenuText);
|
||||
}
|
||||
|
||||
void MenuScene::update() {
|
||||
//Nothing
|
||||
}
|
||||
|
||||
void MenuScene::draw() {
|
||||
state->renderer->begin();
|
||||
|
||||
state->renderer->enableGuiShader();
|
||||
|
||||
Texture* prevTexture = nullptr;
|
||||
|
||||
for (auto &element : entities) {
|
||||
if (element->getTexture() != prevTexture) {
|
||||
prevTexture = element->getTexture();
|
||||
prevTexture->use();
|
||||
}
|
||||
|
||||
state->renderer->drawGui(element);
|
||||
}
|
||||
|
||||
state->renderer->end();
|
||||
}
|
||||
|
||||
void MenuScene::cleanup() {
|
||||
fontTexture->clear();
|
||||
delete fontTexture;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// Created by aurailus on 08/01/19.
|
||||
//
|
||||
|
||||
#ifndef ZEUS_MENUSCENE_H
|
||||
#define ZEUS_MENUSCENE_H
|
||||
|
||||
|
||||
#include "../client/ClientState.h"
|
||||
#include "../client/Scene.h"
|
||||
|
||||
class MenuScene : public Scene {
|
||||
public:
|
||||
explicit MenuScene(ClientState* state);
|
||||
|
||||
void update() override;
|
||||
|
||||
void draw() override;
|
||||
|
||||
void cleanup() override;
|
||||
|
||||
private:
|
||||
Texture* fontTexture;
|
||||
std::vector<Entity*> entities;
|
||||
// DebugGui gui;
|
||||
};
|
||||
|
||||
|
||||
#endif //ZEUS_MENUSCENE_H
|
|
@ -24,10 +24,6 @@ DebugGui::DebugGui() {
|
|||
playerText->setScale(2);
|
||||
playerText->setPosition(glm::vec3(8, 42, 0));
|
||||
|
||||
blockText = new HudText(fontTexture);
|
||||
blockText->setScale(2);
|
||||
blockText->setPosition(glm::vec3(8, 116, 0));
|
||||
|
||||
fpsHistogram = new Entity();
|
||||
fpsHistogram->create(new Mesh(), histogramTexture);
|
||||
fpsHistogram->setPosition(glm::vec3(8, 764, 0));
|
||||
|
@ -36,7 +32,6 @@ DebugGui::DebugGui() {
|
|||
void DebugGui::pushGuiObjects(std::vector<Entity*> &list) {
|
||||
list.push_back(alphaText);
|
||||
list.push_back(fpsText);
|
||||
list.push_back(blockText);
|
||||
list.push_back(playerText);
|
||||
list.push_back(fpsHistogram);
|
||||
}
|
||||
|
@ -94,9 +89,35 @@ std::string string_double(double val) {
|
|||
return string_float((float)val);
|
||||
}
|
||||
|
||||
void DebugGui::update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, std::string block, std::string look, double fps) {
|
||||
glm::vec3 chk = World::chunkVec(*pos);
|
||||
glm::vec3 loc = World::localVec(*pos);
|
||||
void DebugGui::update(Player* player, World* world, Window* window, BlockAtlas* atlas, double fps) {
|
||||
glm::vec3 round = World::roundVec(*player->getPos());
|
||||
round.y -= 2;
|
||||
|
||||
int block = world->getBlock(round);
|
||||
std::string on = "ignore";
|
||||
if (block >= 0) {
|
||||
on = atlas->getBlock(block)->getIdentifier();
|
||||
}
|
||||
|
||||
block = 0;
|
||||
for (Ray ray(player); ray.getLength() < 5; ray.step(0.01)) {
|
||||
auto found = world->getBlock(*ray.getEnd());
|
||||
if (found > 0) {
|
||||
block = found;
|
||||
if (window->mouseIsDown()) {
|
||||
world->setBlock(*ray.getEnd(), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string look = "ignore";
|
||||
if (block >= 0) {
|
||||
look = atlas->getBlock(block)->getIdentifier();
|
||||
}
|
||||
|
||||
glm::vec3 chk = World::chunkVec(*player->getPos());
|
||||
glm::vec3 loc = World::localVec(*player->getPos());
|
||||
|
||||
if (fpsHistory.size() > FPS_HISTOGRAM_SIZE) fpsHistory.erase(fpsHistory.begin());
|
||||
|
||||
|
@ -105,13 +126,13 @@ void DebugGui::update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, st
|
|||
fpsHistUpdate();
|
||||
|
||||
playerText->set(
|
||||
"W: " + to_string((int)pos->x) + "," + to_string((int)pos->y) + "," + to_string((int)pos->z) + "\n" +
|
||||
"Chunk: " + to_string(world->lastGenUpdates) + ",Mesh: " + to_string(world->lastMeshUpdates) + "\n" +
|
||||
"W: " + to_string((int)player->getPos()->x) + "," + to_string((int)player->getPos()->y) + "," + to_string((int)player->getPos()->z) + "\n" +
|
||||
"C: " + to_string((int)chk.x) + "," + to_string((int)chk.y) + "," + to_string((int)chk.z) + " " +
|
||||
"(" + to_string((int)loc.x) + "," + to_string((int)loc.y) + "," + to_string((int)loc.z) + ")\n" +
|
||||
"V: " + string_float(vel->x) + "," + string_float(vel->y) + "," + string_float(vel->z) + "\n" +
|
||||
"Yaw: " + string_float(yaw) + ", Pitch: " + string_float(pitch));
|
||||
|
||||
blockText->set("On: " + block + "\nLooking: " + look);
|
||||
"V: " + string_float(player->getVel()->x) + "," + string_float(player->getVel()->y) + "," + string_float(player->getVel()->z) + "\n" +
|
||||
"Yaw: " + string_float(player->getYaw()) + ", Pitch: " + string_float(player->getPitch()) + "\n" +
|
||||
"On: " + on + "\nLooking: " + look);
|
||||
}
|
||||
|
||||
DebugGui::~DebugGui() = default;
|
|
@ -5,9 +5,11 @@
|
|||
#ifndef ZEUS_DEBUGGUI_H
|
||||
#define ZEUS_DEBUGGUI_H
|
||||
|
||||
|
||||
#include "../../engine/graphics/HudText.h"
|
||||
#include "../world/World.h"
|
||||
#include "../world/Player.h"
|
||||
#include "../../engine/Window.h"
|
||||
#include "../../engine/Ray.h"
|
||||
#include <sstream>
|
||||
|
||||
class DebugGui {
|
||||
|
@ -15,7 +17,7 @@ public:
|
|||
DebugGui();
|
||||
|
||||
void pushGuiObjects(std::vector<Entity*> &list);
|
||||
void update(glm::vec3* pos, glm::vec3* vel, float yaw, float pitch, std::string block, std::string look, double fps);
|
||||
void update(Player* player, World* world, Window* window, BlockAtlas* atlas, double fps);
|
||||
|
||||
~DebugGui();
|
||||
|
||||
|
@ -28,7 +30,6 @@ private:
|
|||
HudText* fpsText;
|
||||
HudText* alphaText;
|
||||
HudText* playerText;
|
||||
HudText* blockText;
|
||||
Entity* fpsHistogram;
|
||||
|
||||
const int FPS_HISTOGRAM_SIZE = 120;
|
||||
|
|
|
@ -29,7 +29,7 @@ void Player::posUpdate(bool *keys, double delta) {
|
|||
float jumpVel = 0.14f;
|
||||
float friction = 0.3f;
|
||||
|
||||
auto moveMult = (float)(moveSpeed * delta);
|
||||
double moveMult = moveSpeed * delta;
|
||||
if (keys[GLFW_KEY_LEFT_SHIFT]) {
|
||||
moveMult *= 2;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ void Player::posUpdate(bool *keys, double delta) {
|
|||
if (keys[GLFW_KEY_A]) mod -= rightFlat;
|
||||
|
||||
if (glm::length(mod) != 0) mod = glm::normalize(mod);
|
||||
mod = mod * moveMult;
|
||||
mod = mod * (float)moveMult;
|
||||
|
||||
glm::vec3 velFlat = glm::vec3(vel.x, 0, vel.z);
|
||||
velFlat = velFlat * (1.0f-friction) + mod * friction;
|
||||
|
|
|
@ -108,6 +108,7 @@ void World::handleChunkGenQueue() {
|
|||
}
|
||||
|
||||
Timer t("Chunk Initialization");
|
||||
int genUpdates = 0;
|
||||
for (auto iter = finishedGen.begin(); iter != finishedGen.end(); ) {
|
||||
if (t.elapsedNs() > 4000000) break;
|
||||
|
||||
|
@ -116,7 +117,10 @@ void World::handleChunkGenQueue() {
|
|||
commitChunk(threadData->pos, threadData->chunk);
|
||||
iter = finishedGen.erase(iter);
|
||||
delete threadData;
|
||||
|
||||
genUpdates++;
|
||||
}
|
||||
lastGenUpdates = genUpdates;
|
||||
// t.printElapsedMs();
|
||||
}
|
||||
|
||||
|
@ -124,8 +128,8 @@ void World::handleChunkGenQueue() {
|
|||
//Takes a threadDef object which contains a vector of tasks to do, and infinitely loops, completing tasks and
|
||||
//re-inserting them into the vector to be further manipulated by the main thread.
|
||||
void World::chunkGenThread(World::ChunkThreadDef* threadDef) {
|
||||
PerlinNoise p(10);
|
||||
PerlinNoise p2(10);
|
||||
PerlinNoise p(9);
|
||||
PerlinNoise p2(9);
|
||||
|
||||
//Infinite loop
|
||||
while (true) {
|
||||
|
@ -167,6 +171,15 @@ void World::chunkGenThread(World::ChunkThreadDef* threadDef) {
|
|||
int block = (val > 0) ? (val > 1) ? (val > 3) ? 3 : 2 : 1 : 0;
|
||||
blocks->push_back(block);
|
||||
}
|
||||
//
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(8, 8, 8)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(7, 8, 8)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(7, 8, 7)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(8, 8, 7)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(8, 7, 8)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(7, 7, 8)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(7, 7, 7)] = 4;
|
||||
// (*blocks)[ArrayTrans3D::vecToInd(8, 7, 7)] = 4;
|
||||
|
||||
data->chunk = new BlockChunk(blocks);
|
||||
data->done = true;
|
||||
|
@ -205,6 +218,7 @@ void World::handleMeshGenQueue() {
|
|||
}
|
||||
|
||||
Timer t("Mesh Initialization");
|
||||
int meshUpdates = 0;
|
||||
for (auto iter = finishedMesh.begin(); iter != finishedMesh.end(); ) {
|
||||
if (t.elapsedNs() > 4000000) break;
|
||||
|
||||
|
@ -225,7 +239,10 @@ void World::handleMeshGenQueue() {
|
|||
|
||||
iter = finishedMesh.erase(iter);
|
||||
delete threadData;
|
||||
|
||||
meshUpdates++;
|
||||
}
|
||||
lastMeshUpdates = meshUpdates;
|
||||
// t.printElapsedMs();
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ public:
|
|||
|
||||
return out;
|
||||
}
|
||||
|
||||
int lastGenUpdates, lastMeshUpdates;
|
||||
private:
|
||||
//Global lists for storing blockChunks and meshChunks
|
||||
std::unordered_map<glm::vec3, BlockChunk*, vec3cmp> blockChunks;
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// Created by aurailus on 10/01/19.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "Packet.h"
|
||||
|
||||
Packet::Packet(Packet::PacketType p) {
|
||||
this->type = p;
|
||||
}
|
||||
|
||||
//Convert a vector of PacketBytes (chars) into a PacketData by splitting the head and body information.
|
||||
Packet Packet::deserialize(std::vector<PacketByte> data) {
|
||||
if (data.size() < 4) std::cerr << "Packet does not contain data." << std::endl;
|
||||
|
||||
//Seperate the packet header from the body,
|
||||
//This can be changed to support more header values in the future.
|
||||
|
||||
//Determine Packet Type
|
||||
int num = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
num <<= 8;
|
||||
num |= data[i];
|
||||
}
|
||||
|
||||
//Get body of the packet
|
||||
std::vector<PacketByte> dataBody;
|
||||
dataBody.reserve(data.size() - 4);
|
||||
|
||||
for (int i = 4; i < data.size(); i++) {
|
||||
dataBody.push_back(data[i]);
|
||||
}
|
||||
|
||||
auto p = Packet();
|
||||
p.type = (PacketType)num;
|
||||
p.length = dataBody.size();
|
||||
p.data = std::move(dataBody);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
//Convert a PacketData into a serialized form to send over UDP.
|
||||
std::vector<Packet::PacketByte> Packet::serialize() {
|
||||
std::vector<PacketByte> data;
|
||||
data.reserve(this->length + 4);
|
||||
|
||||
//Encode Packet Type
|
||||
encodeInt(data, (int)this->type);
|
||||
|
||||
//Add body of the packet
|
||||
for (PacketByte i : this->data) {
|
||||
data.push_back(i);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
void Packet::encodeInt(std::vector<Packet::PacketByte> &target, int num) {
|
||||
target.push_back((num >> 24) & 0xFF);
|
||||
target.push_back((num >> 16) & 0xFF);
|
||||
target.push_back((num >> 8) & 0xFF);
|
||||
target.push_back((num) & 0xFF);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
int Packet::decodeInt(PacketByte* intStart) {
|
||||
int num = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
num <<= 8;
|
||||
num |= *(intStart++);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
void Packet::addIntegers(std::vector<int> &integers) {
|
||||
for (int i : integers) {
|
||||
encodeInt(this->data, i);
|
||||
}
|
||||
this->length = data.size();
|
||||
}
|
||||
|
||||
void Packet::addInt(int integer) {
|
||||
encodeInt(this->data, integer);
|
||||
this->length = data.size();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Created by aurailus on 10/01/19.
|
||||
//
|
||||
|
||||
#ifndef ZEUS_PACKET_H
|
||||
#define ZEUS_PACKET_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Packet {
|
||||
public:
|
||||
typedef unsigned long PacketType;
|
||||
typedef unsigned char PacketByte;
|
||||
|
||||
Packet() = default;
|
||||
explicit Packet(PacketType p);
|
||||
|
||||
void addIntegers(std::vector<int> &integers);
|
||||
void addInt(int integer);
|
||||
|
||||
unsigned long length;
|
||||
PacketType type;
|
||||
std::vector<PacketByte> data;
|
||||
|
||||
~Packet() = default;
|
||||
|
||||
static Packet deserialize(std::vector<PacketByte> data);
|
||||
std::vector<Packet::PacketByte> serialize();
|
||||
|
||||
static void encodeInt(std::vector<PacketByte> &target, int num);
|
||||
static int decodeInt(PacketByte* intStart);
|
||||
public:
|
||||
const static PacketType HANDSHAKE = 0;
|
||||
const static PacketType AUTHENTICATE = 1;
|
||||
const static PacketType KEEPALIVE = 2;
|
||||
};
|
||||
|
||||
|
||||
#endif //ZEUS_PACKET_H
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Created by aurailus on 09/01/19.
|
||||
//
|
||||
|
||||
#include "Server.h"
|
||||
|
||||
Server::Server() = default;
|
||||
|
||||
Server::Server(int port) {
|
||||
//TODO: Use the port in the server initializer
|
||||
this->port = port;
|
||||
alive = true;
|
||||
}
|
||||
|
||||
void Server::start() {
|
||||
server_socket = new asio::ip::udp::socket(io_context, udp::endpoint(udp::v4(), 12346));
|
||||
|
||||
while (alive) loop();
|
||||
}
|
||||
|
||||
void Server::loop() {
|
||||
|
||||
//Collect incoming packets
|
||||
while (server_socket->available() > 0) {
|
||||
size_t pendingSize = server_socket->available();
|
||||
std::vector<Packet::PacketByte> recv_buf((unsigned long)pendingSize);
|
||||
|
||||
auto remote_endpoint = new udp::endpoint();
|
||||
server_socket->receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint);
|
||||
|
||||
auto packet = Packet::deserialize(recv_buf);
|
||||
if (packet.length > 0) handlePacket(packet, remote_endpoint);
|
||||
}
|
||||
|
||||
long sleep_for = 16L*1000000L;
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(sleep_for));
|
||||
}
|
||||
|
||||
void Server::handlePacket(Packet &packet, udp::endpoint* endpoint) {
|
||||
std::cout << packet.type << ", " << Packet::decodeInt(&packet.data[0]) << std::endl;
|
||||
}
|
||||
|
||||
void Server::cleanup() {
|
||||
alive = false;
|
||||
|
||||
delete server_socket;
|
||||
}
|
||||
|
||||
Server::~Server() {
|
||||
cleanup();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Created by aurailus on 09/01/19.
|
||||
//
|
||||
|
||||
#ifndef ZEUS_SERVER_H
|
||||
#define ZEUS_SERVER_H
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "../engine/Timer.h"
|
||||
#include "ClientConnection.h"
|
||||
#include "Packet.h"
|
||||
#include <iostream>
|
||||
#include <asio.hpp>
|
||||
|
||||
using asio::ip::udp;
|
||||
|
||||
class Server {
|
||||
public:
|
||||
Server();
|
||||
explicit Server(int port);
|
||||
|
||||
void start();
|
||||
|
||||
~Server();
|
||||
private:
|
||||
void loop();
|
||||
void cleanup();
|
||||
|
||||
void handlePacket(Packet& packet, udp::endpoint* endpoint);
|
||||
|
||||
std::map<std::string, ClientConnection*> connections;
|
||||
|
||||
int port;
|
||||
bool alive;
|
||||
asio::io_context io_context;
|
||||
udp::socket* server_socket;
|
||||
};
|
||||
|
||||
|
||||
#endif //ZEUS_SERVER_H
|
Loading…
Reference in New Issue