Compare commits
4 Commits
bcd3644813
...
5b42f25302
Author | SHA1 | Date | |
---|---|---|---|
5b42f25302 | |||
00bb2fa4cf | |||
2523a91dfd | |||
6dd8b27ae1 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -46,6 +46,7 @@ Debug/
|
||||
Release/
|
||||
UnitTests/
|
||||
open-builder-unit-tests/
|
||||
external/
|
||||
|
||||
libenet.a
|
||||
libglad.a
|
||||
|
@ -1,12 +1,11 @@
|
||||
#include "engine.hpp"
|
||||
|
||||
#include "../audio/audio.hpp"
|
||||
#include "game/audio/audio.hpp"
|
||||
|
||||
#include "game/world/chunk_renderer.hpp"
|
||||
#include "common/network/network_manager.hpp"
|
||||
#include "common/logger.hpp"
|
||||
#include "game/world/chunk_renderer.hpp"
|
||||
#include "game/screens/game_session_screen.hpp"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "vendor/imgui.h"
|
||||
#include "vendor/imgui_impl_glfw.h"
|
||||
#include "vendor/imgui_impl_opengl3.h"
|
||||
@ -14,38 +13,14 @@
|
||||
using namespace polygun::renderer;
|
||||
using namespace polygun::world;
|
||||
|
||||
int sizex = SCR_WIDTH, sizey = SCR_HEIGHT;
|
||||
static int sizex = SCR_WIDTH, sizey = SCR_HEIGHT;
|
||||
|
||||
namespace polygun::engine {
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); glfwGetWindowSize(window, &sizex, &sizey);}
|
||||
|
||||
void Engine::connection_thread_func() {
|
||||
network::NetworkManager network_manager("127.0.0.1", 1117);
|
||||
network::NetworkPacket handshake = network_manager.create_packet(network::NetworkPacketFlag::FLAG_RELIABLE, network::NetworkPacketID::PACKET_HANDSHAKE);
|
||||
network::NetworkPacket packet;
|
||||
handshake.write("mrkubax10");
|
||||
network_manager.send_packet(handshake);
|
||||
network_manager.update();
|
||||
while(m_running) {
|
||||
if(network_manager.get_socket().recv(packet)) {
|
||||
if((packet.get_flags() & network::NetworkPacketFlag::FLAG_RELIABLE) || packet.get_id()==network::NetworkPacketID::PACKET_ACK)
|
||||
network_manager.push_packet(packet);
|
||||
network_manager.update();
|
||||
if(network_manager.recv_packet(packet)) {
|
||||
// handle
|
||||
}
|
||||
}
|
||||
packet = network_manager.create_packet(network::NetworkPacketFlag::FLAG_NONE, network::NetworkPacketID::PACKET_ACTIVITY);
|
||||
network_manager.send_packet(packet);
|
||||
}
|
||||
packet = network_manager.create_packet(network::NetworkPacketFlag::FLAG_RELIABLE, network::NetworkPacketID::PACKET_EXIT);
|
||||
network_manager.send_packet(packet);
|
||||
while(network_manager.has_outgoing_packets()) {
|
||||
if(network_manager.get_socket().recv(packet) && packet.get_id()==network::NetworkPacketID::PACKET_ACK)
|
||||
network_manager.push_packet(packet);
|
||||
network_manager.update();
|
||||
}
|
||||
}
|
||||
Engine::Engine() :
|
||||
m_screen_manager(*this)
|
||||
{}
|
||||
|
||||
void Engine::init() {
|
||||
audio::init();
|
||||
@ -55,20 +30,17 @@ namespace polygun::engine {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Polygun", NULL, NULL);
|
||||
if (window == NULL) {
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
m_window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Polygun", NULL, NULL);
|
||||
if (m_window == NULL) {
|
||||
glfwTerminate();
|
||||
return;
|
||||
LOG_FATAL("Failed to create GLFW window");
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
glfwSetCursorPosCallback(window, m_camera.mouse_callback);
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
glfwMakeContextCurrent(m_window);
|
||||
glfwSetFramebufferSizeCallback(m_window, framebuffer_size_callback);
|
||||
|
||||
if (glewInit() != GLEW_OK) {
|
||||
std::cout << "GLEW init failed" << std::endl;
|
||||
return;
|
||||
glfwTerminate();
|
||||
LOG_FATAL("GLEW init failed");
|
||||
}
|
||||
|
||||
// Setup Dear ImGui context
|
||||
@ -79,244 +51,30 @@ namespace polygun::engine {
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
// Setup Platform/Renderer bindings
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplGlfw_InitForOpenGL(m_window, true);
|
||||
ImGui_ImplOpenGL3_Init("#version 330");
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
// Push game screen
|
||||
std::unique_ptr<screens::GameSessionScreen> game_session_screen = std::make_unique<screens::GameSessionScreen>();
|
||||
m_screen_manager.push_screen(std::move(game_session_screen));
|
||||
|
||||
Shader chunk_shader("shaders/chunk_vertex.glsl", "shaders/chunk_fragment.glsl");
|
||||
|
||||
float vertices[] = {
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
|
||||
0.1f, -0.1f, -0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
|
||||
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
|
||||
-0.1f, 0.1f, 0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
|
||||
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
-0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, -0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
|
||||
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
-0.1f, 0.1f, 0.1f, 0.0f, 0.0f,
|
||||
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
Chunk chnk;
|
||||
|
||||
unsigned int VBO, VAO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
// position attribute
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
|
||||
unsigned int texture_atlas;
|
||||
|
||||
glGenTextures(1, &texture_atlas);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_atlas);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
int width, height, nrChannels;
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
unsigned char *data = stbi_load("res/textures/gold.png", &width, &height, &nrChannels, 0);
|
||||
if (data)
|
||||
while (!glfwWindowShouldClose(m_window))
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to load texture" << std::endl;
|
||||
}
|
||||
stbi_image_free(data);
|
||||
|
||||
m_screen_manager.render();
|
||||
m_screen_manager.update();
|
||||
|
||||
chunk_shader.bind();
|
||||
chunk_shader.set_uniform("texture_atlas", 0);
|
||||
|
||||
m_delta_time = 0;
|
||||
m_last_frame = 0;
|
||||
|
||||
|
||||
bool is_esc_pressed = false;
|
||||
bool was_camera_locked = false;
|
||||
|
||||
m_running = true;
|
||||
// Note: uncomment to test connection with server
|
||||
// m_connection_thread.reset(new std::thread(&Engine::connection_thread_func, this));
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
float current_frame = static_cast<float>(glfwGetTime());
|
||||
m_delta_time = current_frame - m_last_frame;
|
||||
m_last_frame = current_frame;
|
||||
|
||||
// input
|
||||
// -----
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
if (!is_esc_pressed) {
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
else
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
was_camera_locked = true;
|
||||
}
|
||||
is_esc_pressed = true;
|
||||
}
|
||||
else
|
||||
is_esc_pressed = false;
|
||||
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::FORWARD, m_delta_time);
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::BACKWARD, m_delta_time);
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
m_camera.process_movement(LEFT, m_delta_time);
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::RIGHT, m_delta_time);
|
||||
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::UP, m_delta_time);
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::DOWN, m_delta_time);
|
||||
|
||||
if(glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) {
|
||||
if(was_camera_locked) {
|
||||
m_camera.update(true);
|
||||
was_camera_locked = false;
|
||||
}
|
||||
else
|
||||
m_camera.update(false);
|
||||
}
|
||||
|
||||
|
||||
// rendering
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// bind textures on corresponding texture units
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_atlas);
|
||||
|
||||
// activate shader
|
||||
chunk_shader.bind();
|
||||
|
||||
glm::mat4 projection = glm::perspective(glm::radians(m_camera.m_fov), (float)sizex / (float)sizey, 0.1f, 100.0f);
|
||||
chunk_shader.set_uniform("projection", projection);
|
||||
|
||||
glm::mat4 view = m_camera.get_view_matrix();
|
||||
chunk_shader.set_uniform("view", view);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
for (unsigned int x = 0; x < 32; x++) {
|
||||
for (unsigned int y = 0; y < 32; y++) {
|
||||
for (unsigned int z = 0; z < 32; z++) {
|
||||
if (chnk.get_node(glm::vec3(x,y,z))!= 0) {
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, glm::vec3(x/5.0f, y/5.0f, z/5.0f));
|
||||
chunk_shader.set_uniform("model", model);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// imgui
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(340, 200));
|
||||
|
||||
ImGui::Begin("Debug");
|
||||
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
// Camera pos
|
||||
ImGui::Text("Player Pos: %.3f, %.3f, %.3f", m_camera.m_position.x, m_camera.m_position.y, m_camera.m_position.z);
|
||||
// Camera rot
|
||||
ImGui::Text("Player Rot: %.3f, %.3f", m_camera.m_yaw, m_camera.m_pitch);
|
||||
|
||||
int x_d, y_d, z_d, id_d;
|
||||
|
||||
ImGui::InputInt("ID", &id_d);
|
||||
|
||||
ImGui::InputInt("X", &x_d);
|
||||
ImGui::InputInt("Y", &y_d);
|
||||
ImGui::InputInt("Z", &z_d);
|
||||
|
||||
if (ImGui::Button("Place Block"))
|
||||
{
|
||||
chnk.add_node(id_d, glm::vec3(x_d, y_d, z_d));
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
|
||||
ImGui::EndFrame();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwSwapBuffers(m_window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
|
||||
m_running = false;
|
||||
if(m_connection_thread->joinable()) {
|
||||
LOG_VERBOSE("Waiting for connection thread to finish");
|
||||
m_connection_thread->join();
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
int Engine::get_screen_width() {
|
||||
return sizex;
|
||||
}
|
||||
|
||||
int Engine::get_screen_height() {
|
||||
return sizey;
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,32 @@
|
||||
#ifndef POLYGUN_ENGINE_HPP
|
||||
#define POLYGUN_ENGINE_HPP
|
||||
|
||||
#include <atomic>
|
||||
#define GLFW_INCLUDE_NONE // don't include OpenGL context as it's not needed application-wide
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "game/core.hpp"
|
||||
#include "game/renderer/shader.hpp"
|
||||
#include "game/engine/player_camera.hpp"
|
||||
#include "game/engine/screen_manager.hpp"
|
||||
|
||||
namespace polygun::engine {
|
||||
|
||||
class Engine {
|
||||
private:
|
||||
ScreenManager m_screen_manager;
|
||||
GLFWwindow* m_window;
|
||||
Camera m_camera;
|
||||
|
||||
float m_delta_time;
|
||||
float m_last_frame;
|
||||
|
||||
std::unique_ptr<std::thread> m_connection_thread;
|
||||
std::atomic<bool> m_running;
|
||||
|
||||
private:
|
||||
void connection_thread_func();
|
||||
|
||||
public:
|
||||
Engine() = default;
|
||||
Engine();
|
||||
~Engine() = default;
|
||||
|
||||
void init();
|
||||
void render();
|
||||
void update();
|
||||
|
||||
ScreenManager& get_screen_manager() { return m_screen_manager; }
|
||||
GLFWwindow* get_window() { return m_window; }
|
||||
|
||||
static int get_screen_width();
|
||||
static int get_screen_height();
|
||||
};
|
||||
|
||||
}
|
||||
|
47
src/game/engine/screen.hpp
Normal file
47
src/game/engine/screen.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POLYGUN_ENGINE_SCREEN_HPP
|
||||
#define POLYGUN_ENGINE_SCREEN_HPP
|
||||
|
||||
namespace polygun::engine {
|
||||
class Engine;
|
||||
class Screen {
|
||||
friend class ScreenManager;
|
||||
public:
|
||||
// for some reason this is required
|
||||
// GCC doesn't show warning about this but Clang does
|
||||
virtual ~Screen(){}
|
||||
|
||||
virtual void begin(){}
|
||||
virtual void render(){}
|
||||
virtual void update(double delta){}
|
||||
virtual void finish(){}
|
||||
|
||||
protected:
|
||||
Engine* m_engine;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // POLYGUN_ENGINE_SCREEN_HPP
|
83
src/game/engine/screen_manager.cpp
Normal file
83
src/game/engine/screen_manager.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "game/engine/screen_manager.hpp"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace polygun::engine;
|
||||
|
||||
ScreenManager::ScreenManager(Engine& engine) :
|
||||
m_engine(engine),
|
||||
m_screen_stack(),
|
||||
m_prev_time(glfwGetTime())
|
||||
{}
|
||||
|
||||
ScreenManager::~ScreenManager() {
|
||||
if(m_screen_stack.size()>0) {
|
||||
for(ssize_t i = m_screen_stack.size()-1; i>=0; i--) {
|
||||
m_screen_stack[i]->finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenManager::push_screen(std::unique_ptr<Screen> screen) {
|
||||
Screen* current_screen = get_current_screen();
|
||||
if(current_screen)
|
||||
current_screen->finish();
|
||||
|
||||
screen->m_engine = &m_engine;
|
||||
screen->begin();
|
||||
m_screen_stack.push_back(std::move(screen));
|
||||
}
|
||||
|
||||
void ScreenManager::pop_screen() {
|
||||
Screen* current_screen = get_current_screen();
|
||||
if(!current_screen)
|
||||
return;
|
||||
|
||||
current_screen->finish();
|
||||
m_screen_stack.pop_back();
|
||||
}
|
||||
|
||||
void ScreenManager::render() {
|
||||
Screen* current_screen = get_current_screen();
|
||||
if(current_screen)
|
||||
current_screen->render();
|
||||
}
|
||||
|
||||
void ScreenManager::update() {
|
||||
Screen* current_screen = get_current_screen();
|
||||
double tm = glfwGetTime();
|
||||
if(current_screen)
|
||||
current_screen->update(tm-m_prev_time);
|
||||
m_prev_time = tm;
|
||||
}
|
||||
|
||||
Screen* ScreenManager::get_current_screen() {
|
||||
if(m_screen_stack.size()==0)
|
||||
return nullptr;
|
||||
return m_screen_stack.back().get();
|
||||
}
|
56
src/game/engine/screen_manager.hpp
Normal file
56
src/game/engine/screen_manager.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POLYGUN_ENGINE_SCREEN_MANAGER_HPP
|
||||
#define POLYGUN_ENGINE_SCREEN_MANAGER_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "game/engine/screen.hpp"
|
||||
|
||||
namespace polygun::engine {
|
||||
class Engine;
|
||||
class Screen;
|
||||
class ScreenManager final {
|
||||
public:
|
||||
ScreenManager(Engine& engine);
|
||||
~ScreenManager();
|
||||
|
||||
void push_screen(std::unique_ptr<Screen> screen);
|
||||
void pop_screen();
|
||||
|
||||
void render();
|
||||
void update();
|
||||
|
||||
Screen* get_current_screen();
|
||||
|
||||
private:
|
||||
Engine& m_engine;
|
||||
std::vector<std::unique_ptr<Screen>> m_screen_stack;
|
||||
double m_prev_time;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // POLYGUN_ENGINE_SCREEN_MANAGER_HPP
|
288
src/game/screens/game_session_screen.cpp
Normal file
288
src/game/screens/game_session_screen.cpp
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
2023 kacperks
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "game/screens/game_session_screen.hpp"
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include "common/network/network_manager.hpp"
|
||||
#include "common/logger.hpp"
|
||||
#include "game/engine/engine.hpp"
|
||||
|
||||
using namespace polygun::screens;
|
||||
|
||||
static const float vertices[] = {
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
|
||||
0.1f, -0.1f, -0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
|
||||
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
|
||||
-0.1f, 0.1f, 0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
|
||||
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
-0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, -0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
|
||||
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
|
||||
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
|
||||
|
||||
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
|
||||
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
|
||||
-0.1f, 0.1f, 0.1f, 0.0f, 0.0f,
|
||||
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
GameSessionScreen::GameSessionScreen() :
|
||||
m_chunk_shader("shaders/chunk_vertex.glsl", "shaders/chunk_fragment.glsl"),
|
||||
m_chnk(),
|
||||
m_camera(),
|
||||
m_vbo(0),
|
||||
m_vao(0),
|
||||
m_texture_atlas(0),
|
||||
m_is_esc_pressed(false),
|
||||
m_was_camera_locked(false),
|
||||
m_connection_thread(),
|
||||
m_running(true)
|
||||
{}
|
||||
|
||||
void GameSessionScreen::begin() {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
glGenBuffers(1, &m_vbo);
|
||||
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
// position attribute
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glGenTextures(1, &m_texture_atlas);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture_atlas);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
int width, height, nrChannels;
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
unsigned char *data = stbi_load("res/textures/gold.png", &width, &height, &nrChannels, 0);
|
||||
if (data) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed to load texture" << std::endl;
|
||||
}
|
||||
stbi_image_free(data);
|
||||
|
||||
m_chunk_shader.bind();
|
||||
m_chunk_shader.set_uniform("texture_atlas", 0);
|
||||
|
||||
glfwSetCursorPosCallback(m_engine->get_window(), m_camera.mouse_callback);
|
||||
glfwSetInputMode(m_engine->get_window(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
// Note: uncomment to test connection with server
|
||||
// m_connection_thread.reset(new std::thread(&GameSessionScreen::connection_thread_func, this));
|
||||
}
|
||||
|
||||
void GameSessionScreen::render() {
|
||||
// rendering
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// bind textures on corresponding texture units
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture_atlas);
|
||||
|
||||
// activate shader
|
||||
m_chunk_shader.bind();
|
||||
|
||||
glm::mat4 projection = glm::perspective(glm::radians(m_camera.m_fov), (float)engine::Engine::get_screen_width() / (float)engine::Engine::get_screen_height(), 0.1f, 100.0f);
|
||||
m_chunk_shader.set_uniform("projection", projection);
|
||||
|
||||
glm::mat4 view = m_camera.get_view_matrix();
|
||||
m_chunk_shader.set_uniform("view", view);
|
||||
|
||||
glBindVertexArray(m_vao);
|
||||
|
||||
for (unsigned int x = 0; x < 32; x++) {
|
||||
for (unsigned int y = 0; y < 32; y++) {
|
||||
for (unsigned int z = 0; z < 32; z++) {
|
||||
if (m_chnk.get_node(glm::vec3(x,y,z))!= 0) {
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, glm::vec3(x/5.0f, y/5.0f, z/5.0f));
|
||||
m_chunk_shader.set_uniform("model", model);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// imgui
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(340, 200));
|
||||
|
||||
ImGui::Begin("Debug");
|
||||
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
// Camera pos
|
||||
ImGui::Text("Player Pos: %.3f, %.3f, %.3f", m_camera.m_position.x, m_camera.m_position.y, m_camera.m_position.z);
|
||||
// Camera rot
|
||||
ImGui::Text("Player Rot: %.3f, %.3f", m_camera.m_yaw, m_camera.m_pitch);
|
||||
|
||||
int x_d, y_d, z_d, id_d;
|
||||
|
||||
ImGui::InputInt("ID", &id_d);
|
||||
|
||||
ImGui::InputInt("X", &x_d);
|
||||
ImGui::InputInt("Y", &y_d);
|
||||
ImGui::InputInt("Z", &z_d);
|
||||
|
||||
if (ImGui::Button("Place Block")) {
|
||||
m_chnk.add_node(id_d, glm::vec3(x_d, y_d, z_d));
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
ImGui::EndFrame();
|
||||
}
|
||||
|
||||
void GameSessionScreen::update(double delta) {
|
||||
// input
|
||||
// -----
|
||||
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
if (!m_is_esc_pressed) {
|
||||
if (glfwGetInputMode(m_engine->get_window(), GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
glfwSetInputMode(m_engine->get_window(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
else
|
||||
glfwSetInputMode(m_engine->get_window(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
m_was_camera_locked = true;
|
||||
}
|
||||
m_is_esc_pressed = true;
|
||||
}
|
||||
else
|
||||
m_is_esc_pressed = false;
|
||||
|
||||
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_W) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::FORWARD, delta);
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_S) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::BACKWARD, delta);
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_A) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::LEFT, delta);
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_D) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::RIGHT, delta);
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::UP, delta);
|
||||
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
|
||||
m_camera.process_movement(polygun::engine::DOWN, delta);
|
||||
|
||||
if(glfwGetInputMode(m_engine->get_window(), GLFW_CURSOR) == GLFW_CURSOR_DISABLED) {
|
||||
if(m_was_camera_locked) {
|
||||
m_camera.update(true);
|
||||
m_was_camera_locked = false;
|
||||
}
|
||||
else
|
||||
m_camera.update(false);
|
||||
}
|
||||
}
|
||||
|
||||
void GameSessionScreen::finish() {
|
||||
glDeleteVertexArrays(1, &m_vao);
|
||||
glDeleteBuffers(1, &m_vbo);
|
||||
|
||||
m_running = false;
|
||||
if(m_connection_thread.get() && m_connection_thread->joinable()) {
|
||||
LOG_VERBOSE("Waiting for connection thread to finish");
|
||||
m_connection_thread->join();
|
||||
}
|
||||
}
|
||||
|
||||
void GameSessionScreen::connection_thread_func() {
|
||||
polygun::network::NetworkManager network_manager("127.0.0.1", 1117);
|
||||
polygun::network::NetworkPacket handshake = network_manager.create_packet(polygun::network::NetworkPacketFlag::FLAG_RELIABLE, polygun::network::NetworkPacketID::PACKET_HANDSHAKE);
|
||||
polygun::network::NetworkPacket packet;
|
||||
handshake.write("mrkubax10");
|
||||
network_manager.send_packet(handshake);
|
||||
network_manager.update();
|
||||
while(m_running) {
|
||||
if(network_manager.get_socket().recv(packet)) {
|
||||
if((packet.get_flags() & polygun::network::NetworkPacketFlag::FLAG_RELIABLE) || packet.get_id()==polygun::network::NetworkPacketID::PACKET_ACK)
|
||||
network_manager.push_packet(packet);
|
||||
network_manager.update();
|
||||
if(network_manager.recv_packet(packet)) {
|
||||
// handle
|
||||
}
|
||||
}
|
||||
packet = network_manager.create_packet(polygun::network::NetworkPacketFlag::FLAG_NONE, polygun::network::NetworkPacketID::PACKET_ACTIVITY);
|
||||
network_manager.send_packet(packet);
|
||||
}
|
||||
packet = network_manager.create_packet(polygun::network::NetworkPacketFlag::FLAG_RELIABLE, polygun::network::NetworkPacketID::PACKET_EXIT);
|
||||
network_manager.send_packet(packet);
|
||||
while(network_manager.has_outgoing_packets()) {
|
||||
if(network_manager.get_socket().recv(packet) && packet.get_id()==polygun::network::NetworkPacketID::PACKET_ACK)
|
||||
network_manager.push_packet(packet);
|
||||
network_manager.update();
|
||||
}
|
||||
}
|
64
src/game/screens/game_session_screen.hpp
Normal file
64
src/game/screens/game_session_screen.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
2023 kacperks
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POLYGUN_SCREENS_GAME_SESSION_SCREEN_HPP
|
||||
#define POLYGUN_SCREENS_GAME_SESSION_SCREEN_HPP
|
||||
|
||||
#include "game/engine/screen.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "game/engine/player_camera.hpp"
|
||||
#include "game/renderer/shader.hpp"
|
||||
#include "game/world/chunk.hpp"
|
||||
|
||||
namespace polygun::screens {
|
||||
class GameSessionScreen final : public engine::Screen {
|
||||
public:
|
||||
GameSessionScreen();
|
||||
~GameSessionScreen() = default;
|
||||
|
||||
virtual void begin() override;
|
||||
virtual void render() override;
|
||||
virtual void update(double delta) override;
|
||||
virtual void finish() override;
|
||||
|
||||
private:
|
||||
renderer::Shader m_chunk_shader;
|
||||
world::Chunk m_chnk;
|
||||
engine::Camera m_camera;
|
||||
unsigned int m_vbo, m_vao;
|
||||
unsigned int m_texture_atlas;
|
||||
bool m_is_esc_pressed, m_was_camera_locked;
|
||||
std::unique_ptr<std::thread> m_connection_thread;
|
||||
std::atomic<bool> m_running;
|
||||
|
||||
private:
|
||||
void connection_thread_func();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // POLYGUN_SCREENS_GAME_SESSION_SCREEN_HPP
|
43
src/game/screens/main_menu_screen.cpp
Normal file
43
src/game/screens/main_menu_screen.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "game/screens/main_menu_screen.hpp"
|
||||
|
||||
using namespace polygun::screens;
|
||||
|
||||
void MainMenuScreen::begin() {
|
||||
|
||||
}
|
||||
|
||||
void MainMenuScreen::render() {
|
||||
|
||||
}
|
||||
|
||||
void MainMenuScreen::update(double delta) {
|
||||
|
||||
}
|
||||
|
||||
void MainMenuScreen::finish() {
|
||||
|
||||
}
|
40
src/game/screens/main_menu_screen.hpp
Normal file
40
src/game/screens/main_menu_screen.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POLYGUN_SCREENS_MAIN_MENU_SCREEN_HPP
|
||||
#define POLYGUN_SCREENS_MAIN_MENU_SCREEN_HPP
|
||||
|
||||
#include "game/engine/screen.hpp"
|
||||
|
||||
namespace polygun::screens {
|
||||
class MainMenuScreen final : public engine::Screen {
|
||||
public:
|
||||
virtual void begin() override;
|
||||
virtual void render() override;
|
||||
virtual void update(double delta) override;
|
||||
virtual void finish() override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
88
src/server/command_parser.cpp
Normal file
88
src/server/command_parser.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "server/command_parser.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "server/server.hpp"
|
||||
#include "common/logger.hpp"
|
||||
|
||||
using namespace polygun::server;
|
||||
|
||||
CommandParser::CommandParser(Server& server) :
|
||||
m_server(server)
|
||||
{}
|
||||
|
||||
void CommandParser::parse(const std::string& line) {
|
||||
std::vector<std::string> tokens;
|
||||
std::string current_token;
|
||||
bool inside_quotes = false;
|
||||
bool escaped = false;
|
||||
for(size_t i = 0; i<line.length(); i++) {
|
||||
char ch = line[i];
|
||||
switch(ch) {
|
||||
case '\\':
|
||||
if(!escaped) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
case '"':
|
||||
if(!escaped) {
|
||||
inside_quotes = !inside_quotes;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
if(!current_token.empty() && !inside_quotes) {
|
||||
tokens.push_back(current_token);
|
||||
current_token.clear();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
current_token+=ch;
|
||||
if(escaped)
|
||||
escaped = false;
|
||||
}
|
||||
if(!current_token.empty())
|
||||
tokens.push_back(current_token);
|
||||
|
||||
if(tokens.empty())
|
||||
return;
|
||||
|
||||
const std::string& command = tokens[0];
|
||||
if(command=="quit")
|
||||
m_server.m_running = false;
|
||||
else if(command=="help")
|
||||
handle_help_command();
|
||||
else
|
||||
LOG_ERROR("Unknown command '%s'", command.c_str());
|
||||
}
|
||||
|
||||
void CommandParser::handle_help_command() {
|
||||
std::cout<<"Available commands: "<<std::endl;
|
||||
std::cout<<" quit - shutdowns server"<<std::endl;
|
||||
std::cout<<" help - shows this message"<<std::endl;
|
||||
}
|
47
src/server/command_parser.hpp
Normal file
47
src/server/command_parser.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
PolyGun
|
||||
|
||||
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef POLYGUN_SERVER_COMMAND_PARSER_HPP
|
||||
#define POLYGUN_SERVER_COMMAND_PARSER_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace polygun::server {
|
||||
class Server;
|
||||
class CommandParser final {
|
||||
public:
|
||||
CommandParser(Server& server);
|
||||
~CommandParser() = default;
|
||||
|
||||
void parse(const std::string& line);
|
||||
|
||||
private:
|
||||
Server& m_server;
|
||||
|
||||
private:
|
||||
void handle_help_command();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -26,25 +26,43 @@ SOFTWARE.
|
||||
|
||||
#include <cstring>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
#include <csignal>
|
||||
#if defined(__unix__)
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "common/logger.hpp"
|
||||
#include "server/command_parser.hpp"
|
||||
|
||||
using namespace polygun::server;
|
||||
|
||||
static Server* g_current_server = nullptr;
|
||||
|
||||
Server::Server() :
|
||||
m_running(true),
|
||||
m_clients(),
|
||||
m_latest_client(),
|
||||
m_server_socket(new polygun::network::UDPSocket)
|
||||
m_server_socket(new polygun::network::UDPSocket),
|
||||
m_command_thread()
|
||||
{
|
||||
LOG_INFO("Starting server");
|
||||
glfwInit();
|
||||
srand(time(nullptr));
|
||||
m_server_socket->bind(1117);
|
||||
g_current_server = this;
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
signal(SIGQUIT, signal_handler);
|
||||
signal(SIGSTOP, signal_handler);
|
||||
m_command_thread.reset(new std::thread(&Server::command_thread_func, this));
|
||||
}
|
||||
|
||||
Server::~Server() {
|
||||
LOG_INFO("Shutting down server");
|
||||
LOG_VERBOSE("Waiting for command thread to finish");
|
||||
if(m_command_thread->joinable())
|
||||
m_command_thread->join();
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
@ -104,6 +122,32 @@ void Server::run() {
|
||||
}
|
||||
}
|
||||
|
||||
void Server::command_thread_func() {
|
||||
std::string line;
|
||||
bool has_input_data = false;
|
||||
bool show_input_prompt = true;
|
||||
CommandParser parser(*this);
|
||||
while(m_running) {
|
||||
if(show_input_prompt) {
|
||||
std::cout<<"> ";
|
||||
std::cout.flush();
|
||||
show_input_prompt = false;
|
||||
}
|
||||
#if defined(__unix__)
|
||||
int byte_count = 0;
|
||||
ioctl(0, FIONREAD, &byte_count);
|
||||
if(byte_count>0)
|
||||
has_input_data = true;
|
||||
#endif
|
||||
if(has_input_data) {
|
||||
getline(std::cin, line);
|
||||
parser.parse(line);
|
||||
has_input_data = false;
|
||||
show_input_prompt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Server::handle_packet(polygun::network::NetworkPacket& packet, Client* client) {
|
||||
switch(packet.get_id()) {
|
||||
case polygun::network::NetworkPacketID::PACKET_HANDSHAKE:
|
||||
@ -173,3 +217,29 @@ void Server::handle_player_timeout(const Client* client) {
|
||||
void Server::handle_player_activity(Client* client) {
|
||||
client->update_activity();
|
||||
}
|
||||
|
||||
void Server::signal_handler(int sig) {
|
||||
if(!g_current_server)
|
||||
return;
|
||||
|
||||
std::string signal_name;
|
||||
switch(sig) {
|
||||
case SIGINT:
|
||||
signal_name = "SIGINT";
|
||||
break;
|
||||
case SIGTERM:
|
||||
signal_name = "SIGTERM";
|
||||
break;
|
||||
case SIGQUIT:
|
||||
signal_name = "SIGQUIT";
|
||||
break;
|
||||
case SIGSTOP:
|
||||
signal_name = "SIGSTOP";
|
||||
break;
|
||||
default:
|
||||
signal_name = "SIGUNKNOWN";
|
||||
}
|
||||
|
||||
LOG_INFO("Received %s signal", signal_name.c_str());
|
||||
g_current_server->m_running = false;
|
||||
}
|
||||
|
@ -25,10 +25,14 @@ SOFTWARE.
|
||||
#ifndef POLYGUN_SERVER_SERVER_HPP
|
||||
#define POLYGUN_SERVER_SERVER_HPP
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "server/client.hpp"
|
||||
|
||||
namespace polygun::server {
|
||||
class Server final {
|
||||
friend class CommandParser;
|
||||
public:
|
||||
Server();
|
||||
~Server();
|
||||
@ -36,18 +40,23 @@ namespace polygun::server {
|
||||
void run();
|
||||
|
||||
private:
|
||||
bool m_running;
|
||||
std::atomic<bool> m_running;
|
||||
std::vector<std::unique_ptr<Client>> m_clients;
|
||||
std::unique_ptr<Client> m_latest_client;
|
||||
std::shared_ptr<polygun::network::UDPSocket> m_server_socket;
|
||||
std::unique_ptr<std::thread> m_command_thread;
|
||||
|
||||
private:
|
||||
void command_thread_func();
|
||||
|
||||
bool handle_packet(polygun::network::NetworkPacket& packet, Client* client = nullptr);
|
||||
bool handle_new_player(polygun::network::NetworkPacket& packet);
|
||||
void handle_player_disconnected(const Client* client);
|
||||
void handle_player_timeout(const Client* client);
|
||||
void handle_player_activity(Client* client);
|
||||
void handle_invalid_packet(const Client& client, const polygun::network::NetworkPacket& packet);
|
||||
|
||||
static void signal_handler(int sig);
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user