From 80d4e310d978ca14501115f4b835dccf22bea33a Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Thu, 28 Feb 2019 14:37:06 +0800 Subject: [PATCH] Fix files that were incorrectly merged from another repository --- CMakeLists.txt | 377 --- src/application.cpp | 2318 ----------------- src/controls.cpp | 664 ----- .../antkeeper.manifest => dpi-aware.manifest} | 0 src/game/biome.cpp | 119 - src/input.cpp | 788 ------ src/render-passes.cpp | 1248 --------- src/resources/material-loader.cpp | 303 --- src/resources/model-loader.cpp | 28 - src/settings.cpp | 92 - src/states/loading-state.cpp | 128 - 11 files changed, 6065 deletions(-) delete mode 100644 src/application.cpp delete mode 100644 src/controls.cpp rename src/{windows/antkeeper.manifest => dpi-aware.manifest} (100%) delete mode 100644 src/game/biome.cpp delete mode 100644 src/input.cpp delete mode 100644 src/render-passes.cpp delete mode 100644 src/settings.cpp delete mode 100644 src/states/loading-state.cpp 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); -}