diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1702dd7..b46d33d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,3 @@
-<<<<<<< HEAD
cmake_minimum_required(VERSION 3.7)
# Set compiler flags
@@ -42,379 +41,3 @@ target_link_libraries(${EXECUTABLE_TARGET} ${STATIC_LIBS})
# Install executable
install(TARGETS ${EXECUTABLE_TARGET} DESTINATION bin)
-=======
-cmake_minimum_required(VERSION 3.7)
-project(antkeeper
- VERSION "0.0.0"
-)
-
-option(STANDALONE "Distribute in a standalone archive." OFF)
-set(LANGUAGE "en-us" CACHE STRING "")
-
-# Determine target build platform according to binary dir
-get_filename_component(PLATFORM ${PROJECT_BINARY_DIR} NAME CACHE)
-
-# Check for architecture mismatches
-if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
- if (${PLATFORM} STREQUAL "win64" OR ${PLATFORM} STREQUAL "linux64")
- message(FATAL_ERROR "Compiler architecture is 32-bit but target architecture is 64-bit.")
- endif()
-else()
- if (${PLATFORM} STREQUAL "win32" OR ${PLATFORM} STREQUAL "linux32")
- message(FATAL_ERROR "Compiler architecture is 64-bit but target architecture is 32-bit.")
- endif()
-endif()
-
-# Setup configuration strings
-set(ANTKEEPER_VERSION ${PROJECT_VERSION})
-set(ANTKEEPER_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
-set(ANTKEEPER_VERSION_MINOR ${PROJECT_VERSION_MINOR})
-set(ANTKEEPER_VERSION_PATCH ${PROJECT_VERSION_PATCH})
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- set(ANTKEEPER_BUILD_TYPE debug)
- set(ANTKEEPER_DEBUG ON)
-else()
- set(ANTKEEPER_BUILD_TYPE release)
- set(ANTKEEPER_DEBUG OFF)
-endif()
-
-# Setup build type paths
-set(BUILD_DIR ${PROJECT_SOURCE_DIR}/bin)
-set(BUILD_DEBUG_DIR ${BUILD_DIR}/debug)
-set(BUILD_RELEASE_DIR ${BUILD_DIR}/release)
-
-# Set package name
-set(PACKAGE_NAME ${PROJECT_NAME}-${PROJECT_VERSION}-${PLATFORM})
-set(PACKAGE_BUILD_NAME ${PACKAGE_NAME}-${ANTKEEPER_BUILD_TYPE})
-
-# Set package directory
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- set(PLATFORM_PACKAGE_DIR ${BUILD_DEBUG_DIR}/${PACKAGE_NAME})
-else()
- set(PLATFORM_PACKAGE_DIR ${BUILD_RELEASE_DIR}/${PACKAGE_NAME})
-endif()
-
-# Set C++ compiler flags for debug and release build types
-if(MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W2")
-elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
- # Update if necessary
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -s -DNDEBUG")
-endif()
-
-# Set C and C++ compiler flags for the target architecture
-if(${PLATFORM} STREQUAL "win32" OR ${PLATFORM} STREQUAL "linux32")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
-elseif(${PLATFORM} STREQUAL "win64" OR ${PLATFORM} STREQUAL "linux64")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64")
-elseif(${PLATFORM} STREQUAL "osx" AND CMAKE_OSX_ARCHITECTURES STREQUAL "")
- # 32-bit
- #set(CMAKE_OSX_ARCHITECTURES "i386" CACHE STRING "" FORCE)
-
- # 64-bit
- #set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "" FORCE)
-
- # 96-bit universal
- set(CMAKE_OSX_ARCHITECTURES "x86_64;i386" CACHE STRING "" FORCE)
-endif()
-
-# Disable .manifest generation
-if(${PLATFORM} STREQUAL "win32" OR ${PLATFORM} STREQUAL "win64")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO /OPT:REF /OPT:ICF")
-endif()
-
-# Set C++ version
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
-# Include ExternalProject_Add command
-include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
-
-# Configure, build and install emergent
-set(EMERGENT_BUILD_DIR ${PROJECT_BINARY_DIR}/deps/build/emergent)
-set(EMERGENT_INSTALL_DIR ${PROJECT_BINARY_DIR}/deps/install/emergent)
-set(EMERGENT_INCLUDE_DIR ${EMERGENT_INSTALL_DIR}/include)
-set(EMERGENT_GL3W_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/lib/emergent/lib/gl3w/include)
-set(EMERGENT_GLM_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/lib/emergent/lib/glm)
-set(EMERGENT_STB_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/lib/emergent/lib/stb)
-set(EMERGENT_INCLUDE_DIRS
- ${EMERGENT_INCLUDE_DIR}
- ${EMERGENT_GL3W_INCLUDE_DIR}
- ${EMERGENT_GLM_INCLUDE_DIR}
- ${EMERGENT_STB_INCLUDE_DIR}
-)
-set(EMERGENT_LIBRARY emergent)
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- set(FREETYPE_LIBRARY freetyped)
-else()
- set(FREETYPE_LIBRARY freetype)
-endif()
-set(EMERGENT_LIBRARIES
- ${EMERGENT_LIBRARY}
- ${FREETYPE_LIBRARY}
-)
-ExternalProject_Add(emergent-project
- SOURCE_DIR ${PROJECT_SOURCE_DIR}/lib/emergent
- CMAKE_ARGS
- "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
- "-DCMAKE_INSTALL_PREFIX=${EMERGENT_INSTALL_DIR}"
- BINARY_DIR ${EMERGENT_BUILD_DIR}
- INSTALL_DIR ${EMERGENT_INSTALL_DIR})
-
-# Configure, build and install SDL2
-set(SDL2_BUILD_DIR ${PROJECT_BINARY_DIR}/deps/build/SDL2)
-set(SDL2_INSTALL_DIR ${PROJECT_BINARY_DIR}/deps/install/SDL2)
-set(SDL2_INCLUDE_DIR ${SDL2_INSTALL_DIR}/include)
-set(SDL2_LIBRARY SDL2)
-set(SDL2main_LIBRARY SDL2main)
-set(SDL2_LIBRARIES
- ${SDL2main_LIBRARY}
- ${SDL2_LIBRARY}
-)
-
-if(MSVC)
- set(SDL2_LIBRARIES
- ${SDL2_LIBRARIES}
- dinput8
- dxguid
- user32
- gdi32
- winmm
- imm32
- ole32
- oleaut32
- shell32
- version
- uuid
- )
-else()
- set(SDL2_LIBRARIES
- ${SDL2_LIBRARIES}
- pthread
- dl
- )
-endif()
-
-
-ExternalProject_Add(SDL2-project
- SOURCE_DIR ${PROJECT_SOURCE_DIR}/lib/SDL2
- CMAKE_ARGS
- "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
- "-DCMAKE_INSTALL_PREFIX=${SDL2_INSTALL_DIR}"
- "-DSDL_STATIC=true"
- "-DSDL_SHARED=false"
- BINARY_DIR ${SDL2_BUILD_DIR}
- INSTALL_DIR ${SDL2_INSTALL_DIR})
-
-# Configure, build and install dirent
-set(DIRENT_BUILD_DIR ${PROJECT_BINARY_DIR}/deps/build/dirent)
-set(DIRENT_INSTALL_DIR ${PROJECT_BINARY_DIR}/deps/install/dirent)
-set(DIRENT_INCLUDE_DIR ${DIRENT_INSTALL_DIR}/include)
-ExternalProject_Add(dirent-project
- SOURCE_DIR ${PROJECT_SOURCE_DIR}/lib/dirent
- CMAKE_ARGS
- "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
- "-DCMAKE_INSTALL_PREFIX=${DIRENT_INSTALL_DIR}"
- BINARY_DIR ${DIRENT_BUILD_DIR}
- INSTALL_DIR ${DIRENT_INSTALL_DIR})
-
-# Find OpenGL
-find_package(OpenGL REQUIRED)
-
-# Find executable source directory
-set(EXECUTABLE_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src)
-
-# Generate C++ configuration file
-configure_file(${EXECUTABLE_SOURCE_DIR}/configuration.hpp.in ${EXECUTABLE_SOURCE_DIR}/configuration.hpp)
-
-# Collect executable source files
-set(EXECUTABLE_SOURCES
- ${EXECUTABLE_SOURCE_DIR}/configuration.hpp
- ${EXECUTABLE_SOURCE_DIR}/controls.cpp
- ${EXECUTABLE_SOURCE_DIR}/render-passes.hpp
- ${EXECUTABLE_SOURCE_DIR}/settings.cpp
- ${EXECUTABLE_SOURCE_DIR}/settings.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/terrain.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/terrain.hpp
- ${EXECUTABLE_SOURCE_DIR}/controls.hpp
- ${EXECUTABLE_SOURCE_DIR}/input.cpp
- ${EXECUTABLE_SOURCE_DIR}/input.hpp
- ${EXECUTABLE_SOURCE_DIR}/main.cpp
- ${EXECUTABLE_SOURCE_DIR}/mesh.cpp
- ${EXECUTABLE_SOURCE_DIR}/mesh.hpp
- ${EXECUTABLE_SOURCE_DIR}/application-state.hpp
- ${EXECUTABLE_SOURCE_DIR}/application-state.cpp
- ${EXECUTABLE_SOURCE_DIR}/application.hpp
- ${EXECUTABLE_SOURCE_DIR}/application.cpp
- ${EXECUTABLE_SOURCE_DIR}/states/loading-state.hpp
- ${EXECUTABLE_SOURCE_DIR}/states/loading-state.cpp
- ${EXECUTABLE_SOURCE_DIR}/states/splash-state.hpp
- ${EXECUTABLE_SOURCE_DIR}/states/splash-state.cpp
- ${EXECUTABLE_SOURCE_DIR}/states/title-state.hpp
- ${EXECUTABLE_SOURCE_DIR}/states/title-state.cpp
- ${EXECUTABLE_SOURCE_DIR}/states/game-state.hpp
- ${EXECUTABLE_SOURCE_DIR}/states/game-state.cpp
- ${EXECUTABLE_SOURCE_DIR}/ui/ui.hpp
- ${EXECUTABLE_SOURCE_DIR}/ui/ui.cpp
- ${EXECUTABLE_SOURCE_DIR}/ui/menu.hpp
- ${EXECUTABLE_SOURCE_DIR}/ui/menu.cpp
- ${EXECUTABLE_SOURCE_DIR}/ui/tween.hpp
- ${EXECUTABLE_SOURCE_DIR}/ui/tween.cpp
- ${EXECUTABLE_SOURCE_DIR}/ui/toolbar.hpp
- ${EXECUTABLE_SOURCE_DIR}/ui/toolbar.cpp
- ${EXECUTABLE_SOURCE_DIR}/ui/pie-menu.hpp
- ${EXECUTABLE_SOURCE_DIR}/ui/pie-menu.cpp
- ${EXECUTABLE_SOURCE_DIR}/render-passes.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/ant.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/ant.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/agent.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/agent.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/colony.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/colony.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/habitat.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/habitat.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/nest.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/nest.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/navmesh.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/navmesh.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/pheromone-matrix.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/pheromone-matrix.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/level.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/level.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/biome.hpp
- ${EXECUTABLE_SOURCE_DIR}/game/biome.cpp
- ${EXECUTABLE_SOURCE_DIR}/game/tool.cpp
- ${EXECUTABLE_SOURCE_DIR}/debug.hpp
- ${EXECUTABLE_SOURCE_DIR}/debug.cpp
- ${EXECUTABLE_SOURCE_DIR}/camera-rig.hpp
- ${EXECUTABLE_SOURCE_DIR}/camera-rig.cpp
- ${EXECUTABLE_SOURCE_DIR}/model-loader.hpp
- ${EXECUTABLE_SOURCE_DIR}/model-loader.cpp
- ${EXECUTABLE_SOURCE_DIR}/material-loader.hpp
- ${EXECUTABLE_SOURCE_DIR}/material-loader.cpp
-)
-
-# Setup manifest and exe icon for windows
-if(${PLATFORM} STREQUAL "win32" OR ${PLATFORM} STREQUAL "win64")
- list(APPEND EXECUTABLE_SOURCES "${EXECUTABLE_SOURCE_DIR}/windows/antkeeper.manifest")
-
- if(EXISTS ${PROJECT_SOURCE_DIR}/data)
- set(RC_FILES "${PROJECT_SOURCE_DIR}/data/icons/icon.rc")
- set(EXECUTABLE_SOURCES "${EXECUTABLE_SOURCES};${RC_FILES}")
- endif()
-endif()
-
-# Set link directories
-link_directories(${EMERGENT_INSTALL_DIR}/lib
- ${SDL2_INSTALL_DIR}/lib
-)
-
-# Set executable and library output directories
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PLATFORM_PACKAGE_DIR})
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PLATFORM_PACKAGE_DIR})
-
-# Add executable
-set(EXECUTABLE_NAME antkeeper)
-set(EXECUTABLE_TARGET ${PACKAGE_BUILD_NAME}-executable)
-add_executable(${EXECUTABLE_TARGET} ${EXECUTABLE_SOURCES})
-add_dependencies(${EXECUTABLE_TARGET} emergent-project SDL2-project dirent-project)
-set_target_properties(${EXECUTABLE_TARGET} PROPERTIES OUTPUT_NAME ${EXECUTABLE_NAME})
-
-# Set include directories
-target_include_directories(${EXECUTABLE_TARGET} PUBLIC
- ${EMERGENT_INCLUDE_DIRS}
- ${SDL2_INCLUDE_DIR}
- ${DIRENT_INCLUDE_DIR}
- ${OPENGL_INCLUDE_DIRS}
-)
-
-# Build library list
-list(APPEND EXECUTABLE_LIBRARIES
- ${SDL2_LIBRARIES}
- ${EMERGENT_LIBRARIES}
- ${OPENGL_gl_LIBRARY}
- ${FREETYPE_LIBRARY}
- #m
- #stdc++
-)
-
-# Link libraries
-target_link_libraries(${EXECUTABLE_TARGET} ${EXECUTABLE_LIBRARIES})
-
-# Add run target
-if(${PLATFORM} STREQUAL "linux32" OR ${PLATFORM} STREQUAL "linux64")
- add_custom_target(run
- COMMAND optirun "${PLATFORM_PACKAGE_DIR}/${EXECUTABLE_NAME}"
- DEPENDS ${EXECUTABLE_TARGET}
- WORKING_DIRECTORY ${PLATFORM_PACKAGE_DIR}
- )
-else()
- add_custom_target(run
- COMMAND ${EXECUTABLE_TARGET}
- DEPENDS ${EXECUTABLE_TARGET}
- WORKING_DIRECTORY ${PLATFORM_PACKAGE_DIR}
- )
-endif()
-
-# Add dist target
-add_custom_target(dist
- COMMAND
- ${CMAKE_COMMAND} -E tar "cfvz" "${PROJECT_SOURCE_DIR}/dist/${PACKAGE_NAME}.zip" --format=zip
- "${PLATFORM_PACKAGE_DIR}")
-
-# Add clean targets
-add_custom_target(clean-build
- COMMAND git clean -fdX
- WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/build"
-)
-
-# Add data subdirectory (if it exists)
-if(EXISTS ${PROJECT_SOURCE_DIR}/data)
- add_subdirectory(${PROJECT_SOURCE_DIR}/data)
-endif()
-
-
-# Distribution
-install(TARGETS ${EXECUTABLE_TARGET} DESTINATION ".")
-install(DIRECTORY ${PLATFORM_PACKAGE_DIR}/data
- DESTINATION .)
-
-set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
-set(CPACK_PACKAGE_VENDOR "C. J. Howard")
-set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
-set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
-set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
-set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${PLATFORM})
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- set(CPACK_OUTPUT_FILE_PREFIX "${PROJECT_SOURCE_DIR}/dist/debug")
-else()
- set(CPACK_OUTPUT_FILE_PREFIX "${PROJECT_SOURCE_DIR}/dist/release")
-endif()
-
-if(${PLATFORM} STREQUAL "win32" OR ${PLATFORM} STREQUAL "win64")
- set(CPACK_GENERATOR "ZIP")
- if (NOT STANDALONE)
- set(CPACK_GENERATOR "NSIS")
- set(CPACK_MONOLITHIC_INSTALL 1)
- set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}-installer)
- set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/data/icons/antkeeper-icon.ico")
- set(CPACK_PACKAGE_INSTALL_DIRECTORY "Antkeeper")
- get_target_property(EXECUTABLE_OUTPUT_NAME ${EXECUTABLE_TARGET} OUTPUT_NAME)
- set(CPACK_NSIS_MENU_LINKS "${EXECUTABLE_OUTPUT_NAME}" "Antkeeper")
- endif()
-elseif(${PLATFORM} STREQUAL "linux32" OR ${PLATFORM} STREQUAL "linux64")
- set(CPACK_GENERATOR "TGZ")
- if(NOT STANDALONE)
- set(CPACK_GENERATOR "DEB")
- set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}")
- endif()
-endif()
-
-include(CPack)
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036
diff --git a/src/application.cpp b/src/application.cpp
deleted file mode 100644
index 2a054a0..0000000
--- a/src/application.cpp
+++ /dev/null
@@ -1,2318 +0,0 @@
-/*
- * Copyright (C) 2017 Christopher J. Howard
- *
- * This file is part of Antkeeper Source Code.
- *
- * Antkeeper Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper Source Code. If not, see .
- */
-
-#include "application.hpp"
-#include "application-state.hpp"
-#include "model-loader.hpp"
-#include "material-loader.hpp"
-#include "states/loading-state.hpp"
-#include "states/splash-state.hpp"
-#include "states/title-state.hpp"
-#include "states/game-state.hpp"
-#include "game/colony.hpp"
-#include "game/pheromone-matrix.hpp"
-#include "game/tool.hpp"
-#include "ui/menu.hpp"
-#include "ui/toolbar.hpp"
-#include "ui/pie-menu.hpp"
-#include "debug.hpp"
-#include "camera-rig.hpp"
-#include "configuration.hpp"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define OPENGL_VERSION_MAJOR 3
-#define OPENGL_VERSION_MINOR 3
-
-#undef max
-
-Application::Application(int argc, char* argv[]):
- state(nullptr),
- nextState(nullptr),
- terminationCode(EXIT_SUCCESS)
-{
- window = nullptr;
- context = nullptr;
-
- // Initialize SDL
- std::cout << std::string("Initializing SDL... ");
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER) < 0)
- {
- std::cout << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Print SDL version strings
- SDL_version compiled;
- SDL_version linked;
- SDL_VERSION(&compiled);
- SDL_GetVersion(&linked);
- std::cout << std::string("Compiled with SDL ") << (int)compiled.major << std::string(".") << (int)compiled.minor << std::string(".") << (int)compiled.patch << std::endl;
- std::cout << std::string("Linking to SDL ") << (int)linked.major << std::string(".") << (int)linked.minor << std::string(".") << (int)linked.patch << std::endl;
-
- // Find app and user data paths
- appDataPath = std::string(SDL_GetBasePath()) + std::string("data/");
- userDataPath = SDL_GetPrefPath("cjhoward", "antkeeper");
- std::cout << std::string("Application data path: \"") << appDataPath << std::string("\"") << std::endl;
- std::cout << std::string("User data path: \"") << userDataPath << std::string("\"") << std::endl;
-
- // Form pathes to settings files
- defaultSettingsFilename = appDataPath + std::string("default-settings.txt");
- userSettingsFilename = userDataPath + std::string("settings.txt");
-
- // Load default settings
- std::cout << std::string("Loading default settings from \"") << defaultSettingsFilename << std::string("\"... ");
- if (!settings.load(defaultSettingsFilename))
- {
- std::cout << std::string("failed") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Load user settings
- std::cout << std::string("Loading user settings from \"") << userSettingsFilename << std::string("\"... ");
- if (!settings.load(userSettingsFilename))
- {
- // Failed, save default settings as user settings
- std::cout << std::string("failed") << std::endl;
- saveUserSettings();
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Get values of required settings
- settings.get("fullscreen", &fullscreen);
- settings.get("swap_interval", &swapInterval);
-
- // Select OpenGL version
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, OPENGL_VERSION_MAJOR);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, OPENGL_VERSION_MINOR);
- //SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
- SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
- //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
- //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
-
- // Set OpenGL buffer attributes
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
-
- // Get all possible display modes for the default display
- int displayModeCount = SDL_GetNumDisplayModes(0);
- for (int i = displayModeCount - 1; i >= 0; --i)
- {
- SDL_DisplayMode displayMode;
-
- if (SDL_GetDisplayMode(0, i, &displayMode) != 0)
- {
- std::cerr << std::string("Failed to get display mode: \"") << SDL_GetError() << std::string("\"") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
-
- resolutions.push_back(Vector2(displayMode.w, displayMode.h));
- }
-
- // Read requested windowed and fullscreen resolutions from settings
- Vector2 requestedWindowedResolution;
- Vector2 requestedFullscreenResolution;
- settings.get("windowed_width", &requestedWindowedResolution.x);
- settings.get("windowed_height", &requestedWindowedResolution.y);
- settings.get("fullscreen_width", &requestedFullscreenResolution.x);
- settings.get("fullscreen_height", &requestedFullscreenResolution.y);
-
- // Determine desktop resolution
- SDL_DisplayMode desktopDisplayMode;
- if (SDL_GetDesktopDisplayMode(0, &desktopDisplayMode) != 0)
- {
- std::cerr << std::string("Failed to get desktop display mode: \"") << SDL_GetError() << std::string("\"") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
- Vector2 desktopResolution;
- desktopResolution.x = static_cast(desktopDisplayMode.w);
- desktopResolution.y = static_cast(desktopDisplayMode.h);
-
- // Replace requested resolutions of -1 with native resolution
- requestedWindowedResolution.x = (requestedWindowedResolution.x == -1.0f) ? desktopResolution.x : requestedWindowedResolution.x;
- requestedWindowedResolution.y = (requestedWindowedResolution.y == -1.0f) ? desktopResolution.y : requestedWindowedResolution.y;
- requestedFullscreenResolution.x = (requestedFullscreenResolution.x == -1.0f) ? desktopResolution.x : requestedFullscreenResolution.x;
- requestedFullscreenResolution.y = (requestedFullscreenResolution.y == -1.0f) ? desktopResolution.y : requestedFullscreenResolution.y;
-
- // Find indices of closest resolutions to requested windowed and fullscreen resolutions
- windowedResolutionIndex = 0;
- fullscreenResolutionIndex = 0;
- float minWindowedResolutionDistance = std::numeric_limits::max();
- float minFullscreenResolutionDistance = std::numeric_limits::max();
- for (std::size_t i = 0; i < resolutions.size(); ++i)
- {
- Vector2 windowedResolutionDifference = resolutions[i] - requestedWindowedResolution;
- float windowedResolutionDistance = glm::dot(windowedResolutionDifference, windowedResolutionDifference);
- if (windowedResolutionDistance <= minWindowedResolutionDistance)
- {
- minWindowedResolutionDistance = windowedResolutionDistance;
- windowedResolutionIndex = i;
- }
-
- Vector2 fullscreenResolutionDifference = resolutions[i] - requestedFullscreenResolution;
- float fullscreenResolutionDistance = glm::dot(fullscreenResolutionDifference, fullscreenResolutionDifference);
- if (fullscreenResolutionDistance <= minFullscreenResolutionDistance)
- {
- minFullscreenResolutionDistance = fullscreenResolutionDistance;
- fullscreenResolutionIndex = i;
- }
- }
-
- // Determine window parameters and current resolution
- Uint32 windowFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI;
- if (fullscreen)
- {
- resolution = resolutions[fullscreenResolutionIndex];
- windowFlags |= SDL_WINDOW_FULLSCREEN;
- }
- else
- {
- resolution = resolutions[windowedResolutionIndex];
- }
-
- // Get requested language
- languageIndex = 0;
- std::string requestedLanguage;
- settings.get("language", &requestedLanguage);
- std::string stringsDirectory = appDataPath + std::string("strings/");
-
- // Find available languages
- {
- // Open strings directory
- DIR* dir = opendir(stringsDirectory.c_str());
- if (dir == nullptr)
- {
- std::cout << std::string("Failed to open strings directory \"") << stringsDirectory << std::string("\"") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
-
- // Scan directory for .txt files
- for (struct dirent* entry = readdir(dir); entry != nullptr; entry = readdir(dir))
- {
- if (entry->d_type == DT_DIR || *entry->d_name == '.')
- {
- continue;
- }
-
- std::string filename = entry->d_name;
- std::string::size_type delimeter = filename.find_last_of('.');
- if (delimeter == std::string::npos)
- {
- continue;
- }
-
- std::string extension = filename.substr(delimeter + 1);
- if (extension != "txt")
- {
- continue;
- }
-
- // Add language
- std::string language = filename.substr(0, delimeter);
- languages.push_back(language);
-
- if (language == requestedLanguage)
- {
- languageIndex = languages.size() - 1;
- }
- }
-
- // Close biomes directory
- closedir(dir);
- }
-
- // Load strings
- std::string stringsFile = appDataPath + std::string("strings/") + languages[languageIndex] + std::string(".txt");
- std::cout << std::string("Loading strings from \"") << stringsFile << std::string("\"... ");
- if (!strings.load(stringsFile))
- {
- std::cout << std::string("failed") << std::endl;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Get window title string
- std::string title;
- strings.get("title", &title);
-
- // Create window
- std::cout << std::string("Creating a ") << resolution.x << std::string("x") << resolution.y;
- std::cout << ((fullscreen) ? " fullscreen" : " windowed");
- std::cout << std::string(" window... ");
- window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, static_cast(resolution.x), static_cast(resolution.y), windowFlags);
- if (window == nullptr)
- {
- std::cout << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Print video driver
- const char* videoDriver = SDL_GetCurrentVideoDriver();
- if (!videoDriver)
- {
- std::cout << std::string("Unable to determine video driver") << std::endl;
- }
- else
- {
- std::cout << std::string("Using video driver \"") << videoDriver << std::string("\"") << std::endl;
- }
-
- // Create an OpenGL context
- std::cout << std::string("Creating an OpenGL context... ");
- context = SDL_GL_CreateContext(window);
- if (context == nullptr)
- {
- std::cout << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Initialize GL3W
- std::cout << std::string("Initializing GL3W... ");
- if (gl3wInit())
- {
- std::cout << std::string("failed") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Check if OpenGL version is supported
- if (!gl3wIsSupported(OPENGL_VERSION_MAJOR, OPENGL_VERSION_MINOR))
- {
- std::cout << std::string("OpenGL ") << OPENGL_VERSION_MAJOR << std::string(".") << OPENGL_VERSION_MINOR << std::string(" not supported") << std::endl;
- close(EXIT_FAILURE);
- return;
- }
-
- // Print OpenGL and GLSL version strings
- std::cout << std::string("Using OpenGL ") << glGetString(GL_VERSION) << std::string(", GLSL ") << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
-
- // Set swap interval (vsync)
- if (swapInterval)
- {
- std::cout << std::string("Enabling vertical sync... ");
- }
- else
- {
- std::cout << std::string("Disabling vertical sync... ");
- }
- if (SDL_GL_SetSwapInterval(swapInterval) != 0)
- {
- std::cout << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
- swapInterval = SDL_GL_GetSwapInterval();
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Clear screen to black
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapWindow(window);
-
- // Get display DPI
- std::cout << std::string("Getting DPI of display 0... ");
- if (SDL_GetDisplayDPI(0, &dpi, nullptr, nullptr) != 0)
- {
- std::cerr << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
-
- std::cout << std::string("Reverting to default DPI") << std::endl;
- settings.get("default_dpi", &dpi);
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Print DPI
- std::cout << std::string("Rendering at ") << dpi << std::string(" DPI") << std::endl;
-
- // Determine base font size
- settings.get("font_size", &fontSizePT);
- fontSizePX = fontSizePT * (1.0f / 72.0f) * dpi;
-
- // Print font size
- std::cout << std::string("Base font size is ") << fontSizePT << std::string("pt (") << fontSizePX << std::string("px)") << std::endl;
-
- // Setup input
- inputManager = new SDLInputManager();
- keyboard = (*inputManager->getKeyboards()).front();
- mouse = (*inputManager->getMice()).front();
- bindingControl = nullptr;
-
- // Allocate states
- loadingState = new LoadingState(this);
- splashState = new SplashState(this);
- titleState = new TitleState(this);
- gameState = new GameState(this);
-
- // Setup loaders
- textureLoader = new TextureLoader();
- materialLoader = new MaterialLoader();
- modelLoader = new ModelLoader();
- modelLoader->setMaterialLoader(materialLoader);
-
- // Allocate game variables
- orbitCam = new OrbitCam();
- freeCam = new FreeCam();
- activeRig = orbitCam;
-
- // Enter loading state
- state = nextState = loadingState;
- state->enter();
-
- displayDebugInfo = false;
-}
-
-Application::~Application()
-{
- SDL_GL_DeleteContext(context);
- SDL_DestroyWindow(window);
- SDL_Quit();
-}
-
-int Application::execute()
-{
- // Fixed timestep
- // @see http://gafferongames.com/game-physics/fix-your-timestep/
- t = 0.0f;
- dt = 1.0f / 60.0f;
- float accumulator = 0.0f;
- float maxFrameTime = 0.25f;
-
- int performanceSampleSize = 15; // Number of frames to sample
- int performanceSampleFrame = 0; // Current sample frame
- float performanceSampleTime = 0.0f; // Current sample time
-
- // Start frame timer
- frameTimer.start();
-
- while (state != nullptr)
- {
- // Calculate frame time (in milliseconds) then reset frame timer
- float frameTime = static_cast(frameTimer.microseconds().count()) / 1000.0f;
- frameTimer.reset();
-
- // Add frame time (in seconds) to accumulator
- accumulator += std::min(frameTime / 1000.0f, maxFrameTime);
-
- // If the user tried to close the application
- if (inputManager->wasClosed())
- {
- // Close the application
- close(EXIT_SUCCESS);
- }
- else
- {
- // Execute current state
- //while (accumulator >= dt)
- {
- state->execute();
-
- // Update controls
- menuControlProfile->update();
- gameControlProfile->update();
-
- // Perform tweening
- tweener->update(dt);
-
- //accumulator -= dt;
- //t += dt;
- }
- }
-
- // Check for state change
- if (nextState != state)
- {
- // Exit current state
- state->exit();
-
- // Enter next state (if valid)
- state = nextState;
- if (nextState != nullptr)
- {
- state->enter();
- tweener->update(0.0f);
-
- // Reset frame timer to counteract frames eaten by state exit() and enter() functions
- frameTimer.reset();
- }
- else
- {
- break;
- }
- }
-
- // Bind controls
- if (bindingControl != nullptr)
- {
- InputEvent event;
- inputManager->listen(&event);
-
- if (event.type != InputEvent::Type::NONE)
- {
- bindingControl->bind(event);
- bindingControl = nullptr;
-
- if (activeMenu != nullptr)
- {
- MenuItem* item = activeMenu->getSelectedItem();
- if (item != nullptr)
- {
- if (event.type == InputEvent::Type::KEY)
- {
- const char* keyName = SDL_GetKeyName(SDL_GetKeyFromScancode(static_cast(event.key.second)));
- std::stringstream stream;
- stream << keyName;
- std::string streamstring = stream.str();
- std::u32string label;
- label.assign(streamstring.begin(), streamstring.end());
-
- item->setValueName(item->getValueIndex(), label);
- }
- }
- }
- }
- }
-
- // Update input
- inputManager->update();
-
- // Check if fullscreen was toggled
- if (toggleFullscreen.isTriggered() && !toggleFullscreen.wasTriggered())
- {
- changeFullscreen();
- }
-
- // Check if debug display was toggled
- if (toggleDebugDisplay.isTriggered() && !toggleDebugDisplay.wasTriggered())
- {
- setDisplayDebugInfo(!displayDebugInfo);
- }
-
- // Add frame time to performance sample time and increment the frame count
- performanceSampleTime += frameTime;
- ++performanceSampleFrame;
-
- // If performance sample is complete
- if (performanceSampleFrame >= performanceSampleSize)
- {
- // Calculate mean frame time
- float meanFrameTime = performanceSampleTime / static_cast(performanceSampleSize);
-
- // Reset perform sample timers
- performanceSampleTime = 0.0f;
- performanceSampleFrame = 0;
-
- // Update frame time label
- if (frameTimeLabel->isVisible())
- {
- std::u32string label;
- std::stringstream stream;
- stream.precision(2);
- stream << std::fixed << meanFrameTime;
- std::string streamstring = stream.str();
- label.assign(streamstring.begin(), streamstring.end());
- frameTimeLabel->setText(label);
- }
- }
-
- // Update UI
- if (activeMenu != nullptr)
- {
- activeMenu->update(dt);
- }
-
- uiRootElement->update();
- uiBatcher->batch(uiBatch, uiRootElement);
-
- // Render scene
- renderer.render(scene);
-
- // Swap buffers
- SDL_GL_SwapWindow(window);
- }
-
- return terminationCode;
-}
-
-void Application::changeState(ApplicationState* state)
-{
- nextState = state;
-}
-
-void Application::setTerminationCode(int code)
-{
- terminationCode = code;
-}
-
-void Application::close(int terminationCode)
-{
- setTerminationCode(terminationCode);
- changeState(nullptr);
-}
-
-void Application::changeFullscreen()
-{
- fullscreen = !fullscreen;
-
- if (fullscreen)
- {
- resolution = resolutions[fullscreenResolutionIndex];
-
- SDL_SetWindowSize(window, static_cast(resolution.x), static_cast(resolution.y));
- if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) != 0)
- {
- std::cerr << std::string("Failed to set fullscreen mode: \"") << SDL_GetError() << std::string("\"") << std::endl;
- fullscreen = false;
- }
- }
- else
- {
- resolution = resolutions[windowedResolutionIndex];
-
- if (SDL_SetWindowFullscreen(window, 0) != 0)
- {
- std::cerr << std::string("Failed to set windowed mode: \"") << SDL_GetError() << std::string("\"") << std::endl;
- fullscreen = true;
- }
- else
- {
- SDL_SetWindowSize(window, static_cast(resolution.x), static_cast(resolution.y));
- SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
- }
- }
-
- // Print mode and resolution
- if (fullscreen)
- {
- std::cout << std::string("Changed to fullscreen mode at resolution ") << resolution.x << std::string("x") << resolution.y << std::endl;
- }
- else
- {
- std::cout << std::string("Changed to windowed mode at resolution ") << resolution.x << std::string("x") << resolution.y << std::endl;
- }
-
- // Save settings
- settings.set("fullscreen", fullscreen);
- saveUserSettings();
-
- // Resize UI
- resizeUI();
-
- // Notify window observers
- inputManager->update();
-}
-
-void Application::changeVerticalSync()
-{
- swapInterval = (swapInterval == 1) ? 0 : 1;
-
- if (swapInterval == 1)
- {
- std::cout << std::string("Enabling vertical sync... ");
- }
- else
- {
- std::cout << std::string("Disabling vertical sync... ");
- }
-
- if (SDL_GL_SetSwapInterval(swapInterval) != 0)
- {
- std::cout << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
- swapInterval = SDL_GL_GetSwapInterval();
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Save settings
- settings.set("swap_interval", swapInterval);
- saveUserSettings();
-}
-
-void Application::saveUserSettings()
-{
- std::cout << std::string("Saving user setttings to \"") << userSettingsFilename << std::string("\"... ");
- if (!settings.save(userSettingsFilename))
- {
- std::cout << std::string("failed") << std::endl;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-}
-
-bool Application::loadModels()
-{
- antModel = modelLoader->load("data/models/common-worker-ant.mdl");
- antHillModel = modelLoader->load("data/models/ant-hill.mdl");
- nestModel = modelLoader->load("data/models/nest.mdl");
- forcepsModel = modelLoader->load("data/models/forceps.mdl");
- lensModel = modelLoader->load("data/models/lens.mdl");
- brushModel = modelLoader->load("data/models/brush.mdl");
- sidewalkPanelModel = modelLoader->load("data/models/sidewalk-panel.mdl");
- soilModel = modelLoader->load("data/models/soil.mdl");
-
- if (!antModel || !antHillModel || !nestModel || !forcepsModel || !lensModel || !brushModel)
- {
- return false;
- }
-
- antModelInstance.setModel(antModel);
- antModelInstance.setTransform(Transform::getIdentity());
- antHillModelInstance.setModel(antHillModel);
- antHillModelInstance.setRotation(glm::angleAxis(glm::radians(90.0f), Vector3(1, 0, 0)));
- nestModelInstance.setModel(nestModel);
- sidewalkPanelInstance.setModel(sidewalkPanelModel);
-
- sidewalkPanelInstance1.setModel(sidewalkPanelModel);
- sidewalkPanelInstance2.setModel(sidewalkPanelModel);
- sidewalkPanelInstance3.setModel(sidewalkPanelModel);
- sidewalkPanelInstance4.setModel(sidewalkPanelModel);
- soilInstance.setModel(soilModel);
-
- float offset = 100.5f;
- sidewalkPanelInstance1.setTranslation(Vector3(-offset, 0.0f, 0.0f));
- sidewalkPanelInstance2.setTranslation(Vector3(-offset * 2.0f, 0.0f, 0.0f));
- sidewalkPanelInstance3.setTranslation(Vector3(offset, 0.0f, 0.0f));
- sidewalkPanelInstance4.setTranslation(Vector3(offset * 2.0f, 0.0f, 0.0f));
-
- soilInstance.setTranslation(Vector3(0.0f, -3.0f, 0.0f));
-
- return true;
-}
-
-bool Application::loadScene()
-{
- // Create scene layers
- defaultLayer = scene.addLayer();
- uiLayer = scene.addLayer();
-
- // Set shadow map resolution
- shadowMapResolution = 4096;
-
- // Generate shadow map framebuffer
- glGenFramebuffers(1, &shadowMapFramebuffer);
- glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFramebuffer);
-
- // Generate shadow map depth texture
- glGenTextures(1, &shadowMapDepthTextureID);
- glBindTexture(GL_TEXTURE_2D, shadowMapDepthTextureID);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapResolution, shadowMapResolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
-
- // Attach depth texture to framebuffer
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowMapDepthTextureID, 0);
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
-
- // Unbind shadow map depth texture
- glBindTexture(GL_TEXTURE_2D, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- // Setup shadow map render target
- shadowMapRenderTarget.width = shadowMapResolution;
- shadowMapRenderTarget.height = shadowMapResolution;
- shadowMapRenderTarget.framebuffer = shadowMapFramebuffer;
-
- // Setup texture class
- shadowMapDepthTexture.setTextureID(shadowMapDepthTextureID);
- shadowMapDepthTexture.setWidth(shadowMapResolution);
- shadowMapDepthTexture.setHeight(shadowMapResolution);
-
- // Setup shadow map render pass
- shadowMapPass.setRenderTarget(&shadowMapRenderTarget);
- shadowMapPass.setViewCamera(&camera);
- shadowMapPass.setLightCamera(&sunlightCamera);
-
- // Setup shadow map compositor
- shadowMapCompositor.addPass(&shadowMapPass);
- shadowMapCompositor.load(nullptr);
-
- // Post-processing framebuffers
- {
- // Generate color texture
- glGenTextures(1, &framebufferAColorTextureID);
- glBindTexture(GL_TEXTURE_2D, framebufferAColorTextureID);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast(resolution.x), static_cast(resolution.y), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- // Generate depth texture
- glGenTextures(1, &framebufferADepthTextureID);
- glBindTexture(GL_TEXTURE_2D, framebufferADepthTextureID);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, static_cast(resolution.x), static_cast(resolution.y), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
- //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
-
- // Generate framebuffer
- glGenFramebuffers(1, &framebufferA);
- glBindFramebuffer(GL_FRAMEBUFFER, framebufferA);
-
- // Attach textures to framebuffer
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferAColorTextureID, 0);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, framebufferADepthTextureID, 0);
- glDrawBuffer(GL_COLOR_ATTACHMENT0);
- //glReadBuffer(GL_COLOR_ATTACHMENT0);
-
- // Unbind framebuffer and texture
- glBindTexture(GL_TEXTURE_2D, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- // Setup render target
- framebufferARenderTarget.width = static_cast(resolution.x);
- framebufferARenderTarget.height = static_cast(resolution.y);
- framebufferARenderTarget.framebuffer = framebufferA;
-
- // Setup texture class
- framebufferAColorTexture.setTextureID(framebufferAColorTextureID);
- framebufferAColorTexture.setWidth(static_cast(resolution.x));
- framebufferAColorTexture.setHeight(static_cast(resolution.y));
- }
-
- {
- // Generate color texture
- glGenTextures(1, &framebufferBColorTextureID);
- glBindTexture(GL_TEXTURE_2D, framebufferBColorTextureID);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast(resolution.x), static_cast(resolution.y), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- // Generate framebuffer
- glGenFramebuffers(1, &framebufferB);
- glBindFramebuffer(GL_FRAMEBUFFER, framebufferB);
-
- // Attach textures to framebuffer
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferBColorTextureID, 0);
- glDrawBuffer(GL_COLOR_ATTACHMENT0);
- //glReadBuffer(GL_COLOR_ATTACHMENT0);
-
- // Unbind framebuffer and texture
- glBindTexture(GL_TEXTURE_2D, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- // Setup render target
- framebufferBRenderTarget.width = static_cast(resolution.x);
- framebufferBRenderTarget.height = static_cast(resolution.y);
- framebufferBRenderTarget.framebuffer = framebufferB;
-
- // Setup texture class
- framebufferBColorTexture.setTextureID(framebufferBColorTextureID);
- framebufferBColorTexture.setWidth(static_cast(resolution.x));
- framebufferBColorTexture.setHeight(static_cast(resolution.y));
- }
-
- // Pheromone PBO
- {
- glGenBuffers(1, &pheromonePBO);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pheromonePBO);
- glBufferData(GL_PIXEL_UNPACK_BUFFER, 4 * PHEROMONE_MATRIX_COLUMNS * PHEROMONE_MATRIX_ROWS, nullptr, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-
- glGenTextures(1, &pheromoneTextureID);
- glBindTexture(GL_TEXTURE_2D, pheromoneTextureID);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PHEROMONE_MATRIX_COLUMNS, PHEROMONE_MATRIX_ROWS, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- // Setup texture class
- pheromoneTexture.setWidth(PHEROMONE_MATRIX_COLUMNS);
- pheromoneTexture.setHeight(PHEROMONE_MATRIX_ROWS);
- pheromoneTexture.setTextureID(pheromoneTextureID);
- }
-
- // Enable seamless cubemap filtering
- glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
-
- // Setup skybox pass
- //skyboxPass.setRenderTarget(&framebufferARenderTarget);
- skyboxPass.setRenderTarget(&defaultRenderTarget);
-
- // Setup clear depth pass
- //clearDepthPass.setRenderTarget(&framebufferARenderTarget);
- clearDepthPass.setRenderTarget(&defaultRenderTarget);
- clearDepthPass.setClear(false, true, false);
- clearDepthPass.setClearDepth(1.0f);
-
- // Setup lighting pass
- //lightingPass.setRenderTarget(&framebufferARenderTarget);
- lightingPass.setRenderTarget(&defaultRenderTarget);
- lightingPass.setShadowMap(&shadowMapDepthTexture);
- lightingPass.setShadowCamera(&sunlightCamera);
- lightingPass.setShadowMapPass(&shadowMapPass);
-
- // Setup blur passes
- horizontalBlurPass.setRenderTarget(&framebufferBRenderTarget);
- horizontalBlurPass.setTexture(&framebufferAColorTexture);
- horizontalBlurPass.setDirection(Vector2(0.0f, 0.0f));
- verticalBlurPass.setRenderTarget(&framebufferARenderTarget);
- verticalBlurPass.setTexture(&framebufferBColorTexture);
- verticalBlurPass.setDirection(Vector2(0.0f, 0.0f));
- horizontalBlurPass2.setRenderTarget(&framebufferBRenderTarget);
- horizontalBlurPass2.setTexture(&framebufferAColorTexture);
- horizontalBlurPass2.setDirection(Vector2(0.0f, 0.0f));
- verticalBlurPass2.setRenderTarget(&defaultRenderTarget);
- verticalBlurPass2.setTexture(&framebufferBColorTexture);
- verticalBlurPass2.setDirection(Vector2(0.0f, 0.0f));
- verticalBlurPass2.setGammaCorrect(true);
-
-
- // Setup debug pass
- debugPass.setRenderTarget(&defaultRenderTarget);
-
- defaultCompositor.addPass(&clearDepthPass);
- defaultCompositor.addPass(&skyboxPass);
- defaultCompositor.addPass(&lightingPass);
- //defaultCompositor.addPass(&horizontalBlurPass);
- //defaultCompositor.addPass(&verticalBlurPass);
- //defaultCompositor.addPass(&horizontalBlurPass2);
- //defaultCompositor.addPass(&verticalBlurPass2);
- //defaultCompositor.addPass(&debugPass);
- defaultCompositor.load(nullptr);
-
- // Setup sunlight camera
- sunlightCamera.lookAt(Vector3(0, 0, 0), -Vector3(0.5f, 2.0f, 2.0f), Vector3(0, 1, 0));
- sunlightCamera.setOrthographic(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
- sunlightCamera.setCompositor(&shadowMapCompositor);
- sunlightCamera.setCompositeIndex(0);
- sunlightCamera.setCullingMask(nullptr);
- defaultLayer->addObject(&sunlightCamera);
-
- // Setup camera
- camera.lookAt(Vector3(0.0f, 0.0f, 10.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f));
- camera.setCompositor(&defaultCompositor);
- camera.setCompositeIndex(1);
- defaultLayer->addObject(&camera);
-
- // Debug
- lineBatcher = new LineBatcher(4096);
- BillboardBatch* lineBatch = lineBatcher->getBatch();
- lineBatch->setAlignment(&camera, BillboardAlignmentMode::CYLINDRICAL);
- lineBatch->setAlignmentVector(Vector3(1, 0, 0));
- defaultLayer->addObject(lineBatch);
-
- return true;
-}
-
-bool Application::loadUI()
-{
- // Load fonts
- FontLoader* fontLoader = new FontLoader();
-
- menuFont = new Font(512, 512);
- if (!fontLoader->load("data/fonts/NotoSansCJKsc-Regular.otf", static_cast(fontSizePX + 0.5f), {UnicodeRange::BASIC_LATIN}, menuFont))
- {
- std::cerr << std::string("Failed to load menu font") << std::endl;
- }
-
- copyrightFont = new Font(256, 256);
- if (!fontLoader->load("data/fonts/Varela-Regular.ttf", static_cast(fontSizePX * 0.8f + 0.5f), {UnicodeRange::BASIC_LATIN}, copyrightFont))
- {
- std::cerr << std::string("Failed to load copyright font") << std::endl;
- }
-
- levelNameFont = new Font(512, 512);
- if (!fontLoader->load("data/fonts/Vollkorn-Regular.ttf", static_cast(fontSizePX * 2.0f + 0.5f), {UnicodeRange::BASIC_LATIN}, levelNameFont))
- {
- std::cerr << std::string("Failed to load level name font") << std::endl;
- }
-
- delete fontLoader;
-
- // Load UI textures
- textureLoader->setGamma(1.0f);
- textureLoader->setMipmapChain(false);
- textureLoader->setMaxAnisotropy(1.0f);
- textureLoader->setWrapS(false);
- textureLoader->setWrapT(false);
-
- splashTexture = textureLoader->load2D("data/textures/ui-splash.png");
- titleTexture = textureLoader->load2D("data/textures/ui-title.png");
- rectangularPaletteTexture = textureLoader->load2D("data/textures/rectangular-palette.png");
- foodIndicatorTexture = textureLoader->load2D("data/textures/food-indicator.png");
- toolBrushTexture = textureLoader->load2D("data/textures/tool-brush.png");
- toolLensTexture = textureLoader->load2D("data/textures/tool-lens.png");
- toolForcepsTexture = textureLoader->load2D("data/textures/tool-forceps.png");
- toolTrowelTexture = textureLoader->load2D("data/textures/tool-trowel.png");
-
- toolbarTopTexture = textureLoader->load2D("data/textures/toolbar-top.png");
- toolbarBottomTexture = textureLoader->load2D("data/textures/toolbar-bottom.png");
- toolbarMiddleTexture = textureLoader->load2D("data/textures/toolbar-middle.png");
- toolbarButtonRaisedTexture = textureLoader->load2D("data/textures/toolbar-button-raised.png");
- toolbarButtonDepressedTexture = textureLoader->load2D("data/textures/toolbar-button-depressed.png");
-
- arcNorthTexture = textureLoader->load2D("data/textures/pie-menu-arc-north.png");
- arcEastTexture = textureLoader->load2D("data/textures/pie-menu-arc-east.png");
- arcSouthTexture = textureLoader->load2D("data/textures/pie-menu-arc-south.png");
- arcWestTexture = textureLoader->load2D("data/textures/pie-menu-arc-west.png");
-
- mouseLeftTexture = textureLoader->load2D("data/textures/mouse-left.png");
- mouseRightTexture = textureLoader->load2D("data/textures/mouse-right.png");
-
- // Set colors
- selectedColor = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
- deselectedColor = Vector4(1.0f, 1.0f, 1.0f, 0.35f);
-
- // Create tweener
- tweener = new Tweener();
-
- // Setup root UI element
- uiRootElement = new UIContainer();
- uiRootElement->setDimensions(resolution);
- mouse->addMouseMotionObserver(uiRootElement);
- mouse->addMouseButtonObserver(uiRootElement);
-
- // Create blackout element (for screen transitions)
- blackoutImage = new UIImage();
- blackoutImage->setLayerOffset(ANTKEEPER_UI_LAYER_BLACKOUT);
- blackoutImage->setTintColor(Vector4(0.0f, 0.0f, 0.0f, 1.0f));
- blackoutImage->setVisible(false);
- uiRootElement->addChild(blackoutImage);
-
- // Create darken element (for darkening title screen)
- darkenImage = new UIImage();
- darkenImage->setLayerOffset(ANTKEEPER_UI_LAYER_DARKEN);
- darkenImage->setTintColor(Vector4(0.0f, 0.0f, 0.0f, 0.35f));
- darkenImage->setVisible(false);
- uiRootElement->addChild(darkenImage);
-
- // Create splash screen background element
- splashBackgroundImage = new UIImage();
- splashBackgroundImage->setLayerOffset(-1);
- splashBackgroundImage->setTintColor(Vector4(0.0f, 0.0f, 0.0f, 1.0f));
- splashBackgroundImage->setVisible(false);
- uiRootElement->addChild(splashBackgroundImage);
-
- // Create splash screen element
- splashImage = new UIImage();
- splashImage->setTexture(splashTexture);
- splashImage->setVisible(false);
- uiRootElement->addChild(splashImage);
-
- // Create game title element
- titleImage = new UIImage();
- titleImage->setTexture(titleTexture);
- titleImage->setVisible(false);
- titleImage->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- uiRootElement->addChild(titleImage);
-
- frameTimeLabel = new UILabel();
- frameTimeLabel->setLayerOffset(99);
- frameTimeLabel->setTintColor(Vector4(1.0f, 1.0f, 0.0f, 1.0f));
- frameTimeLabel->setVisible(false);
- uiRootElement->addChild(frameTimeLabel);
-
- //bool frameTimeLabelVisible = false;
- //settings.get("show_frame_time", &frameTimeLabelVisible);
- //frameTimeLabel->setVisible(frameTimeLabelVisible);
-
- // Create "Press any key" element
- anyKeyLabel = new UILabel();
- anyKeyLabel->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- anyKeyLabel->setVisible(false);
- uiRootElement->addChild(anyKeyLabel);
-
- // Create copyright element
- copyrightLabel = new UILabel();
- copyrightLabel->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- copyrightLabel->setVisible(false);
- copyrightLabel->setTintColor(Vector4(1.0f, 1.0f, 1.0f, 0.15f));
- uiRootElement->addChild(copyrightLabel);
-
- rectangularPaletteImage = new UIImage();
- rectangularPaletteImage->setTexture(rectangularPaletteTexture);
- rectangularPaletteImage->setVisible(false);
- rectangularPaletteImage->setActive(false);
- rectangularPaletteImage->setLayerOffset(ANTKEEPER_UI_LAYER_HUD);
- uiRootElement->addChild(rectangularPaletteImage);
-
- contextButtonImage0 = new UIImage();
- contextButtonImage0->setTexture(mouseLeftTexture);
- //uiRootElement->addChild(contextButtonImage0);
-
- foodIndicatorImage = new UIImage();
- foodIndicatorImage->setTexture(foodIndicatorTexture);
- //uiRootElement->addChild(foodIndicatorImage);
-
- depthTextureImage = new UIImage();
- depthTextureImage->setTexture(&shadowMapDepthTexture);
- depthTextureImage->setVisible(false);
- //uiRootElement->addChild(depthTextureImage);
-
- // Create level name label
- levelNameLabel = new UILabel();
- levelNameLabel->setVisible(false);
- levelNameLabel->setLayerOffset(ANTKEEPER_UI_LAYER_HUD);
- uiRootElement->addChild(levelNameLabel);
-
- // Create toolbar
- toolbar = new Toolbar();
- toolbar->setToolbarTopTexture(toolbarTopTexture);
- toolbar->setToolbarBottomTexture(toolbarBottomTexture);
- toolbar->setToolbarMiddleTexture(toolbarMiddleTexture);
- toolbar->setButtonRaisedTexture(toolbarButtonRaisedTexture);
- toolbar->setButtonDepressedTexture(toolbarButtonDepressedTexture);
- toolbar->addButton(toolBrushTexture, std::bind(&std::printf, "0\n"), std::bind(&std::printf, "0\n"));
- toolbar->addButton(toolLensTexture, std::bind(&std::printf, "1\n"), std::bind(&std::printf, "1\n"));
- toolbar->addButton(toolForcepsTexture, std::bind(&std::printf, "2\n"), std::bind(&std::printf, "2\n"));
- toolbar->addButton(toolTrowelTexture, std::bind(&std::printf, "3\n"), std::bind(&std::printf, "3\n"));
- toolbar->resize();
- //uiRootElement->addChild(toolbar->getContainer());
- toolbar->getContainer()->setVisible(false);
- toolbar->getContainer()->setActive(false);
-
- // Create pie menu
- pieMenu = new PieMenu(tweener);
- pieMenu->addOption(arcNorthTexture, toolLensTexture, std::bind(&Application::selectTool, this, lens), std::bind(&Application::deselectTool, this, lens));
- pieMenu->addOption(arcEastTexture, toolForcepsTexture, std::bind(&Application::selectTool, this, forceps), std::bind(&Application::deselectTool, this, forceps));
- pieMenu->addOption(arcSouthTexture, toolTrowelTexture, std::bind(&Application::selectTool, this, nullptr), std::bind(&Application::deselectTool, this, nullptr));
- pieMenu->addOption(arcWestTexture, toolBrushTexture, std::bind(&Application::selectTool, this, brush), std::bind(&Application::deselectTool, this, brush));
- uiRootElement->addChild(pieMenu->getContainer());
- pieMenu->resize();
- pieMenu->getContainer()->setVisible(false);
- pieMenu->getContainer()->setActive(true);
-
- // Setup screen fade in/fade out tween
- fadeInTween = new Tween(EaseFunction::IN_QUINT, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
- fadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, blackoutImage, std::placeholders::_1));
- tweener->addTween(fadeInTween);
- fadeOutTween = new Tween(EaseFunction::OUT_QUINT, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
- fadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, blackoutImage, std::placeholders::_1));
- tweener->addTween(fadeOutTween);
-
- // Setup darken fade in/fade out tweens
- darkenFadeInTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 0.4f));
- darkenFadeInTween->setStartCallback(std::bind(&UIElement::setVisible, darkenImage, true));
- darkenFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, darkenImage, std::placeholders::_1));
- tweener->addTween(darkenFadeInTween);
- darkenFadeOutTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, Vector4(0.0f, 0.0f, 0.0f, 0.4f), Vector4(0.0f, 0.0f, 0.0f, -0.4f));
- darkenFadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, darkenImage, std::placeholders::_1));
- darkenFadeOutTween->setEndCallback(std::bind(&UIElement::setVisible, darkenImage, false));
- tweener->addTween(darkenFadeOutTween);
-
- // Setup blur fade in/fade out tweens
- blurFadeInTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, 0.0f, 1.0f);
- blurFadeInTween->setUpdateCallback
- (
- [this](float t)
- {
- float factor = blurFadeInTween->getTweenValue();
- horizontalBlurPass.setDirection(Vector2(1.0f, 0.0f) * t);
- horizontalBlurPass2.setDirection(Vector2(3.0f, 0.0f) * t);
- verticalBlurPass.setDirection(Vector2(0.0f, 1.0f) * t);
- verticalBlurPass2.setDirection(Vector2(0.0f, 3.0f) * t);
- }
- );
- tweener->addTween(blurFadeInTween);
-
- blurFadeOutTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, 1.0f, -1.0f);
- blurFadeOutTween->setUpdateCallback
- (
- [this](float t)
- {
- float factor = blurFadeInTween->getTweenValue();
- horizontalBlurPass.setDirection(Vector2(1.0f, 0.0f) * t);
- horizontalBlurPass2.setDirection(Vector2(3.0f, 0.0f) * t);
- verticalBlurPass.setDirection(Vector2(0.0f, 1.0f) * t);
- verticalBlurPass2.setDirection(Vector2(0.0f, 3.0f) * t);
- }
- );
- tweener->addTween(blurFadeOutTween);
-
- // Setup splash screen tween
- splashFadeInTween = new Tween(EaseFunction::IN_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
- splashFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, splashImage, std::placeholders::_1));
- tweener->addTween(splashFadeInTween);
-
- splashHangTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 1.0f, 0.0f, 1.0f);
- tweener->addTween(splashHangTween);
-
- splashFadeOutTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
- splashFadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, splashImage, std::placeholders::_1));
- tweener->addTween(splashFadeOutTween);
-
- splashFadeInTween->setEndCallback(std::bind(&TweenBase::start, splashHangTween));
- splashHangTween->setEndCallback(std::bind(&TweenBase::start, splashFadeOutTween));
- splashFadeOutTween->setEndCallback(std::bind(&Application::changeState, this, titleState));
-
- // Setup game title tween
- titleFadeInTween = new Tween(EaseFunction::IN_CUBIC, 0.0f, 2.0f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
- titleFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, titleImage, std::placeholders::_1));
- tweener->addTween(titleFadeInTween);
- titleFadeOutTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.25f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
- titleFadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, titleImage, std::placeholders::_1));
- tweener->addTween(titleFadeOutTween);
-
- // Setup "Press any key" tween
- anyKeyFadeInTween = new Tween(EaseFunction::LINEAR, 0.0f, 1.5f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(1.0f, 1.0f, 1.0f, 1.0f));
- anyKeyFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, anyKeyLabel, std::placeholders::_1));
- tweener->addTween(anyKeyFadeInTween);
- anyKeyFadeOutTween = new Tween(EaseFunction::LINEAR, 0.0f, 1.5f, Vector4(1.0f, 1.0f, 1.0f, 1.0f), Vector4(1.0f, 1.0f, 1.0f, -1.0f));
- anyKeyFadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, anyKeyLabel, std::placeholders::_1));
- anyKeyFadeInTween->setEndCallback(std::bind(&TweenBase::start, anyKeyFadeOutTween));
- anyKeyFadeOutTween->setEndCallback(std::bind(&TweenBase::start, anyKeyFadeInTween));
- tweener->addTween(anyKeyFadeOutTween);
-
- float menuFadeInDuration = 0.5f;
- Vector4 menuFadeInStartColor = Vector4(1.0f, 1.0f, 1.0f, 0.0f);
- Vector4 menuFadeInDeltaColor = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
- float menuFadeOutDuration = 0.25f;
- Vector4 menuFadeOutStartColor = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
- Vector4 menuFadeOutDeltaColor = Vector4(0.0f, 0.0f, 0.0f, -1.0f);
-
- // Setup main menu tween
- menuFadeInTween = new Tween(EaseFunction::OUT_QUINT, 0.0f, menuFadeInDuration, menuFadeInStartColor, menuFadeInDeltaColor);
- tweener->addTween(menuFadeInTween);
- menuActivateTween = new Tween(EaseFunction::OUT_QUINT, 0.0f, 0.01f, 0.0f, 0.0f);
- tweener->addTween(menuActivateTween);
- menuFadeOutTween = new Tween(EaseFunction::OUT_QUINT, 0.0f, menuFadeOutDuration, menuFadeOutStartColor, menuFadeOutDeltaColor);
- tweener->addTween(menuFadeOutTween);
-
- // Camera translation tween
- cameraTranslationTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 0.0f, Vector3(0.0f), Vector3(0.0f));
- tweener->addTween(cameraTranslationTween);
-
- // Tool tweens
- forcepsSwoopTween = new Tween(EaseFunction::OUT_CUBIC, 0.0f, 1.0f, 0.0f, 0.5f);
- tweener->addTween(forcepsSwoopTween);
-
- // Build menu system
- activeMenu = nullptr;
- previousActiveMenu = nullptr;
-
- // Allocate menus
- mainMenu = new Menu();
- levelsMenu = new Menu();
- optionsMenu = new Menu();
- controlsMenu = new Menu();
- pauseMenu = new Menu();
-
- // Main menu
- {
- mainMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
- mainMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- mainMenu->setLineSpacing(1.0f);
- mainMenu->getUIContainer()->setActive(false);
- mainMenu->getUIContainer()->setVisible(false);
- uiRootElement->addChild(mainMenu->getUIContainer());
-
- mainMenuContinueItem = mainMenu->addItem();
- mainMenuContinueItem->setActivatedCallback(std::bind(&Application::continueGame, this));
-
- mainMenuLevelsItem = mainMenu->addItem();
- mainMenuLevelsItem->setActivatedCallback(std::bind(&Application::openMenu, this, levelsMenu));
-
- mainMenuNewGameItem = mainMenu->addItem();
- mainMenuNewGameItem->setActivatedCallback(std::bind(&Application::newGame, this));
-
- mainMenuSandboxItem = mainMenu->addItem();
- mainMenuSandboxItem->setActivatedCallback(std::bind(&std::printf, "1\n"));
-
- mainMenuOptionsItem = mainMenu->addItem();
- mainMenuOptionsItem->setActivatedCallback
- (
- [this]()
- {
- optionsMenuBackItem->setActivatedCallback(std::bind(&Application::openMenu, this, mainMenu));
- openMenu(optionsMenu);
- }
- );
-
- mainMenuExitItem = mainMenu->addItem();
- mainMenuExitItem->setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS));
- }
-
- // Levels menu
- {
- levelsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
- levelsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- levelsMenu->setLineSpacing(1.0f);
-
- for (std::size_t world = 0; world < campaign.getWorldCount(); ++world)
- {
- for (std::size_t level = 0; level < campaign.getLevelCount(world); ++level)
- {
- MenuItem* levelItem = levelsMenu->addItem();
- levelItem->setActivatedCallback
- (
- [this, world, level]()
- {
- loadWorld(world);
- loadLevel(level);
-
- // Close levels menu
- closeMenu();
-
- // Begin title fade-out
- titleFadeOutTween->reset();
- titleFadeOutTween->start();
-
- // Begin fade-out
- fadeOutTween->setEndCallback(std::bind(&Application::changeState, this, gameState));
- fadeOutTween->reset();
- fadeOutTween->start();
- }
- );
- }
- }
-
- levelsMenuBackItem = levelsMenu->addItem();
- levelsMenuBackItem->setActivatedCallback
- (
- [this]()
- {
- openMenu(previousActiveMenu);
- }
- );
-
- levelsMenu->getUIContainer()->setActive(false);
- levelsMenu->getUIContainer()->setVisible(false);
- uiRootElement->addChild(levelsMenu->getUIContainer());
- }
-
- // Options menu
- {
- optionsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
- optionsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- optionsMenu->setLineSpacing(1.0f);
- optionsMenu->setColumnMargin(menuFont->getWidth(U"MM"));
-
- optionsMenuWindowedResolutionItem = optionsMenu->addItem();
- optionsMenuFullscreenResolutionItem = optionsMenu->addItem();
- for (const Vector2& resolution: resolutions)
- {
- optionsMenuWindowedResolutionItem->addValue();
- optionsMenuFullscreenResolutionItem->addValue();
- }
- optionsMenuWindowedResolutionItem->setValueIndex(windowedResolutionIndex);
- optionsMenuWindowedResolutionItem->setActivatedCallback(std::bind(&Application::incrementMenuItem, this));
- optionsMenuWindowedResolutionItem->setValueChangedCallback(std::bind(&Application::selectWindowedResolution, this, std::placeholders::_1));
- optionsMenuFullscreenResolutionItem->setValueIndex(fullscreenResolutionIndex);
- optionsMenuFullscreenResolutionItem->setActivatedCallback(std::bind(&Application::incrementMenuItem, this));
- optionsMenuFullscreenResolutionItem->setValueChangedCallback(std::bind(&Application::selectFullscreenResolution, this, std::placeholders::_1));
-
- optionsMenuFullscreenItem = optionsMenu->addItem();
- optionsMenuFullscreenItem->addValue();
- optionsMenuFullscreenItem->addValue();
- optionsMenuFullscreenItem->setValueIndex((fullscreen == 0) ? 0 : 1);
- optionsMenuFullscreenItem->setActivatedCallback(std::bind(&Application::incrementMenuItem, this));
- optionsMenuFullscreenItem->setValueChangedCallback(std::bind(&Application::selectFullscreenMode, this, std::placeholders::_1));
-
- optionsMenuVSyncItem = optionsMenu->addItem();
- optionsMenuVSyncItem->addValue();
- optionsMenuVSyncItem->addValue();
- optionsMenuVSyncItem->setValueIndex((swapInterval == 0) ? 0 : 1);
- optionsMenuVSyncItem->setActivatedCallback(std::bind(&Application::incrementMenuItem, this));
- optionsMenuVSyncItem->setValueChangedCallback(std::bind(&Application::selectVSyncMode, this, std::placeholders::_1));
-
- optionsMenuLanguageItem = optionsMenu->addItem();
- for (std::size_t i = 0; i < languages.size(); ++i)
- {
- optionsMenuLanguageItem->addValue();
- }
- optionsMenuLanguageItem->setValueIndex(languageIndex);
- optionsMenuLanguageItem->setActivatedCallback(std::bind(&Application::incrementMenuItem, this));
- optionsMenuLanguageItem->setValueChangedCallback(std::bind(&Application::selectLanguage, this, std::placeholders::_1));
-
- optionsMenuControlsItem = optionsMenu->addItem();
- optionsMenuControlsItem->setActivatedCallback
- (
- [this]()
- {
- controlsMenuBackItem->setActivatedCallback(std::bind(&Application::openMenu, this, optionsMenu));
- openMenu(controlsMenu);
- }
- );
-
- optionsMenuBackItem = optionsMenu->addItem();
- optionsMenuBackItem->setActivatedCallback
- (
- [this]()
- {
- openMenu(previousActiveMenu);
- }
- );
-
- optionsMenu->getUIContainer()->setActive(false);
- optionsMenu->getUIContainer()->setVisible(false);
- uiRootElement->addChild(optionsMenu->getUIContainer());
- }
-
- // Controls menu
- {
- controlsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
- controlsMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- controlsMenu->setLineSpacing(1.0f);
- controlsMenu->setColumnMargin(menuFont->getWidth(U"MM"));
- controlsMenu->getUIContainer()->setActive(false);
- controlsMenu->getUIContainer()->setVisible(false);
- uiRootElement->addChild(controlsMenu->getUIContainer());
-
- controlsMenuResetToDefaultItem = controlsMenu->addItem();
-
- controlsMenuMoveForwardItem = controlsMenu->addItem();
- controlsMenuMoveForwardItem->addValue();
- controlsMenuMoveForwardItem->setActivatedCallback(std::bind(&Application::bindControl, this, &cameraMoveForward));
-
- controlsMenuMoveBackItem = controlsMenu->addItem();
- controlsMenuMoveBackItem->addValue();
- controlsMenuMoveBackItem->setActivatedCallback(std::bind(&Application::bindControl, this, &cameraMoveBack));
-
- controlsMenuMoveLeftItem = controlsMenu->addItem();
- controlsMenuMoveLeftItem->addValue();
- controlsMenuMoveLeftItem->setActivatedCallback(std::bind(&Application::bindControl, this, &cameraMoveLeft));
-
- controlsMenuMoveRightItem = controlsMenu->addItem();
- controlsMenuMoveRightItem->addValue();
- controlsMenuMoveRightItem->setActivatedCallback(std::bind(&Application::bindControl, this, &cameraMoveRight));
-
- controlsMenuBackItem = controlsMenu->addItem();
- controlsMenuBackItem->setActivatedCallback
- (
- [this]()
- {
- openMenu(optionsMenu);
- }
- );
- }
-
- // Pause menu
- {
- pauseMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.5f));
- pauseMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
- pauseMenu->setLineSpacing(1.0f);
-
- pauseMenuResumeItem = pauseMenu->addItem();
- pauseMenuResumeItem->setActivatedCallback(std::bind(&Application::closePauseMenu, this));
-
- pauseMenuLevelsItem = pauseMenu->addItem();
- pauseMenuLevelsItem->setActivatedCallback(std::bind(&Application::openMenu, this, levelsMenu));
-
- pauseMenuOptionsItem = pauseMenu->addItem();
- pauseMenuOptionsItem->setActivatedCallback
- (
- [this]()
- {
- optionsMenuBackItem->setActivatedCallback(std::bind(&Application::openMenu, this, pauseMenu));
- openMenu(optionsMenu);
- }
- );
-
- pauseMenuMainMenuItem = pauseMenu->addItem();
- pauseMenuMainMenuItem->setActivatedCallback
- (
- [this]()
- {
- // Close pause menu
- closeMenu();
-
- // Begin fade-out to title state
- fadeOutTween->setEndCallback(std::bind(&Application::changeState, this, titleState));
- fadeOutTween->reset();
- fadeOutTween->start();
- }
- );
-
- pauseMenuExitItem = pauseMenu->addItem();
- pauseMenuExitItem->setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS));
-
- pauseMenu->getUIContainer()->setActive(false);
- pauseMenu->getUIContainer()->setVisible(false);
- uiRootElement->addChild(pauseMenu->getUIContainer());
- }
-
- // Set UI strings
- restringUI();
- resizeUI();
-
- // Setup UI batch
- uiBatch = new BillboardBatch();
- uiBatch->resize(512);
- uiBatcher = new UIBatcher();
-
- // Setup UI render pass and compositor
- uiPass.setRenderTarget(&defaultRenderTarget);
- uiCompositor.addPass(&uiPass);
- uiCompositor.load(nullptr);
-
- // Setup UI camera
- uiCamera.lookAt(glm::vec3(0), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0));
- uiCamera.setCompositor(&uiCompositor);
- uiCamera.setCompositeIndex(0);
-
- // Setup UI scene
- uiLayer->addObject(uiBatch);
- uiLayer->addObject(&uiCamera);
-
- defaultRenderTarget.width = static_cast(resolution.x);
- defaultRenderTarget.height = static_cast(resolution.y);
- defaultRenderTarget.framebuffer = 0;
- resizeUI();
-
- return true;
-}
-
-bool Application::loadControls()
-{
- // Setup menu navigation controls
- menuControlProfile = new ControlProfile(inputManager);
- menuControlProfile->registerControl("menu_left", &menuLeft);
- menuControlProfile->registerControl("menu_right", &menuRight);
- menuControlProfile->registerControl("menu_up", &menuUp);
- menuControlProfile->registerControl("menu_down", &menuDown);
- menuControlProfile->registerControl("menu_select", &menuSelect);
- menuControlProfile->registerControl("menu_cancel", &menuCancel);
- menuControlProfile->registerControl("toggle_fullscreen", &toggleFullscreen);
- menuControlProfile->registerControl("toggle_debug_display", &toggleDebugDisplay);
- menuControlProfile->registerControl("escape", &escape);
- menuLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
- menuLeft.bindKey(keyboard, SDL_SCANCODE_A);
- menuRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
- menuRight.bindKey(keyboard, SDL_SCANCODE_D);
- menuUp.bindKey(keyboard, SDL_SCANCODE_UP);
- menuUp.bindKey(keyboard, SDL_SCANCODE_W);
- menuDown.bindKey(keyboard, SDL_SCANCODE_DOWN);
- menuDown.bindKey(keyboard, SDL_SCANCODE_S);
- menuSelect.bindKey(keyboard, SDL_SCANCODE_RETURN);
- menuSelect.bindKey(keyboard, SDL_SCANCODE_SPACE);
- menuSelect.bindKey(keyboard, SDL_SCANCODE_Z);
- menuCancel.bindKey(keyboard, SDL_SCANCODE_BACKSPACE);
- menuCancel.bindKey(keyboard, SDL_SCANCODE_X);
- toggleFullscreen.bindKey(keyboard, SDL_SCANCODE_F11);
- toggleDebugDisplay.bindKey(keyboard, SDL_SCANCODE_GRAVE);
- escape.bindKey(keyboard, SDL_SCANCODE_ESCAPE);
-
- // Setup in-game controls
- gameControlProfile = new ControlProfile(inputManager);
- gameControlProfile->registerControl("camera-move-forward", &cameraMoveForward);
- gameControlProfile->registerControl("camera-move-back", &cameraMoveBack);
- gameControlProfile->registerControl("camera-move-left", &cameraMoveLeft);
- gameControlProfile->registerControl("camera-move-right", &cameraMoveRight);
- gameControlProfile->registerControl("camera-rotate-cw", &cameraRotateCW);
- gameControlProfile->registerControl("camera-rotate-ccw", &cameraRotateCCW);
- gameControlProfile->registerControl("camera-zoom-in", &cameraZoomIn);
- gameControlProfile->registerControl("camera-zoom-out", &cameraZoomOut);
- gameControlProfile->registerControl("camera-toggle-nest-view", &cameraToggleNestView);
- gameControlProfile->registerControl("camera-toggle-overhead-view", &cameraToggleOverheadView);
- gameControlProfile->registerControl("walk-forward", &walkForward);
- gameControlProfile->registerControl("walk-back", &walkBack);
- gameControlProfile->registerControl("turn-left", &turnLeft);
- gameControlProfile->registerControl("turn-right", &turnRight);
- gameControlProfile->registerControl("toggle-pause", &togglePause);
- gameControlProfile->registerControl("toggle-pause-menu", &togglePauseMenu);
- gameControlProfile->registerControl("fast-forward", &fastForward);
- gameControlProfile->registerControl("switch-rig", &switchRig);
-
- cameraMoveForward.bindKey(keyboard, SDL_SCANCODE_W);
- cameraMoveBack.bindKey(keyboard, SDL_SCANCODE_S);
- cameraMoveLeft.bindKey(keyboard, SDL_SCANCODE_A);
- cameraMoveRight.bindKey(keyboard, SDL_SCANCODE_D);
- cameraRotateCW.bindKey(keyboard, SDL_SCANCODE_Q);
- cameraRotateCCW.bindKey(keyboard, SDL_SCANCODE_E);
- cameraZoomIn.bindKey(keyboard, SDL_SCANCODE_EQUALS);
- cameraZoomOut.bindKey(keyboard, SDL_SCANCODE_MINUS);
- cameraZoomIn.bindMouseWheelAxis(mouse, MouseWheelAxis::POSITIVE_Y);
- cameraZoomOut.bindMouseWheelAxis(mouse, MouseWheelAxis::NEGATIVE_Y);
- cameraToggleOverheadView.bindKey(keyboard, SDL_SCANCODE_R);
- cameraToggleNestView.bindKey(keyboard, SDL_SCANCODE_F);
- walkForward.bindKey(keyboard, SDL_SCANCODE_UP);
- walkBack.bindKey(keyboard, SDL_SCANCODE_DOWN);
- turnLeft.bindKey(keyboard, SDL_SCANCODE_LEFT);
- turnRight.bindKey(keyboard, SDL_SCANCODE_RIGHT);
- togglePause.bindKey(keyboard, SDL_SCANCODE_SPACE);
- togglePauseMenu.bindKey(keyboard, SDL_SCANCODE_ESCAPE);
- fastForward.bindKey(keyboard, SDL_SCANCODE_F);
- switchRig.bindKey(keyboard, SDL_SCANCODE_TAB);
-
- return true;
-}
-
-bool Application::loadGame()
-{
- // Load biosphere
- biosphere.load("data/biomes/");
-
- // Load campaign
- campaign.load("data/levels/");
- currentWorldIndex = 0;
- currentLevelIndex = 0;
- simulationPaused = false;
-
- // Allocate level
- currentLevel = new Level();
-
- // Create colony
- colony = new Colony();
- colony->setAntModel(antModel);
-
- currentTool = nullptr;
-
- // Create tools
- forceps = new Forceps(forcepsModel);
- forceps->setColony(colony);
- forceps->setOrbitCam(orbitCam);
-
- lens = new Lens(lensModel);
- lens->setOrbitCam(orbitCam);
- lens->setSunDirection(glm::normalize(-Vector3(0.5f, 2.0f, 2.0f)));
-
- brush = new Brush(brushModel);
- brush->setColony(colony);
- brush->setOrbitCam(orbitCam);
-
- loadWorld(0);
- loadLevel(0);
-
- return true;
-}
-
-void Application::resizeUI()
-{
- // Adjust render target dimensions
- defaultRenderTarget.width = static_cast(resolution.x);
- defaultRenderTarget.height = static_cast(resolution.y);
-
- // Adjust UI dimensions
- uiRootElement->setDimensions(resolution);
- uiRootElement->update();
-
- // Adjust title
- titleImage->setAnchor(Vector2(0.5f, 0.0f));
- titleImage->setDimensions(Vector2(titleTexture->getWidth(), titleTexture->getHeight()));
- titleImage->setTranslation(Vector2(0.0f, (int)(resolution.y * (1.0f / 4.0f) - titleTexture->getHeight() * 0.5f)));
- blackoutImage->setDimensions(resolution);
- darkenImage->setDimensions(resolution);
- splashBackgroundImage->setDimensions(resolution);
- splashImage->setAnchor(Anchor::CENTER);
- splashImage->setDimensions(Vector2(splashTexture->getWidth(), splashTexture->getHeight()));
- frameTimeLabel->setAnchor(Vector2(0.0f, 0.0f));
- frameTimeLabel->setTranslation(Vector2(0.0f));
- anyKeyLabel->setAnchor(Vector2(0.5f, 1.0f));
- anyKeyLabel->setTranslation(Vector2(0.0f, (int)(-resolution.y * (1.0f / 4.0f) - menuFont->getMetrics().getHeight() * 0.5f)));
-
- copyrightLabel->setAnchor(Vector2(0.0f, 1.0f));
- copyrightLabel->setTranslation(Vector2(resolution.x, -resolution.y) * 0.02f);
-
- rectangularPaletteImage->setAnchor(Vector2(0.0f, 1.0f));
- rectangularPaletteImage->setDimensions(Vector2(rectangularPaletteTexture->getWidth(), rectangularPaletteTexture->getHeight()));
- rectangularPaletteImage->setTranslation(Vector2(16.0f, -16.0f));
- contextButtonImage0->setAnchor(Vector2(0.5f, 1.0f));
- contextButtonImage0->setDimensions(Vector2(mouseLeftTexture->getWidth(), mouseLeftTexture->getHeight()));
- contextButtonImage0->setTranslation(Vector2(0.0f, -16.0f));
- foodIndicatorImage->setAnchor(Vector2(1.0f, 0.0f));
- foodIndicatorImage->setDimensions(Vector2(foodIndicatorTexture->getWidth(), foodIndicatorTexture->getHeight()));
- foodIndicatorImage->setTranslation(Vector2(-16.0f, 16.0f));
- depthTextureImage->setAnchor(Vector2(0.0f, 1.0f));
- depthTextureImage->setDimensions(Vector2(256, 256));
- depthTextureImage->setTranslation(Vector2(0.0f, 0.0f));
- levelNameLabel->setAnchor(Vector2(0.5f, 0.5f));
-
- // Adjust UI camera projection
- uiCamera.setOrthographic(0.0f, resolution.x, resolution.y, 0.0f, -1.0f, 1.0f);
-}
-
-void Application::restringUI()
-{
- // Build map of UTF-8 string names to UTF-32 string values
- std::map stringMap;
- const std::map* stringParameters = strings.getParameters();
- for (auto it = stringParameters->begin(); it != stringParameters->end(); ++it)
- {
- std::u32string u32value;
- strings.get(it->first, &stringMap[it->first]);
- }
-
- // Build set of Unicode characters which encompass all strings
- std::set unicodeSet;
- for (auto it = stringMap.begin(); it != stringMap.end(); ++it)
- {
- for (char32_t charcode: it->second)
- {
- unicodeSet.insert(charcode);
- }
- }
-
- // Insert basic latin Unicode block
- for (char32_t charcode = UnicodeRange::BASIC_LATIN.start; charcode <= UnicodeRange::BASIC_LATIN.end; ++charcode)
- {
- unicodeSet.insert(charcode);
- }
-
- // Transform character set into character ranges
- std::vector unicodeRanges;
- for (auto it = unicodeSet.begin(); it != unicodeSet.end(); ++it)
- {
- char32_t charcode = *it;
- unicodeRanges.push_back(UnicodeRange(charcode));
- }
-
- // Delete previously loaded fonts
- delete menuFont;
- delete copyrightFont;
- delete levelNameFont;
-
- // Determine fonts for current language
- std::string menuFontBasename;
- std::string copyrightFontBasename;
- std::string levelNameFontBasename;
- strings.get("menu-font", &menuFontBasename);
- strings.get("copyright-font", ©rightFontBasename);
- strings.get("level-name-font", &levelNameFontBasename);
- std::string fontsDirectory = appDataPath + std::string("fonts/");
-
- // Load fonts with the custom Unicode ranges
- FontLoader* fontLoader = new FontLoader();
-
- menuFont = new Font(512, 512);
- if (!fontLoader->load(fontsDirectory + menuFontBasename, static_cast(fontSizePX + 0.5f), unicodeRanges, menuFont))
- {
- std::cerr << std::string("Failed to load menu font") << std::endl;
- }
-
- copyrightFont = new Font(256, 256);
- if (!fontLoader->load(fontsDirectory + copyrightFontBasename, static_cast(fontSizePX * 0.8f + 0.5f), unicodeRanges, copyrightFont))
- {
- std::cerr << std::string("Failed to load copyright font") << std::endl;
- }
-
- levelNameFont = new Font(512, 512);
- if (!fontLoader->load(fontsDirectory + levelNameFontBasename, static_cast(fontSizePX * 2.0f + 0.5f), unicodeRanges, levelNameFont))
- {
- std::cerr << std::string("Failed to load level name font") << std::endl;
- }
-
- delete fontLoader;
-
- // Set fonts
- levelNameLabel->setFont(levelNameFont);
- frameTimeLabel->setFont(copyrightFont);
- anyKeyLabel->setFont(menuFont);
- copyrightLabel->setFont(copyrightFont);
- mainMenu->setFont(menuFont);
- levelsMenu->setFont(menuFont);
- optionsMenu->setFont(menuFont);
- controlsMenu->setFont(menuFont);
- pauseMenu->setFont(menuFont);
-
- // Title screen
- anyKeyLabel->setText(stringMap["press-any-key"]);
- copyrightLabel->setText(stringMap["copyright"]);
-
- // Main menu
- mainMenuContinueItem->setName(stringMap["continue"]);
- mainMenuLevelsItem->setName(stringMap["levels"]);
- mainMenuNewGameItem->setName(stringMap["new-game"]);
- mainMenuSandboxItem->setName(stringMap["sandbox"]);
- mainMenuOptionsItem->setName(stringMap["options"]);
- mainMenuExitItem->setName(stringMap["exit"]);
-
- // Levels menu
- std::size_t levelItemIndex = 0;
- for (std::size_t world = 0; world < campaign.getWorldCount(); ++world)
- {
- for (std::size_t level = 0; level < campaign.getLevelCount(world); ++level)
- {
- // Look up level name
- std::u32string levelName = getLevelName(world, level);
-
- // Create label
- /*
- std::u32string label;
- std::stringstream stream;
- stream << (world + 1) << std::string("-") << (level + 1) << std::string(": ";
- label = std::wstring_convert, char32_t>().from_bytes(stream.str()) + levelName;
- */
-
- // Set item name
- MenuItem* levelItem = levelsMenu->getItem(levelItemIndex);
- levelItem->setName(levelName);
-
- ++levelItemIndex;
- }
- }
- levelsMenuBackItem->setName(stringMap["back"]);
-
- // Options menu
- optionsMenuWindowedResolutionItem->setName(stringMap["windowed-resolution"]);
- optionsMenuFullscreenResolutionItem->setName(stringMap["fullscreen-resolution"]);
- std::size_t resolutionIndex = 0;
- for (std::size_t i = 0; i < resolutions.size(); ++i)
- {
-
- std::u32string label;
- std::stringstream stream;
- stream << resolutions[i].x << std::string("x") << resolutions[i].y;
- std::string streamstring = stream.str();
- label.assign(streamstring.begin(), streamstring.end());
-
- optionsMenuWindowedResolutionItem->setValueName(i, label);
- optionsMenuFullscreenResolutionItem->setValueName(i, label);
- }
- optionsMenuFullscreenItem->setName(stringMap["fullscreen"]);
- optionsMenuFullscreenItem->setValueName(0, stringMap["off"]);
- optionsMenuFullscreenItem->setValueName(1, stringMap["on"]);
- optionsMenuVSyncItem->setName(stringMap["vertical-sync"]);
- optionsMenuVSyncItem->setValueName(0, stringMap["off"]);
- optionsMenuVSyncItem->setValueName(1, stringMap["on"]);
-
- optionsMenuLanguageItem->setName(stringMap["language"]);
- for (std::size_t i = 0; i < languages.size(); ++i)
- {
- optionsMenuLanguageItem->setValueName(i, stringMap[languages[i]]);
- }
-
- optionsMenuControlsItem->setName(stringMap["controls"]);
- optionsMenuBackItem->setName(stringMap["back"]);
-
- // Controls menu
- controlsMenuResetToDefaultItem->setName(stringMap["reset-to-default"]);
- controlsMenuMoveForwardItem->setName(stringMap["move-forward"]);
- controlsMenuMoveForwardItem->setValueName(0, U"W");
- controlsMenuMoveBackItem->setName(stringMap["move-back"]);
- controlsMenuMoveBackItem->setValueName(0, U"S");
- controlsMenuMoveLeftItem->setName(stringMap["move-left"]);
- controlsMenuMoveLeftItem->setValueName(0, U"A");
- controlsMenuMoveRightItem->setName(stringMap["move-right"]);
- controlsMenuMoveRightItem->setValueName(0, U"D");
- controlsMenuBackItem->setName(stringMap["back"]);
-
- // Pause menu
- pauseMenuResumeItem->setName(stringMap["resume"]);
- pauseMenuLevelsItem->setName(stringMap["levels"]);
- pauseMenuOptionsItem->setName(stringMap["options"]);
- pauseMenuMainMenuItem->setName(stringMap["main-menu"]);
- pauseMenuExitItem->setName(stringMap["exit"]);
-}
-
-void Application::openMenu(Menu* menu)
-{
- if (activeMenu != nullptr)
- {
- closeMenu();
- }
-
- activeMenu = menu;
- activeMenu->select(0);
- activeMenu->getUIContainer()->setVisible(true);
- activeMenu->getUIContainer()->setActive(false);
- activeMenu->getUIContainer()->setTintColor(Vector4(1.0f, 1.0f, 1.0f, 0.0f));
- /*
- if (activeMenu->getSelectedItem() == nullptr)
- {
- activeMenu->select(0);
- }
- */
-
- // Delay menu activation
- menuActivateTween->setEndCallback(std::bind(&UIElement::setActive, activeMenu->getUIContainer(), true));
- menuActivateTween->reset();
- menuActivateTween->start();
-
- // Begin menu fade-in
- menuFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, activeMenu->getUIContainer(), std::placeholders::_1));
- menuFadeInTween->reset();
- menuFadeInTween->start();
-}
-
-void Application::closeMenu()
-{
- if (activeMenu != nullptr)
- {
- // Deactivate menu
- activeMenu->getUIContainer()->setActive(false);
- activeMenu->getUIContainer()->setVisible(false);
-
- // Begin menu fade-out
- /*
- menuFadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, activeMenu->getUIContainer(), std::placeholders::_1));
- menuFadeOutTween->setEndCallback(std::bind(&UIElement::setVisible, activeMenu->getUIContainer(), false));
- menuFadeOutTween->reset();
- menuFadeOutTween->start();
- */
-
- previousActiveMenu = activeMenu;
- activeMenu = nullptr;
- }
-}
-
-void Application::selectMenuItem(std::size_t index)
-{
- if (activeMenu != nullptr)
- {
- activeMenu->select(index);
- }
-}
-
-void Application::activateMenuItem()
-{
- if (activeMenu != nullptr)
- {
- activeMenu->activate();
- }
-}
-
-void Application::incrementMenuItem()
-{
- if (activeMenu != nullptr)
- {
- MenuItem* item = activeMenu->getSelectedItem();
- if (item != nullptr)
- {
- if (item->getValueCount() != 0)
- {
- item->setValueIndex((item->getValueIndex() + 1) % item->getValueCount());
- }
- }
- }
-}
-
-void Application::decrementMenuItem()
-{
- if (activeMenu != nullptr)
- {
- MenuItem* item = activeMenu->getSelectedItem();
- if (item != nullptr)
- {
- if (item->getValueCount() != 0)
- {
- if (!item->getValueIndex())
- {
- item->setValueIndex(item->getValueCount() - 1);
- }
- else
- {
- item->setValueIndex(item->getValueIndex() - 1);
- }
- }
- }
- }
-}
-
-void Application::continueGame()
-{
- closeMenu();
-
- int world = 0;
- int level = 0;
-
- settings.get("continue_world", &world);
- settings.get("continue_level", &level);
-
- if (world != currentWorldIndex)
- {
- loadWorld(world);
- }
- if (level != currentLevelIndex)
- {
- loadLevel(level);
- }
-
- // Begin title fade-out
- titleFadeOutTween->reset();
- titleFadeOutTween->start();
-
- // Begin fade-out
- fadeOutTween->setEndCallback(std::bind(&Application::changeState, this, gameState));
- fadeOutTween->reset();
- fadeOutTween->start();
-}
-
-void Application::newGame()
-{
- // Close main menu
- closeMenu();
-
- // Begin title fade-out
- titleFadeOutTween->reset();
- titleFadeOutTween->start();
-
- if (currentWorldIndex != 0 || currentLevelIndex != 0)
- {
- // Select first level of the first world
- currentWorldIndex = 0;
- currentLevelIndex = 0;
-
- // Begin fade-out
- fadeOutTween->setEndCallback(std::bind(&Application::changeState, this, gameState));
- fadeOutTween->reset();
- fadeOutTween->start();
- }
- else
- {
- // Begin fade-out
- fadeOutTween->setEndCallback(std::bind(&Application::changeState, this, gameState));
- fadeOutTween->reset();
- fadeOutTween->start();
-
- // Change state
- //changeState(gameState);
- }
-}
-
-void Application::deselectTool(Tool* tool)
-{
- if (tool != nullptr)
- {
- tool->setActive(false);
- return;
- }
-}
-
-void Application::selectTool(Tool* tool)
-{
- if (tool != nullptr)
- {
- tool->setActive(true);
- }
-
- currentTool = tool;
-}
-
-void Application::loadWorld(std::size_t index)
-{
- // Set current world
- currentWorldIndex = index;
-
- // Get world biome
- const LevelParameterSet* levelParams = campaign.getLevelParams(currentWorldIndex, 0);
- const Biome* biome = &biosphere.biomes[levelParams->biome];
-
- // Setup rendering passes
- lightingPass.setDiffuseCubemap(biome->diffuseCubemap);
- lightingPass.setSpecularCubemap(biome->specularCubemap);
- skyboxPass.setCubemap(biome->specularCubemap);
-}
-
-void Application::loadLevel(std::size_t index)
-{
- // Set current level
- currentLevelIndex = index;
-
- // Load level
- const LevelParameterSet* levelParams = campaign.getLevelParams(currentWorldIndex, currentLevelIndex);
- currentLevel->load(*levelParams);
-
- Material* material = materialLoader->load("data/materials/debug-terrain-surface.mtl");
- ShaderTexture2D* albedoOpacityMap = static_cast(material->getVariable("albedoOpacityMap"));
- if (albedoOpacityMap != nullptr)
- {
- albedoOpacityMap->setValue(&pheromoneTexture);
- }
-
- material->setFlags(MATERIAL_FLAG_TRANSLUCENT | MATERIAL_FLAG_DISABLE_SHADOW_CASTING);
- //material->shadowCaster = false;
- //material->flags |= (unsigned int)PhysicalMaterial::Flags::TRANSLUCENT;
-
- currentLevel->terrain.getSurfaceModel()->getGroup(0)->material = material;
-}
-
-void Application::pauseSimulation()
-{
- simulationPaused = true;
-}
-
-void Application::unpauseSimulation()
-{
- simulationPaused = false;
-}
-
-void Application::openPauseMenu()
-{
- simulationPaused = true;
-
- darkenFadeOutTween->stop();
- darkenFadeInTween->reset();
- darkenFadeInTween->start();
-
- blurFadeOutTween->stop();
- blurFadeInTween->reset();
- blurFadeInTween->start();
-
- openMenu(pauseMenu);
- pauseMenu->select(0);
-}
-
-void Application::closePauseMenu()
-{
- simulationPaused = false;
-
- darkenFadeInTween->stop();
- darkenFadeOutTween->reset();
- darkenFadeOutTween->start();
-
- blurFadeInTween->stop();
- blurFadeOutTween->reset();
- blurFadeOutTween->start();
-
- closeMenu();
-}
-
-void Application::setDisplayDebugInfo(bool display)
-{
- displayDebugInfo = display;
-
- frameTimeLabel->setVisible(displayDebugInfo);
- depthTextureImage->setVisible(displayDebugInfo);
-}
-
-std::u32string Application::getLevelName(std::size_t world, std::size_t level) const
-{
- // Form level ID string
- char levelIDBuffer[6];
- std::sprintf(levelIDBuffer, "%02d-%02d", static_cast(world + 1), static_cast(level + 1));
- std::string levelID(levelIDBuffer);
-
- // Look up level name
- std::u32string levelName;
- strings.get(levelIDBuffer, &levelName);
-
- return levelName;
-}
-
-void Application::selectWindowedResolution(std::size_t index)
-{
- windowedResolutionIndex = index;
-
- if (!fullscreen)
- {
- // Select resolution
- resolution = resolutions[windowedResolutionIndex];
-
- // Resize window
- SDL_SetWindowSize(window, static_cast(resolution.x), static_cast(resolution.y));
- SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
-
- // Resize UI
- resizeUI();
-
- // Notify window observers
- inputManager->update();
- }
-
- // Save settings
- settings.set("windowed_width", resolutions[windowedResolutionIndex].x);
- settings.set("windowed_height", resolutions[windowedResolutionIndex].y);
- saveUserSettings();
-}
-
-void Application::selectFullscreenResolution(std::size_t index)
-{
- fullscreenResolutionIndex = index;
-
- if (fullscreen)
- {
- // Select resolution
- resolution = resolutions[fullscreenResolutionIndex];
-
- // Resize window
- SDL_SetWindowSize(window, static_cast(resolution.x), static_cast(resolution.y));
- SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
-
- // Resize UI
- resizeUI();
-
- // Notify window observers
- inputManager->update();
- }
-
- // Save settings
- settings.set("fullscreen_width", resolutions[fullscreenResolutionIndex].x);
- settings.set("fullscreen_height", resolutions[fullscreenResolutionIndex].y);
- saveUserSettings();
-}
-
-void Application::selectFullscreenMode(std::size_t index)
-{
- fullscreen = (index == 1);
-
- if (fullscreen)
- {
- resolution = resolutions[fullscreenResolutionIndex];
-
- SDL_SetWindowSize(window, static_cast(resolution.x), static_cast(resolution.y));
- if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) != 0)
- {
- std::cerr << std::string("Failed to set fullscreen mode: \"") << SDL_GetError() << std::string("\"") << std::endl;
- fullscreen = false;
- }
- }
- else
- {
- resolution = resolutions[windowedResolutionIndex];
-
- if (SDL_SetWindowFullscreen(window, 0) != 0)
- {
- std::cerr << std::string("Failed to set windowed mode: \"") << SDL_GetError() << std::string("\"") << std::endl;
- fullscreen = true;
- }
- else
- {
- SDL_SetWindowSize(window, static_cast(resolution.x), static_cast(resolution.y));
- SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
- }
- }
-
- // Print mode and resolution
- if (fullscreen)
- {
- std::cout << std::string("Changed to fullscreen mode at resolution ") << resolution.x << std::string("x") << resolution.y << std::endl;
- }
- else
- {
- std::cout << std::string("Changed to windowed mode at resolution ") << resolution.x << std::string("x") << resolution.y << std::endl;
- }
-
- // Save settings
- settings.set("fullscreen", fullscreen);
- saveUserSettings();
-
- // Resize UI
- resizeUI();
-
- // Notify window observers
- inputManager->update();
-}
-
-// index: 0 = off, 1 = on
-void Application::selectVSyncMode(std::size_t index)
-{
- swapInterval = (index == 0) ? 0 : 1;
-
- if (swapInterval == 1)
- {
- std::cout << std::string("Enabling vertical sync... ");
- }
- else
- {
- std::cout << std::string("Disabling vertical sync... ");
- }
-
- if (SDL_GL_SetSwapInterval(swapInterval) != 0)
- {
- std::cout << std::string("failed: \"") << SDL_GetError() << std::string("\"") << std::endl;
- swapInterval = SDL_GL_GetSwapInterval();
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Save settings
- settings.set("swap_interval", swapInterval);
- saveUserSettings();
-}
-
-void Application::selectLanguage(std::size_t index)
-{
- // Set language index
- languageIndex = index;
-
- // Clear strings
- strings.clear();
-
- // Load strings
- std::string stringsFile = appDataPath + std::string("strings/") + languages[languageIndex] + std::string(".txt");
- std::cout << std::string("Loading strings from \"") << stringsFile << std::string("\"... ");
- if (!strings.load(stringsFile))
- {
- std::cout << std::string("failed") << std::endl;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- // Save settings
- settings.set("language", languages[languageIndex]);
- saveUserSettings();
-
- // Change window title
- std::string title;
- strings.get("title", &title);
- SDL_SetWindowTitle(window, title.c_str());
-
- // Restring UI
- restringUI();
-}
-
-void Application::bindControl(Control* control)
-{
- bindingControl = control;
- bindingControl->unbind();
-}
diff --git a/src/controls.cpp b/src/controls.cpp
deleted file mode 100644
index 0aaeabd..0000000
--- a/src/controls.cpp
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- * Copyright (C) 2017 Christopher J. Howard
- *
- * This file is part of Antkeeper Source Code.
- *
- * Antkeeper Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper Source Code. If not, see .
- */
-
-#include "controls.hpp"
-#include
-#include
-#include
-
-Control::Control():
- deadzone(0.1f),
- currentValue(0.0f),
- previousValue(0.0f)
-{}
-
-Control::~Control()
-{}
-
-void Control::setDeadzone(float value)
-{
- deadzone = value;
-}
-
-void Control::update()
-{
- if (!boundMouseWheelAxes.empty())
- {
- currentValue = 0.0f;
- }
-
- previousValue = currentValue;
-}
-
-bool Control::isTriggered() const
-{
- return currentValue > deadzone;
-}
-
-bool Control::wasTriggered() const
-{
- return previousValue > deadzone;
-}
-
-bool Control::isUnbound() const
-{
- return (boundKeys.empty() && boundMouseButtons.empty() && boundMouseWheelAxes.empty() && boundGamepadButtons.empty() && boundGamepadAxes.empty());
-}
-
-void Control::bindKey(Keyboard* keyboard, int scancode)
-{
- // Check if already observing this keyboard
- bool observing = false;
- for (auto it: boundKeys)
- {
- if (it.first == keyboard)
- {
- observing = true;
- break;
- }
- }
-
- if (!observing)
- keyboard->addKeyObserver(static_cast(this));
- boundKeys.push_back(std::pair(keyboard, scancode));
-}
-
-void Control::bindMouseButton(Mouse* mouse, int button)
-{
- // Checking if already observing this mouse
- bool observing = false;
- for (auto it: boundMouseButtons)
- {
- if (it.first == mouse)
- {
- observing = true;
- break;
- }
- }
-
- if (!observing)
- mouse->addMouseButtonObserver(static_cast(this));
- boundMouseButtons.push_back(std::pair(mouse, button));
-}
-
-void Control::bindMouseWheelAxis(Mouse* mouse, MouseWheelAxis axis)
-{
- // Checking if already observing this mouse
- bool observing = false;
- for (auto it: boundMouseWheelAxes)
- {
- if (it.first == mouse)
- {
- observing = true;
- break;
- }
- }
-
- if (!observing)
- mouse->addMouseWheelObserver(static_cast(this));
- boundMouseWheelAxes.push_back(std::pair(mouse, axis));
-}
-
-void Control::bindGamepadButton(Gamepad* gamepad, int button)
-{
- bool observing = false;
- for (auto it: boundGamepadButtons)
- {
- if (it.first == gamepad)
- {
- observing = true;
- break;
- }
- }
-
- if (!observing)
- gamepad->addGamepadButtonObserver(static_cast(this));
- boundGamepadButtons.push_back(std::pair(gamepad, button));
-}
-
-void Control::bindGamepadAxis(Gamepad* gamepad, int axis, bool negative)
-{
- bool observing = false;
- for (auto it: boundGamepadAxes)
- {
- if (std::get<0>(it) == gamepad)
- {
- observing = true;
- break;
- }
- }
-
- if (!observing)
- gamepad->addGamepadAxisObserver(static_cast(this));
- boundGamepadAxes.push_back(std::make_tuple(gamepad, axis, negative));
-}
-
-void Control::bind(const InputEvent& event)
-{
- switch (event.type)
- {
- case InputEvent::Type::KEY:
- bindKey(event.key.first, event.key.second);
- break;
-
- case InputEvent::Type::MOUSE_BUTTON:
- bindMouseButton(event.mouseButton.first, event.mouseButton.second);
- break;
-
- case InputEvent::Type::MOUSE_WHEEL:
- {
- int x = std::get<1>(event.mouseWheel);
- int y = std::get<2>(event.mouseWheel);
-
- MouseWheelAxis axis;
- if (x > 0)
- axis = MouseWheelAxis::POSITIVE_X;
- else if (x < 0)
- axis = MouseWheelAxis::NEGATIVE_X;
- else if (y > 0)
- axis = MouseWheelAxis::POSITIVE_Y;
- else if (y < 0)
- axis = MouseWheelAxis::NEGATIVE_Y;
- else
- break;
-
- bindMouseWheelAxis(std::get<0>(event.mouseWheel), axis);
- break;
- }
-
- case InputEvent::Type::GAMEPAD_BUTTON:
- bindGamepadButton(event.gamepadButton.first, event.gamepadButton.second);
- break;
-
- case InputEvent::Type::GAMEPAD_AXIS:
- bindGamepadAxis(std::get<0>(event.gamepadAxis), std::get<1>(event.gamepadAxis), std::get<2>(event.gamepadAxis));
- break;
-
- default:
- break;
- }
-}
-
-void Control::unbind()
-{
- while (!boundKeys.empty())
- {
- // Remove the first bound key and stop observing its keyboard
- Keyboard* keyboard = boundKeys.front().first;
- keyboard->removeKeyObserver(static_cast(this));
- boundKeys.pop_front();
-
- // Remove other bound keys which are associated with the keyboard
- auto it = boundKeys.begin();
- while (it != boundKeys.end())
- {
- if (it->first == keyboard)
- boundKeys.erase(it++);
- else
- ++it;
- }
- }
-
- while (!boundMouseButtons.empty())
- {
- // Remove the first bound mouse button and stop observing its mouse
- Mouse* mouse = boundMouseButtons.front().first;
- mouse->removeMouseButtonObserver(static_cast(this));
- boundMouseButtons.pop_front();
-
- // Remove other bound mouse buttons which are associated with the mouse
- auto it = boundMouseButtons.begin();
- while (it != boundMouseButtons.end())
- {
- if (it->first == mouse)
- boundMouseButtons.erase(it++);
- else
- ++it;
- }
- }
-
- while (!boundMouseWheelAxes.empty())
- {
- // Remove the first bound mouse button and stop observing its mouse
- Mouse* mouse = boundMouseWheelAxes.front().first;
- mouse->removeMouseWheelObserver(static_cast(this));
- boundMouseWheelAxes.pop_front();
-
- // Remove other bound mouse buttons which are associated with the mouse
- auto it = boundMouseWheelAxes.begin();
- while (it != boundMouseWheelAxes.end())
- {
- if (it->first == mouse)
- boundMouseWheelAxes.erase(it++);
- else
- ++it;
- }
- }
-
- while (!boundGamepadButtons.empty())
- {
- // Remove the first bound gamepad button and stop observing its gamepad
- Gamepad* gamepad = boundGamepadButtons.front().first;
- gamepad->removeGamepadButtonObserver(static_cast(this));
- boundGamepadButtons.pop_front();
-
- // Remove other bound gamepad buttons which are associated with the gamepad
- auto it = boundGamepadButtons.begin();
- while (it != boundGamepadButtons.end())
- {
- if (it->first == gamepad)
- boundGamepadButtons.erase(it++);
- else
- ++it;
- }
- }
-
- while (!boundGamepadAxes.empty())
- {
- // Remove the first bound gamepad axis and stop observing its gamepad
- Gamepad* gamepad = std::get<0>(boundGamepadAxes.front());
- gamepad->removeGamepadAxisObserver(static_cast(this));
- boundGamepadAxes.pop_front();
-
- // Remove other bound gamepad axes which are associated with the gamepad
- auto it = boundGamepadAxes.begin();
- while (it != boundGamepadAxes.end())
- {
- if (std::get<0>(*it) == gamepad)
- boundGamepadAxes.erase(it++);
- else
- ++it;
- }
- }
-}
-
-void Control::keyPressed(int scancode)
-{
- for (auto it: boundKeys)
- {
- if (it.second == scancode)
- {
- currentValue = 1.0f;
- break;
- }
- }
-}
-
-void Control::keyReleased(int scancode)
-{
- for (auto it: boundKeys)
- {
- if (it.second == scancode)
- {
- currentValue = 0.0f;
- break;
- }
- }
-}
-
-void Control::mouseButtonPressed(int button, int x, int y)
-{
- for (auto it: boundMouseButtons)
- {
- if (it.second == button)
- {
- currentValue = 1.0f;
- break;
- }
- }
-}
-
-void Control::mouseButtonReleased(int button, int x, int y)
-{
- for (auto it: boundMouseButtons)
- {
- if (it.second == button)
- {
- currentValue = 0.0f;
- break;
- }
- }
-}
-
-void Control::mouseWheelScrolled(int x, int y)
-{
- for (auto it: boundMouseWheelAxes)
- {
- if (it.second == MouseWheelAxis::POSITIVE_X && x > 0)
- {
- currentValue += x;
- break;
- }
- else if (it.second == MouseWheelAxis::NEGATIVE_X && x < 0)
- {
- currentValue -= x;
- break;
- }
- else if (it.second == MouseWheelAxis::POSITIVE_Y && y > 0)
- {
- currentValue += y;
- break;
- }
- else if (it.second == MouseWheelAxis::NEGATIVE_Y && y < 0)
- {
- currentValue -= y;
- break;
- }
- }
-}
-
-void Control::gamepadButtonPressed(int button)
-{
- for (auto it: boundGamepadButtons)
- {
- if (it.second == button)
- {
- currentValue = 1.0f;
- break;
- }
- }
-}
-
-void Control::gamepadButtonReleased(int button)
-{
- for (auto it: boundGamepadButtons)
- {
- if (it.second == button)
- {
- currentValue = 0.0f;
- break;
- }
- }
-}
-
-void Control::gamepadAxisMoved(int axis, bool negative, float value)
-{
- for (auto it: boundGamepadAxes)
- {
- if (std::get<1>(it) == axis && std::get<2>(it) == negative)
- {
- currentValue = value;
- break;
- }
- }
-}
-
-const std::list>* Control::getBoundKeys() const
-{
- return &boundKeys;
-}
-
-const std::list>* Control::getBoundMouseButtons() const
-{
- return &boundMouseButtons;
-}
-
-const std::list>* Control::getBoundMouseWheelAxes() const
-{
- return &boundMouseWheelAxes;
-}
-
-const std::list>* Control::getBoundGamepadButtons() const
-{
- return &boundGamepadButtons;
-}
-
-const std::list>* Control::getBoundGamepadAxes() const
-{
- return &boundGamepadAxes;
-}
-
-ControlProfile::ControlProfile(InputManager* inputManager):
- inputManager(inputManager)
-{}
-
-void ControlProfile::registerControl(const std::string& name, Control* control)
-{
- controls[name] = control;
-}
-
-bool ControlProfile::save(const std::string& filename)
-{
- // Open control profile
- std::ofstream file(filename.c_str());
- if (!file.is_open())
- {
- std::cerr << std::string("Failed to open control profile \"") << filename << std::string("\"") << std::endl;
- return false;
- }
-
- for (auto it = controls.begin(); it != controls.end(); ++it)
- {
- Control* control = it->second;
- const std::list>* boundKeys = control->getBoundKeys();
- const std::list>* boundMouseButtons = control->getBoundMouseButtons();
- const std::list>* boundMouseWheelAxes = control->getBoundMouseWheelAxes();
- const std::list>* boundGamepadButtons = control->getBoundGamepadButtons();
- const std::list>* boundGamepadAxes = control->getBoundGamepadAxes();
-
- for (auto boundKey: *boundKeys)
- {
- int key = boundKey.second;
- file << std::string("control\t") << it->first << std::string("\tkeyboard\tkey\t") << key << '\n';
- }
-
- for (auto boundMouseButton: *boundMouseButtons)
- {
- int button = boundMouseButton.second;
- file << std::string("control\t") << it->first << std::string("\tmouse\tbutton\t") << button << '\n';
- }
-
- for (auto boundMouseWheelAxis: *boundMouseWheelAxes)
- {
- MouseWheelAxis axis = boundMouseWheelAxis.second;
-
- file << std::string("control\t") << it->first << std::string("\tmouse\twheel\t");
- if (axis == MouseWheelAxis::POSITIVE_X)
- file << std::string("+x");
- else if (axis == MouseWheelAxis::NEGATIVE_X)
- file << std::string("-x");
- else if (axis == MouseWheelAxis::POSITIVE_Y)
- file << std::string("+y");
- else if (axis == MouseWheelAxis::NEGATIVE_Y)
- file << std::string("-y");
- else
- file << std::string("unknown");
- file << '\n';
- }
-
- for (auto boundGamepadButton: *boundGamepadButtons)
- {
- const std::string& gamepadName = boundGamepadButton.first->getName();
- int button = boundGamepadButton.second;
- file << std::string("control\t") << it->first << std::string("\tgamepad\t") << gamepadName << std::string("\tbutton\t") << button << '\n';
- }
-
- for (auto boundGamepadAxis: *boundGamepadAxes)
- {
- const std::string& gamepadName = std::get<0>(boundGamepadAxis)->getName();
- int axis = std::get<1>(boundGamepadAxis);
- bool negative = std::get<2>(boundGamepadAxis);
-
- std::stringstream axisstream;
- if (negative)
- axisstream << std::string("-");
- else
- axisstream << std::string("+");
- axisstream << axis;
-
- file << std::string("control\t") << it->first << std::string("\tgamepad\t") << gamepadName << std::string("\taxis\t") << axisstream.str() << '\n';
- }
- }
-
- file.close();
-
- return true;
-}
-
-bool ControlProfile::load(const std::string& filename)
-{
- // Open control profile
- std::ifstream file(filename.c_str());
- if (!file.is_open())
- {
- std::cerr << std::string("Failed to open control profile \"") << filename << std::string("\"") << std::endl;
- return false;
- }
-
- // Read profile
- std::string line;
- while (file.good() && std::getline(file, line))
- {
- // Tokenize line (tab-delimeted)
- std::vector tokens;
- std::string token;
- std::istringstream linestream(line);
- while (std::getline(linestream, token, '\t'))
- tokens.push_back(token);
-
- if (tokens.empty() || tokens[0][0] == '#')
- continue;
-
- if (tokens[0] == "control" && tokens.size() >= 5)
- {
- // Use control name to get control pointer
- auto it = controls.find(tokens[1]);
- if (it == controls.end())
- {
- std::cerr << std::string("Attempted to load unregistered control \"") << tokens[1] << std::string("\" from control profile \"") << filename << std::string("\"") << std::endl;
- continue;
- }
- Control* control = it->second;
-
- // Find input device
- if (tokens[2] == "keyboard")
- {
- Keyboard* keyboard = inputManager->getKeyboards()->front();
-
- if (tokens[3] == "key")
- {
- std::stringstream keystream(tokens[4]);
- int scancode = -1;
- keystream >> scancode;
-
- control->bindKey(keyboard, scancode);
- }
- else
- {
- std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl;
- }
- }
- else if (tokens[2] == "mouse")
- {
- Mouse* mouse = inputManager->getMice()->front();
-
- if (tokens[3] == "button")
- {
- std::stringstream buttonstream(tokens[4]);
- int button = -1;
- buttonstream >> button;
-
- control->bindMouseButton(mouse, button);
- }
- else if (tokens[3] == "wheel")
- {
- MouseWheelAxis axis;
- if (tokens[4] == "+x")
- axis = MouseWheelAxis::POSITIVE_X;
- else if (tokens[4] == "-x")
- axis = MouseWheelAxis::NEGATIVE_X;
- else if (tokens[4] == "+y")
- axis = MouseWheelAxis::POSITIVE_Y;
- else if (tokens[4] == "-y")
- axis = MouseWheelAxis::NEGATIVE_Y;
- else
- {
- std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl;
- continue;
- }
-
- control->bindMouseWheelAxis(mouse, axis);
- }
- else
- {
- std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl;
- continue;
- }
- }
- else if (tokens[2] == "gamepad")
- {
- if (tokens.size() != 6)
- {
- std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl;
- continue;
- }
-
- Gamepad* gamepad = inputManager->getGamepad(tokens[3]);
- if (!gamepad)
- {
- gamepad = new Gamepad(tokens[3]);
- gamepad->setDisconnected(true);
- inputManager->registerGamepad(gamepad);
- }
-
- if (tokens[4] == "button")
- {
- std::stringstream buttonstream(tokens[5]);
- int button = -1;
- buttonstream >> button;
-
- control->bindGamepadButton(gamepad, button);
- }
- else if (tokens[4] == "axis")
- {
- bool negative = (tokens[5][0] == '-');
-
- std::stringstream axisstream(tokens[5].substr(1, tokens[5].length() - 1));
- int axis = -1;
- axisstream >> axis;
-
- control->bindGamepadAxis(gamepad, axis, negative);
- }
- else
- {
- std::cerr << std::string("Invalid line \"") << line << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl;
- continue;
- }
- }
- else
- {
- std::cerr << std::string("Unsupported input device \"") << tokens[3] << std::string("\" in control profile \"") << filename << std::string("\"") << std::endl;
- continue;
- }
- }
- }
-
- file.close();
-
- return true;
-}
-
-void ControlProfile::update()
-{
- for (auto it = controls.begin(); it != controls.end(); ++it)
- {
- it->second->update();
- }
-}
-
diff --git a/src/windows/antkeeper.manifest b/src/dpi-aware.manifest
similarity index 100%
rename from src/windows/antkeeper.manifest
rename to src/dpi-aware.manifest
diff --git a/src/game/biome.cpp b/src/game/biome.cpp
deleted file mode 100644
index 36793bc..0000000
--- a/src/game/biome.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "biome.hpp"
-#include "../settings.hpp"
-
-#include
-#include
-
-Biome::Biome()
-{}
-
-Biome::~Biome()
-{}
-
-bool Biome::load()
-{
- ParameterDict parameters;
- if (!parameters.load(filename))
- {
- return false;
- }
-
- parameters.get("name", &name);
- parameters.get("soil-horizon-o", &soilHorizonOFilename);
- parameters.get("soil-horizon-a", &soilHorizonAFilename);
- parameters.get("soil-horizon-b", &soilHorizonBFilename);
- parameters.get("soil-horizon-c", &soilHorizonCFilename);
- parameters.get("cubemap", &cubemapName);
-
- TextureLoader textureLoader;
- textureLoader.setMipmapChain(false);
- textureLoader.setWrapS(true);
- textureLoader.setWrapT(true);
-
- // Load soil horizon textures
- soilHorizonO = textureLoader.load2D(std::string("data/textures/") + soilHorizonOFilename);
- soilHorizonA = textureLoader.load2D(std::string("data/textures/") + soilHorizonAFilename);
- soilHorizonB = textureLoader.load2D(std::string("data/textures/") + soilHorizonBFilename);
- soilHorizonC = textureLoader.load2D(std::string("data/textures/") + soilHorizonCFilename);
-
- // Load diffuse cubemap
- textureLoader.setMipmapChain(true);
- textureLoader.setWrapS(false);
- textureLoader.setWrapT(false);
- textureLoader.setWrapR(false);
-
- std::string diffuseCubemapFilename = std::string("data/textures/") + cubemapName + std::string("-irradiance-m%02d.hdr");
- diffuseCubemap = textureLoader.loadCube(diffuseCubemapFilename);
- if (!diffuseCubemap)
- {
- std::cerr << std::string("Failed to load diffuse cubemap \"") << diffuseCubemapFilename << std::string("\"") << std::endl;
- }
-
- // Load specular cubemap
- std::string specularCubemapFilename = std::string("data/textures/") + cubemapName + std::string("-radiance-m%02d.hdr");
- specularCubemap = textureLoader.loadCube(specularCubemapFilename);
- if (!specularCubemap)
- {
- std::cerr << std::string("Failed to load specular cubemap \"") << specularCubemapFilename << std::string("\"") << std::endl;
- }
-
- return true;
-}
-
-bool Biosphere::load(const std::string& directory)
-{
- // Open biomes directory
- DIR* dir = opendir(directory.c_str());
- if (dir == nullptr)
- {
- std::cout << std::string("Failed to open biome directory \"") << directory << std::string("\"") << std::endl;
- return false;
- }
-
- // Scan directory for .bio files
- for (struct dirent* entry = readdir(dir); entry != nullptr; entry = readdir(dir))
- {
- if (entry->d_type == DT_DIR || *entry->d_name == '.')
- {
- continue;
- }
-
- std::string filename = entry->d_name;
- std::string::size_type delimeter = filename.find_last_of('.');
- if (delimeter == std::string::npos)
- {
- continue;
- }
-
- std::string extension = filename.substr(delimeter + 1);
- if (extension != "bio")
- {
- continue;
- }
-
- // Add biome
- std::string name = filename.substr(0, delimeter);
- Biome* biome = &biomes[name];
- biome->filename = directory + filename;
- }
-
- // Close biomes directory
- closedir(dir);
-
- // Load biomes
- for (std::map::iterator it = biomes.begin(); it != biomes.end(); ++it)
- {
- Biome* biome = &it->second;
-
- if (!biome->load())
- {
- std::cout << std::string("Failed to load biome \"") << biome->filename << std::string("\"") << std::endl;
- }
- else
- {
- std::cout << std::string("Loaded biome \"") << biome->filename << std::string("\"") << std::endl;
- }
- }
-
- return true;
-}
diff --git a/src/input.cpp b/src/input.cpp
deleted file mode 100644
index 8b4841d..0000000
--- a/src/input.cpp
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright (C) 2017 Christopher J. Howard
- *
- * This file is part of Antkeeper Source Code.
- *
- * Antkeeper Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper Source Code. If not, see .
- */
-
-#include "input.hpp"
-#include
-
-InputDevice::InputDevice(const std::string& name):
- name(name),
- disconnected(true)
-{}
-
-void InputDevice::setDisconnected(bool disconnected)
-{
- this->disconnected = disconnected;
-}
-
-Keyboard::Keyboard(const std::string& name):
- InputDevice(name)
-{}
-
-Keyboard::~Keyboard()
-{}
-
-void Keyboard::addKeyObserver(KeyObserver* observer)
-{
- keyObservers.push_back(observer);
-}
-
-void Keyboard::removeKeyObserver(KeyObserver* observer)
-{
- keyObservers.remove(observer);
-}
-
-void Keyboard::removeKeyObservers()
-{
- keyObservers.clear();
-}
-
-void Keyboard::press(int scancode)
-{
- for (auto observer: keyObservers)
- {
- observer->keyPressed(scancode);
- }
-}
-
-void Keyboard::release(int scancode)
-{
- for (auto observer: keyObservers)
- {
- observer->keyReleased(scancode);
- }
-}
-
-Mouse::Mouse(const std::string& name):
- InputDevice(name),
- notifyingMotionObservers(false),
- notifyingButtonObservers(false),
- notifyingWheelObservers(false)
-{}
-
-Mouse::~Mouse()
-{}
-
-void Mouse::addMouseMotionObserver(MouseMotionObserver* observer)
-{
- if (notifyingMotionObservers)
- {
- additionFlaggedMotionObservers.push_back(observer);
- }
- else
- {
- motionObservers.push_back(observer);
- }
-}
-
-void Mouse::addMouseButtonObserver(MouseButtonObserver* observer)
-{
- if (notifyingButtonObservers)
- {
- additionFlaggedButtonObservers.push_back(observer);
- }
- else
- {
- buttonObservers.push_back(observer);
- }
-}
-
-void Mouse::addMouseWheelObserver(MouseWheelObserver* observer)
-{
- if (notifyingWheelObservers)
- {
- additionFlaggedWheelObservers.push_back(observer);
- }
- else
- {
- wheelObservers.push_back(observer);
- }
-}
-
-void Mouse::removeMouseMotionObserver(MouseMotionObserver* observer)
-{
- if (notifyingMotionObservers)
- {
- removalFlaggedMotionObservers.push_back(observer);
- }
- else
- {
- motionObservers.remove(observer);
- }
-}
-
-void Mouse::removeMouseButtonObserver(MouseButtonObserver* observer)
-{
- if (notifyingButtonObservers)
- {
- removalFlaggedButtonObservers.push_back(observer);
- }
- else
- {
- buttonObservers.remove(observer);
- }
-}
-
-void Mouse::removeMouseWheelObserver(MouseWheelObserver* observer)
-{
- if (notifyingWheelObservers)
- {
- removalFlaggedWheelObservers.push_back(observer);
- }
- else
- {
- wheelObservers.remove(observer);
- }
-}
-
-void Mouse::removeMouseMotionObservers()
-{
- motionObservers.clear();
-}
-
-void Mouse::removeMouseButtonObservers()
-{
- buttonObservers.clear();
-}
-
-void Mouse::removeMouseWheelObservers()
-{
- wheelObservers.clear();
-}
-
-void Mouse::press(int button, int x, int y)
-{
- // Notify observers
- notifyingButtonObservers = true;
- for (auto observer: buttonObservers)
- {
- observer->mouseButtonPressed(button, x, y);
- }
- notifyingButtonObservers = false;
-
- // Process flags
- processFlaggedButtonObservers();
-}
-
-void Mouse::release(int button, int x, int y)
-{
- // Notify observers
- notifyingButtonObservers = true;
- for (auto observer: buttonObservers)
- {
- observer->mouseButtonReleased(button, x, y);
- }
- notifyingButtonObservers = false;
-
- // Process flags
- processFlaggedButtonObservers();
-}
-
-void Mouse::move(int x, int y)
-{
- previousPosition = currentPosition;
- currentPosition = glm::ivec2(x, y);
-
- // Notify observers
- notifyingMotionObservers = true;
- for (auto observer: motionObservers)
- {
- observer->mouseMoved(x, y);
- }
- notifyingMotionObservers = false;
-
- // Process flags
- processFlaggedMotionObservers();
-}
-
-void Mouse::scroll(int x, int y)
-{
- // Notify observers
- notifyingWheelObservers = true;
- for (auto observer: wheelObservers)
- {
- observer->mouseWheelScrolled(x, y);
- }
- notifyingWheelObservers = false;
-
- // Process flags
- processFlaggedWheelObservers();
-}
-
-void Mouse::processFlaggedMotionObservers()
-{
- // Remove observers which are flagged for removal
- for (auto observer: removalFlaggedMotionObservers)
- {
- motionObservers.remove(observer);
- }
- removalFlaggedMotionObservers.clear();
-
- // Add observers which are flagged for addition
- for (auto observer: additionFlaggedMotionObservers)
- {
- motionObservers.push_back(observer);
- }
- additionFlaggedMotionObservers.clear();
-}
-
-void Mouse::processFlaggedButtonObservers()
-{
- // Remove observers which are flagged for removal
- for (auto observer: removalFlaggedButtonObservers)
- {
- buttonObservers.remove(observer);
- }
- removalFlaggedButtonObservers.clear();
-
- // Add observers which are flagged for addition
- for (auto observer: additionFlaggedButtonObservers)
- {
- buttonObservers.push_back(observer);
- }
- additionFlaggedButtonObservers.clear();
-}
-
-void Mouse::processFlaggedWheelObservers()
-{
- // Remove observers which are flagged for removal
- for (auto observer: removalFlaggedWheelObservers)
- {
- wheelObservers.remove(observer);
- }
- removalFlaggedWheelObservers.clear();
-
- // Add observers which are flagged for addition
- for (auto observer: additionFlaggedWheelObservers)
- {
- wheelObservers.push_back(observer);
- }
- additionFlaggedWheelObservers.clear();
-}
-
-Gamepad::Gamepad(const std::string& name):
- InputDevice(name)
-{}
-
-Gamepad::~Gamepad()
-{}
-
-void Gamepad::addGamepadButtonObserver(GamepadButtonObserver* observer)
-{
- buttonObservers.push_back(observer);
-}
-
-void Gamepad::removeGamepadButtonObserver(GamepadButtonObserver* observer)
-{
- buttonObservers.remove(observer);
-}
-
-void Gamepad::removeGamepadButtonObservers()
-{
- buttonObservers.clear();
-}
-
-void Gamepad::addGamepadAxisObserver(GamepadAxisObserver* observer)
-{
- axisObservers.push_back(observer);
-}
-
-void Gamepad::removeGamepadAxisObserver(GamepadAxisObserver* observer)
-{
- axisObservers.remove(observer);
-}
-
-void Gamepad::removeGamepadAxisObservers()
-{
- axisObservers.clear();
-}
-
-void Gamepad::press(int button)
-{
- for (auto observer: buttonObservers)
- {
- observer->gamepadButtonPressed(button);
- }
-}
-
-void Gamepad::release(int button)
-{
- for (auto observer: buttonObservers)
- {
- observer->gamepadButtonReleased(button);
- }
-}
-
-void Gamepad::move(int axis, bool negative, float value)
-{
- for (auto observer: axisObservers)
- {
- observer->gamepadAxisMoved(axis, negative, value);
- }
-}
-
-InputEvent::InputEvent():
- type(InputEvent::Type::NONE)
-{}
-
-InputManager::InputManager():
- closed(false)
-{}
-
-void InputManager::addWindowObserver(WindowObserver* observer)
-{
- windowObservers.push_back(observer);
-}
-
-void InputManager::removeWindowObserver(WindowObserver* observer)
-{
- windowObservers.remove(observer);
-}
-
-void InputManager::removeWindowObservers()
-{
- windowObservers.clear();
-}
-
-void InputManager::registerKeyboard(Keyboard* keyboard)
-{
- keyboards.push_back(keyboard);
-}
-
-void InputManager::registerMouse(Mouse* mouse)
-{
- mice.push_back(mouse);
-}
-
-void InputManager::registerGamepad(Gamepad* gamepad)
-{
- gamepads.push_back(gamepad);
-}
-
-void InputManager::unregisterKeyboard(Keyboard* keyboard)
-{
- keyboards.remove(keyboard);
-}
-
-void InputManager::unregisterMouse(Mouse* mouse)
-{
- mice.remove(mouse);
-}
-
-void InputManager::unregisterGamepad(Gamepad* gamepad)
-{
- gamepads.remove(gamepad);
-}
-
-bool InputManager::isRegistered(const Keyboard* keyboard) const
-{
- for (auto it = keyboards.begin(); it != keyboards.end(); ++it)
- {
- if (*it == keyboard)
- return true;
- }
-
- return false;
-}
-
-bool InputManager::isRegistered(const Mouse* mouse) const
-{
- for (auto it = mice.begin(); it != mice.end(); ++it)
- {
- if (*it == mouse)
- return true;
- }
-
- return false;
-}
-
-bool InputManager::isRegistered(const Gamepad* gamepad) const
-{
- for (auto it = gamepads.begin(); it != gamepads.end(); ++it)
- {
- if (*it == gamepad)
- return true;
- }
-
- return false;
-}
-
-const Gamepad* InputManager::getGamepad(const std::string& name) const
-{
- for (auto gamepad: gamepads)
- {
- if (gamepad->getName() == name)
- return gamepad;
- }
-
- return nullptr;
-}
-
-Gamepad* InputManager::getGamepad(const std::string& name)
-{
- for (auto gamepad: gamepads)
- {
- if (gamepad->getName() == name)
- return gamepad;
- }
-
- return nullptr;
-}
-
-SDLInputManager::SDLInputManager()
-{
- keyboard = new Keyboard("Default Keyboard");
- mouse = new Mouse("Default Mouse");
-
- registerKeyboard(keyboard);
- registerMouse(mouse);
-
- keyboard->setDisconnected(false);
- mouse->setDisconnected(false);
-}
-
-SDLInputManager::~SDLInputManager()
-{
- unregisterKeyboard(keyboard);
- unregisterMouse(mouse);
-
- for (auto gamepad: allocatedGamepads)
- {
- unregisterGamepad(gamepad);
- delete gamepad;
- }
-
- delete keyboard;
- delete mouse;
-}
-
-void SDLInputManager::update()
-{
- while (SDL_PollEvent(&event))
- {
- switch (event.type)
- {
- case SDL_KEYDOWN:
- {
- int scancode = event.key.keysym.scancode;
- keyboard->press(scancode);
- break;
- }
-
- case SDL_KEYUP:
- {
- int scancode = event.key.keysym.scancode;
- keyboard->release(scancode);
- break;
- }
-
- case SDL_MOUSEMOTION:
- {
- int x = event.motion.x;
- int y = event.motion.y;
- mouse->move(x, y);
- break;
- }
-
- case SDL_MOUSEBUTTONDOWN:
- {
- int button = event.button.button;
- mouse->press(button, event.button.x, event.button.y);
- break;
- }
-
- case SDL_MOUSEBUTTONUP:
- {
- int button = event.button.button;
- mouse->release(button, event.button.x, event.button.y);
- break;
- }
-
- case SDL_MOUSEWHEEL:
- {
- int direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) ? -1 : 1;
- int x = event.wheel.x * direction;
- int y = event.wheel.y * direction;
- mouse->scroll(x, y);
- break;
- }
-
- case SDL_CONTROLLERBUTTONDOWN:
- {
- int instanceID = event.cbutton.which;
- auto it = gamepadMap.find(instanceID);
- if (it == gamepadMap.end())
- {
- std::cerr << std::string("Received event from invalid gamepad") << std::endl;
- break;
- }
-
- Gamepad* gamepad = it->second;
- int button = event.cbutton.button;
- gamepad->press(button);
- break;
- }
-
- case SDL_CONTROLLERBUTTONUP:
- {
- int instanceID = event.cbutton.which;
- auto it = gamepadMap.find(instanceID);
- if (it == gamepadMap.end())
- {
- std::cerr << std::string("Received event from invalid gamepad") << std::endl;
- break;
- }
-
- Gamepad* gamepad = it->second;
- int button = event.cbutton.button;
- gamepad->release(button);
- break;
- }
-
- case SDL_CONTROLLERAXISMOTION:
- {
- int instanceID = event.caxis.which;
- auto it = gamepadMap.find(instanceID);
- if (it == gamepadMap.end())
- {
- std::cerr << std::string("Received event from invalid gamepad") << std::endl;
- break;
- }
-
- Gamepad* gamepad = it->second;
- int axis = event.caxis.axis;
- bool negative;
- float value;
- if (event.caxis.value < 0)
- {
- negative = true;
- value = (float)event.caxis.value / -32768.0f;
- }
- else
- {
- negative = false;
- value = (float)event.caxis.value / 32767.0f;
- }
-
- gamepad->move(axis, negative, value);
- break;
- }
-
- case SDL_CONTROLLERDEVICEADDED:
- {
- SDL_GameController* controller = SDL_GameControllerOpen(event.cdevice.which);
- if (controller != nullptr)
- {
- // Find controller's joystick instance ID
- SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
- int instanceID = SDL_JoystickInstanceID(joystick);
-
- // Determine gamepad name
- std::string name = SDL_GameControllerName(controller);
- if (name.empty())
- {
- name = "Unknown Gamepad";
- }
-
- bool reconnected = false;
- const std::list* gamepads = getGamepads();
- for (auto it = gamepads->begin(); it != gamepads->end(); ++it)
- {
- // Check if this gamepad was previously connected
- if ((*it)->isDisconnected() && (*it)->getName() == name)
- {
- // Map to new instance ID
- Gamepad* gamepad = *it;
- gamepadMap[instanceID] = gamepad;
- gamepad->setDisconnected(false);
- reconnected = true;
-
- std::cout << std::string("Reconnected gamepad \"") << name << std::string("\" with ID ") << instanceID << std::endl;
- break;
- }
- }
-
- if (!reconnected)
- {
- // Create new gamepad
- Gamepad* gamepad = new Gamepad(name);
-
- // Add to list of allocated gamepads
- allocatedGamepads.push_back(gamepad);
-
- // Register with the input manager
- registerGamepad(gamepad);
-
- // Map instance ID to gamepad pointer
- gamepadMap[instanceID] = gamepad;
-
- // Connect gamepad
- gamepad->setDisconnected(false);
-
- std::cout << std::string("Connected gamepad \"") << name << std::string("\" with ID ") << instanceID << std::endl;
- }
- }
- break;
- }
-
- case SDL_CONTROLLERDEVICEREMOVED:
- {
- int instanceID = event.cdevice.which;
-
- // Find gamepad
- auto mapIt = gamepadMap.find(instanceID);
- if (mapIt == gamepadMap.end())
- {
- std::cerr << std::string("Attempted to remove nonexistent gamepad with ID ") << instanceID << std::endl;
- break;
- }
- Gamepad* gamepad = mapIt->second;
-
- // Remove from gamepad map
- gamepadMap.erase(mapIt);
-
- // Set disconnected flag
- gamepad->setDisconnected(true);
-
- std::cout << std::string("Disconnected gamepad \"") << gamepad->getName() << std::string("\" with ID ") << instanceID << std::endl;
- break;
- }
-
- case SDL_WINDOWEVENT:
- {
- if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
- {
- for (auto observer: windowObservers)
- {
- observer->windowResized(event.window.data1, event.window.data2);
- }
- }
- else if (event.window.event == SDL_WINDOWEVENT_CLOSE)
- {
- closed = true;
-
- for (auto observer: windowObservers)
- {
- observer->windowClosed();
- }
- }
- break;
- }
-
- case SDL_QUIT:
- {
- closed = true;
-
- for (auto observer: windowObservers)
- {
- observer->windowClosed();
- }
- break;
- }
-
- default:
- break;
- }
- }
-}
-
-void SDLInputManager::listen(InputEvent* inputEvent)
-{
- int eventCount;
-
- // Gather events
- SDL_PumpEvents();
-
- // Check for key events
- eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN);
- if (eventCount)
- {
- int scancode = event.key.keysym.scancode;
- inputEvent->type = InputEvent::Type::KEY;
- inputEvent->key.first = keyboard;
- inputEvent->key.second = scancode;
- return;
- }
-
- // Check for mouse button events
- eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN);
- if (eventCount)
- {
- int button = event.button.button;
- inputEvent->type = InputEvent::Type::MOUSE_BUTTON;
- inputEvent->mouseButton.first = mouse;
- inputEvent->mouseButton.second = button;
- return;
- }
-
- // Check for mouse wheel events
- eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEWHEEL, SDL_MOUSEWHEEL);
- if (eventCount)
- {
- int direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) ? -1 : 1;
- int x = event.wheel.x * direction;
- int y = event.wheel.y * direction;
- inputEvent->type = InputEvent::Type::MOUSE_WHEEL;
- std::get<0>(inputEvent->mouseWheel) = mouse;
- std::get<1>(inputEvent->mouseWheel) = x;
- std::get<2>(inputEvent->mouseWheel) = y;
- return;
- }
-
- // Check for gamepad button events
- eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONDOWN);
- if (eventCount)
- {
- int instanceID = event.cbutton.which;
- auto it = gamepadMap.find(instanceID);
- if (it == gamepadMap.end())
- {
- std::cerr << std::string("Received event from invalid gamepad") << std::endl;
- return;
- }
-
- Gamepad* gamepad = it->second;
- int button = event.cbutton.button;
- inputEvent->type = InputEvent::Type::GAMEPAD_BUTTON;
- inputEvent->gamepadButton.first = gamepad;
- inputEvent->gamepadButton.second = button;
- return;
- }
-
- // Check for gamepad axis events
- eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERAXISMOTION);
- if (eventCount)
- {
- int instanceID = event.caxis.which;
- auto it = gamepadMap.find(instanceID);
- if (it == gamepadMap.end())
- {
- std::cerr << std::string("Received event from invalid gamepad") << std::endl;
- return;
- }
-
- Gamepad* gamepad = it->second;
- int axis = event.caxis.axis;
- bool negative = event.caxis.value < 0;
- inputEvent->type = InputEvent::Type::GAMEPAD_AXIS;
- std::get<0>(inputEvent->gamepadAxis) = gamepad;
- std::get<1>(inputEvent->gamepadAxis) = axis;
- std::get<2>(inputEvent->gamepadAxis) = negative;
- return;
- }
-}
diff --git a/src/render-passes.cpp b/src/render-passes.cpp
deleted file mode 100644
index 1f426a7..0000000
--- a/src/render-passes.cpp
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * Copyright (C) 2017 Christopher J. Howard
- *
- * This file is part of Antkeeper Source Code.
- *
- * Antkeeper Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper Source Code. If not, see .
- */
-
-#include "render-passes.hpp"
-#include "configuration.hpp"
-#include "ui/ui.hpp"
-#include
-#include
-
-ClearRenderPass::ClearRenderPass():
- clearColor(true),
- clearDepth(true),
- clearStencil(true),
- color(0.0f),
- depth(1.0f),
- index(0)
-{}
-
-bool ClearRenderPass::load(const RenderContext* renderContext)
-{
- return true;
-}
-
-void ClearRenderPass::unload()
-{}
-
-void ClearRenderPass::render(RenderContext* renderContext)
-{
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
-
- GLbitfield mask = 0;
- if (clearColor)
- {
- mask |= GL_COLOR_BUFFER_BIT;
- glClearColor(color[0], color[1], color[2], color[3]);
- }
-
- if (clearDepth)
- {
- mask |= GL_DEPTH_BUFFER_BIT;
- glClearDepth(depth);
- }
-
- if (clearStencil)
- {
- mask |= GL_STENCIL_BUFFER_BIT;
- glClearStencil(index);
- }
-
- glClear(mask);
-}
-
-void ClearRenderPass::setClear(bool color, bool depth, bool stencil)
-{
- clearColor = color;
- clearDepth = depth;
- clearStencil = stencil;
-}
-
-void ClearRenderPass::setClearColor(const Vector4& color)
-{
- this->color = color;
-}
-
-void ClearRenderPass::setClearDepth(float depth)
-{
- this->depth = depth;
-}
-
-void ClearRenderPass::setClearStencil(int index)
-{
- this->index = index;
-}
-
-BlurRenderPass::BlurRenderPass():
- gammaCorrect(false)
-{}
-
-bool BlurRenderPass::load(const RenderContext* renderContext)
-{
- permutation = (gammaCorrect) ? 1 : 0;
-
- // Load shader source
- if (!shader.loadSource("data/shaders/blur.glsl"))
- {
- std::cerr << std::string("BlurRenderPass: failed to load shader source.") << std::endl;
- return false;
- }
-
- // Generate permutation
- if (!shader.generatePermutation(permutation))
- {
- std::cerr << std::string("BlurRenderPass: failed to generate shader permutation.") << std::endl;
- return false;
- }
-
- // Connect shader variables
- textureParam.connect(shader.getInput("blurTexture"));
- resolutionParam.connect(shader.getInput("resolution"));
- directionParam.connect(shader.getInput("direction"));
- if (!textureParam.isConnected() ||
- !resolutionParam.isConnected() ||
- !directionParam.isConnected())
- {
- std::cerr << std::string("BlurRenderPass: one or more shader variables were not connected to shader inputs.") << std::endl;
- return false;
- }
-
- // Initialize shader variables
- resolutionParam.setValue(Vector2(renderTarget->width, renderTarget->height));
-
- const float quadVertexData[] =
- {
- -1.0f, 1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f,
- 1.0f, -1.0f, 0.0f,
- 1.0f, 1.0f, 0.0f
- };
-
- const std::uint32_t quadIndexData[] =
- {
- 0, 1, 3,
- 3, 1, 2
- };
-
- quadVertexCount = 4;
- quadIndexCount = 6;
-
- // Create AABB geometry
- glGenVertexArrays(1, &quadVAO);
- glBindVertexArray(quadVAO);
- glGenBuffers(1, &quadVBO);
- glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * quadVertexCount, quadVertexData, GL_STATIC_DRAW);
- glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
- glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
- glGenBuffers(1, &quadIBO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * quadIndexCount, quadIndexData, GL_STATIC_DRAW);
-
- return true;
-}
-
-void BlurRenderPass::unload()
-{
- textureParam.disconnect();
- resolutionParam.disconnect();
- directionParam.disconnect();
- shader.deleteAllPermutations();
-
- glDeleteBuffers(1, &quadIBO);
- glDeleteBuffers(1, &quadVBO);
- glDeleteVertexArrays(1, &quadVAO);
-}
-
-void BlurRenderPass::render(RenderContext* renderContext)
-{
- // Bind framebuffer and set up viewport
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- // Set up OpenGL state
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDisable(GL_BLEND);
- glDisable(GL_CULL_FACE);
-
- // Activate shader permutation
- shader.activate(permutation);
-
- // Upload shader variables to shader permutation
- textureParam.upload();
- resolutionParam.upload();
- directionParam.upload();
-
- // Render quad
- glBindVertexArray(quadVAO);
- glDrawElementsBaseVertex(GL_TRIANGLES, quadIndexCount, GL_UNSIGNED_INT, (void*)0, 0);
-
- // Unbind texture
- //glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-ShadowMapRenderPass::ShadowMapRenderPass():
- croppedShadowMapViewports(nullptr),
- viewCamera(nullptr),
- splitViewFrustum(nullptr),
- cropMatrices(nullptr),
- tileMatrices(nullptr)
-{}
-
-bool ShadowMapRenderPass::load(const RenderContext* renderContext)
-{
- // Set maximum number of bones for skinned meshes
- maxBoneCount = 64;
-
- // Create split view frustum
- splitViewFrustum = new SplitViewFrustum(4);
- splitViewFrustum->setSplitSchemeWeight(0.85f);
-
- // Determine resolution of shadow maps
- shadowMapResolution = 4096;
- croppedShadowMapResolution = shadowMapResolution >> 1;
-
- // Allocate viewports
- croppedShadowMapViewports = new Vector4[splitViewFrustum->getSubfrustumCount()];
-
- // Setup viewports
- for (int i = 0; i < splitViewFrustum->getSubfrustumCount(); ++i)
- {
- int x = i % 2;
- int y = i / 2;
-
- Vector4* viewport = &croppedShadowMapViewports[i];
- (*viewport)[0] = static_cast(x * croppedShadowMapResolution);
- (*viewport)[1] = static_cast(y * croppedShadowMapResolution);
- (*viewport)[2] = static_cast(croppedShadowMapResolution);
- (*viewport)[3] = static_cast(croppedShadowMapResolution);
- }
-
- // Allocate matrices
- cropMatrices = new Matrix4[splitViewFrustum->getSubfrustumCount()];
- tileMatrices = new Matrix4[splitViewFrustum->getSubfrustumCount()];
-
- // Setup tile matrices
- Matrix4 tileScale = glm::scale(Vector3(0.5f, 0.5f, 1.0f));
- for (int i = 0; i < splitViewFrustum->getSubfrustumCount(); ++i)
- {
- float x = static_cast(i % 2) * 0.5f;
- float y = static_cast(i / 2) * 0.5f;
- tileMatrices[i] = glm::translate(Vector3(x, y, 0.0f)) * tileScale;
- }
-
- // Setup permutation values
- unskinnedPermutation = 0;
- skinnedPermutation = 1;
-
- // Load shader source
- if (!shader.loadSource("data/shaders/depth-pass.glsl"))
- {
- std::cerr << std::string("ShadowMapRenderPass: failed to load shader source.") << std::endl;
- return false;
- }
-
- // Generate unskinned and skinned permutations
- if (!shader.generatePermutation(unskinnedPermutation) || !shader.generatePermutation(skinnedPermutation))
- {
- std::cerr << std::string("ShadowMapRenderPass: failed to generate shader permutation.") << std::endl;
- return false;
- }
-
- // Allocate bone palette parameter
- matrixPaletteParam = new ShaderMatrix4(maxBoneCount);
-
- // Connect shader variables
- modelViewProjectionParam.connect(shader.getInput("modelViewProjectionMatrix"));
- matrixPaletteParam->connect(shader.getInput("matrixPalette"));
- if (!modelViewProjectionParam.isConnected() ||
- !matrixPaletteParam->isConnected())
- {
- std::cerr << std::string("ShadowMapRenderPass: one or more shader variables were not connected to shader inputs.") << std::endl;
- return false;
- }
-
- return true;
-}
-
-void ShadowMapRenderPass::unload()
-{
- modelViewProjectionParam.disconnect();
- matrixPaletteParam->disconnect();
- delete matrixPaletteParam;
- shader.deleteAllPermutations();
-
- delete[] croppedShadowMapViewports;
- croppedShadowMapViewports = nullptr;
-
- delete splitViewFrustum;
- splitViewFrustum = nullptr;
-
- delete[] cropMatrices;
- cropMatrices = nullptr;
-
- delete[] tileMatrices;
- tileMatrices = nullptr;
-}
-
-void ShadowMapRenderPass::render(RenderContext* renderContext)
-{
- // Bind framebuffer and setup viewport
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- // Enable depth testing
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_LESS);
-
- // Clear the framebuffer depth
- glClear(GL_DEPTH_BUFFER_BIT);
-
- // Draw front and back faces
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
- // Disable alpha blending
- glDisable(GL_BLEND);
-
- //const Camera& lightCamera = *(renderContext->camera);
- std::list* operations = renderContext->queue->getOperations();
-
- GLuint boundVAO = 0;
-
- splitViewFrustum->setMatrices(viewCamera->getView(), viewCamera->getProjection());
-
- // Sort operations
- operations->sort(RenderOpCompare());
-
- std::uint32_t permutation = 0xDEADBEEF;
-
- // For each frustum split
- for (int i = 0; i < splitViewFrustum->getSubfrustumCount(); ++i)
- {
- // Calculate crop matrix
- {
- const ViewFrustum& subfrustum = splitViewFrustum->getSubfrustum(i);
-
- // Create AABB containing the subfrustum corners
- AABB subfrustumBounds(subfrustum.getCorner(0), subfrustum.getCorner(0));
- for (std::size_t j = 1; j < 8; ++j)
- {
- subfrustumBounds.add(subfrustum.getCorner(j));
- }
-
- // Transform subfrustum bounds into light's clip space
- AABB croppingBounds = subfrustumBounds.transformed(lightCamera->getViewProjection());
- Vector3 cropMax = croppingBounds.getMax();
- Vector3 cropMin = croppingBounds.getMin();
-
- // Calculate scale
- Vector3 scale;
- scale.x = 2.0f / (cropMax.x - cropMin.x);
- scale.y = 2.0f / (cropMax.y - cropMin.y);
- scale.z = 1.0f / (cropMax.z - cropMin.z);
-
- // Quantize scale
- float scaleQuantizer = 64.0f;
- scale.x = 1.0f / std::ceil(1.0f / scale.x * scaleQuantizer) * scaleQuantizer;
- scale.y = 1.0f / std::ceil(1.0f / scale.y * scaleQuantizer) * scaleQuantizer;
-
- // Calculate offset
- Vector3 offset;
- offset.x = (cropMax.x + cropMin.x) * scale.x * -0.5f;
- offset.y = (cropMax.y + cropMin.y) * scale.y * -0.5f;
- offset.z = -cropMin.z * scale.z;
-
- // Quantize offset
- float halfTextureSize = static_cast(croppedShadowMapResolution) * 0.5f;
- offset.x = std::ceil(offset.x * halfTextureSize) / halfTextureSize;
- offset.y = std::ceil(offset.y * halfTextureSize) / halfTextureSize;
-
- cropMatrices[i] = glm::translate(offset) * glm::scale(scale);
- }
-
- Matrix4 croppedViewProjection = cropMatrices[i] * lightCamera->getViewProjection();
-
- // Activate viewport for corresponding cropped shadow map
- const Vector4& viewport = croppedShadowMapViewports[i];
- glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
-
- // Render operations
- for (const RenderOperation& operation: *operations)
- {
- // Skip operations with no materials and materials with no shadows
- if (operation.material == nullptr || (operation.material->getFlags() & MATERIAL_FLAG_DISABLE_SHADOW_CASTING))
- {
- continue;
- }
-
- // TODO: Perform culling for subfrustums
-
- // Select permutation
- std::uint32_t targetPermutation = (operation.pose != nullptr) ? skinnedPermutation : unskinnedPermutation;
- if (permutation != targetPermutation)
- {
- permutation = targetPermutation;
- shader.activate(permutation);
- }
-
- // Pass matrix palette
- if (operation.pose != nullptr)
- {
- matrixPaletteParam->getConnectedInput()->upload(0, operation.pose->getMatrixPalette(), operation.pose->getSkeleton()->getBoneCount());
- }
-
- const Matrix4& modelMatrix = operation.transform;
- Matrix4 modelViewProjectionMatrix = croppedViewProjection * modelMatrix;
-
- modelViewProjectionParam.setValue(modelViewProjectionMatrix);
- modelViewProjectionParam.upload();
-
- if (boundVAO != operation.vao)
- {
- glBindVertexArray(operation.vao);
- boundVAO = operation.vao;
- }
-
- glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
- }
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-}
-
-bool ShadowMapRenderPass::RenderOpCompare::operator()(const RenderOperation& opA, const RenderOperation& opB) const
-{
- // If A is rigged
- if (opA.pose != nullptr)
- {
- // And B is rigged
- if (opB.pose != nullptr)
- {
- // Sort by VAO ID
- return (opA.vao <= opB.vao);
- }
- else
- {
- // Render A first
- return true;
- }
- }
-
- // Sort by VAO ID
- return (opA.vao <= opB.vao);
-}
-
-LightingRenderPass::LightingRenderPass():
- shadowMap(0),
- shadowCamera(nullptr),
- diffuseCubemap(nullptr),
- specularCubemap(nullptr),
- shadowMapPass(nullptr)
-{
- // Initialize bias matrix for calculating the model-view-projection-bias matrix (used for shadow map texture coordinate calculation)
- biasMatrix = glm::translate(Vector3(0.5f)) * glm::scale(Vector3(0.5f));
-
- maxBoneCount = 64;
- maxDirectionalLightCount = 1;
- maxSpotlightCount = 1;
-}
-
-bool LightingRenderPass::load(const RenderContext* renderContext)
-{
- // Load shaders for each material
-
- // Register parameter sets for each unique shader
-
- if (!shader.loadSource("data/shaders/standard.glsl"))
- {
- std::cerr << std::string("LightingRenderPass: Failed to load shader source.") << std::endl;
- return false;
- }
-
- /*
- if (renderContext != nullptr)
- {
- std::list* operations = renderContext->queue->getOperations();
-
- for (RenderOperation& op: *operations)
- {
-
- }
- }
- */
-
- // Set permutation values
- std::uint32_t IS_SKINNED = 1;
- std::uint32_t HAS_AMBIENT_CUBE = 1 << 7;
- unskinnedPermutation = HAS_AMBIENT_CUBE;
- skinnedPermutation = IS_SKINNED | HAS_AMBIENT_CUBE;
-
- // Generate shader permutations
- if (!shader.generatePermutation(unskinnedPermutation) || !shader.generatePermutation(skinnedPermutation))
- {
- std::cerr << std::string("LightingRenderPass: failed to generate shader permutation.") << std::endl;
- return false;
- }
-
- // Allocate shader array parameters
- parameters.matrixPalette = new ShaderMatrix4(maxBoneCount);
- parameters.lightViewProjectionMatrices = new ShaderMatrix4(4);
-
- // Connect shader parameters
- parameters.matrixPalette->connect(shader.getInput("matrixPalette"));
- parameters.modelMatrix.connect(shader.getInput("modelMatrix"));
- parameters.modelViewMatrix.connect(shader.getInput("modelViewMatrix"));
- parameters.modelViewProjectionMatrix.connect(shader.getInput("modelViewProjectionMatrix"));
- parameters.normalModelViewMatrix.connect(shader.getInput("normalModelViewMatrix"));
- parameters.normalModelMatrix.connect(shader.getInput("normalModelMatrix"));
- parameters.lightViewProjectionMatrices->connect(shader.getInput("lightViewProjectionMatrices"));
- parameters.splitDistances.connect(shader.getInput("splitDistances"));
- parameters.shadowMap.connect(shader.getInput("shadowMap"));
- parameters.cameraPosition.connect(shader.getInput("cameraPosition"));
- parameters.diffuseCubemap.connect(shader.getInput("diffuseCubemap"));
- parameters.specularCubemap.connect(shader.getInput("specularCubemap"));
-
- parameters.albedoOpacityMap.connect(shader.getInput("albedoOpacityMap"));
- parameters.metalnessRoughnessMap.connect(shader.getInput("metalnessRoughnessMap"));
- parameters.normalOcclusionMap.connect(shader.getInput("normalOcclusionMap"));
-
- if (!parameters.matrixPalette->isConnected() ||
- !parameters.modelMatrix.isConnected() ||
- !parameters.modelViewMatrix.isConnected() ||
- !parameters.modelViewProjectionMatrix.isConnected() ||
- !parameters.normalModelViewMatrix.isConnected() ||
- !parameters.normalModelMatrix.isConnected() ||
- !parameters.lightViewProjectionMatrices->isConnected() ||
- !parameters.splitDistances.isConnected() ||
- !parameters.shadowMap.isConnected() ||
- !parameters.cameraPosition.isConnected() ||
- !parameters.diffuseCubemap.isConnected() ||
- !parameters.specularCubemap.isConnected())
- {
- std::cerr << std::string("LightingRenderPass: one or more shader variables were not connected to shader inputs.") << std::endl;
- }
-
- return true;
-}
-
-void LightingRenderPass::unload()
-{
- // Free shader array parameters
- delete parameters.matrixPalette;
- delete parameters.lightViewProjectionMatrices;
- parameters.matrixPalette = nullptr;
- parameters.lightViewProjectionMatrices = nullptr;
- shader.deleteAllPermutations();
-}
-
-void LightingRenderPass::render(RenderContext* renderContext)
-{
- const Camera& camera = *(renderContext->camera);
- std::list* operations = renderContext->queue->getOperations();
-
- // Bind framebuffer and setup viewport
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- // Enable depth testing
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_LEQUAL);
-
- // Enable backface culling
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
- // Enable alpha blending
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDisable(GL_BLEND);
-
-
- Vector4 splitDistances;
- for (int i = 0; i < 4; ++i)
- {
- splitDistances[i] = shadowMapPass->getSplitViewFrustum().getSplitDistance(i + 1);
- }
-
- Vector3 directionalLightColors[3];
- Vector3 directionalLightDirections[3];
-
- Vector3 spotlightColors[3];
- Vector3 spotlightPositions[3];
- Vector3 spotlightAttenuations[3];
- Vector3 spotlightDirections[3];
- float spotlightCutoffs[3];
- float spotlightExponents[3];
-
- // Add directional light
- int directionalLightCount = 1;
- directionalLightColors[0] = Vector3(1);
- directionalLightDirections[0] = glm::normalize(Vector3(camera.getView() * -Vector4(0, -2, -1, 0)));
-
- // Add spotlights
- int spotlightCount = 0;
- const std::list* lights = renderContext->layer->getObjects(SceneObjectType::LIGHT);
- if (lights != nullptr)
- {
- for (auto object: *lights)
- {
- const Light* light = static_cast(object);
- LightType lightType = light->getLightType();
-
- if (lightType == LightType::SPOTLIGHT && light->isActive())
- {
- const Spotlight* spotlight = static_cast(light);
-
- spotlightColors[spotlightCount] = spotlight->getScaledColor();
- spotlightPositions[spotlightCount] = Vector3(camera.getView() * Vector4(spotlight->getTranslation(), 1.0f));
- spotlightAttenuations[spotlightCount] = spotlight->getAttenuation();
- spotlightDirections[spotlightCount] = glm::normalize(Vector3(camera.getView() * Vector4(-spotlight->getDirection(), 0.0f)));
- spotlightCutoffs[spotlightCount] = spotlight->getCutoff();
- spotlightExponents[spotlightCount] = spotlight->getExponent();
-
- ++spotlightCount;
- }
- }
- }
-
- // Calculate the (light-space) view-projection matrices
- Matrix4 lightViewProjectionMatrices[4];
- for (int i = 0; i < 4; ++i)
- {
- lightViewProjectionMatrices[i] = shadowMapPass->getTileMatrix(i) * biasMatrix * shadowMapPass->getCropMatrix(i) * shadowCamera->getViewProjection();
- }
-
- // Set shader parameter values
- parameters.lightViewProjectionMatrices->setValues(0, &lightViewProjectionMatrices[0], 4);
- parameters.splitDistances.setValue(splitDistances);
- parameters.cameraPosition.setValue(camera.getTranslation());
- parameters.diffuseCubemap.setValue(diffuseCubemap);
- parameters.specularCubemap.setValue(specularCubemap);
- parameters.shadowMap.setValue(shadowMap);
- parameters.directionalLightCount.setValue(0);
- parameters.spotlightCount.setValue(0);
-
- std::uint32_t permutation = 0xDEADBEEF;
- bool blending = false;
- GLuint boundVAO = 0;
-
- // Sort operations
- operations->sort(RenderOpCompare());
-
- // Render operations
- for (const RenderOperation& operation: *operations)
- {
- // Skip operations without materials
- if (!operation.material)
- {
- continue;
- }
-
- bool hasTranslucency = operation.material->getFlags() & MATERIAL_FLAG_TRANSLUCENT;
- if (hasTranslucency && !blending)
- {
- glEnable(GL_BLEND);
- blending = true;
- }
-
- // Select permutation
- std::uint32_t targetPermutation = (operation.pose != nullptr) ? skinnedPermutation : unskinnedPermutation;
- if (permutation != targetPermutation)
- {
- permutation = targetPermutation;
- shader.activate(permutation);
-
- // Pass static params
- parameters.lightViewProjectionMatrices->upload();
- parameters.splitDistances.upload();
- parameters.cameraPosition.upload();
- parameters.diffuseCubemap.upload();
- parameters.specularCubemap.upload();
- parameters.shadowMap.upload();
- parameters.directionalLightCount.upload();
- parameters.spotlightCount.upload();
-
- /*
- shader->setParameter(directionalLightCountParam, directionalLightCount);
- shader->setParameter(directionalLightColorsParam, 0, &directionalLightColors[0], directionalLightCount);
- shader->setParameter(directionalLightDirectionsParam, 0, &directionalLightDirections[0], directionalLightCount);
-
- shader->setParameter(spotlightCountParam, spotlightCount);
- shader->setParameter(spotlightColorsParam, 0, &spotlightColors[0], spotlightCount);
- shader->setParameter(spotlightPositionsParam, 0, &spotlightPositions[0], spotlightCount);
- shader->setParameter(spotlightAttenuationsParam, 0, &spotlightAttenuations[0], spotlightCount);
- shader->setParameter(spotlightDirectionsParam, 0, &spotlightDirections[0], spotlightCount);
- shader->setParameter(spotlightCutoffsParam, 0, &spotlightCutoffs[0], spotlightCount);
- shader->setParameter(spotlightExponentsParam, 0, &spotlightExponents[0], spotlightCount);
- */
- }
-
- const Matrix4& modelMatrix = operation.transform;
- Matrix4 modelViewMatrix = camera.getView() * modelMatrix;
- Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
- Matrix3 normalModelViewMatrix = glm::transpose(glm::inverse(Matrix3(modelViewMatrix)));
- Matrix3 normalModelMatrix = glm::transpose(glm::inverse(Matrix3(modelMatrix)));
-
- parameters.modelMatrix.setValue(modelMatrix);
- parameters.modelViewMatrix.setValue(modelViewMatrix);
- parameters.modelViewProjectionMatrix.setValue(modelViewProjectionMatrix);
- parameters.normalModelViewMatrix.setValue(normalModelViewMatrix);
- parameters.normalModelMatrix.setValue(normalModelMatrix);
-
- // Upload matrix parameters
- parameters.modelMatrix.upload();
- parameters.modelViewMatrix.upload();
- parameters.modelViewProjectionMatrix.upload();
- parameters.normalModelViewMatrix.upload();
- parameters.normalModelMatrix.upload();
-
- // Upload pose matrix palette
- if (operation.pose != nullptr && parameters.matrixPalette->isConnected())
- {
- parameters.matrixPalette->getConnectedInput()->upload(0, operation.pose->getMatrixPalette(), operation.pose->getSkeleton()->getBoneCount());
- }
-
- // Upload material parameters
- if (operation.material != nullptr)
- {
- if (operation.material->getShader() != &shader)
- {
- ((Material*)operation.material)->setShader(&shader);
- }
- operation.material->upload();
- }
-
- if (boundVAO != operation.vao)
- {
- glBindVertexArray(operation.vao);
- boundVAO = operation.vao;
- }
-
- glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
- }
-
- glActiveTexture(GL_TEXTURE5);
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-bool LightingRenderPass::RenderOpCompare::operator()(const RenderOperation& opA, const RenderOperation& opB) const
-{
- if (!opA.material)
- return false;
- else if (!opB.material);
- return true;
-
- // Determine transparency
- bool transparentA = opA.material->getFlags() & MATERIAL_FLAG_TRANSLUCENT;
- bool transparentB = opB.material->getFlags() & MATERIAL_FLAG_TRANSLUCENT;
-
- if (transparentA)
- {
- if (transparentB)
- {
- // A and B are both transparent, render back to front
- return (opA.depth >= opB.depth);
- }
- else
- {
- // A is transparent, B is opaque. Render B first
- return false;
- }
- }
- else
- {
- if (transparentB)
- {
- // A is opaque, B is transparent. Render A first
- return true;
- }
- else
- {
- // A and B are both opaque
- if (opA.material->getShader() == opB.material->getShader())
- {
- // A and B have the same shader
- if (opA.vao == opB.vao)
- {
- // A and B have the same VAO, sort by depth
- return (opA.depth < opB.depth);
- }
- else
- {
- // Sort by VAO
- return (opA.vao < opB.vao);
- }
- }
- }
- }
-
- // A and B are both opaque and have different shaders, sort by shader
- return (opA.material->getShader() < opB.material->getShader());
-}
-
-DebugRenderPass::DebugRenderPass()
-{}
-
-bool DebugRenderPass::load(const RenderContext* renderContext)
-{
- if (!shader.loadSource("data/shaders/unlit-solid.glsl"))
- {
- std::cerr << std::string("DebugRenderPass: Failed to load shader source.") << std::endl;
- return false;
- }
-
- // Set permutation values
- permutation = 0;
-
- // Generate shader permutations
- if (!shader.generatePermutation(permutation))
- {
- std::cerr << std::string("DebugRenderPass: failed to generate shader permutation.") << std::endl;
- return false;
- }
-
- // Connect shader variables
- modelViewProjectionMatrixParam.connect(shader.getInput("modelViewProjectionMatrix"));
- if (!modelViewProjectionMatrixParam.isConnected())
- {
- std::cerr << std::string("DebugRenderPass: one or more shader variables were not connected to shader inputs.") << std::endl;
- return false;
- }
-
- const float aabbVertexData[] =
- {
- -0.5, -0.5, -0.5,
- 0.5, -0.5, -0.5,
- 0.5, 0.5, -0.5,
- -0.5, 0.5, -0.5,
- -0.5, -0.5, 0.5,
- 0.5, -0.5, 0.5,
- 0.5, 0.5, 0.5,
- -0.5, 0.5, 0.5,
- };
-
- const std::uint32_t aabbIndexData[] =
- {
- 0, 1, 1, 2, 2, 3, 3, 0,
- 4, 5, 5, 6, 6, 7, 7, 4,
- 0, 4, 1, 5, 2, 6, 3, 7
- };
-
- aabbVertexCount = 8;
- aabbIndexCount = 24;
-
- // Create AABB geometry
- glGenVertexArrays(1, &aabbVAO);
- glBindVertexArray(aabbVAO);
- glGenBuffers(1, &aabbVBO);
- glBindBuffer(GL_ARRAY_BUFFER, aabbVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * aabbVertexCount, aabbVertexData, GL_STATIC_DRAW);
- glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
- glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
- glGenBuffers(1, &aabbIBO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, aabbIBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * aabbIndexCount, aabbIndexData, GL_STATIC_DRAW);
-
- return true;
-}
-
-void DebugRenderPass::unload()
-{
- modelViewProjectionMatrixParam.disconnect();
- shader.deleteAllPermutations();
-
- glDeleteBuffers(1, &aabbIBO);
- glDeleteBuffers(1, &aabbVBO);
- glDeleteVertexArrays(1, &aabbVAO);
-}
-
-void DebugRenderPass::render(RenderContext* renderContext)
-{
- // Bind framebuffer and setup viewport
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- const Camera& camera = *(renderContext->camera);
-
- /*
- // Bind framebuffer and setup viewport
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- // Clear the framebuffer depth
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClearDepth(1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- // Disable depth testing
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_LESS);
- */
-
- // Disable backface culling
- glDisable(GL_CULL_FACE);
-
- // Disable alpha blending
- glDisable(GL_BLEND);
-
- // Bind unlit solid shader
- shader.activate(permutation);
-
- // Bind AABB geometry
- glBindVertexArray(aabbVAO);
-
- const std::list* objects = renderContext->layer->getObjects();
- for (auto object: *objects)
- {
- if (!camera.getCullingMask()->intersects(object->getBounds()))
- continue;
-
- const AABB& bounds = object->getBounds();
- const Vector3& min = bounds.getMin();
- const Vector3& max = bounds.getMax();
-
- Vector3 scale = max - min;
- Vector3 center = (min + max) * 0.5f;
- const Vector3& translation = center;
- Matrix4 modelMatrix = glm::translate(translation) * glm::scale(scale);
- Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
-
- modelViewProjectionMatrixParam.setValue(modelViewProjectionMatrix);
- modelViewProjectionMatrixParam.upload();
-
- glDrawElements(GL_LINES, aabbIndexCount, GL_UNSIGNED_INT, (void*)0);
- }
-}
-
-UIRenderPass::UIRenderPass()
-{}
-
-bool UIRenderPass::load(const RenderContext* renderContext)
-{
- if (!shader.loadSource("data/shaders/ui.glsl"))
- {
- std::cerr << std::string("UIRenderPass: Failed to load shader source.") << std::endl;
- return false;
- }
-
- // Set permutation values
- untexturedPermutation = 0;
- texturedPermutation = 1;
-
- // Generate shader permutations
- if (!shader.generatePermutation(untexturedPermutation) || !shader.generatePermutation(texturedPermutation))
- {
- std::cerr << std::string("UIRenderPass: failed to generate shader permutation.") << std::endl;
- return false;
- }
-
- // Connect shader variables
- modelViewProjectionMatrixParam.connect(shader.getInput("modelViewProjectionMatrix"));
- textureParam.connect(shader.getInput("tex"));
- textureOffsetParam.connect(shader.getInput("texcoordOffset"));
- textureScaleParam.connect(shader.getInput("texcoordScale"));
- if (!modelViewProjectionMatrixParam.isConnected() ||
- !textureParam.isConnected() ||
- !textureOffsetParam.isConnected() ||
- !textureScaleParam.isConnected())
- {
- std::cerr << std::string("UIRenderPass: one or more shader variables were not connected to shader inputs.") << std::endl;
- return false;
- }
-
- return true;
-}
-
-void UIRenderPass::unload()
-{
- modelViewProjectionMatrixParam.disconnect();
- textureParam.disconnect();
- textureOffsetParam.disconnect();
- textureScaleParam.disconnect();
- shader.deleteAllPermutations();
-}
-
-void UIRenderPass::render(RenderContext* renderContext)
-{
- const Camera& camera = *(renderContext->camera);
-
- // Bind framebuffer and setup viewport
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- // Disable depth testing
- glDisable(GL_DEPTH_TEST);
- //glDepthMask(GL_FALSE);
- //glDepthFunc(GL_LESS);
-
- // Disable backface culling
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
- // Enable alpha blending
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- // Render operations
- const std::list* operations = renderContext->queue->getOperations();
- for (const RenderOperation& operation: *operations)
- {
- // Skip render operations with unsupported materials
- /*
- if (operation.material->getMaterialFormatID() != static_cast(MaterialFormat::UI))
- {
- continue;
- }
- */
-
- const UIMaterial* material = static_cast(operation.material);
-
- if (material->texture->getValue() != nullptr)
- {
- shader.activate(texturedPermutation);
-
- textureParam.setValue(material->texture->getValue());
- textureOffsetParam.setValue(material->textureOffset->getValue());
- textureScaleParam.setValue(material->textureScale->getValue());
-
- textureParam.upload();
- textureOffsetParam.upload();
- textureScaleParam.upload();
- }
- else
- {
- shader.activate(untexturedPermutation);
- }
-
- const Matrix4& modelMatrix = operation.transform;
- Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
-
- // Upload matrix parameters
- modelViewProjectionMatrixParam.setValue(modelViewProjectionMatrix);
- modelViewProjectionMatrixParam.upload();
-
- // Upload material parameters
- //operation.material->upload();
-
- // Draw geometry
- glBindVertexArray(operation.vao);
- glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
- }
-}
-
-/*
-VignetteRenderPass::VignetteRenderPass():
- shader(nullptr)
-{
- bayerTextureParam = parameterSet.addParameter("bayerTexture", ShaderParameter::Type::INT, 1);
- modelViewProjectionParam = parameterSet.addParameter("modelViewProjectionMatrix", ShaderParameter::Type::MATRIX_4, 1);
-}
-
-bool VignetteRenderPass::load(const RenderContext* renderContext)
-{
- shaderLoader.undefine();
- shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
- shaderLoader.define("VERTEX_COLOR", EMERGENT_VERTEX_COLOR);
- shaderLoader.define("TEXTURE_COUNT", 1);
-
- shader = shaderLoader.load("data/shaders/vignette.glsl", ¶meterSet);
- if (!shader)
- {
- return false;
- }
-
- /// @see http://www.anisopteragames.com/how-to-fix-color-banding-with-dithering/
- static const char pattern[] =
- {
- 0, 32, 8, 40, 2, 34, 10, 42,
- 48, 16, 56, 24, 50, 18, 58, 26,
- 12, 44, 4, 36, 14, 46, 6, 38,
- 60, 28, 52, 20, 62, 30, 54, 22,
- 3, 35, 11, 43, 1, 33, 9, 41,
- 51, 19, 59, 27, 49, 17, 57, 25,
- 15, 47, 7, 39, 13, 45, 5, 37,
- 63, 31, 55, 23, 61, 29, 53, 21
- };
-
- glGenTextures(1, &bayerTextureID);
- glBindTexture(GL_TEXTURE_2D, bayerTextureID);
- 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_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 8, 8, 0, GL_RED, GL_UNSIGNED_BYTE, pattern);
-
- return true;
-}
-
-void VignetteRenderPass::unload()
-{
- delete shader;
- shader = nullptr;
-
- glDeleteTextures(1, &bayerTextureID);
-}
-
-void VignetteRenderPass::render(RenderContext* renderContext)
-{
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
-
- // Bind shader
- shader->bind();
-
- // Bind texture
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, bayerTextureID);
-
- // Pass texture unit to shader
- shader->setParameter(bayerTextureParam, 0);
-
- const Camera& camera = *(renderContext->camera);
- const std::list* operations = renderContext->queue->getOperations();
-
- // Render operations
- for (const RenderOperation& operation: *operations)
- {
- const Material* material = operation.material;
-
- const Matrix4& modelMatrix = operation.transform;
- Matrix4 modelViewProjectionMatrix = camera.getViewProjection() * modelMatrix;
- shader->setParameter(modelViewProjectionParam, modelViewProjectionMatrix);
-
- glBindVertexArray(operation.vao);
- glDrawElementsBaseVertex(GL_TRIANGLES, operation.triangleCount * 3, GL_UNSIGNED_INT, (void*)0, operation.indexOffset);
- }
-}
-*/
-
-SkyboxRenderPass::SkyboxRenderPass():
- cubemap(nullptr)
-{}
-
-bool SkyboxRenderPass::load(const RenderContext* renderContext)
-{
- if (!shader.loadSource("data/shaders/skybox.glsl"))
- {
- std::cerr << std::string("SkyboxRenderPass: Failed to load shader source.") << std::endl;
- return false;
- }
-
- // Set permutation values
- permutation = 0;
-
- // Generate shader permutations
- if (!shader.generatePermutation(permutation))
- {
- std::cerr << std::string("SkyboxRenderPass: failed to generate shader permutation.") << std::endl;
- return false;
- }
-
- // Connect shader variables
- matrixParam.connect(shader.getInput("matrix"));
- cubemapParam.connect(shader.getInput("cubemap"));
- if (!matrixParam.isConnected() || !cubemapParam.isConnected())
- {
- std::cerr << std::string("SkyboxRenderPass: one or more shader variables were not connected to shader inputs.") << std::endl;
- return false;
- }
-
-
- const float quadVertexData[] =
- {
- -1.0f, 1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f,
- 1.0f, -1.0f, 0.0f,
- 1.0f, 1.0f, 0.0f
- };
-
- const std::uint32_t quadIndexData[] =
- {
- 0, 1, 3,
- 3, 1, 2
- };
-
- quadVertexCount = 4;
- quadIndexCount = 6;
-
- // Create AABB geometry
- glGenVertexArrays(1, &quadVAO);
- glBindVertexArray(quadVAO);
- glGenBuffers(1, &quadVBO);
- glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * quadVertexCount, quadVertexData, GL_STATIC_DRAW);
- glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
- glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
- glGenBuffers(1, &quadIBO);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * quadIndexCount, quadIndexData, GL_STATIC_DRAW);
-
- return true;
-}
-
-void SkyboxRenderPass::unload()
-{
- matrixParam.disconnect();
- cubemapParam.disconnect();
- shader.deleteAllPermutations();
-
- glDeleteBuffers(1, &quadIBO);
- glDeleteBuffers(1, &quadVBO);
- glDeleteVertexArrays(1, &quadVAO);
-}
-
-void SkyboxRenderPass::render(RenderContext* renderContext)
-{
- if (!cubemap)
- {
- return;
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
- glViewport(0, 0, renderTarget->width, renderTarget->height);
-
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
-
- //glDisable(GL_CULL_FACE);
- //glCullFace(GL_BACK);
-
- // Bind shader
- shader.activate(permutation);
-
- // Bind cubemap texture
- cubemapParam.setValue(cubemap);
- cubemapParam.upload();
-
- // Calculate matrix
- const Camera& camera = *(renderContext->camera);
- Matrix4 modelView = Matrix4(Matrix3(camera.getView()));
- Matrix4 matrix = glm::inverse(modelView) * glm::inverse(camera.getProjection());
-
- // Upload matrix to shader
- matrixParam.setValue(matrix);
- matrixParam.upload();
-
- // Render quad
- glBindVertexArray(quadVAO);
- glDrawElementsBaseVertex(GL_TRIANGLES, quadIndexCount, GL_UNSIGNED_INT, (void*)0, 0);
-}
diff --git a/src/resources/material-loader.cpp b/src/resources/material-loader.cpp
index 0dbc9d3..eb34c0e 100755
--- a/src/resources/material-loader.cpp
+++ b/src/resources/material-loader.cpp
@@ -179,7 +179,6 @@ static bool loadShaderTextureCube(ResourceManager* resourceManager, ShaderTextur
{
for (int i = 0; i < elements.size(); ++i)
{
-<<<<<<< HEAD:src/resources/material-loader.cpp
std::string filename;
std::stringstream stream;
stream << elements[i][0];
@@ -188,11 +187,6 @@ static bool loadShaderTextureCube(ResourceManager* resourceManager, ShaderTextur
TextureCube* value = resourceManager->load(filename);
variable->setValue(i, value);
-=======
- std::cerr << std::string("MaterialLoader::load(): Failed to open material file \"") << filename << std::string("\"") << std::endl;
- delete material;
- return nullptr;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
return true;
@@ -243,32 +237,20 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
std::size_t equalsSignPosition = line.find_first_of("=", commandPosition);
if (equalsSignPosition == std::string::npos)
{
-<<<<<<< HEAD:src/resources/material-loader.cpp
// Line has no equals sign
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- // Skip lines with no equals sign
- std::cerr << std::string("MaterialLoader::load(): Invalid line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- continue;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
// Find position of first character in the value string
std::size_t valueStartPosition = line.find_first_not_of(whitespace, equalsSignPosition + 1);
if (valueStartPosition == std::string::npos)
{
-<<<<<<< HEAD:src/resources/material-loader.cpp
// Line has no value
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- // Skip lines with no value
- std::cerr << std::string("MaterialLoader::load(): Invalid line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- continue;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
// Find position the end of the value string
@@ -292,11 +274,7 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
Shader* shader = nullptr;
try
{
-<<<<<<< HEAD:src/resources/material-loader.cpp
shader = resourceManager->load(valueString);
-=======
- std::cerr << std::string("MaterialLoader::load(): Failed to load shader \"") << valueString << std::string("\" on line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
catch (const std::exception& e)
{
@@ -324,14 +302,9 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
if (variableNamePosition == std::string::npos)
{
// Skip lines with no variable name
-<<<<<<< HEAD:src/resources/material-loader.cpp
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid variable on line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- std::cerr << std::string("MaterialLoader::load(): Invalid variable on line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- continue;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
// Find position of equals sign
@@ -339,14 +312,9 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
if (equalsSignPosition == std::string::npos)
{
// Skip lines with no equals sign
-<<<<<<< HEAD:src/resources/material-loader.cpp
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid variable on line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- std::cerr << std::string("MaterialLoader::load(): Invalid variable on line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- continue;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
// Find position of first character in variable type
@@ -354,14 +322,9 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
if (variableTypePosition == std::string::npos)
{
// Skip lines with no variable type definition
-<<<<<<< HEAD:src/resources/material-loader.cpp
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid variable on line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- std::cerr << std::string("MaterialLoader::load(): Invalid variable on line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- continue;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
// Count parentheses
@@ -370,14 +333,9 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
if (leftParenthesisCount != rightParenthesisCount || leftParenthesisCount == 0)
{
// Skip lines with invalid number of parentheses
-<<<<<<< HEAD:src/resources/material-loader.cpp
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid variable on line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- std::cerr << std::string("MaterialLoader::load(): Invalid variable on line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- continue;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
std::string variableName = line.substr(variableNamePosition, line.find_first_of(" \t=", variableNamePosition) - variableNamePosition);
@@ -495,273 +453,12 @@ Material* ResourceLoader::load(ResourceManager* resourceManager, std::
}
// Invalid command
-<<<<<<< HEAD:src/resources/material-loader.cpp
std::stringstream stream;
stream << "ResourceLoader::load(): Invalid command \"" << command << "\" on line " << lineNumber << ".";
throw std::runtime_error(stream.str().c_str());
-=======
- std::cerr << std::string("MaterialLoader::load(): Invalid command \"") << command << std::string("\" on line ") << lineNumber << std::string(" in \"") << filename << std::string("\"") << std::endl;
- }
- }
-
- // Close file
- file.close();
-
- // Add material to cache
- materialCache[filename] = material;
-
- return material;
-}
-
-Shader* MaterialLoader::loadShader(const std::string& filename)
-{
- auto it = shaderCache.find(filename);
- if (it != shaderCache.end())
- {
- return it->second;
- }
-
- std::string fullFilename = std::string("data/shaders/") + filename;
-
- std::cout << std::string("Loading shader \"") << fullFilename << std::string("\"\n");
-
- // Load shader
- Shader* shader = new Shader();
- if (!shader->loadSource(fullFilename))
- {
- delete shader;
- return nullptr;
- }
-
- // Add shader to cache
- shaderCache[filename] = shader;
-
- return shader;
-}
-
-Texture2D* MaterialLoader::loadTexture2D(const std::string& filename)
-{
- // Check if texture exists in cache
- auto it = texture2DCache.find(filename);
- if (it != texture2DCache.end())
- {
- return it->second;
- }
-
- std::string fullFilename = std::string("data/textures/") + filename;
-
- // Load texture
- Texture2D* texture = textureLoader.load2D(fullFilename);
- if (!texture)
- {
- std::cerr << std::string("MaterialLoader::loadTexture2D(): Failed to load texture file \"") << fullFilename << std::string("\"") << std::endl;
- return nullptr;
- }
-
- // Add texture to cache
- texture2DCache[filename] = texture;
-
- return texture;
-}
-
-TextureCube* MaterialLoader::loadTextureCube(const std::string& filename)
-{
- // Check if texture exists in cache
- auto it = textureCubeCache.find(filename);
- if (it != textureCubeCache.end())
- {
- return it->second;
- }
-
- std::string fullFilename = std::string("data/textures/") + filename;
-
- // Load texture
- TextureCube* texture = textureLoader.loadCube(fullFilename);
- if (!texture)
- {
- std::cerr << std::string("MaterialLoader::loadTextureCube(): Failed to load texture file \"") << fullFilename << std::string("\"") << std::endl;
- return nullptr;
- }
-
- // Add texture to cache
- textureCubeCache[filename] = texture;
-
- return texture;
-}
-
-bool MaterialLoader::loadShaderInt(ShaderInt* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- int value;
- std::stringstream stream;
- stream << elements[i][0];
- stream >> value;
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderFloat(ShaderFloat* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- float value;
- std::stringstream stream;
- stream << elements[i][0];
- stream >> value;
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderVector2(ShaderVector2* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- Vector2 value;
-
- for (int j = 0; j < 2; ++j)
- {
- std::stringstream stream;
- stream << elements[i][j];
- stream >> value[j];
- }
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderVector3(ShaderVector3* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- Vector3 value;
-
- for (int j = 0; j < 3; ++j)
- {
- std::stringstream stream;
- stream << elements[i][j];
- stream >> value[j];
- }
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderVector4(ShaderVector4* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- Vector4 value;
-
- for (int j = 0; j < 4; ++j)
- {
- std::stringstream stream;
- stream << elements[i][j];
- stream >> value[j];
- }
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderMatrix3(ShaderMatrix3* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- Matrix3 value;
-
- for (int j = 0; j < 3; ++j)
- {
- for (int k = 0; k < 3; ++k)
- {
- std::stringstream stream;
- stream << elements[i][k * 3 + j];
- stream >> value[j][k];
- }
- }
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderMatrix4(ShaderMatrix4* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- Matrix4 value;
-
- for (int j = 0; j < 4; ++j)
- {
- for (int k = 0; k < 4; ++k)
- {
- std::stringstream stream;
- stream << elements[i][k * 4 + j];
- stream >> value[j][k];
- }
- }
-
- variable->setValue(i, value);
- }
-
- return true;
-}
-
-bool MaterialLoader::loadShaderTexture2D(ShaderTexture2D* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- std::string filename;
- std::stringstream stream;
- stream << elements[i][0];
- stream >> filename;
-
- Texture2D* value = loadTexture2D(filename);
- if (!value)
- {
- std::cerr << std::string("MaterialLoader::loadShaderTexture2D(): Failed to load 2D texture \"") << filename << std::string("\"") << std::endl;
- return false;
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
}
}
return material;
}
-<<<<<<< HEAD:src/resources/material-loader.cpp
-=======
-bool MaterialLoader::loadShaderTextureCube(ShaderTextureCube* variable, const std::vector>& elements)
-{
- for (int i = 0; i < elements.size(); ++i)
- {
- std::string filename;
- std::stringstream stream;
- stream << elements[i][0];
- stream >> filename;
-
- TextureCube* value = loadTextureCube(filename);
- if (!value)
- {
- std::cerr << std::string("MaterialLoader::loadShaderTextureCube(): Failed to load cube texture \"") << filename << std::string("\"") << std::endl;
- return false;
- }
-
- variable->setValue(i, value);
- }
-
- return true;
-}
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/material-loader.cpp
diff --git a/src/resources/model-loader.cpp b/src/resources/model-loader.cpp
index d112ce3..2fdab4e 100755
--- a/src/resources/model-loader.cpp
+++ b/src/resources/model-loader.cpp
@@ -148,17 +148,6 @@ inline static void readString(std::string* result, unsigned char** data)
template <>
Model* ResourceLoader::load(ResourceManager* resourceManager, std::istream* is)
{
-<<<<<<< HEAD:src/resources/model-loader.cpp
-=======
- // Open file
- std::ifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
- if (!file.is_open())
- {
- std::cerr << std::string("ModelLoader::load(): Failed to open model file \"") << filename << std::string("\"") << std::endl;
- return nullptr;
- }
-
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/model-loader.cpp
// Allocate file data buffer
is->seekg(0, is->end);
int filesize = is->tellg();
@@ -512,25 +501,8 @@ Model* ResourceLoader::load(ResourceManager* resourceManager, std::istrea
modelGroup->name = modelDataGroup->materialName;
// Load material
-<<<<<<< HEAD:src/resources/model-loader.cpp
std::string materialFilename = modelDataGroup->materialName + std::string(".mtl");
modelGroup->material = resourceManager->load(materialFilename);
-=======
- std::string materialFilename = std::string("data/materials/") + modelDataGroup->materialName + std::string(".mtl");
- if (materialLoader != nullptr)
- {
- modelGroup->material = materialLoader->load(materialFilename);
- if (!modelGroup->material)
- {
- std::cerr << std::string("ModelLoader::load(): Failed to load material file \"") << materialFilename << std::string("\" for model file \"") << filename << std::string("\"") << std::endl;
- }
- }
- else
- {
- modelGroup->material = nullptr;
- std::cerr << std::string("ModelLoader::load(): No valid material loader, material file \"") << materialFilename << std::string("\" not loaded") << std::endl;
- }
->>>>>>> df8405f4e83febb81a5ce8f772bd7f5b9e9b6036:src/model-loader.cpp
// Setup model group geometry
modelGroup->indexOffset = modelDataGroup->indexOffset;
diff --git a/src/settings.cpp b/src/settings.cpp
deleted file mode 100644
index cd701e3..0000000
--- a/src/settings.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2017 Christopher J. Howard
- *
- * This file is part of Antkeeper Source Code.
- *
- * Antkeeper Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper Source Code. If not, see .
- */
-
-#include "settings.hpp"
-#include
-#include
-#include
-#include
-
-bool ParameterDict::load(const std::string& filename)
-{
- // Open parameter dict file
- std::ifstream file(filename.c_str());
- if (!file.is_open())
- {
- std::cerr << std::string("Failed to open file \"") << filename << std::string("\"") << std::endl;
- return false;
- }
-
- // Read file
- std::string line;
- std::size_t lineNumber = 0;
- while (file.good() && std::getline(file, line))
- {
- ++lineNumber;
-
- if (!line.empty() && line[line.size() - 1] == '\r')
- {
- line = line.substr(0, line.size() - 1);
- }
-
- // Tokenize line (tab-delimeted)
- std::vector tokens;
- std::string token;
- std::istringstream linestream(line);
- while (std::getline(linestream, token, '\t'))
- tokens.push_back(token);
-
- if (tokens.empty() || tokens[0][0] == '#')
- continue;
-
- if (tokens.size() != 2)
- {
- std::cerr << std::string("Invalid line \"") << lineNumber << std::string("\" in file \"") << filename << std::string("\"") << std::endl;
- continue;
- }
-
- parameters[tokens[0]] = tokens[1];
- }
-
- file.close();
-
- return true;
-}
-
-bool ParameterDict::save(const std::string& filename)
-{
- std::ofstream file(filename.c_str());
- if (!file.is_open())
- {
- std::cerr << std::string("Failed to open file \"") << filename << std::string("\"") << std::endl;
- return false;
- }
-
- for (auto it = parameters.begin(); it != parameters.end(); ++it)
- file << it->first << std::string("\t") << it->second << std::endl;
-
- file.close();
-
- return true;
-}
-
-void ParameterDict::clear()
-{
- parameters.clear();
-}
diff --git a/src/states/loading-state.cpp b/src/states/loading-state.cpp
deleted file mode 100644
index 20ba4fa..0000000
--- a/src/states/loading-state.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2017 Christopher J. Howard
- *
- * This file is part of Antkeeper Source Code.
- *
- * Antkeeper Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper Source Code. If not, see .
- */
-
-#include "loading-state.hpp"
-#include "../application.hpp"
-#include "splash-state.hpp"
-#include "title-state.hpp"
-
-LoadingState::LoadingState(Application* application):
- ApplicationState(application)
-{}
-
-LoadingState::~LoadingState()
-{}
-
-void LoadingState::enter()
-{
- bool failure = false;
-
- std::cout << std::string("Loading controls... ");
- if (!application->loadControls())
- {
- std::cout << std::string("failed") << std::endl;
- failure = true;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- std::cout << std::string("Loading scene... ");
- if (!application->loadScene())
- {
- std::cout << std::string("failed") << std::endl;
- failure = true;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- std::cout << std::string("Loading models... ");
- if (!application->loadModels())
- {
- std::cout << std::string("failed") << std::endl;
- failure = true;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- std::cout << std::string("Loading game... ");
- if (!application->loadGame())
- {
- std::cout << std::string("failed") << std::endl;
- failure = true;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- std::cout << std::string("Loading UI... ");
- if (!application->loadUI())
- {
- std::cout << std::string("failed") << std::endl;
- failure = true;
- }
- else
- {
- std::cout << std::string("success") << std::endl;
- }
-
- if (failure)
- {
- application->close(EXIT_FAILURE);
- }
-
- application->splashBackgroundImage->setVisible(true);
-}
-
-void LoadingState::execute()
-{
- // Check for splash screen and title skip settings
- bool skipSplash = false;
- bool skipTitle = false;
- application->settings.get("skip_splash", &skipSplash);
- //application->settings.get("skip_title", &skipTitle);
-
- // Determine next state
- ApplicationState* nextState = application->splashState;
- if (skipSplash)
- {
- nextState = application->titleState;
-
- /*
- if (skipTitle)
- {
- nextState = application->mainMenuState;
- }
- */
- }
-
- // Change state
- application->changeState(nextState);
-}
-
-void LoadingState::exit()
-{
- application->splashBackgroundImage->setVisible(false);
-}