diff --git a/include/client/camera.hpp b/include/client/camera.hpp index 770814a7..1e622c73 100644 --- a/include/client/camera.hpp +++ b/include/client/camera.hpp @@ -15,19 +15,72 @@ #define GLM_ENABLE_EXPERIMENTAL #include "glm/gtx/string_cast.hpp" +/** + * @brief Class representing a camera for rendering. Primarily used to compute the + * view-projection matrix and pass it to the Client for rendering objects from + * different viewing angles. + */ class Camera { public: + /** + * @brief Constructs a new Camera object. + * + */ Camera(); + + /** + * @brief Destroys the Camera object. + * + */ ~Camera(); // Access functions + /** + * @brief Sets the aspect ratio of the camera. + * + * @param a The new aspect ratio. + */ void setAspect(float a) { aspect = a; } + /** + * @brief Updates the the camera based on the input screen coordinates. + * + * @param xpos New x-coordinate for the cursor. + * @param ypos New y-coordinate for the cursor. + */ void update(float xpos, float ypos); + + /** + * @brief Moves the camera based on the axis, direction, and speed. Factors in the current + * direction of the camera to compute proper lateral and forward movement. + * + * @param is_x_axis A flag denoting whether the movement is along the x-axis or z-axis. + * @param dir The direction that the camera is moving in. + * @return glm::vec3 An output vector representing the movement of the camera in the specified + * axis and direction. + */ glm::vec3 move(bool is_x_axis, float dir); - glm::mat4 getViewProj(); + /** + * @brief Returns the view-projection matrix of the Camera, for use in rendering. + * + * @return glm::mat4 The view-projection matrix. + */ + glm::mat4 getViewProj() { return viewProjMat; } + + /** + * @brief Returns a normalized vector representing the direction that the camera is facing. + * + * @return glm::vec3 A normalized vector representing the direction the camera is facing. + */ + glm::vec3 getFacing() { return cameraFront; } + + /** + * @brief Updates the position of the camera. + * + * @param pos The new position of the camera. + */ void updatePos(glm::vec3 pos); glm::vec3 getPos(); diff --git a/include/client/client.hpp b/include/client/client.hpp index f0fb8336..3931f009 100644 --- a/include/client/client.hpp +++ b/include/client/client.hpp @@ -20,7 +20,6 @@ #include "client/camera.hpp" #include "client/audiomanager.hpp" -//#include "shared/game/gamestate.hpp" #include "shared/game/sharedgamestate.hpp" #include "shared/network/packet.hpp" #include "shared/network/session.hpp" @@ -37,87 +36,184 @@ using namespace boost::asio::ip; +/** + * @brief A clsas that represents the client for the game. Contains all local information, + * including the SharedGameState, as well as callbacks for rendering objects and initializing + * glfw, glew, shaders, and windows. + */ class Client { public: + /** + * @brief Constructs a new Client object. + * + * @param io_service + * @param config + */ + Client(boost::asio::io_service& io_service, GameConfig config); + + /** + * @brief Destroys the Client object. + */ + ~Client(); + + /** + * @brief Initializes glfw, glew, shaders, and the GLFWwindow. + * + * @return true if all libraries and objects were initialized correctly, false otherwise + */ + bool init(); + + /** + * @brief Frees all pointers, deletes the GLFWwindow, and terminates glfw. + * + * @return true if all objects were cleaned up correclty, false otherwise + */ + bool cleanup(); + // Callbacks + /** + * @brief Display callback which handles the rendering of all local objects. Abstracts + * the logic of the main render loop. All logic relating to rendering and any glfw + * or OpenGL calls should go in here. + */ void displayCallback(); + /** + * @brief Callback which handles all updates to the local SharedGameState, and sends + * events to the server based on any local inputs. All logic relating to state updates + * shoud go in here. + * + * @param context + */ void idleCallback(boost::asio::io_context& context); - void handleKeys(int eid, int keyType, bool keyHeld, bool *eventSent, glm::vec3 movement = glm::vec3(0.0f)); - - // Bound window callbacks - static void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); - static void mouseCallback(GLFWwindow* window, double xposIn, double yposIn); - static void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); - static void charCallback(GLFWwindow* window, unsigned int codepoint); + /** + * @brief Callback which handles keyboard inputs to the GLFWwindow. Binds to the GLFWwindow. + * + * @param window The GLFWwindow being monitered. + * @param key The key that is being pressed or released. + * @param scancode A unique platform-specific code for each key. + * @param action One of GLFW_PRESS, GLFW_REPEAT, or GLFW_RELEASE representing the state of the key. + * @param mods Any modifiers to the key pressed (i.e. shift, ctrl, alt, etc.). + */ + void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); + + /** + * @brief Callback which handles mouse cursor movement. Does not include mouse button presses. + * + * @param window The GLFWwindow being monitered. + * @param xposIn The current x-coordinate of the cursor. + * @param yposIn The current y-coordinate of the cursor. + */ + void mouseCallback(GLFWwindow* window, double xposIn, double yposIn); + + /** + * @brief Callback which handles mouse button presses. + * + * @param window The GLFWwindow being monitered. + * @param button The mouse button pressed. + * @param action One of GLFW_PRESS, GLFW_REPEAT, or GLFW_RELEASE representing the state of the button. + * @param mods Any modifiers to the key pressed (i.e. shift, ctrl, alt, etc.). + */ + void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); + + /** + * @brief + * + * @param window + * @param codepoint + */ + void charCallback(GLFWwindow* window, unsigned int codepoint); + + /** + * @brief Get a vec2 representing of the window size. + * + * @return glm::vec2 + */ static glm::vec2 getWindowSize(); + /** + * @brief Get the time of last keystroke. + * + * @return time_t + */ static time_t getTimeOfLastKeystroke(); // Getter / Setters + /** + * @brief Returns a pointer to the GLFWwindow object. + * + * @return GLFWwindow* The GLFWwindow being used in the Client. + */ GLFWwindow* getWindow() { return window; } - Client(boost::asio::io_service& io_service, GameConfig config); - ~Client(); - - bool init(); - bool cleanup(); - - void draw(); + /** + * @brief Creates and connects to a Session at the specified IP address. + * + * @param ip_addr + */ void connectAndListen(std::string ip_addr); AudioManager* getAudioManager(); private: - void processClientInput(); + /** + * @brief Processes all data received from the server and updates the SharedGameState. + * + * @param context + */ void processServerInput(boost::asio::io_context& context); + /** + * @brief Draws all objects in the SharedGameState. + */ + void draw(); + + /* Current game state */ SharedGameState gameState; + /* Shader objects for various */ std::shared_ptr cube_shader; std::shared_ptr model_shader; std::shared_ptr light_source_shader; + /* Character models and lighting objects, might need to move to different classes later */ std::unique_ptr player_model; std::unique_ptr bear_model; std::unique_ptr light_source; - float playerMovementDelta = 0.05f; - GLFWwindow *window; + /* GUI */ friend class gui::GUI; gui::GUI gui; gui::GUIState gui_state; - Camera *cam; AudioManager* audioManager; - // Flags - static bool is_held_up; - static bool is_held_down; - static bool is_held_right; - static bool is_held_left; - static bool is_held_space; - static bool is_held_shift; - - static bool cam_is_held_up; - static bool cam_is_held_down; - static bool cam_is_held_right; - static bool cam_is_held_left; - - static bool is_left_mouse_down; - static bool is_click_available; - static float mouse_xpos; - static float mouse_ypos; + /* Camera object representing player's current position & orientation */ + std::unique_ptr cam; + /* Flags */ static int window_width; static int window_height; static time_t time_of_last_keystroke; + /* Key held flags */ + bool is_held_up = false; + bool is_held_down = false; + bool is_held_right = false; + bool is_held_left = false; + bool is_held_space = false; + + bool is_left_mouse_down = false; + + /* Mouse position coordinates */ + float mouse_xpos = 0.0f; + float mouse_ypos = 0.0f; + GameConfig config; tcp::resolver resolver; tcp::socket socket; diff --git a/src/client/camera.cpp b/src/client/camera.cpp index 07fa3ca9..260cd04f 100644 --- a/src/client/camera.cpp +++ b/src/client/camera.cpp @@ -16,25 +16,15 @@ Camera::Camera() : cameraPos(glm::vec3(0.0f)), cameraFront(glm::vec3(0.0f, 0.0f, sensitivity = 0.1f; firstMouse = true; - // cameraPos = glm::vec3(0.0f); - // cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); - // cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); - worldUp = cameraUp; speed = 0.125f; - - // viewProjMat = glm::mat4(1.0f); } Camera::~Camera() { } -glm::mat4 Camera::getViewProj() { - return viewProjMat; -} - glm::vec3 Camera::getPos() { return cameraPos; } @@ -72,6 +62,7 @@ void Camera::update(float xpos, float ypos) { front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); cameraFront = glm::normalize(front); + glm::vec3 oldCamUp = cameraUp; cameraRight = glm::normalize(glm::cross(cameraFront, worldUp)); cameraUp = glm::normalize(glm::cross(cameraRight, cameraFront)); @@ -82,14 +73,13 @@ void Camera::update(float xpos, float ypos) { } glm::vec3 Camera::move(bool is_x_axis, float dir) { + glm::vec3 effCameraFront = glm::normalize(glm::vec3(cameraFront.x, 0.0f, cameraFront.z)); + if (is_x_axis) { - //glm::vec3 effCameraFront = glm::normalize(cameraFront - cameraFront.y); - // cameraPos += dir * speed * effCameraFront; - //return dir * speed * effCameraFront; - return dir * speed * cameraRight; + return dir * glm::normalize(glm::cross(effCameraFront, cameraUp)) * speed; } else { - // cameraPos += dir * glm::normalize(glm::cross(cameraFront, cameraUp)) * speed; - return dir * speed * cameraFront; + return dir * speed * effCameraFront; + // return dir * speed * cameraRight; } } diff --git a/src/client/client.cpp b/src/client/client.cpp index fcbb8b77..ee5b38d9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -33,28 +33,9 @@ using namespace boost::asio::ip; using namespace std::chrono_literals; -// Flags -bool Client::is_held_up = false; -bool Client::is_held_down = false; -bool Client::is_held_right = false; -bool Client::is_held_left = false; -bool Client::is_held_space = false; -bool Client::is_held_shift = false; - // Checker for events sent / later can be made in an array glm::vec3 sentCamMovement = glm::vec3(-1.0f); -bool shiftEvent = false; - -bool Client::cam_is_held_up = false; -bool Client::cam_is_held_down = false; -bool Client::cam_is_held_right = false; -bool Client::cam_is_held_left = false; -bool Client::is_left_mouse_down = false; - -float Client::mouse_xpos = 0.0f; -float Client::mouse_ypos = 0.0f; - int Client::window_width = UNIT_WINDOW_WIDTH; int Client::window_height = UNIT_WINDOW_HEIGHT; @@ -70,9 +51,8 @@ Client::Client(boost::asio::io_context& io_context, GameConfig config): session(nullptr), gui(this), gui_state(gui::GUIState::INITIAL_LOAD), - lobby_finder(io_context, config) -{ - cam = new Camera(); + lobby_finder(io_context, config), + cam(new Camera()) { audioManager = new AudioManager(); @@ -108,9 +88,7 @@ void Client::connectAndListen(std::string ip_addr) { this->session->startListen(); } -Client::~Client() { - -} +Client::~Client() {} // TODO: error flags / output for broken init bool Client::init() { @@ -188,6 +166,13 @@ bool Client::init() { } bool Client::cleanup() { + cam.reset(nullptr); + + // Destroy the window. + glfwDestroyWindow(window); + // Terminate GLFW. + glfwTerminate(); + delete audioManager; return true; } @@ -225,72 +210,46 @@ void Client::idleCallback(boost::asio::io_context& context) { // or send any movement related events if (this->gui_state != GUIState::GAME_HUD) { return; } - std::optional jump = glm::vec3(0.0f); - std::optional cam_movement = glm::vec3(0.0f); + glm::vec3 cam_movement = glm::vec3(0.0f); // Sets a direction vector - if (cam_is_held_right) - cam_movement.value() += cam->move(true, 1.0f); - if (cam_is_held_left) - cam_movement.value() += cam->move(true, -1.0f); - if (cam_is_held_up) - cam_movement.value() += cam->move(false, 1.0f); - if (cam_is_held_down) - cam_movement.value() += cam->move(false, -1.0f); - if (is_held_space) - jump.value() += glm::vec3(0.0f, 1.0f, 0.0f); - + if(is_held_right) + cam_movement += cam->move(true, 1.0f); + if(is_held_left) + cam_movement += cam->move(true, -1.0f); + if (is_held_up) + cam_movement += cam->move(false, 1.0f); + if (is_held_down) + cam_movement += cam->move(false, -1.0f); + + // Update camera facing direction cam->update(mouse_xpos, mouse_ypos); // IF PLAYER, allow moving if (this->session != nullptr && this->session->getInfo().client_eid.has_value()) { auto eid = this->session->getInfo().client_eid.value(); - this->session->sendEventAsync(Event(eid, EventType::ChangeFacing, ChangeFacingEvent(eid, cam_movement.value()))); + this->session->sendEventAsync(Event(eid, EventType::ChangeFacing, ChangeFacingEvent(eid, cam->getFacing()))); // Send jump action if (is_held_space) { - this->session->sendEventAsync(Event(eid, EventType::StartAction, StartActionEvent(eid, jump.value(), ActionType::Jump))); + this->session->sendEventAsync(Event(eid, EventType::StartAction, StartActionEvent(eid, glm::vec3(0.0f, 1.0f, 0.0f), ActionType::Jump))); } - // Handles individual keys - handleKeys(eid, GLFW_KEY_LEFT_SHIFT, is_held_shift, &shiftEvent); - // If movement 0, send stopevent - if ((sentCamMovement != cam_movement.value()) && cam_movement.value() == glm::vec3(0.0f)) { - this->session->sendEventAsync(Event(eid, EventType::StopAction, StopActionEvent(eid, cam_movement.value(), ActionType::MoveCam))); - sentCamMovement = cam_movement.value(); + if ((sentCamMovement != cam_movement) && cam_movement == glm::vec3(0.0f)) { + this->session->sendEventAsync(Event(eid, EventType::StopAction, StopActionEvent(eid, cam_movement, ActionType::MoveCam))); + sentCamMovement = cam_movement; } + // If movement detected, different from previous, send start event - else if (sentCamMovement != cam_movement.value()) { - this->session->sendEventAsync(Event(eid, EventType::StartAction, StartActionEvent(eid, cam_movement.value(), ActionType::MoveCam))); - sentCamMovement = cam_movement.value(); + else if (sentCamMovement != cam_movement) { + this->session->sendEventAsync(Event(eid, EventType::StartAction, StartActionEvent(eid, cam_movement, ActionType::MoveCam))); + sentCamMovement = cam_movement; } } } -// Handles given key -// send startAction key is held but not sent -// send stopAction when unheld -void Client::handleKeys(int eid, int keyType, bool keyHeld, bool *eventSent, glm::vec3 movement){ - if (keyHeld == *eventSent) { return; } - - ActionType sendAction; - switch (keyType) { - case GLFW_KEY_LEFT_SHIFT: - sendAction = ActionType::Sprint; - break; - } - if (keyHeld && !*eventSent) { - this->session->sendEventAsync(Event(eid, EventType::StartAction, StartActionEvent(eid, movement, sendAction))); - *eventSent = true; - } - if (!keyHeld && *eventSent) { - this->session->sendEventAsync(Event(eid, EventType::StopAction, StopActionEvent(eid, movement, sendAction))); - *eventSent = false; - } -} - void Client::processServerInput(boost::asio::io_context& context) { context.run_for(30ms); @@ -313,8 +272,6 @@ void Client::processServerInput(boost::asio::io_context& context) { } void Client::draw() { - glm::vec3 test(1.0f); - for (int i = 0; i < this->gameState.objects.size(); i++) { std::shared_ptr sharedObject = this->gameState.objects.at(i); @@ -389,69 +346,65 @@ void Client::draw() { // callbacks - for Interaction void Client::keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { - Client* client = static_cast(glfwGetWindowUserPointer(window)); - // Check for a key press. + /* Store player EID for use in certain key handling */ + std::optional eid; + + if (this->session->getInfo().client_eid.has_value()) { + eid = this->session->getInfo().client_eid.value(); + } + if (action == GLFW_PRESS) { switch (key) { case GLFW_KEY_ESCAPE: - if (client->gameState.phase == GamePhase::GAME) { - if (client->gui_state == GUIState::GAME_ESC_MENU) { - client->gui_state = GUIState::GAME_HUD; - } else if (client->gui_state == GUIState::GAME_HUD) { - client->gui_state = GUIState::GAME_ESC_MENU; + if (this->gameState.phase == GamePhase::GAME) { + if (this->gui_state == GUIState::GAME_ESC_MENU) { + this->gui_state = GUIState::GAME_HUD; + } else if (this->gui_state == GUIState::GAME_HUD) { + this->gui_state = GUIState::GAME_ESC_MENU; } } - client->gui.setCaptureKeystrokes(false); + this->gui.setCaptureKeystrokes(false); break; case GLFW_KEY_TAB: - client->gui.setCaptureKeystrokes(true); + this->gui.setCaptureKeystrokes(true); break; case GLFW_KEY_BACKSPACE: - client->gui.captureBackspace(); + this->gui.captureBackspace(); Client::time_of_last_keystroke = getMsSinceEpoch(); break; - case GLFW_KEY_DOWN: - is_held_down = true; - break; - - case GLFW_KEY_UP: - is_held_up = true; - break; - - case GLFW_KEY_LEFT: - is_held_left = true; - break; - - case GLFW_KEY_RIGHT: - is_held_right = true; - break; - + /* For movement keys (WASD), activate flags and use it to generate + * movement in idleCallback() instead of sending individual events + */ case GLFW_KEY_S: - cam_is_held_down = true; + is_held_down = true; break; case GLFW_KEY_W: - cam_is_held_up = true; + is_held_up = true; break; case GLFW_KEY_A: - cam_is_held_left = true; + is_held_left = true; break; case GLFW_KEY_D: - cam_is_held_right = true; + is_held_right = true; break; + /* Space also uses a flag to constantly send events when key is held */ case GLFW_KEY_SPACE: is_held_space = true; break; + /* Send an event to start 'shift' movement (i.e. sprint) */ case GLFW_KEY_LEFT_SHIFT: - is_held_shift = true; + if (eid.has_value()) { + this->session->sendEventAsync(Event(eid.value(), EventType::StartAction, StartActionEvent(eid.value(), glm::vec3(0.0f), ActionType::Sprint))); + } break; default: @@ -461,44 +414,30 @@ void Client::keyCallback(GLFWwindow *window, int key, int scancode, int action, if (action == GLFW_RELEASE) { switch (key) { - case GLFW_KEY_DOWN: - is_held_down = false; - break; - - case GLFW_KEY_UP: - is_held_up = false; - break; - - case GLFW_KEY_LEFT: - is_held_left = false; - break; - - case GLFW_KEY_RIGHT: - is_held_right = false; - break; - case GLFW_KEY_S: - cam_is_held_down = false; + is_held_down = false; break; case GLFW_KEY_W: - cam_is_held_up = false; + is_held_up = false; break; case GLFW_KEY_A: - cam_is_held_left = false; + is_held_left = false; break; case GLFW_KEY_D: - cam_is_held_right = false; + is_held_right = false; break; - + case GLFW_KEY_SPACE: is_held_space = false; break; case GLFW_KEY_LEFT_SHIFT: - is_held_shift = false; + if (eid.has_value()) { + this->session->sendEventAsync(Event(eid.value(), EventType::StopAction, StopActionEvent(eid.value(), glm::vec3(0.0f), ActionType::Sprint))); + } break; default: @@ -511,7 +450,7 @@ void Client::keyCallback(GLFWwindow *window, int key, int scancode, int action, auto ms_since_epoch = getMsSinceEpoch(); if (Client::time_of_last_keystroke + 100 < ms_since_epoch) { Client::time_of_last_keystroke = ms_since_epoch; - client->gui.captureBackspace(); + this->gui.captureBackspace(); } } } @@ -533,9 +472,7 @@ void Client::mouseButtonCallback(GLFWwindow* window, int button, int action, int } void Client::charCallback(GLFWwindow* window, unsigned int codepoint) { - Client* client = static_cast(glfwGetWindowUserPointer(window)); - - client->gui.captureKeystroke(static_cast(codepoint)); + gui.captureKeystroke(static_cast(codepoint)); Client::time_of_last_keystroke = getMsSinceEpoch(); } diff --git a/src/client/gui/widget/dyntext.cpp b/src/client/gui/widget/dyntext.cpp index 43e2dbc7..f875407e 100644 --- a/src/client/gui/widget/dyntext.cpp +++ b/src/client/gui/widget/dyntext.cpp @@ -49,8 +49,6 @@ DynText::DynText(const std::string& text, std::shared_ptr fon DynText({0.0f, 0.0f}, text, fonts, options) {} void DynText::render() { - glEnable(GL_CULL_FACE); - DynText::shader->use(); auto projection = GUI_PROJECTION_MATRIX(); @@ -99,8 +97,6 @@ void DynText::render() { glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); glUseProgram(0); - - glDisable(GL_CULL_FACE); } void DynText::changeColor(font::Color new_color) { diff --git a/src/client/main.cpp b/src/client/main.cpp index 17029b00..6a80aec3 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -20,26 +20,41 @@ void error_callback(int error, const char* description) { std::cerr << description << std::endl; } -void set_callbacks(GLFWwindow* window, Client* client) { +/** + * @brief Sets various callbacks for the GLFWwindow. Uses the windowUserPointer object which + * points to a Client object and wraps the member function calls with a lambda to pass in as + * the static callback. + * + * @param window + */ +void set_callbacks(GLFWwindow* window) { // Set the error callback. glfwSetErrorCallback(error_callback); - // Set the window resize callback. - // glfwSetWindowSizeCallback(window, Client::windowResizeCallback); + /* Set key callback */ + glfwSetKeyCallback(window, [](GLFWwindow* w, int key, int scancode, int action, int mods) { + static_cast(glfwGetWindowUserPointer(w))->keyCallback(w, key, scancode, action, mods); + }); - // Set the key callback. - glfwSetKeyCallback(window, Client::keyCallback); + /* Set mouse and cursor callbacks */ + glfwSetMouseButtonCallback(window, [](GLFWwindow* w, int button, int action, int mods) { + static_cast(glfwGetWindowUserPointer(w))->mouseButtonCallback(w, button, action, mods); + }); - // Set the mouse and cursor callbacks - glfwSetMouseButtonCallback(window, Client::mouseButtonCallback); - glfwSetCursorPosCallback(window, Client::mouseCallback); + glfwSetCursorPosCallback(window, [](GLFWwindow* w, double xposIn, double yposIn) { + static_cast(glfwGetWindowUserPointer(w))->mouseCallback(w, xposIn, yposIn); + }); - glfwSetCharCallback(window, Client::charCallback); + /* Set character callback for typing */ + glfwSetCharCallback(window, [](GLFWwindow* w, unsigned int codepoint) { + static_cast(glfwGetWindowUserPointer(w))->charCallback(w, codepoint); + }); } void set_opengl_settings(GLFWwindow* window) { // Enable depth buffering. glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); // Related to shaders and z value comparisons for the depth buffer. glDepthFunc(GL_LEQUAL); @@ -47,7 +62,7 @@ void set_opengl_settings(GLFWwindow* window) { // Set polygon drawing mode to fill front and back of each polygon. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - // Set clear color to black. + // Sets initial background color. glClearColor(0.8f, 0.8f, 0.8f, 1.0f); // Set cursor position to (0, 0) @@ -58,24 +73,25 @@ int main(int argc, char* argv[]) { auto config = GameConfig::parse(argc, argv); boost::asio::io_context context; - Client client(context, config); - if (!client.init()) { + std::unique_ptr client(new Client(context, config)); + + if (!client->init()) { std::cout << "client init failed" << std::endl; exit(EXIT_FAILURE); } - - GLFWwindow* window = client.getWindow(); + + GLFWwindow* window = client->getWindow(); if (!window) exit(EXIT_FAILURE); - glfwSetWindowUserPointer(window, &client); - + // Set the user pointer for the glfw window + glfwSetWindowUserPointer(window, client.get()); // Setup callbacks. - set_callbacks(window, &client); + set_callbacks(window); // Setup OpenGL settings. set_opengl_settings(window); - AudioManager* clientAudioManager = client.getAudioManager(); + AudioManager* clientAudioManager = client->getAudioManager(); clientAudioManager->playAudio(SoundType::Background); @@ -84,18 +100,13 @@ int main(int argc, char* argv[]) // Loop while GLFW window should stay open. while (!glfwWindowShouldClose(window)) { // Main render display callback. Rendering of objects is done here. - client.displayCallback(); + client->displayCallback(); // Idle callback. Updating objects, etc. can be done here. - client.idleCallback(context); + client->idleCallback(context); } - client.cleanup(); - - // Destroy the window. - glfwDestroyWindow(window); - // Terminate GLFW. - glfwTerminate(); + client->cleanup(); exit(EXIT_SUCCESS);