From 061ecaebe1efa3d908a47f4f7bb7a665f8d0d456 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 3 Mar 2021 15:59:00 +0100 Subject: [PATCH] New structure --- .gitignore | 2 +- CMakeLists.txt | 42 ++++++- later_use/dynamiclibrary.cpp | 26 ++++ later_use/network_mgr.hpp | 35 ++++++ later_use/network_packet.hpp | 31 +++++ later_use/peer.cpp | 13 ++ later_use/peer.hpp | 11 ++ later_use/udp_socket.cpp | 56 +++++++++ later_use/udp_socket.hpp | 35 ++++++ shaders/vertex.glsl | 1 + src/animations.cpp | 35 ++++++ src/animations.hpp | 38 ++++++ src/async_mgr.cpp | 41 +++++++ src/async_mgr.hpp | 27 ++++ src/{dragonblocks => }/block.cpp | 0 src/{dragonblocks => }/block.hpp | 0 src/block_def.cpp | 15 +++ src/{dragonblocks => }/block_def.hpp | 8 +- .../cube.cpp => box_vertices.cpp} | 4 +- src/box_vertices.hpp | 8 ++ src/{dragonblocks => }/camera.cpp | 18 ++- src/{dragonblocks => }/camera.hpp | 10 +- src/{dragonblocks => }/chunk.cpp | 57 +++++---- src/{dragonblocks => }/chunk.hpp | 15 ++- src/client.cpp | 88 +++++++++++++ src/client.hpp | 33 +++++ src/dragonblocks/CMakeLists.txt | 41 ------- src/dragonblocks/block_def.cpp | 26 ---- src/dragonblocks/client.cpp | 60 --------- src/dragonblocks/client.hpp | 25 ---- src/dragonblocks/core.cpp | 15 --- src/dragonblocks/core.hpp | 14 --- src/dragonblocks/cube.hpp | 10 -- src/dragonblocks/gl.hpp | 6 - src/dragonblocks/gldebug.hpp | 10 -- src/dragonblocks/input_handler.cpp | 76 ------------ src/dragonblocks/input_handler.hpp | 35 ------ src/dragonblocks/log.cpp | 17 --- src/dragonblocks/log.hpp | 8 -- src/dragonblocks/mesh_gen_mgr.cpp | 60 --------- src/dragonblocks/mesh_gen_mgr.hpp | 32 ----- src/dragonblocks/player.cpp | 88 ------------- src/dragonblocks/render_engine.cpp | 116 ------------------ src/dragonblocks/render_engine.hpp | 43 ------- src/dragonblocks/world.cpp | 1 - src/dragonblocks/world.hpp | 12 -- src/dragonblockslauncher/CMakeLists.txt | 13 -- src/dragonblockslauncher/launcher.cpp | 52 -------- src/dragonblockslauncher/launcher.hpp | 10 -- src/dragonblockslauncher/main.cpp | 6 - src/entity.cpp | 53 ++++++++ src/entity.hpp | 40 ++++++ src/{dragonblocks => }/face_dir.cpp | 0 src/{dragonblocks => }/face_dir.hpp | 0 src/{dragonblocks => }/game.cpp | 3 +- src/{dragonblocks => }/game.hpp | 0 src/{dragonblocks/gldebug.cpp => gl.cpp} | 6 +- src/gl.hpp | 14 +++ src/input_handler.cpp | 58 +++++++++ src/input_handler.hpp | 31 +++++ src/launcher/main.c | 53 ++++++++ src/local_entity.cpp | 71 +++++++++++ src/local_entity.hpp | 37 ++++++ src/local_player.cpp | 75 +++++++++++ .../player.hpp => local_player.hpp} | 21 ++-- src/{dragonblocks => }/map.cpp | 4 +- src/{dragonblocks => }/map.hpp | 8 +- src/{dragonblocks => }/mapgen.cpp | 3 +- src/{dragonblocks => }/mapgen.hpp | 2 +- src/{dragonblocks => }/mesh.cpp | 113 +++++++++-------- src/{dragonblocks => }/mesh.hpp | 46 +++---- src/render_engine.cpp | 71 +++++++++++ src/render_engine.hpp | 28 +++++ src/{dragonblocks => }/scene.cpp | 5 +- src/{dragonblocks => }/scene.hpp | 3 +- src/{dragonblocks => }/shader_program.cpp | 0 src/{dragonblocks => }/shader_program.hpp | 0 src/{dragonblocks => }/texture.cpp | 5 +- src/{dragonblocks => }/texture.hpp | 0 src/tile_def.cpp | 30 +++++ src/tile_def.hpp | 20 +++ src/{dragonblocks => }/window.cpp | 6 +- src/{dragonblocks => }/window.hpp | 2 +- textures/leaves.png | Bin 979 -> 0 bytes 84 files changed, 1293 insertions(+), 940 deletions(-) create mode 100644 later_use/dynamiclibrary.cpp create mode 100644 later_use/network_mgr.hpp create mode 100644 later_use/network_packet.hpp create mode 100644 later_use/peer.cpp create mode 100644 later_use/peer.hpp create mode 100644 later_use/udp_socket.cpp create mode 100644 later_use/udp_socket.hpp create mode 100644 src/animations.cpp create mode 100644 src/animations.hpp create mode 100644 src/async_mgr.cpp create mode 100644 src/async_mgr.hpp rename src/{dragonblocks => }/block.cpp (100%) rename src/{dragonblocks => }/block.hpp (100%) create mode 100644 src/block_def.cpp rename src/{dragonblocks => }/block_def.hpp (51%) rename src/{dragonblocks/cube.cpp => box_vertices.cpp} (93%) create mode 100644 src/box_vertices.hpp rename src/{dragonblocks => }/camera.cpp (72%) rename src/{dragonblocks => }/camera.hpp (70%) rename src/{dragonblocks => }/chunk.cpp (72%) rename src/{dragonblocks => }/chunk.hpp (75%) create mode 100644 src/client.cpp create mode 100644 src/client.hpp delete mode 100644 src/dragonblocks/CMakeLists.txt delete mode 100644 src/dragonblocks/block_def.cpp delete mode 100644 src/dragonblocks/client.cpp delete mode 100644 src/dragonblocks/client.hpp delete mode 100644 src/dragonblocks/core.cpp delete mode 100644 src/dragonblocks/core.hpp delete mode 100644 src/dragonblocks/cube.hpp delete mode 100644 src/dragonblocks/gl.hpp delete mode 100644 src/dragonblocks/gldebug.hpp delete mode 100644 src/dragonblocks/input_handler.cpp delete mode 100644 src/dragonblocks/input_handler.hpp delete mode 100644 src/dragonblocks/log.cpp delete mode 100644 src/dragonblocks/log.hpp delete mode 100644 src/dragonblocks/mesh_gen_mgr.cpp delete mode 100644 src/dragonblocks/mesh_gen_mgr.hpp delete mode 100644 src/dragonblocks/player.cpp delete mode 100644 src/dragonblocks/render_engine.cpp delete mode 100644 src/dragonblocks/render_engine.hpp delete mode 100644 src/dragonblocks/world.cpp delete mode 100644 src/dragonblocks/world.hpp delete mode 100644 src/dragonblockslauncher/CMakeLists.txt delete mode 100644 src/dragonblockslauncher/launcher.cpp delete mode 100644 src/dragonblockslauncher/launcher.hpp delete mode 100644 src/dragonblockslauncher/main.cpp create mode 100644 src/entity.cpp create mode 100644 src/entity.hpp rename src/{dragonblocks => }/face_dir.cpp (100%) rename src/{dragonblocks => }/face_dir.hpp (100%) rename src/{dragonblocks => }/game.cpp (75%) rename src/{dragonblocks => }/game.hpp (100%) rename src/{dragonblocks/gldebug.cpp => gl.cpp} (87%) create mode 100644 src/gl.hpp create mode 100644 src/input_handler.cpp create mode 100644 src/input_handler.hpp create mode 100644 src/launcher/main.c create mode 100644 src/local_entity.cpp create mode 100644 src/local_entity.hpp create mode 100644 src/local_player.cpp rename src/{dragonblocks/player.hpp => local_player.hpp} (60%) rename src/{dragonblocks => }/map.cpp (87%) rename src/{dragonblocks => }/map.hpp (84%) rename src/{dragonblocks => }/mapgen.cpp (93%) rename src/{dragonblocks => }/mapgen.hpp (81%) rename src/{dragonblocks => }/mesh.cpp (51%) rename src/{dragonblocks => }/mesh.hpp (54%) create mode 100644 src/render_engine.cpp create mode 100644 src/render_engine.hpp rename src/{dragonblocks => }/scene.cpp (66%) rename src/{dragonblocks => }/scene.hpp (75%) rename src/{dragonblocks => }/shader_program.cpp (100%) rename src/{dragonblocks => }/shader_program.hpp (100%) rename src/{dragonblocks => }/texture.cpp (95%) rename src/{dragonblocks => }/texture.hpp (100%) create mode 100644 src/tile_def.cpp create mode 100644 src/tile_def.hpp rename src/{dragonblocks => }/window.cpp (96%) rename src/{dragonblocks => }/window.hpp (97%) delete mode 100644 textures/leaves.png diff --git a/.gitignore b/.gitignore index d552926..d38d963 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,5 @@ compile_commands.json CTestTestfile.cmake _deps libdragonblocks.so -dragonblockslauncher +dragonblocks.bin oprofile_data/ diff --git a/CMakeLists.txt b/CMakeLists.txt index fb1894d..df2de30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,5 +6,43 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -add_subdirectory("${PROJECT_SOURCE_DIR}/src/dragonblocks/") -add_subdirectory("${PROJECT_SOURCE_DIR}/src/dragonblockslauncher/") +add_library(dragonblocks SHARED + src/animations.cpp + src/async_mgr.cpp + src/block.cpp + src/block_def.cpp + src/box_vertices.cpp + src/camera.cpp + src/chunk.cpp + src/client.cpp + src/entity.cpp + src/face_dir.cpp + src/game.cpp + src/gl.cpp + src/input_handler.cpp + src/local_entity.cpp + src/local_player.cpp + src/map.cpp + src/mapgen.cpp + src/mesh.cpp + src/render_engine.cpp + src/scene.cpp + src/shader_program.cpp + src/texture.cpp + src/tile_def.cpp + src/window.cpp +) + +target_link_libraries(dragonblocks + GL + GLEW + glfw +) + +target_include_directories(dragonblocks PUBLIC + "${PROJECT_SOURCE_DIR}/lib/" +) + +add_executable(dragonblocks.bin src/launcher/main.c) + +target_link_libraries(dragonblocks.bin dl) diff --git a/later_use/dynamiclibrary.cpp b/later_use/dynamiclibrary.cpp new file mode 100644 index 0000000..e450931 --- /dev/null +++ b/later_use/dynamiclibrary.cpp @@ -0,0 +1,26 @@ +// Just some code to use later when C++ Runtime Mods are introduced + +class DynamicLibrary +{ + public: + std::string filename; + std::string error; + bool success; + void *handle; + DynamicLibrary(std::string); +}; +DynamicLibrary *loadDynamicLibrary(std::string); + +DynamicLibrary::DynamicLibrary(std::string f) +{ + filename = f; + + handle = dlmopen(LM_ID_BASE, filename.c_str(), RTLD_NOW | RTLD_GLOBAL); + + if (handle) { + success = true; + } else { + error = dlerror(); + success = false; + } +} diff --git a/later_use/network_mgr.hpp b/later_use/network_mgr.hpp new file mode 100644 index 0000000..600b76b --- /dev/null +++ b/later_use/network_mgr.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include +#include +#include "udp_socket.hpp" + +namespace dragonblocks +{ + class NetworkMgr + { + public: + class IPeer + { + public: + UDPSocket::Address *address; + NetworkMgr *network_mgr; + }; + + class INamespace + { + public: + virtual void handle(Packet *); + }; + + UDPSocket *socket; + std::queue out_queue; + std::set peers_set; + std::map
peers; + void sendPacket(Packet *); + void disconnectPeer(IPeer *); + std::map namespaces; + }; +} diff --git a/later_use/network_packet.hpp b/later_use/network_packet.hpp new file mode 100644 index 0000000..93e9fb6 --- /dev/null +++ b/later_use/network_packet.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +namespace dragonblocks +{ + class Connection; + + class NetworkPacket + { + public: + enum Type + { + INVALID, + TOSERVER_HELLO, + TOCLIENT_HELLO, + TOSERVER_BYE, + TOCLIENT_BYE, + TYPE_COUNT, + }; + + std::stringstream content; + + NetworkPacket() = default; + NetworkPacket(const Type &); + NetworkPacket(const NetworkPacket &) = default; + + private: + Type type = INVALID; + }; +} diff --git a/later_use/peer.cpp b/later_use/peer.cpp new file mode 100644 index 0000000..9ea61d4 --- /dev/null +++ b/later_use/peer.cpp @@ -0,0 +1,13 @@ +#include +#include "connection.hpp" + +using namespace std; +using namespace dragonblocks; + +void Connection::setAddress(const string &addr) +{ + if(inet_pton(AF_INET, addr.c_str(), &address.sin_addr) <= 0) + throw runtime_error(string("Invalid address: ") + addr); +} + + diff --git a/later_use/peer.hpp b/later_use/peer.hpp new file mode 100644 index 0000000..5a148b9 --- /dev/null +++ b/later_use/peer.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include "network_packet.hpp" + +namespace dragonblocks +{ + std::queue in_packets; + std::queue out_packets; +} diff --git a/later_use/udp_socket.cpp b/later_use/udp_socket.cpp new file mode 100644 index 0000000..04ce87a --- /dev/null +++ b/later_use/udp_socket.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include "udp_socket.hpp" + +#define PACKSIZE DRAGONBLOCKS_UPD_SOCKET_PACKAGE_SIZE + +using namespace std; +using namespace dragonblocks; + +UDPSocket::Address::Address(const string &adr, int port) +{ + address.sin_family = AF_INET; + address.sin_port = htons(port); + inet_pton(AF_INET, adr.c_str(), &address.sin_addr); +} +void UDPSocket::connect() +{ + if (::connect(sockfd, (struct sockaddr *)&address.address, address.length) < 0) + throw runtime_error("Connection failed"); +} + +void UDPSocket::bind() +{ + if (::bind(sockfd, (struct sockaddr *)&address.address, address.length) < 0) + throw runtime_error("Bind failed"); +} + +void UDPSocket::close() +{ + ::close(sockfd); +} + +void UDPSocket::send(const std::string &str, Address *addr) +{ + if (! addr) { + addr = &address; + } + sendto(sockfd, str.c_str(), min((int)str.size(), PACKSIZE), MSG_CONFIRM, (struct sockaddr *)&addr->address, addr->length); +} + +string UDPSocket::recv(Address *addr) +{ + if (! addr) { + addr = &address; + } + char buffer[PACKSIZE + 1] = {0}; // include \0 at the end + recvfrom(sockfd, buffer, PACKSIZE, MSG_WAITALL, (struct sockaddr *)&addr->address, (socklen_t *)&addr->length); + return buffer; +} + +UDPSocket::UDPSocket(const string &adr, int port) : address(adr, port) +{ + sockfd = socket(AF_INET, SOCK_DGRAM, 0); +} diff --git a/later_use/udp_socket.hpp b/later_use/udp_socket.hpp new file mode 100644 index 0000000..3dec081 --- /dev/null +++ b/later_use/udp_socket.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#define DRAGONBLOCKS_UPD_SOCKET_PACKAGE_SIZE 1024 + +namespace dragonblocks +{ + class UDPSocket + { + public: + class Address + { + public: + struct sockaddr_in address; + int length; + + Address() = default; + Address(const std::string &, int); + }; + + void connect(); + void bind(); + void close(); + void send(const std::string &, Address * = nullptr); // server specifies address + std::string recv(Address * = nullptr); // server provides a buffer for the address + + UDPSocket(const std::string &, int); + + private: + int sockfd; + Address address; // for client, this is the address of the server; for server it is the own address. + }; +} diff --git a/shaders/vertex.glsl b/shaders/vertex.glsl index 28fc533..b418d98 100755 --- a/shaders/vertex.glsl +++ b/shaders/vertex.glsl @@ -16,3 +16,4 @@ void main() gl_Position = projection * cameraRelCoords; ourTexCoord = aTexCoord; } + diff --git a/src/animations.cpp b/src/animations.cpp new file mode 100644 index 0000000..14eeff1 --- /dev/null +++ b/src/animations.cpp @@ -0,0 +1,35 @@ +#include +#include "animations.hpp" + +using namespace glm; +using namespace dragonblocks; + +vec3 FlyInAnimation::getPos(vec3 pos) +{ + pos.y -= offset * time_left / last_for; + return pos; +} + +FlyInAnimation::FlyInAnimation(double l, double o, void (*on)(void *), void *e) : Mesh::IAnimation(l, on, e), last_for(l), offset(o) +{ +} + +vec3 GrowAnimation::getSize(vec3 size) +{ + size *= 1 - time_left / last_for; + return size; +} + +GrowAnimation::GrowAnimation(double l, void (*o)(void *), void *e) : Mesh::IAnimation(l, o, e), last_for(l) +{ +} + +float RotateAnimation::getRotationAngle(float rotation_angle) +{ + rotation_angle += glfwGetTime() * speed * pi() * 2; + return rotation_angle; +} + +RotateAnimation::RotateAnimation(double s) : speed(s) +{ +} diff --git a/src/animations.hpp b/src/animations.hpp new file mode 100644 index 0000000..642521b --- /dev/null +++ b/src/animations.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "gl.hpp" +#include "mesh.hpp" + +namespace dragonblocks +{ + class FlyInAnimation : public Mesh::IAnimation + { + public: + double last_for; + double offset; + + glm::vec3 getPos(glm::vec3); + + FlyInAnimation(double = 0.4, double = 20.0, void (*)(void *) = nullptr, void * = nullptr); + }; + + class GrowAnimation : public Mesh::IAnimation + { + public: + double last_for; + + glm::vec3 getSize(glm::vec3); + + GrowAnimation(double = 0.25, void (*)(void *) = nullptr, void * = nullptr); + }; + + class RotateAnimation : public Mesh::IAnimation + { + public: + double speed; + + float getRotationAngle(float); + + RotateAnimation(double = 1.0); + }; +} diff --git a/src/async_mgr.cpp b/src/async_mgr.cpp new file mode 100644 index 0000000..b72d0eb --- /dev/null +++ b/src/async_mgr.cpp @@ -0,0 +1,41 @@ +#include +#include +#include "async_mgr.hpp" + +using namespace std; +using namespace dragonblocks; + +void AsyncMgr::ITask::doAsyncTask() +{ +} + +void AsyncMgr::addTask(AsyncMgr::ITask *t) +{ + mtx.lock(); + queued_jobs.push_back(t); + mtx.unlock(); +} + +void AsyncMgr::run() +{ + while (true) { + set active_set; + mtx.lock(); + vector active = queued_jobs; + queued_jobs.clear(); + mtx.unlock(); + for (auto it = active.begin(); it != active.end(); it++) { + AsyncMgr::ITask *t = *it; + if (active_set.find(t) == active_set.end()) { + t->doAsyncTask(); + } + } + } +} + + + +void AsyncMgr::start() +{ + async_thread = thread(&AsyncMgr::run, this); +} diff --git a/src/async_mgr.hpp b/src/async_mgr.hpp new file mode 100644 index 0000000..a62be0d --- /dev/null +++ b/src/async_mgr.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +namespace dragonblocks +{ + class AsyncMgr : public std::thread + { + public: + class ITask + { + public: + virtual void doAsyncTask(); + }; + + void addTask(ITask *); + void run(); + void start(); + + private: + std::mutex mtx; + std::vector queued_jobs; + std::thread async_thread; + }; +} diff --git a/src/dragonblocks/block.cpp b/src/block.cpp similarity index 100% rename from src/dragonblocks/block.cpp rename to src/block.cpp diff --git a/src/dragonblocks/block.hpp b/src/block.hpp similarity index 100% rename from src/dragonblocks/block.hpp rename to src/block.hpp diff --git a/src/block_def.cpp b/src/block_def.cpp new file mode 100644 index 0000000..a797320 --- /dev/null +++ b/src/block_def.cpp @@ -0,0 +1,15 @@ +#include "block_def.hpp" + +using namespace std; +using namespace dragonblocks; + +BlockDef::BlockDef(const string &n, const TileDef &t) : name(n), tile_def(t) +{ + if (tile_def.size() == 0) { + drawable = false; + } +} + +BlockDef::BlockDef(const string &n) : BlockDef(n, TileDef()) +{ +} diff --git a/src/dragonblocks/block_def.hpp b/src/block_def.hpp similarity index 51% rename from src/dragonblocks/block_def.hpp rename to src/block_def.hpp index b4ac3c7..140422d 100644 --- a/src/dragonblocks/block_def.hpp +++ b/src/block_def.hpp @@ -1,9 +1,8 @@ #pragma once #include -#include #include "gl.hpp" -#include "texture.hpp" +#include "tile_def.hpp" namespace dragonblocks { @@ -11,11 +10,10 @@ namespace dragonblocks { public: std::string name; - std::vector tiles; + TileDef tile_def; bool drawable = true; BlockDef(const std::string &); - BlockDef(const std::string &, const Texture &); - BlockDef(const std::string &, const std::vector &); + BlockDef(const std::string &, const TileDef &); }; } diff --git a/src/dragonblocks/cube.cpp b/src/box_vertices.cpp similarity index 93% rename from src/dragonblocks/cube.cpp rename to src/box_vertices.cpp index e132b70..1148614 100644 --- a/src/dragonblocks/cube.cpp +++ b/src/box_vertices.cpp @@ -1,6 +1,6 @@ -#include "cube.hpp" +#include "box_vertices.hpp" -GLfloat dragonblocks::cube[DRAGONBLOCKS_CUBE_VERTEX_COUNT] = { +GLfloat dragonblocks::box_vertices[6][6][5] = { // x y z s t -0.5, -0.5, -0.5, +0.0, +0.0, +0.5, -0.5, -0.5, +1.0, +0.0, diff --git a/src/box_vertices.hpp b/src/box_vertices.hpp new file mode 100644 index 0000000..7fa551b --- /dev/null +++ b/src/box_vertices.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "gl.hpp" + +namespace dragonblocks +{ + extern GLfloat box_vertices[6][6][5]; +} diff --git a/src/dragonblocks/camera.cpp b/src/camera.cpp similarity index 72% rename from src/dragonblocks/camera.cpp rename to src/camera.cpp index 2aa749d..71405e7 100644 --- a/src/dragonblocks/camera.cpp +++ b/src/camera.cpp @@ -9,7 +9,12 @@ mat4 Camera::getViewMatrix() const return lookAt(pos, pos + m_front, m_up); } -void Camera::update(double yaw, double pitch) +void Camera::toggleMode() +{ + m_third_person = ! m_third_person; +} + +void Camera::update(double yaw, double pitch, const vec3 &p) { yaw = radians(yaw); pitch = radians(pitch); @@ -17,6 +22,12 @@ void Camera::update(double yaw, double pitch) m_front = normalize(vec3(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch))); m_right = normalize(cross(m_front, m_world_up)); m_up = normalize(cross(m_right, m_front)); + + pos = p; + + if (m_third_person) { + pos -= m_front * 2.0f; + } } vec3 Camera::up() const @@ -34,6 +45,11 @@ vec3 Camera::right() const return m_right; } +bool Camera::thirdPerson() const +{ + return m_third_person; +} + Camera::Camera() : pos(0, 0, 0), m_up(0, 1, 0), m_world_up(0, 1, 0), m_front(0, 0, -1) { } diff --git a/src/dragonblocks/camera.hpp b/src/camera.hpp similarity index 70% rename from src/dragonblocks/camera.hpp rename to src/camera.hpp index 4ed82df..7e01840 100644 --- a/src/dragonblocks/camera.hpp +++ b/src/camera.hpp @@ -7,17 +7,19 @@ namespace dragonblocks class Camera { public: - glm::vec3 pos; - glm::mat4 getViewMatrix() const; - void update(double, double); + void toggleMode(); + void update(double, double, const glm::vec3 &); glm::vec3 up() const; glm::vec3 front() const; glm::vec3 right() const; + bool thirdPerson() const; Camera(); - private: + private: + glm::vec3 pos; + bool m_third_person; glm::vec3 m_up; glm::vec3 m_world_up; glm::vec3 m_front; diff --git a/src/dragonblocks/chunk.cpp b/src/chunk.cpp similarity index 72% rename from src/dragonblocks/chunk.cpp rename to src/chunk.cpp index 2100511..bf356e0 100644 --- a/src/dragonblocks/chunk.cpp +++ b/src/chunk.cpp @@ -1,9 +1,10 @@ +#include #include -#include "block_def.hpp" +#include "animations.hpp" +#include "block_def.hpp" +#include "box_vertices.hpp" #include "chunk.hpp" -#include "cube.hpp" #include "face_dir.hpp" -#include "log.hpp" #include "map.hpp" #include "mesh.hpp" #include "texture.hpp" @@ -14,30 +15,30 @@ using namespace std; using namespace glm; using namespace dragonblocks; -void Chunk::checkPos(const ivec3 &pos) +bool Chunk::checkPos(const ivec3 &pos) { - if (pos.x < 0 || pos.y < 0 || pos.z < 0 || pos.x >= SIZE || pos.y >= SIZE || pos.z >= SIZE) - throw out_of_range("Block position out of range"); + return pos.x >= 0 && pos.y >= 0 && pos.z >= 0 && pos.x < SIZE && pos.y < SIZE && pos.z < SIZE; } const Block *Chunk::getBlock(const ivec3 &pos) const { - Chunk::checkPos(pos); - return &data.blocks[pos.x][pos.y][pos.z]; + const Block *b = getBlockNoEx(pos); + if (! b) { + throw out_of_range("Block position out of range"); + } + return b; } const Block *Chunk::getBlockNoEx(const ivec3 &pos) const { - try { - return getBlock(pos); - } catch (out_of_range &) { - return nullptr; - } + return Chunk::checkPos(pos) ? &data.blocks[pos.x][pos.y][pos.z] : nullptr; } void Chunk::setBlock(const ivec3 &pos, const Block &block) { - Chunk::checkPos(pos); + if (! Chunk::checkPos(pos)) { + throw out_of_range("Block position out of range"); + } data.blocks[pos.x][pos.y][pos.z] = block; } @@ -51,7 +52,7 @@ void Chunk::setBlockNoEx(const ivec3 &pos, const Block &block) void Chunk::addMeshUpdateTask() { - mesh_gen_mgr->addTask(this); + async_mgr->addTask(this); } void Chunk::addMeshUpdateTaskWithEdge() @@ -66,7 +67,7 @@ void Chunk::addMeshUpdateTaskWithEdge() void Chunk::updateMesh() { - log(string("Update Chunk Mesh at ") + to_string(pos.x) + " " + to_string(pos.y) + " " + to_string(pos.z)); + cout << "Update Chunk Mesh at " << pos.x << " " << pos.y << " " << pos.z << endl; if (mesh_created && ! animation_finished) return; @@ -98,11 +99,10 @@ void Chunk::updateMesh() if (! mesh_created_before) neighbor = neighbor_own; if (! mesh_created_before && ! neighbor || neighbor && ! neighbor->getDef()->drawable) { - textures.push_back(def->tiles[facenr]); + textures.push_back(def->tile_def.get(facenr)); for (int vertex_index = 0; vertex_index < 6; vertex_index++) { for (int attribute_index = 0; attribute_index < 5; attribute_index++) { - int index = facenr * 6 * 5 + vertex_index * 5 + attribute_index; - GLdouble value = cube[index]; + GLdouble value = box_vertices[facenr][vertex_index][attribute_index]; switch (attribute_index) { case 0: value += pos_from_mesh_origin.x; @@ -127,7 +127,7 @@ void Chunk::updateMesh() if (! mesh_created_before) { afterAnimation(); } else if (mesh) { - delete mesh; + mesh->die(); mesh = nullptr; } return; @@ -135,14 +135,14 @@ void Chunk::updateMesh() Mesh *oldmesh = mesh; - mesh = new Mesh(scene, &vertices[0], vertices.size() * sizeof(GLfloat)); + mesh = new Mesh(scene, shader_program, &vertices[0], vertices.size()); mesh->pos = pos * SIZE + SIZE / 2; - mesh->minp = vec3(- SIZE / 2 - 1); - mesh->maxp = vec3(+ SIZE / 2 + 1); + mesh->minp = vec3(- SIZE / 2); + mesh->maxp = vec3(+ SIZE / 2); mesh->textures = textures; mesh->vertices_per_texture = 6; if (! mesh_created_before) { - mesh->animation = Mesh::Animation(Mesh::Animation::Type::FLYIN, Chunk::staticAfterAnimation, this); + mesh->animation = new FlyInAnimation(0.4, 20.0, Chunk::staticAfterAnimation, this); } if (oldmesh) { @@ -150,7 +150,12 @@ void Chunk::updateMesh() } } -Chunk::Chunk(Map *m, const glm::ivec3 &p, const Data &d, MeshGenMgr *mg, Scene *s) : map(m), data(d), pos(p), mesh_gen_mgr(mg), scene(s) +void Chunk::doAsyncTask() +{ + updateMesh(); +} + +Chunk::Chunk(Map *m, const ivec3 &p, const Data &d, AsyncMgr *a, Scene *s, ShaderProgram *sh) : map(m), data(d), pos(p), async_mgr(a), scene(s), shader_program(sh) { addMeshUpdateTask(); } @@ -158,7 +163,7 @@ Chunk::Chunk(Map *m, const glm::ivec3 &p, const Data &d, MeshGenMgr *mg, Scene * Chunk::~Chunk() { if (mesh) { - delete mesh; + mesh->die(); } } diff --git a/src/dragonblocks/chunk.hpp b/src/chunk.hpp similarity index 75% rename from src/dragonblocks/chunk.hpp rename to src/chunk.hpp index 5561c38..ac12851 100644 --- a/src/dragonblocks/chunk.hpp +++ b/src/chunk.hpp @@ -2,7 +2,7 @@ #include "block.hpp" #include "gl.hpp" -#include "mesh_gen_mgr.hpp" +#include "async_mgr.hpp" #define DRAGONBLOCKS_CHUNK_SIZE 16 @@ -11,11 +11,12 @@ namespace dragonblocks class Map; class Mesh; class Scene; + class ShaderProgram; - class Chunk : public MeshGenMgr::MeshGenerator + class Chunk : public AsyncMgr::ITask { public: - static void checkPos(const glm::ivec3 &); + static bool checkPos(const glm::ivec3 &); class Data { @@ -34,17 +35,19 @@ namespace dragonblocks void addMeshUpdateTask(); void addMeshUpdateTaskWithEdge(); void updateMesh(); + void doAsyncTask(); - Chunk(Map *, const glm::ivec3 &, const Data &, MeshGenMgr *, Scene *); + Chunk(Map *, const glm::ivec3 &, const Data &, AsyncMgr *, Scene *, ShaderProgram *); ~Chunk(); private: static void staticAfterAnimation(void *); Map *map; - Mesh *mesh = nullptr; - MeshGenMgr *mesh_gen_mgr; + AsyncMgr *async_mgr; Scene *scene; + ShaderProgram *shader_program; + Mesh *mesh = nullptr; Data data; bool animation_finished = false; bool mesh_created = false; diff --git a/src/client.cpp b/src/client.cpp new file mode 100644 index 0000000..0b6809f --- /dev/null +++ b/src/client.cpp @@ -0,0 +1,88 @@ +#include +#include +#include "async_mgr.hpp" +#include "client.hpp" +#include "game.hpp" +#include "gl.hpp" +#include "input_handler.hpp" +#include "local_player.hpp" +#include "map.hpp" +#include "mapgen.hpp" +#include "render_engine.hpp" +#include "shader_program.hpp" +#include "texture.hpp" +#include "window.hpp" + +using namespace std; +using namespace glm; +using namespace dragonblocks; + +void Client::run() +{ + async_mgr->start(); + while (render_engine->running()) { + double dtime = glfwGetTime() - last_time; + last_time = glfwGetTime(); + + player->step(dtime); + + render_engine->render(dtime); + + input_handler->processInput(dtime); + + // process keys + if (input_handler->wasKeyDown(GLFW_KEY_F11)) { + render_engine->window->toggleFullscreen(); + } + } +} + +Client::Client() +{ + cout << "Initalizing Client..." << endl; + + Texture::mipmap = true; + Texture::bilinear_filter = false; + Texture::initArgs(); + + async_mgr = new AsyncMgr; + + input_handler = new InputHandler(); + input_handler->mouse_sensitivity = 20; + input_handler->listenFor(GLFW_KEY_F11); + + render_engine = new RenderEngine; + render_engine->render_distance = 1000; + render_engine->fov = 86.1; + render_engine->sky = vec3(0.52941176470588, 0.8078431372549, 0.92156862745098); // HTML skyblue + render_engine->window->setSize(1250, 750); + render_engine->window->setPos(0, 0); + render_engine->window->setTitle("Dragonblocks"); + + input_handler->setWindow(render_engine->window); + + shader_program = new ShaderProgram("shaders"); + + mapgen = new Mapgen; + + map = new Map(mapgen, async_mgr, render_engine->scene, shader_program); + + Texture player_texture; + player_texture.load("textures/stone.png"); + + player = new LocalPlayer(map, render_engine->scene, player_texture, shader_program, render_engine->camera, input_handler); + player->pitch_move = false; + player->speed = 10; + player->setSize(vec3(0.75, 1.5, 0.75)); + + game = new Game(mapgen); + + last_time = glfwGetTime(); + + cout << "Initialisation done." << endl; +} + +extern "C" void _dragonblocks_start_client() +{ + Client().run(); +} diff --git a/src/client.hpp b/src/client.hpp new file mode 100644 index 0000000..d50886a --- /dev/null +++ b/src/client.hpp @@ -0,0 +1,33 @@ +#pragma once + +namespace dragonblocks +{ + class AsyncMgr; + class Game; + class InputHandler; + class Map; + class LocalPlayer; + class Mapgen; + class RenderEngine; + class ShaderProgram; + + class Client + { + public: + AsyncMgr *async_mgr; + Game *game; + InputHandler *input_handler; + LocalPlayer *player; + Map *map; + Mapgen *mapgen; + RenderEngine *render_engine; + ShaderProgram *shader_program; + + void run(); + + Client(); + + private: + double last_time; + }; +} diff --git a/src/dragonblocks/CMakeLists.txt b/src/dragonblocks/CMakeLists.txt deleted file mode 100644 index bb7c5e4..0000000 --- a/src/dragonblocks/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -set(srcpath "${PROJECT_SOURCE_DIR}/src/dragonblocks") - -add_library(dragonblocks SHARED - block.cpp - block_def.cpp - camera.cpp - chunk.cpp - client.cpp - core.cpp - cube.cpp - face_dir.cpp - game.cpp - gldebug.cpp - input_handler.cpp - log.cpp - map.cpp - mapgen.cpp - mesh.cpp - mesh_gen_mgr.cpp - player.cpp - render_engine.cpp - scene.cpp - shader_program.cpp - texture.cpp - window.cpp - world.cpp -) - -target_link_libraries(dragonblocks - GL - GLEW - glfw -) - -target_include_directories(dragonblocks PUBLIC - "${PROJECT_SOURCE_DIR}/lib/" - "${PROJECT_SOURCE_DIR}/src/" -) - diff --git a/src/dragonblocks/block_def.cpp b/src/dragonblocks/block_def.cpp deleted file mode 100644 index 2e200ee..0000000 --- a/src/dragonblocks/block_def.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "block_def.hpp" - -using namespace std; -using namespace dragonblocks; - -BlockDef::BlockDef(const string &n, const vector &t) : name(n), tiles(t) -{ - int s = tiles.size(); - if (s == 0) { - drawable = false; - } else { - for (int i = 0; s < 6; i += s) { - for (int j = 0; j < i && j + i < 6; j++) { - tiles[i + j] = tiles[j]; - } - } - } -} - -BlockDef::BlockDef(const string &n, const Texture &t) : BlockDef(n, {t, t, t, t, t, t}) -{ -} - -BlockDef::BlockDef(const string &n) : BlockDef(n, vector()) -{ -} diff --git a/src/dragonblocks/client.cpp b/src/dragonblocks/client.cpp deleted file mode 100644 index c8fa8db..0000000 --- a/src/dragonblocks/client.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "camera.hpp" -#include "client.hpp" -#include "game.hpp" -#include "gl.hpp" -#include "input_handler.hpp" -#include "log.hpp" -#include "map.hpp" -#include "mapgen.hpp" -#include "player.hpp" -#include "render_engine.hpp" -#include "texture.hpp" -#include "window.hpp" - -using namespace glm; -using namespace dragonblocks; - -Client::Client() -{ - log("Initalizing..."); - - Texture::mipmap = true; - Texture::bilinear_filter = false; - Texture::initArgs(); - - render_engine = new RenderEngine; - - render_engine->window->setSize(1250, 750); - render_engine->window->setPos(0, 0); - render_engine->window->setTitle("Dragonblocks"); - render_engine->window->toggleFullscreen(); - render_engine->input_handler->mouse_sensitivity = 20; - - render_engine->setSky(vec3(0.52941176470588, 0.8078431372549, 0.92156862745098)); - render_engine->setRenderDistance(1000); - render_engine->setFov(86.1); - - mapgen = new Mapgen; - - map = new Map(mapgen, render_engine->mesh_gen_mgr, render_engine->scene); - - player = Player::createLocalplayer(render_engine->camera, render_engine->input_handler, map); - - player->pitch_move = false; - player->yaw = 0; - player->pitch = 0; - player->speed = 10; - player->pos = vec3(8, 8, 8); - - game = new Game(mapgen); - - log("Initialisation complete."); -} - -void Client::start() -{ - render_engine->startMeshGenMgr(); - while (render_engine->running()) { - render_engine->render(); - } -} diff --git a/src/dragonblocks/client.hpp b/src/dragonblocks/client.hpp deleted file mode 100644 index f779b68..0000000 --- a/src/dragonblocks/client.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -namespace dragonblocks -{ - class Game; - class Map; - class Mapgen; - class Player; - class RenderEngine; - - class Client - { - public: - Game *game; - Map *map; - Mapgen *mapgen; - Player *player; - RenderEngine *render_engine; - - void start(); - - Client(); - ~Client(); - }; -} diff --git a/src/dragonblocks/core.cpp b/src/dragonblocks/core.cpp deleted file mode 100644 index a04ee56..0000000 --- a/src/dragonblocks/core.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "core.hpp" -#include "client.hpp" -#include "render_engine.hpp" - -using namespace dragonblocks; - -Gametype dragonblocks::gametype; -Client *dragonblocks::client = nullptr; - -extern "C" void _dragonblocks_start_client() -{ - gametype = Gametype::CLIENT; - client = new Client(); - client->start(); -} diff --git a/src/dragonblocks/core.hpp b/src/dragonblocks/core.hpp deleted file mode 100644 index 788e899..0000000 --- a/src/dragonblocks/core.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -namespace dragonblocks -{ - class Client; - - enum Gametype - { - CLIENT - }; - - extern Gametype gametype; - extern Client *client; -} diff --git a/src/dragonblocks/cube.hpp b/src/dragonblocks/cube.hpp deleted file mode 100644 index cf6ab7c..0000000 --- a/src/dragonblocks/cube.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "gl.hpp" - -#define DRAGONBLOCKS_CUBE_VERTEX_COUNT 5 * 6 * 6 // 5 floats per vertex, 6 vertices per face, 6 faces - -namespace dragonblocks -{ - extern GLfloat cube[DRAGONBLOCKS_CUBE_VERTEX_COUNT]; -} diff --git a/src/dragonblocks/gl.hpp b/src/dragonblocks/gl.hpp deleted file mode 100644 index dcfe0bc..0000000 --- a/src/dragonblocks/gl.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include -#include -#include -#include diff --git a/src/dragonblocks/gldebug.hpp b/src/dragonblocks/gldebug.hpp deleted file mode 100644 index bc56bb6..0000000 --- a/src/dragonblocks/gldebug.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "gl.hpp" - -#define CHECKERR dragonblocks::checkGLError(__FILE__, __LINE__); - -namespace dragonblocks -{ - GLenum checkGLError(const char *file, int line); -} diff --git a/src/dragonblocks/input_handler.cpp b/src/dragonblocks/input_handler.cpp deleted file mode 100644 index 6ac64c3..0000000 --- a/src/dragonblocks/input_handler.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "camera.hpp" -#include "input_handler.hpp" -#include "window.hpp" - -using namespace std; -using namespace glm; -using namespace dragonblocks; - -void InputHandler::processInput(double dtime) -{ - processMouseInput(dtime); - processKeyInput(dtime); -} - -void InputHandler::listenFor(int key) -{ - listened_keys.insert(key); -} - -void InputHandler::dontListenFor(int key) -{ - listened_keys.erase(key); -} - -void InputHandler::addMouseHandler(void (*callback)(double, double, double)) -{ - mouse_handlers.insert(callback); -} - -void InputHandler::removeMouseHandler(void (*callback)(double, double, double)) -{ - mouse_handlers.erase(callback); -} - -void InputHandler::addKeyHandler(void (*callback)(double, set)) -{ - key_handlers.insert(callback); -} - -void InputHandler::removeKeyHandler(void (*callback)(double, set)) -{ - key_handlers.erase(callback); -} - -InputHandler::InputHandler(Window *w) : window(w) -{ -} - -void InputHandler::processMouseInput(double dtime) -{ - vec2 cursor_delta = vec2(mouse_sensitivity * dtime) * (vec2)window->getCursorDelta(); - double x, y; - x = cursor_delta.x; - y = cursor_delta.y; - if (x != 0 && y != 0) { - for (auto it = mouse_handlers.begin(); it != mouse_handlers.end(); it++) { - (**it)(dtime, x, y); - } - } -} - -void InputHandler::processKeyInput(double dtime) -{ - set keysDown; - for (auto it = listened_keys.begin(); it != listened_keys.end(); it++) { - int key = *it; - if (window->wasKeyDown(key)) { - keysDown.insert(key); - } - } - if (keysDown.begin() != keysDown.end()) { - for (auto it = key_handlers.begin(); it != key_handlers.end(); it++) { - (**it)(dtime, keysDown); - } - } -} diff --git a/src/dragonblocks/input_handler.hpp b/src/dragonblocks/input_handler.hpp deleted file mode 100644 index bf4d4e9..0000000 --- a/src/dragonblocks/input_handler.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include "gl.hpp" - -namespace dragonblocks -{ - class Camera; - class Window; - - class InputHandler - { - public: - void processInput(double); - void listenFor(int); - void dontListenFor(int); - void addMouseHandler(void (*)(double, double, double)); - void removeMouseHandler(void (*)(double, double, double)); - void addKeyHandler(void (*)(double, std::set)); - void removeKeyHandler(void (*)(double, std::set)); - - double mouse_sensitivity; - - InputHandler(Window *); - - private: - void processMouseInput(double); - void processKeyInput(double); - - Window *window; - std::set listened_keys; - std::set mouse_handlers; - std::set)> key_handlers; - }; -} diff --git a/src/dragonblocks/log.cpp b/src/dragonblocks/log.cpp deleted file mode 100644 index 6a17fee..0000000 --- a/src/dragonblocks/log.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include "core.hpp" -#include "log.hpp" - -using namespace std; -using namespace dragonblocks; - -void dragonblocks::log(const string &l) -{ - string gt; - switch (gametype) { - case Gametype::CLIENT: - gt = "Client"; - break; - } - cout << "[" << gt << "] " << l << endl; -} diff --git a/src/dragonblocks/log.hpp b/src/dragonblocks/log.hpp deleted file mode 100644 index c40c3ed..0000000 --- a/src/dragonblocks/log.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -namespace dragonblocks -{ - void log(const std::string &); -} diff --git a/src/dragonblocks/mesh_gen_mgr.cpp b/src/dragonblocks/mesh_gen_mgr.cpp deleted file mode 100644 index 7d0c0b6..0000000 --- a/src/dragonblocks/mesh_gen_mgr.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include "mesh_gen_mgr.hpp" -#include "window.hpp" - -using namespace std; -using namespace dragonblocks; - -void MeshGenMgr::MeshGenerator::updateMesh() -{ -} - -void MeshGenMgr::addTask(MeshGenMgr::MeshGenerator *gen) -{ - queued_jobs.push(gen); -} - -void MeshGenMgr::step() -{ - if (! runJob()) { - generateJobList(); - } -} - -void MeshGenMgr::run() -{ - while (true) { - step(); - } -} - -void MeshGenMgr::generateJobList() -{ - set active_jobs_set; - while (! queued_jobs.empty()) { - MeshGenMgr::MeshGenerator *gen = queued_jobs.front(); - queued_jobs.pop(); - if (active_jobs_set.find(gen) == active_jobs_set.end()) { - active_jobs_set.insert(gen); - active_jobs.push(gen); - } - } -} - - -bool MeshGenMgr::runJob() -{ - if (active_jobs.empty()) - return false; - MeshGenMgr::MeshGenerator *gen = active_jobs.front(); - active_jobs.pop(); - if (gen) { - gen->updateMesh(); - } - return true; -} - -void MeshGenMgr::start() -{ - mesh_gen_thread = thread(&MeshGenMgr::run, this); -} diff --git a/src/dragonblocks/mesh_gen_mgr.hpp b/src/dragonblocks/mesh_gen_mgr.hpp deleted file mode 100644 index 57b6192..0000000 --- a/src/dragonblocks/mesh_gen_mgr.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include - -namespace dragonblocks -{ - class Window; - - class MeshGenMgr : public std::thread - { - public: - class MeshGenerator - { - public: - virtual void updateMesh(); - }; - - void addTask(MeshGenerator *); - void step(); - void run(); - void start(); - - private: - void generateJobList(); - bool runJob(); - - std::queue queued_jobs; - std::queue active_jobs; - std::thread mesh_gen_thread; - }; -} diff --git a/src/dragonblocks/player.cpp b/src/dragonblocks/player.cpp deleted file mode 100644 index b007d79..0000000 --- a/src/dragonblocks/player.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include "camera.hpp" -#include "input_handler.hpp" -#include "map.hpp" -#include "player.hpp" - -using namespace std; -using namespace glm; -using namespace dragonblocks; - -Player* Player::localplayer = nullptr; - -Player *Player::createLocalplayer(Camera *c, InputHandler *i, Map *m) -{ - if (localplayer) - throw runtime_error("Localplayer already exists"); - return localplayer = new Player(c, i, m); -} - -void Player::staticMouseHandler(double dtime, double x, double y) -{ - localplayer->mouseHandler(dtime, x, y); -} - -void Player::staticKeyHandler(double dtime, set keys) -{ - localplayer->keyHandler(dtime, keys); -} - -void Player::mouseHandler(double dtime, double x, double y) -{ - yaw += x; - pitch -= y; - pitch = clamp(pitch, -89.0, 89.0); - camera->update(yaw, pitch); -} - -void Player::keyHandler(double dtime, set keys) -{ - vec3 vel = vec3(speed * dtime); - vec3 front = camera->front(), right = camera->right(), up = camera->up(); - if (! pitch_move) { - front = normalize(vec3(front.x, 0, front.z)); - up = normalize(vec3(0, up.y, 0)); - } - if (keys.find(GLFW_KEY_W) != keys.end()) { - pos += vel * front; - } else if (keys.find(GLFW_KEY_S) != keys.end()) { - pos -= vel * front; - } - if (keys.find(GLFW_KEY_D) != keys.end()) { - pos += vel * right; - } else if (keys.find(GLFW_KEY_A) != keys.end()) { - pos -= vel * right; - } - if (keys.find(GLFW_KEY_SPACE) != keys.end()) { - pos += vel * up; - } else if (keys.find(GLFW_KEY_LEFT_SHIFT) != keys.end()) { - pos -= vel * up; - } - camera->pos = pos; - loadChunks(); -} - -void Player::loadChunks() -{ - ivec3 chunkp = Map::getChunkPos(pos); - for (int x = chunkp.x - 1; x <= chunkp.x + 1; x++) { - for (int y = chunkp.y - 1; y < chunkp.y + 1; y++) { - for (int z = chunkp.z - 1; z <= chunkp.z + 1; z++) { - map->createChunk(ivec3(x, y, z)); - } - } - } -} - -Player::Player(Camera *c, InputHandler *i, Map *m) : camera(c), input_handler(i), map(m) -{ - input_handler->listenFor(GLFW_KEY_W); - input_handler->listenFor(GLFW_KEY_A); - input_handler->listenFor(GLFW_KEY_S); - input_handler->listenFor(GLFW_KEY_D); - input_handler->listenFor(GLFW_KEY_SPACE); - input_handler->listenFor(GLFW_KEY_LEFT_SHIFT); - - input_handler->addMouseHandler(Player::staticMouseHandler); - input_handler->addKeyHandler(Player::staticKeyHandler); -} diff --git a/src/dragonblocks/render_engine.cpp b/src/dragonblocks/render_engine.cpp deleted file mode 100644 index fb23d35..0000000 --- a/src/dragonblocks/render_engine.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include "FrustumCull.h" -#include "camera.hpp" -#include "gldebug.hpp" -#include "input_handler.hpp" -#include "mesh_gen_mgr.hpp" -#include "render_engine.hpp" -#include "scene.hpp" -#include "shader_program.hpp" -#include "window.hpp" - -using namespace std; -using namespace glm; -using namespace dragonblocks; - -void RenderEngine::render() -{ - double dtime = glfwGetTime() - last_time; - last_time = glfwGetTime(); - - input_handler->processInput(dtime); - - glEnable(GL_DEPTH_TEST); CHECKERR - glEnable(GL_CULL_FACE); CHECKERR - glCullFace(GL_BACK); CHECKERR - glFrontFace(GL_CW); CHECKERR - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); CHECKERR - - updateViewMatrix(); CHECKERR - - Frustum frustum(projection_matrix * view_matrix); - - scene->render(dtime, shader_program, &frustum); - - window->swapBuffers(); CHECKERR - glfwPollEvents(); CHECKERR -} - -bool RenderEngine::running() -{ - return ! window->shouldClose(); -} - -void RenderEngine::updateProjectionMatrix() -{ - dvec2 bounds = window->getSize(); - projection_matrix = perspective(radians(fov), bounds.x / bounds.y, 0.01, render_distance); - shader_program->set("projection", projection_matrix); CHECKERR -} - -void RenderEngine::updateViewMatrix() -{ - view_matrix = camera->getViewMatrix(); - shader_program->set("view", view_matrix); CHECKERR -} - -void RenderEngine::setSky(vec3 sky) -{ - glClearColor(sky.r, sky.g, sky.b, 1.0); CHECKERR - shader_program->set("sky", sky); CHECKERR -} - -void RenderEngine::setRenderDistance(double d) -{ - render_distance = d; - updateProjectionMatrix(); -} - -void RenderEngine::setFov(double f) -{ - fov = f; - updateProjectionMatrix(); -} - -void RenderEngine::startMeshGenMgr() -{ - mesh_gen_mgr->start(); -} - -RenderEngine::RenderEngine() -{ - if (! glfwInit()) - throw runtime_error("Failed to initialize GLFW"); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - window = Window::create(this); - camera = new Camera; - input_handler = new InputHandler(window); - mesh_gen_mgr = new MeshGenMgr; - scene = new Scene; - - GLenum glew_init_err = glewInit(); - if (glew_init_err != GLEW_OK) - throw runtime_error("Failed to initialize GLEW"); - - shader_program = new ShaderProgram("shaders"); - - setSky(vec3(1.0, 1.0, 1.0)); - setRenderDistance(16); - setFov(45); - - last_time = glfwGetTime(); -} - -RenderEngine::~RenderEngine() -{ - delete window; - delete camera; - delete input_handler; - delete mesh_gen_mgr; - delete scene; - delete shader_program; -} diff --git a/src/dragonblocks/render_engine.hpp b/src/dragonblocks/render_engine.hpp deleted file mode 100644 index c1732c6..0000000 --- a/src/dragonblocks/render_engine.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "gl.hpp" - -namespace dragonblocks -{ - class Camera; - class InputHandler; - class MeshGenMgr; - class ShaderProgram; - class Scene; - class Window; - - class RenderEngine - { - public: - Camera *camera; - InputHandler *input_handler; - MeshGenMgr *mesh_gen_mgr; - Scene *scene; - ShaderProgram *shader_program; - Window *window; - - void render(); - bool running(); - void updateViewMatrix(); - void updateProjectionMatrix(); - void setSky(glm::vec3); - void setRenderDistance(double); - void setFov(double); - void startMeshGenMgr(); - - - RenderEngine(); - ~RenderEngine(); - - private: - glm::mat4 view_matrix, projection_matrix; - double last_time; - double render_distance; - double fov; - }; -} diff --git a/src/dragonblocks/world.cpp b/src/dragonblocks/world.cpp deleted file mode 100644 index 22f48a1..0000000 --- a/src/dragonblocks/world.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "world.hpp" diff --git a/src/dragonblocks/world.hpp b/src/dragonblocks/world.hpp deleted file mode 100644 index 33091e9..0000000 --- a/src/dragonblocks/world.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "map.hpp" - -namespace dragonblocks -{ - class World - { - public: - Map map; - }; -} diff --git a/src/dragonblockslauncher/CMakeLists.txt b/src/dragonblockslauncher/CMakeLists.txt deleted file mode 100644 index 0a0098c..0000000 --- a/src/dragonblockslauncher/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -add_executable(dragonblockslauncher - launcher.cpp - main.cpp -) - -target_link_libraries(dragonblockslauncher dl) - -target_include_directories(dragonblockslauncher PUBLIC - "${PROJECT_SOURCE_DIR}/lib/" - "${PROJECT_SOURCE_DIR}/src/" -) diff --git a/src/dragonblockslauncher/launcher.cpp b/src/dragonblockslauncher/launcher.cpp deleted file mode 100644 index 1a44919..0000000 --- a/src/dragonblockslauncher/launcher.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include "dragonblockslauncher/launcher.hpp" - -using namespace dragonblockslauncher; - -void dragonblockslauncher::log(std::string message) -{ - std::cout << "[Launcher] " << message << std::endl; -} - -void dragonblockslauncher::fail(std::string error, std::string details) -{ - std::cerr - << "Unable to launch dragonblocks: " << error << std::endl - << "Details: " << details << std::endl; - abort(); -} - -void dragonblockslauncher::launchDragonblocks(std::string gametype) -{ - void* handle; - std::string filename; - std::string start_function_name; - void (*start_function)(); - - filename = "./libdragonblocks.so"; - - log("Opening dynamic library at " + filename); - - handle = dlmopen(LM_ID_BASE, filename.c_str(), RTLD_NOW | RTLD_GLOBAL); - - if (!handle) - fail("Failed to load " + filename, dlerror()); - - if (gametype != "server" && gametype != "client" && gametype != "mainmenu") - fail("Trying to start dragonblocks with unknown gametype", "gameype = " + gametype); - - start_function_name = "_dragonblocks_start_" + gametype; - - log("Obtaining start function pointer"); - - start_function = (void (*)())dlsym(handle, start_function_name.c_str()); - - if (!start_function) - fail("Failed to obtain dragonblocks start function pointer", dlerror()); - - log("Launching dragonblocks"); - - (*start_function)(); -} diff --git a/src/dragonblockslauncher/launcher.hpp b/src/dragonblockslauncher/launcher.hpp deleted file mode 100644 index d1fcab1..0000000 --- a/src/dragonblockslauncher/launcher.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -namespace dragonblockslauncher -{ - void log(std::string); - void fail(std::string, std::string); - void launchDragonblocks(std::string); -} diff --git a/src/dragonblockslauncher/main.cpp b/src/dragonblockslauncher/main.cpp deleted file mode 100644 index b260649..0000000 --- a/src/dragonblockslauncher/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "dragonblockslauncher/launcher.hpp" - -int main(int argc, char *argv[]) -{ - dragonblockslauncher::launchDragonblocks("client"); -} diff --git a/src/entity.cpp b/src/entity.cpp new file mode 100644 index 0000000..0c634fa --- /dev/null +++ b/src/entity.cpp @@ -0,0 +1,53 @@ +#include "entity.hpp" + +using namespace glm; +using namespace dragonblocks; + +void IEntity::setPos(vec3 p) +{ +} + +vec3 IEntity::getPos() +{ + return vec3(0); +} + +void IEntity::setSize(vec3 s) +{ +} + +vec3 IEntity::getSize() +{ + return vec3(0); +} + +void IEntity::setRotationAxis(vec3 r) +{ +} + +vec3 IEntity::getRotationAxis() +{ + return vec3(0); +} + +void IEntity::setRotationAngle(double r) +{ +} + +double IEntity::getRotationAngle() +{ + return 0.0; +} + +void IEntity::setVisible(bool v) +{ +} + +bool IEntity::isVisible() +{ + return false; +} + +IEntity::IEntity(Map *m) : map(m) +{ +} diff --git a/src/entity.hpp b/src/entity.hpp new file mode 100644 index 0000000..e727374 --- /dev/null +++ b/src/entity.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "async_mgr.hpp" +#include "gl.hpp" +#include "tile_def.hpp" + +namespace dragonblocks +{ + class Map; + + class IEntity + { + public: + /*double vertical_speed; + double vertical_acceleration; + double horizontal_speed; + double horizontal_max_speed; + double horizontal_acceleration; + glm::vec3 horizontal_move_dir; + glm::vec3 vertical_move_dir; + */ + double speed; + + virtual void setPos(glm::vec3); + virtual glm::vec3 getPos(); + virtual void setSize(glm::vec3); + virtual glm::vec3 getSize(); + virtual void setRotationAxis(glm::vec3); + virtual glm::vec3 getRotationAxis(); + virtual void setRotationAngle(double); + virtual double getRotationAngle(); + virtual void setVisible(bool); + virtual bool isVisible(); + + protected: + Map *map; + + IEntity(Map *); + }; +} diff --git a/src/dragonblocks/face_dir.cpp b/src/face_dir.cpp similarity index 100% rename from src/dragonblocks/face_dir.cpp rename to src/face_dir.cpp diff --git a/src/dragonblocks/face_dir.hpp b/src/face_dir.hpp similarity index 100% rename from src/dragonblocks/face_dir.hpp rename to src/face_dir.hpp diff --git a/src/dragonblocks/game.cpp b/src/game.cpp similarity index 75% rename from src/dragonblocks/game.cpp rename to src/game.cpp index 492e632..651f223 100644 --- a/src/dragonblocks/game.cpp +++ b/src/game.cpp @@ -1,6 +1,7 @@ #include "block_def.hpp" #include "game.hpp" #include "mapgen.hpp" +#include "tile_def.hpp" using namespace dragonblocks; @@ -12,7 +13,7 @@ Game::Game(Mapgen *m) : mapgen(m) stone_texture.load("textures/stone.png"); air = new BlockDef("dragonblocks:air"); - grass = new BlockDef("dragonblocks:grass", {grass_side_texture, grass_side_texture, grass_side_texture, grass_side_texture, dirt_texture, grass_texture}); + grass = new BlockDef("dragonblocks:grass", TileDef({grass_side_texture, grass_side_texture, grass_side_texture, grass_side_texture, dirt_texture, grass_texture})); dirt = new BlockDef("dragonblocks:dirt", dirt_texture); stone = new BlockDef("dragonblocks:stone", stone_texture); diff --git a/src/dragonblocks/game.hpp b/src/game.hpp similarity index 100% rename from src/dragonblocks/game.hpp rename to src/game.hpp diff --git a/src/dragonblocks/gldebug.cpp b/src/gl.cpp similarity index 87% rename from src/dragonblocks/gldebug.cpp rename to src/gl.cpp index f71c4c3..7dc542c 100644 --- a/src/dragonblocks/gldebug.cpp +++ b/src/gl.cpp @@ -1,6 +1,6 @@ +#include #include -#include "gldebug.hpp" -#include "log.hpp" +#include "gl.hpp" using namespace std; using namespace dragonblocks; @@ -21,7 +21,7 @@ GLenum dragonblocks::checkGLError(const char *file, int line) case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break; case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break; } - log(string("OpenGL Error: ") + error + " | " + file + " (" + to_string(line) + ")"); + cout << "OpenGL Error: " << error << " | " << file << " (" << line << ")" << endl; } return errorCode; } diff --git a/src/gl.hpp b/src/gl.hpp new file mode 100644 index 0000000..3f2e59d --- /dev/null +++ b/src/gl.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include +#include + +//#define CHECKERR dragonblocks::checkGLError(__FILE__, __LINE__); +#define CHECKERR + +namespace dragonblocks +{ + GLenum checkGLError(const char *file, int line); +} diff --git a/src/input_handler.cpp b/src/input_handler.cpp new file mode 100644 index 0000000..418706e --- /dev/null +++ b/src/input_handler.cpp @@ -0,0 +1,58 @@ +#include "camera.hpp" +#include "input_handler.hpp" +#include "window.hpp" + +using namespace std; +using namespace glm; +using namespace dragonblocks; + +void InputHandler::processInput(double dtime) +{ + cursor_delta = vec2(mouse_sensitivity * dtime) * (vec2)window->getCursorDelta(); + was_down.clear(); + for (auto it = is_down.begin(); it != is_down.end(); it++) { + int key = *it; + if (! window->isKeyDown(key)) { + was_down.insert(key); + } + } + is_down.clear(); + for (auto it = listened_keys.begin(); it != listened_keys.end(); it++) { + int key = *it; + if (window->isKeyDown(key)) { + is_down.insert(key); + } + } +} + +void InputHandler::listenFor(int key) +{ + listened_keys.insert(key); +} + +void InputHandler::dontListenFor(int key) +{ + listened_keys.erase(key); +} + +bool InputHandler::isKeyDown(int key) +{ + return is_down.find(key) != is_down.end(); +} + +bool InputHandler::wasKeyDown(int key) +{ + return was_down.find(key) != was_down.end(); +} + +vec2 InputHandler::getCursorDelta() +{ + return cursor_delta; +} + +void InputHandler::setWindow(Window *w) +{ + if (! window) { + window = w; + } +} diff --git a/src/input_handler.hpp b/src/input_handler.hpp new file mode 100644 index 0000000..23939d9 --- /dev/null +++ b/src/input_handler.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "gl.hpp" + +namespace dragonblocks +{ + class Camera; + class Window; + + class InputHandler + { + public: + double mouse_sensitivity; + + void processInput(double); + void listenFor(int); + void dontListenFor(int); + bool isKeyDown(int); + bool wasKeyDown(int); + glm::vec2 getCursorDelta(); + void setWindow(Window *); + + private: + Window *window; + std::set listened_keys; + std::set is_down; + std::set was_down; + glm::vec2 cursor_delta; + }; +} diff --git a/src/launcher/main.c b/src/launcher/main.c new file mode 100644 index 0000000..c5fdf67 --- /dev/null +++ b/src/launcher/main.c @@ -0,0 +1,53 @@ +#include +#include +#include +#define __USE_GNU +#include + +void launch_dragonblocks(const char *gametype) +{ + void* handle; + const char *filename; + char *start_function_name; + void (*start_function)(); + + filename = "./libdragonblocks.so"; + + printf("Opening %s\n", filename); + + handle = dlmopen(LM_ID_BASE, filename, RTLD_NOW | RTLD_GLOBAL); + + if (! handle) { + printf("Failed to load %s\n\tDetails: %s\n", filename, dlerror()); + abort(); + } + + if (strcmp(gametype, "client")) { // && strcmp(gametype, "server") && strcmp(gametype, "menu") + printf("Trying to start dragonblocks with unknown gametype (\"%s\")\n", gametype); + abort(); + } + + start_function_name = malloc(strlen("_dragonblocks_start_") + strlen(gametype) + 1); + strcpy(start_function_name, "_dragonblocks_start_"); + strcat(start_function_name, gametype); + + printf("Obtaing pointer to start function\n"); + + start_function = (void (*)())dlsym(handle, start_function_name); + + free(start_function_name); + + if (! start_function) { + printf("Failed to obtain dragonblocks start function pointer\n\tDetails: %s\n", dlerror()); + abort(); + } + + printf("Starting dragonblocks\n"); + + (*start_function)(); +} + +int main(int argc, char *argv[]) +{ + launch_dragonblocks("client"); +} diff --git a/src/local_entity.cpp b/src/local_entity.cpp new file mode 100644 index 0000000..a69593d --- /dev/null +++ b/src/local_entity.cpp @@ -0,0 +1,71 @@ +#include "animations.hpp" +#include "box_vertices.hpp" +#include "local_entity.hpp" +#include "mesh.hpp" + +using namespace glm; +using namespace dragonblocks; + +void LocalEntity::setPos(vec3 p) +{ + mesh->pos = p; +} + +vec3 LocalEntity::getPos() +{ + return mesh->pos; +} + +void LocalEntity::setSize(vec3 s) +{ + mesh->minp = -(s / 2.0f); + mesh->maxp = +(s / 2.0f); + mesh->size = s; +} + +vec3 LocalEntity::getSize() +{ + return mesh->size; +} + +void LocalEntity::setRotationAxis(vec3 r) +{ + mesh->rotation_axis = r; +} + +vec3 LocalEntity::getRotationAxis() +{ + return mesh->rotation_axis; +} + +void LocalEntity::setRotationAngle(double r) +{ + mesh->rotation_angle = r; +} + +double LocalEntity::getRotationAngle() +{ + return mesh->rotation_angle; +} + +void LocalEntity::setVisible(bool v) +{ + mesh->visible = v; +} + +bool LocalEntity::isVisible() +{ + return mesh->visible; +} + +LocalEntity::LocalEntity(Map *m, Scene *s, const TileDef &t, ShaderProgram *sh) : IEntity(m), tile_def(t) +{ + mesh = new Mesh(s, sh, &box_vertices[0][0][0], 6 * 6 * 5); + mesh->textures = tile_def.tiles; + mesh->vertices_per_texture = 6; +} + +LocalEntity::~LocalEntity() +{ + mesh->die(); +} diff --git a/src/local_entity.hpp b/src/local_entity.hpp new file mode 100644 index 0000000..1248bc1 --- /dev/null +++ b/src/local_entity.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "async_mgr.hpp" +#include "entity.hpp" +#include "gl.hpp" +#include "tile_def.hpp" + +namespace dragonblocks +{ + class Map; + class Mesh; + class Scene; + class ShaderProgram; + + class LocalEntity : public IEntity + { + public: + void setPos(glm::vec3); + glm::vec3 getPos(); + void setSize(glm::vec3); + glm::vec3 getSize(); + void setRotationAxis(glm::vec3); + glm::vec3 getRotationAxis(); + void setRotationAngle(double); + double getRotationAngle(); + void setVisible(bool); + bool isVisible(); + void step(double); + + LocalEntity(Map *, Scene *, const TileDef &, ShaderProgram *); + ~LocalEntity(); + + protected: + TileDef tile_def; + Mesh *mesh; + }; +} diff --git a/src/local_player.cpp b/src/local_player.cpp new file mode 100644 index 0000000..c0f4a86 --- /dev/null +++ b/src/local_player.cpp @@ -0,0 +1,75 @@ +#include +#include "camera.hpp" +#include "input_handler.hpp" +#include "local_player.hpp" +#include "map.hpp" + +using namespace std; +using namespace glm; +using namespace dragonblocks; + +void LocalPlayer::step(double dtime) +{ + // Cursor input + vec2 cd = input_handler->getCursorDelta(); + yaw += cd.x; + pitch -= cd.y; + pitch = clamp(pitch, -89.0, 89.0); + + // Key input + vec3 pos = getPos(); + vec3 vel = vec3(speed * dtime); + vec3 front = camera->front(), right = camera->right(), up = camera->up(); + if (! pitch_move) { + front = normalize(vec3(front.x, 0, front.z)); + up = normalize(vec3(0, up.y, 0)); + } + if (input_handler->isKeyDown(GLFW_KEY_W)) { + pos += vel * front; + } else if (input_handler->isKeyDown(GLFW_KEY_S)) { + pos -= vel * front; + } + if (input_handler->isKeyDown(GLFW_KEY_D)) { + pos += vel * right; + } else if (input_handler->isKeyDown(GLFW_KEY_A)) { + pos -= vel * right; + } + if (input_handler->isKeyDown(GLFW_KEY_SPACE)) { + pos += vel * up; + } else if (input_handler->isKeyDown(GLFW_KEY_LEFT_SHIFT)) { + pos -= vel * up; + } + + if (input_handler->wasKeyDown(GLFW_KEY_C)) { + camera->toggleMode(); + } + + camera->update(yaw, pitch, pos); + setPos(pos); + setVisible(camera->thirdPerson()); + loadChunks(); +} + +void LocalPlayer::loadChunks() +{ + int dist = 4; + ivec3 chunkp = Map::getChunkPos(getPos()); + for (int x = chunkp.x - dist; x <= chunkp.x + dist; x++) { + for (int y = chunkp.y - dist; y < chunkp.y + dist; y++) { + for (int z = chunkp.z - dist; z <= chunkp.z + dist; z++) { + map->createChunk(ivec3(x, y, z)); + } + } + } +} + +LocalPlayer::LocalPlayer(Map *m, Scene *s, const TileDef &t, ShaderProgram *sh, Camera *c, InputHandler *i) : LocalEntity(m, s, t, sh), camera(c), input_handler(i) +{ + input_handler->listenFor(GLFW_KEY_W); + input_handler->listenFor(GLFW_KEY_A); + input_handler->listenFor(GLFW_KEY_S); + input_handler->listenFor(GLFW_KEY_D); + input_handler->listenFor(GLFW_KEY_SPACE); + input_handler->listenFor(GLFW_KEY_LEFT_SHIFT); + input_handler->listenFor(GLFW_KEY_C); +} diff --git a/src/dragonblocks/player.hpp b/src/local_player.hpp similarity index 60% rename from src/dragonblocks/player.hpp rename to src/local_player.hpp index 81bd5e6..8a061cb 100644 --- a/src/dragonblocks/player.hpp +++ b/src/local_player.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "local_entity.hpp" #include "gl.hpp" namespace dragonblocks @@ -8,31 +9,27 @@ namespace dragonblocks class Camera; class InputHandler; class Map; + class Scene; + class ShaderProgram; - class Player + class LocalPlayer : public LocalEntity { - public: - static Player *createLocalplayer(Camera *, InputHandler *, Map *); - - glm::vec3 pos; + public: bool pitch_move; double yaw, pitch; - double speed; - private: - static Player *localplayer; + void step(double); + + LocalPlayer(Map *, Scene *, const TileDef &, ShaderProgram *, Camera *, InputHandler *); + private: static void staticMouseHandler(double, double, double); static void staticKeyHandler(double, std::set); Camera *camera; InputHandler *input_handler; - Map *map; - void mouseHandler(double, double, double); void keyHandler(double, std::set); void loadChunks(); - - Player(Camera *, InputHandler *, Map *); }; } diff --git a/src/dragonblocks/map.cpp b/src/map.cpp similarity index 87% rename from src/dragonblocks/map.cpp rename to src/map.cpp index 8b338d9..351cd31 100644 --- a/src/dragonblocks/map.cpp +++ b/src/map.cpp @@ -44,7 +44,7 @@ void Map::createChunk(const glm::ivec3 &p, const Chunk::Data &data) if (chunks[poshash]) return; - chunks[poshash] = new Chunk(this, p, data, mesh_gen_mgr, scene); + chunks[poshash] = new Chunk(this, p, data, async_mgr, scene, shader_program); } void Map::createChunk(const glm::ivec3 &p) @@ -65,7 +65,7 @@ void Map::clear() chunks.clear(); } -Map::Map(Mapgen *m, MeshGenMgr *mg, Scene *s) : mapgen(m), mesh_gen_mgr(mg), scene(s) +Map::Map(Mapgen *m, AsyncMgr *a, Scene *s, ShaderProgram *sh) : mapgen(m), async_mgr(a), scene(s), shader_program(sh) { } diff --git a/src/dragonblocks/map.hpp b/src/map.hpp similarity index 84% rename from src/dragonblocks/map.hpp rename to src/map.hpp index e7b9f7e..0bd941c 100644 --- a/src/dragonblocks/map.hpp +++ b/src/map.hpp @@ -8,11 +8,12 @@ namespace dragonblocks { + class AsyncMgr; class BlockDef; class Block; class Mapgen; - class MeshGenMgr; class Scene; + class ShaderProgram; class Map { @@ -29,13 +30,14 @@ namespace dragonblocks Chunk *getChunk(const glm::ivec3 &); void clear(); - Map(Mapgen *, MeshGenMgr *, Scene *); + Map(Mapgen *, AsyncMgr *, Scene *, ShaderProgram *); ~Map(); private: std::map chunks; Mapgen *mapgen; - MeshGenMgr *mesh_gen_mgr; + AsyncMgr *async_mgr; Scene *scene; + ShaderProgram *shader_program; }; } diff --git a/src/dragonblocks/mapgen.cpp b/src/mapgen.cpp similarity index 93% rename from src/dragonblocks/mapgen.cpp rename to src/mapgen.cpp index a5b4d07..5cad82c 100644 --- a/src/dragonblocks/mapgen.cpp +++ b/src/mapgen.cpp @@ -1,3 +1,4 @@ +#include #include #include "mapgen.hpp" @@ -14,7 +15,7 @@ Chunk::Data Mapgen::generate(const ivec3 &chunkp) const int rx = x - minx; for (int z = minz; z < maxz; z++) { int rz = z - minz; - int grass_layer = grass_layer_middle + grass_layer_range * perlin(vec2((float)x / 128, (float)z / 128)); + int grass_layer = grass_layer_middle + grass_layer_range * perlin(vec2((float)x / 64, (float)z / 64)); for (int y = miny; y < maxy; y++) { int ry = y - miny; BlockDef *blockdef; diff --git a/src/dragonblocks/mapgen.hpp b/src/mapgen.hpp similarity index 81% rename from src/dragonblocks/mapgen.hpp rename to src/mapgen.hpp index 261cd2f..8c44d63 100644 --- a/src/dragonblocks/mapgen.hpp +++ b/src/mapgen.hpp @@ -10,7 +10,7 @@ namespace dragonblocks class Mapgen { public: - float grass_layer_middle = 0, grass_layer_range = 64; + float grass_layer_middle = 0, grass_layer_range = 32; BlockDef *air_def, *stone_def, *dirt_def, *grass_def; Chunk::Data generate(const glm::ivec3 &) const; diff --git a/src/dragonblocks/mesh.cpp b/src/mesh.cpp similarity index 51% rename from src/dragonblocks/mesh.cpp rename to src/mesh.cpp index e8741ac..cb01438 100644 --- a/src/dragonblocks/mesh.cpp +++ b/src/mesh.cpp @@ -1,10 +1,9 @@ +#include #include #include #include #include -#include #include "FrustumCull.h" -#include "gldebug.hpp" #include "mesh.hpp" #include "scene.hpp" #include "shader_program.hpp" @@ -13,71 +12,46 @@ using namespace std; using namespace glm; using namespace dragonblocks; -double Mesh::Animation::grow_time = 0.25; // s -double Mesh::Animation::flyin_time = 0.4; // s -double Mesh::Animation::flyin_offset = 20; // m -double Mesh::Animation::rotate_speed = 1; // turns/s - -mat4 Mesh::Animation::getModelMatrix(double dtime, vec3 pos, vec3 size, vec3 rotation_axis, float rotation_angle) +bool Mesh::IAnimation::expired(double dtime) { - mat4 trans = mat4(1.0); - - if (type == Mesh::Animation::Type::NONE) - goto finish; - if (expires) { time_left -= dtime; if (time_left < 0) { - type = Mesh::Animation::Type::NONE; if (on_finish) { (*on_finish)(extra_data); } - goto finish; + return true; } - } - - switch (type) { - case Mesh::Animation::Type::FLYIN: - pos.y -= Mesh::Animation::flyin_offset * time_left / Mesh::Animation::flyin_time; - break; - - case Mesh::Animation::Type::GROW: - size *= 1 - time_left / Mesh::Animation::grow_time; - break; - - case Mesh::Animation::Type::ROTATE: - rotation_angle += glfwGetTime() * Mesh::Animation::rotate_speed * pi() * 2; } + return false; +} - finish: - - trans = translate(trans, pos); - trans = rotate(trans, rotation_angle, rotation_axis); - trans = scale(trans, size); - - return trans; +vec3 Mesh::IAnimation::getPos(vec3 p) +{ + return p; } -Mesh::Animation::Animation(Mesh::Animation::Type t, void (*o)(void *), void *e) : type(t), on_finish(o), extra_data(e) +vec3 Mesh::IAnimation::getSize(vec3 s) { - switch(type) { - case Mesh::Animation::Type::FLYIN: - expires = true; - time_left = Mesh::Animation::flyin_time; - break; - - case Mesh::Animation::Type::GROW: - expires = true; - time_left = Mesh::Animation::grow_time; - break; - - case Mesh::Animation::Type::ROTATE: - expires = false; - break; - } + return s; +} + +vec3 Mesh::IAnimation::getRotationAxis(vec3 r) +{ + return r; } -void Mesh::render(double dtime, ShaderProgram *shader_program, Frustum *frustum) +float Mesh::IAnimation::getRotationAngle(float r) +{ + return r; +} + +Mesh::IAnimation::IAnimation(double t, void (*o)(void *), void *e) : time_left(t), on_finish(o), extra_data(e) +{ + expires = true; +} + +void Mesh::render(double dtime, Frustum *frustum, mat4 projection_matrix, mat4 view_matrix, vec3 sky) { rendering = true; @@ -94,12 +68,34 @@ void Mesh::render(double dtime, ShaderProgram *shader_program, Frustum *frustum) shader_program->use(); CHECKERR - mat4 model_matrix = animation.getModelMatrix(dtime, pos, size, rotation_axis, rotation_angle); CHECKERR + mat4 model_matrix = identity(); + + vec3 n_pos = pos, n_size = size, n_rotation_axis = rotation_axis; + float n_rotation_angle = rotation_angle; + + if (animation) { + if (animation->expired(dtime)) { + delete animation; + animation = nullptr; + } else { + n_pos = animation->getPos(n_pos); + n_size = animation->getSize(n_size); + n_rotation_axis = animation->getRotationAxis(n_rotation_axis); + n_rotation_angle = animation->getRotationAngle(n_rotation_angle); + } + } + + model_matrix = translate(model_matrix, n_pos); + model_matrix = rotate(model_matrix, n_rotation_angle, n_rotation_axis); + model_matrix = scale(model_matrix, n_size); - if (! frustum->IsBoxVisible(model_matrix * vec4(minp, 1.0), model_matrix * vec4(maxp, 1.0))) + if (! visible || ! frustum->IsBoxVisible(model_matrix * vec4(minp - vec3(1.0), 1.0), model_matrix * vec4(maxp + vec3(1.0), 1.0))) return; shader_program->set("model", model_matrix); CHECKERR + shader_program->set("view", view_matrix); CHECKERR + shader_program->set("projection", projection_matrix); CHECKERR + shader_program->set("sky", sky); CHECKERR glBindVertexArray(VAO); CHECKERR for (int i = 0; i < textures.size(); i++) { @@ -122,12 +118,12 @@ void Mesh::die() prepare_death = true; } -Mesh::Mesh(Scene *s, const GLvoid *v, GLsizei vs): pos(0), size(1), rotation_axis(0, 1, 0), scene(s), vertices_size(vs) +Mesh::Mesh(Scene *s, ShaderProgram *sh, const GLfloat *v, GLsizei vs): pos(0), size(1), rotation_axis(0, 1, 0), scene(s), shader_program(sh), vertices_size(vs * sizeof(GLfloat)) { if (! v || ! vs) throw runtime_error("Invalid Mesh configuration"); - vertices = malloc(vs); - memcpy(vertices, v, vs); + vertices = malloc(vertices_size); + memcpy(vertices, v, vertices_size); scene->add(this); } @@ -140,6 +136,9 @@ Mesh::~Mesh() if (VBO) { glDeleteBuffers(1, &VAO); CHECKERR } + if (animation) { + delete animation; + } } void Mesh::configure() diff --git a/src/dragonblocks/mesh.hpp b/src/mesh.hpp similarity index 54% rename from src/dragonblocks/mesh.hpp rename to src/mesh.hpp index 4dafcc9..14e64d0 100644 --- a/src/dragonblocks/mesh.hpp +++ b/src/mesh.hpp @@ -14,34 +14,23 @@ namespace dragonblocks class Mesh { public: - class Animation + class IAnimation { - public: - static double grow_time; - static double flyin_time; - static double flyin_offset; - static double rotate_speed; + public: + bool expired(double); + virtual glm::vec3 getPos(glm::vec3); + virtual glm::vec3 getSize(glm::vec3); + virtual glm::vec3 getRotationAxis(glm::vec3); + virtual float getRotationAngle(float); - enum Type - { - NONE, - FLYIN, - GROW, - ROTATE - }; - - glm::mat4 getModelMatrix(double, glm::vec3, glm::vec3, glm::vec3, float); - - Animation() = default; - Animation(Type, void (*)(void *) = nullptr, void * = nullptr); - Animation(const Animation &) = default; - - private: - Type type = Type::NONE; + protected: + bool expires = false; double time_left; void (*on_finish)(void *); void *extra_data; - bool expires; + + IAnimation() = default; + IAnimation(double, void (*)(void *), void *); }; int vertices_per_texture; @@ -49,18 +38,19 @@ namespace dragonblocks glm::vec3 minp, maxp; float rotation_angle = 0; std::vector textures; - Animation animation; + IAnimation *animation = nullptr; + bool visible = true; - void render(double dtime, ShaderProgram *, Frustum *); + void render(double dtime, Frustum *, glm::mat4, glm::mat4, glm::vec3); bool isRendering(); void die(); - Mesh(Scene *, const GLvoid *, GLsizei); - ~Mesh(); + Mesh(Scene *, ShaderProgram *, const GLfloat *, GLsizei); private: GLuint VAO = 0, VBO = 0; Scene *scene; + ShaderProgram *shader_program; GLvoid *vertices = NULL; GLsizeiptr vertices_size; bool configured = false; @@ -69,5 +59,7 @@ namespace dragonblocks bool do_delete = false; void configure(); + + ~Mesh(); }; } diff --git a/src/render_engine.cpp b/src/render_engine.cpp new file mode 100644 index 0000000..eeebd0c --- /dev/null +++ b/src/render_engine.cpp @@ -0,0 +1,71 @@ +#include +#include +#include "FrustumCull.h" +#include "camera.hpp" +#include "input_handler.hpp" +#include "render_engine.hpp" +#include "scene.hpp" +#include "shader_program.hpp" +#include "window.hpp" + +using namespace std; +using namespace glm; +using namespace dragonblocks; + +void RenderEngine::render(double dtime) +{ + glClearColor(sky.r, sky.g, sky.b, 1.0); CHECKERR + + /* + glEnable(GL_CULL_FACE); CHECKERR + glCullFace(GL_BACK); CHECKERR + glFrontFace(GL_CW); CHECKERR + */ + + glEnable(GL_DEPTH_TEST); CHECKERR + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); CHECKERR + + + dvec2 window_size = window->getSize(); + mat4 projection_matrix = perspective(radians(fov), window_size.x / window_size.y, 0.01, render_distance); + + mat4 view_matrix = camera->getViewMatrix(); + + Frustum frustum(projection_matrix * view_matrix); + + scene->render(dtime, &frustum, projection_matrix, view_matrix, sky); + + window->swapBuffers(); CHECKERR + glfwPollEvents(); CHECKERR +} + +bool RenderEngine::running() +{ + return ! window->shouldClose(); +} + +RenderEngine::RenderEngine() +{ + if (! glfwInit()) { + throw runtime_error("Failed to initialize GLFW"); + } + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + window = Window::create(this); + camera = new Camera; + scene = new Scene; + + GLenum glew_init_err = glewInit(); + if (glew_init_err != GLEW_OK) { + throw runtime_error("Failed to initialize GLEW"); + } +} + +RenderEngine::~RenderEngine() +{ + delete window; + delete camera; + delete scene; +} diff --git a/src/render_engine.hpp b/src/render_engine.hpp new file mode 100644 index 0000000..8181f22 --- /dev/null +++ b/src/render_engine.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "gl.hpp" + +namespace dragonblocks +{ + class Camera; + class InputHandler; + class Scene; + class Window; + + class RenderEngine + { + public: + Camera *camera; + Scene *scene; + Window *window; + double render_distance = 16; + double fov = 45; + glm::vec3 sky; + + void render(double); + bool running(); + + RenderEngine(); + ~RenderEngine(); + }; +} diff --git a/src/dragonblocks/scene.cpp b/src/scene.cpp similarity index 66% rename from src/dragonblocks/scene.cpp rename to src/scene.cpp index 2f74bb2..1152d9e 100644 --- a/src/dragonblocks/scene.cpp +++ b/src/scene.cpp @@ -2,6 +2,7 @@ #include "scene.hpp" using namespace std; +using namespace glm; using namespace dragonblocks; void Scene::add(Mesh *m) @@ -14,12 +15,12 @@ void Scene::remove(Mesh *m) meshes.erase(m); } -void Scene::render(double dtime, ShaderProgram *shader_program, Frustum *frustum) +void Scene::render(double dtime, Frustum *frustum, mat4 projection_matrix, mat4 view_matrix, vec3 sky) { auto renderlist = meshes; for (auto it = renderlist.begin(); it != renderlist.end(); it++) { Mesh *mesh = *it; - mesh->render(dtime, shader_program, frustum); + mesh->render(dtime, frustum, projection_matrix, view_matrix, sky); } } diff --git a/src/dragonblocks/scene.hpp b/src/scene.hpp similarity index 75% rename from src/dragonblocks/scene.hpp rename to src/scene.hpp index fc0f62d..86e0a4f 100644 --- a/src/dragonblocks/scene.hpp +++ b/src/scene.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include "gl.hpp" class Frustum; @@ -13,7 +14,7 @@ namespace dragonblocks public: void add(Mesh *); void remove(Mesh *); - void render(double, ShaderProgram *, Frustum *); + void render(double, Frustum *, glm::mat4, glm::mat4, glm::vec3); void clear(); void run(); diff --git a/src/dragonblocks/shader_program.cpp b/src/shader_program.cpp similarity index 100% rename from src/dragonblocks/shader_program.cpp rename to src/shader_program.cpp diff --git a/src/dragonblocks/shader_program.hpp b/src/shader_program.hpp similarity index 100% rename from src/dragonblocks/shader_program.hpp rename to src/shader_program.hpp diff --git a/src/dragonblocks/texture.cpp b/src/texture.cpp similarity index 95% rename from src/dragonblocks/texture.cpp rename to src/texture.cpp index ab0b4b1..a595411 100644 --- a/src/dragonblocks/texture.cpp +++ b/src/texture.cpp @@ -1,8 +1,7 @@ +#include #include #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" -#include "gldebug.hpp" -#include "log.hpp" #include "texture.hpp" using namespace std; @@ -47,6 +46,6 @@ void Texture::load(const string &path) glGenerateMipmap(GL_TEXTURE_2D); CHECKERR stbi_image_free(data); glBindTexture(GL_TEXTURE_2D, 0); CHECKERR - log("Loaded texture " + path); + cout << "Loaded texture " << path << endl; } diff --git a/src/dragonblocks/texture.hpp b/src/texture.hpp similarity index 100% rename from src/dragonblocks/texture.hpp rename to src/texture.hpp diff --git a/src/tile_def.cpp b/src/tile_def.cpp new file mode 100644 index 0000000..a4c77d7 --- /dev/null +++ b/src/tile_def.cpp @@ -0,0 +1,30 @@ +#include "tile_def.hpp" + +using namespace std; +using namespace dragonblocks; + +Texture TileDef::get(int i) const +{ + return tiles[i]; +} + +int TileDef::size() const +{ + return tiles.size(); +} + +TileDef::TileDef(const vector &t) : tiles(t) +{ + int s = size(); + for (int i = 0; s < 6; i += s) { + for (int j = 0; j < i && j + i < 6; j++) { + tiles[i + j] = tiles[j]; + } + } +} + +TileDef::TileDef(const Texture &t) : TileDef({t, t, t, t, t, t}) +{ +} + + diff --git a/src/tile_def.hpp b/src/tile_def.hpp new file mode 100644 index 0000000..dd5c7e0 --- /dev/null +++ b/src/tile_def.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include "texture.hpp" + +namespace dragonblocks +{ + class TileDef + { + public: + std::vector tiles; + + Texture get(int) const; + int size() const; + + TileDef() = default; + TileDef(const Texture &); + TileDef(const std::vector &); + }; +} diff --git a/src/dragonblocks/window.cpp b/src/window.cpp similarity index 96% rename from src/dragonblocks/window.cpp rename to src/window.cpp index 9bb3541..7729453 100644 --- a/src/dragonblocks/window.cpp +++ b/src/window.cpp @@ -10,8 +10,9 @@ Window *Window::singleton = nullptr; Window *Window::create(RenderEngine *r) { - if (singleton) + if (singleton) { throw runtime_error("Window already exists"); + } return singleton = new Window(r); } @@ -23,7 +24,6 @@ void Window::windowPosCallback(GLFWwindow *id, int x, int y) void Window::framebufferSizeCallback(GLFWwindow *id, int width, int height) { glViewport(0, 0, width, height); - singleton->render_engine->updateProjectionMatrix(); singleton->sizeInput(width, height); } @@ -75,7 +75,7 @@ bool Window::shouldClose() const return glfwWindowShouldClose(id); } -bool Window::wasKeyDown(int key) const +bool Window::isKeyDown(int key) const { return glfwGetKey(id, key) == GLFW_PRESS; } diff --git a/src/dragonblocks/window.hpp b/src/window.hpp similarity index 97% rename from src/dragonblocks/window.hpp rename to src/window.hpp index 1ca300a..e3b0f36 100644 --- a/src/dragonblocks/window.hpp +++ b/src/window.hpp @@ -22,7 +22,7 @@ namespace dragonblocks void close(); void swapBuffers(); bool shouldClose() const; - bool wasKeyDown(int) const; + bool isKeyDown(int) const; void makeContextCurrent() const; glm::ivec2 getSize() const; glm::ivec2 getCursorPos() const; diff --git a/textures/leaves.png b/textures/leaves.png deleted file mode 100644 index 02b6cf03afb1d602cea9b94340806c43983e5ebf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 979 zcmV;^11$WBP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=H0lH4E+hWDHzM?exn;y64^Rc?^u=f{mbJ(Ec) zsbrBwn=)X5C81ApcR0R%o#6{Ej+8@E^IUR{xKc@lD<&QvS3P@*>FoDIye9AD;a-5+ zC>Z7O=y}Tz$Qk>2%lp<-A=f8G<=6}D{X*S}*tdbp;x;7oFc7!mP`4uCZ8<%j+v8X< z7q{ml^u2%X^)n2(!|IY4XU${@ed1`A3+B!-8R9mUqqB2a?`hkLK0JqOE5j!~ge0Q( z<)J+8irdi>)^Q*yn8Px9l^uQ1;t&ne!6*RMPem+Kq(JEZrFejHB&ihc;QO+6mwH2-Nt&C>4 zHTnwnY6ZLokYo+5Qy~V%Nr?tknsl6Frw$hrA8Z(zI}7yyp#w(YE(>m2jV2o~ z4`65MNC$zGZ(ry%TTXMG9EJyZKz0z6Axr+Qh2PmU=PD?o=y$B(7q3c#7mFNGh=gq* zLURXI&j4TTO9SvXrMKjg6SQEXVtf=Z+1LsYB6y&1h6Ds+CQ-^1 zjX4+*0_gx$;W|s=1}vn?15R=h$$*0@fNi{EbZ%wkhZrA1fKbT+<>#vq0V^d%{#bJ4 zP*u^Ss##54i`Fc8RanlJ*B7;#STeP2W^To5aPj2o+0EUH*TO~c#npm(EM7{f6-FyG zSG--Zq1MJtT58&Iv*xX|+BtOTscX;Oy7$uS;2{HbJo2#Nql|jcfmAxup+`RK@S_}c zBGsnMGUEiubf8Ue|BtCu8{8!k>;WMK47!MK47!MK47!MgO~^iGL3zdv3=uCgi;tIa0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN z9Z5t%R5;6H