diff --git a/.gitignore b/.gitignore
index f9e4e7c93..b4d39213a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,9 @@ internal/
#os
.DS_Store
+
+
+CMakeCache.txt
+cmake_install.cmake
+CMakeFiles/
+Makefile
diff --git a/AndroidManifest.xml.in b/AndroidManifest.xml.in
new file mode 100644
index 000000000..76495b541
--- /dev/null
+++ b/AndroidManifest.xml.in
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 552a4d9e4..232f95b1a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,17 @@
cmake_minimum_required(VERSION 3.16)
project(Gothic2Notr LANGUAGES C CXX)
+
+# Option to generate Android build directory (run with: cmake -DGENERATE_ANDROID_BUILD=ON -P CMakeLists.txt)
+option(GENERATE_ANDROID_BUILD "Generate Android/Gradle build directory from templates" OFF)
+if(GENERATE_ANDROID_BUILD)
+ include(${CMAKE_SOURCE_DIR}/cmake/android/GenerateAndroidBuild.cmake)
+ generate_android_build(
+ SOURCE_DIR "${CMAKE_SOURCE_DIR}"
+ OUTPUT_DIR "${CMAKE_SOURCE_DIR}/build/android-build"
+ )
+ return()
+endif()
set(CMAKE_CXX_STANDARD 20)
set(BUILD_SHARED_LIBS OFF)
@@ -11,7 +22,11 @@ set(CMAKE_RELWITHDEBINFO_POSTFIX "")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_SKIP_RPATH ON)
-add_executable(${PROJECT_NAME})
+if(ANDROID)
+ add_library(${PROJECT_NAME} SHARED)
+else()
+ add_executable(${PROJECT_NAME})
+endif()
if(MSVC)
add_definitions(-D_USE_MATH_DEFINES)
@@ -59,6 +74,12 @@ elseif(IOS)
MACOSX_BUNDLE_BUNDLE_VERSION 1
MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")
+elseif(ANDROID)
+ # Android build configuration
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
+ # Build as shared library for Android
+ set_target_properties(${PROJECT_NAME} PROPERTIES
+ LIBRARY_OUTPUT_NAME "opengothic")
elseif(APPLE)
enable_language(OBJCXX)
endif()
@@ -96,6 +117,12 @@ endif()
if(WIN32)
target_link_libraries(${PROJECT_NAME} shlwapi DbgHelp)
+elseif(ANDROID)
+ # Add android_native_app_glue
+ set(ANDROID_NATIVE_APP_GLUE_DIR "${ANDROID_NDK}/sources/android/native_app_glue")
+ target_sources(${PROJECT_NAME} PRIVATE "${ANDROID_NATIVE_APP_GLUE_DIR}/android_native_app_glue.c")
+ target_include_directories(${PROJECT_NAME} PRIVATE "${ANDROID_NATIVE_APP_GLUE_DIR}")
+ target_link_libraries(${PROJECT_NAME} android log)
elseif(UNIX)
target_link_libraries(${PROJECT_NAME} -lpthread -ldl)
endif()
diff --git a/cmake/android/GenerateAndroidBuild.cmake b/cmake/android/GenerateAndroidBuild.cmake
new file mode 100644
index 000000000..ff93fee23
--- /dev/null
+++ b/cmake/android/GenerateAndroidBuild.cmake
@@ -0,0 +1,114 @@
+# GenerateAndroidBuild.cmake
+# Generates a complete Android/Gradle build directory from templates
+#
+# Usage from CMakeLists.txt:
+# cmake -DGENERATE_ANDROID_BUILD=ON .
+
+# Default configuration values
+set(ANDROID_PROJECT_NAME "OpenGothic" CACHE STRING "Android project name")
+set(ANDROID_NAMESPACE "com.example.opengothic" CACHE STRING "Android namespace")
+set(ANDROID_APPLICATION_ID "com.example.opengothic" CACHE STRING "Android application ID")
+set(ANDROID_LIB_NAME "opengothic" CACHE STRING "Native library name")
+set(ANDROID_COMPILE_SDK "35" CACHE STRING "Android compile SDK version")
+set(ANDROID_MIN_SDK "24" CACHE STRING "Android minimum SDK version")
+set(ANDROID_TARGET_SDK "35" CACHE STRING "Android target SDK version")
+set(ANDROID_VERSION_CODE "1" CACHE STRING "Android version code")
+set(ANDROID_VERSION_NAME "1.0" CACHE STRING "Android version name")
+set(ANDROID_GRADLE_PLUGIN_VERSION "8.7.3" CACHE STRING "Android Gradle Plugin version")
+set(ANDROID_CMAKE_VERSION "3.22.1" CACHE STRING "CMake version for Android build")
+set(ANDROID_ABI_LIST "\"arm64-v8a\", \"x86_64\"" CACHE STRING "Android ABI list")
+
+function(generate_android_build)
+ cmake_parse_arguments(ARG "" "OUTPUT_DIR;SOURCE_DIR" "" ${ARGN})
+
+ if(NOT ARG_SOURCE_DIR)
+ set(ARG_SOURCE_DIR "${CMAKE_SOURCE_DIR}")
+ endif()
+ if(NOT ARG_OUTPUT_DIR)
+ set(ARG_OUTPUT_DIR "${CMAKE_BINARY_DIR}/android-build")
+ endif()
+
+ set(OPENGOTHIC_SOURCE_DIR "${ARG_SOURCE_DIR}")
+ set(ANDROID_BUILD_DIR "${ARG_OUTPUT_DIR}")
+
+ message(STATUS "Generating Android build directory: ${ANDROID_BUILD_DIR}")
+
+ # Create directory structure
+ file(MAKE_DIRECTORY "${ANDROID_BUILD_DIR}/app/src/main")
+ file(MAKE_DIRECTORY "${ANDROID_BUILD_DIR}/gradle/wrapper")
+
+ # settings.gradle
+ file(WRITE "${ANDROID_BUILD_DIR}/settings.gradle"
+"pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = \"${ANDROID_PROJECT_NAME}\"
+include ':app'
+")
+
+ # build.gradle (root)
+ file(WRITE "${ANDROID_BUILD_DIR}/build.gradle"
+"plugins {
+ id 'com.android.application' version '${ANDROID_GRADLE_PLUGIN_VERSION}' apply false
+}
+")
+
+ # gradle.properties
+ file(WRITE "${ANDROID_BUILD_DIR}/gradle.properties"
+"org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+android.useAndroidX=true
+android.nonTransitiveRClass=true
+")
+
+ # gradle-wrapper.properties
+ file(WRITE "${ANDROID_BUILD_DIR}/gradle/wrapper/gradle-wrapper.properties"
+"distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\\://services.gradle.org/distributions/gradle-8.9-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+")
+
+ # app/build.gradle (from template - more complex)
+ configure_file(
+ "${OPENGOTHIC_SOURCE_DIR}/cmake/android/app.build.gradle.in"
+ "${ANDROID_BUILD_DIR}/app/build.gradle"
+ @ONLY
+ )
+
+ # AndroidManifest.xml (from template)
+ configure_file(
+ "${OPENGOTHIC_SOURCE_DIR}/AndroidManifest.xml.in"
+ "${ANDROID_BUILD_DIR}/app/src/main/AndroidManifest.xml"
+ @ONLY
+ )
+
+ # local.properties (SDK path)
+ if(DEFINED ENV{ANDROID_HOME})
+ set(SDK_DIR "$ENV{ANDROID_HOME}")
+ elseif(DEFINED ENV{ANDROID_SDK_ROOT})
+ set(SDK_DIR "$ENV{ANDROID_SDK_ROOT}")
+ else()
+ set(SDK_DIR "")
+ endif()
+
+ if(SDK_DIR)
+ string(REPLACE "\\" "/" SDK_DIR "${SDK_DIR}")
+ file(WRITE "${ANDROID_BUILD_DIR}/local.properties" "sdk.dir=${SDK_DIR}\n")
+ else()
+ file(WRITE "${ANDROID_BUILD_DIR}/local.properties" "# sdk.dir=/path/to/Android/Sdk\n")
+ endif()
+
+ message(STATUS "Done. Build: cd ${ANDROID_BUILD_DIR} && ./gradlew assembleRelease")
+endfunction()
diff --git a/cmake/android/app.build.gradle.in b/cmake/android/app.build.gradle.in
new file mode 100644
index 000000000..fcc6bca7a
--- /dev/null
+++ b/cmake/android/app.build.gradle.in
@@ -0,0 +1,66 @@
+// App build file - generated by CMake
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ namespace '@ANDROID_NAMESPACE@'
+ compileSdk @ANDROID_COMPILE_SDK@
+
+ defaultConfig {
+ applicationId "@ANDROID_APPLICATION_ID@"
+ minSdk @ANDROID_MIN_SDK@
+ targetSdk @ANDROID_TARGET_SDK@
+ versionCode @ANDROID_VERSION_CODE@
+ versionName "@ANDROID_VERSION_NAME@"
+
+ ndk {
+ abiFilters 'arm64-v8a', 'x86_64'
+ }
+
+ externalNativeBuild {
+ cmake {
+ cppFlags '-std=c++20 -fvisibility=hidden -ffunction-sections -fdata-sections'
+ arguments '-DANDROID_STL=c++_static',
+ '-DBUILD_SHARED_LIBS=ON',
+ '-DCMAKE_BUILD_TYPE=Release',
+ '-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384'
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+ externalNativeBuild {
+ cmake {
+ // Point directly to the project root CMakeLists.txt
+ path file('@OPENGOTHIC_SOURCE_DIR@/CMakeLists.txt')
+ version '@ANDROID_CMAKE_VERSION@'
+ }
+ }
+
+ buildFeatures {
+ prefab true
+ }
+
+ sourceSets {
+ main {
+ manifest.srcFile '@ANDROID_BUILD_DIR@/app/src/main/AndroidManifest.xml'
+ }
+ }
+}
+
+dependencies {
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.games:games-activity:3.0.5'
+}
diff --git a/game/commandline.cpp b/game/commandline.cpp
index eda2039ba..6b4639535 100644
--- a/game/commandline.cpp
+++ b/game/commandline.cpp
@@ -225,13 +225,23 @@ std::u16string CommandLine::nestedPath(const std::initializer_list main;
-
+
/// Reverse direction (e.g. S or Down arrow)
std::array reverse;
@@ -108,7 +109,7 @@ class PlayerControl final {
}
return false;
}
-
+
/// Is any key pressed that activates the reverse direction
/// (e.g. S or Down arrow in Forward-Backward axis)
auto anyReverse() const -> bool {
@@ -120,7 +121,7 @@ class PlayerControl final {
};
struct MovementStatus {
- AxisStatus forwardBackward;
+ AxisStatus forwardBackward;
AxisStatus strafeRightLeft;
AxisStatus turnRightLeft;
@@ -131,7 +132,7 @@ class PlayerControl final {
this->turnRightLeft.reset();
}
} movement;
-
+
bool ctrl[Action::Last]={};
bool wctrl[WeaponAction::Last]={};
bool actrl[7]={};
@@ -142,6 +143,8 @@ class PlayerControl final {
Focus currentFocus;
float rotMouse=0;
float rotMouseY=0;
+ float gamepadLX=0;
+ float gamepadLY=0;
bool casting = false;
size_t pickLockProgress = 0;
@@ -180,17 +183,17 @@ class PlayerControl final {
//////////////////////////////////
auto wantsToMoveForward() const -> bool {
- return movement.forwardBackward.value() > 0.f;
+ return movement.forwardBackward.value() > 0.f || gamepadLY < -0.2f;
}
auto wantsToMoveBackward() const -> bool {
- return movement.forwardBackward.value() < 0.f;
+ return movement.forwardBackward.value() < 0.f || gamepadLY > 0.2f;
}
auto wantsToStrafeRight() const -> bool {
- return movement.strafeRightLeft.value() > 0.f;
+ return movement.strafeRightLeft.value() > 0.f || gamepadLX > 0.2f;
}
auto wantsToStrafeLeft() const -> bool {
- return movement.strafeRightLeft.value() < 0.f;
+ return movement.strafeRightLeft.value() < 0.f || gamepadLX < -0.2f;
}
auto wantsToTurnRight() const -> bool {
diff --git a/game/main.cpp b/game/main.cpp
index de00118e9..42603bc74 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -14,7 +14,7 @@
#include
#endif
-#if defined(__IOS__)
+#if defined(__IOS__) || defined(__ANDROID__)
#include "utils/installdetect.h"
#endif
@@ -53,7 +53,7 @@ std::unique_ptr mkApi(const CommandLine& g) {
break;
#endif
case CommandLine::Vulkan:
-#if !defined(__APPLE__)
+#if !defined(__APPLE__) || defined(__ANDROID__)
return std::make_unique(flg);
#else
break;
@@ -73,6 +73,13 @@ int main(int argc,const char** argv) {
auto appdir = InstallDetect::applicationSupportDirectory();
std::filesystem::current_path(appdir);
}
+#elif defined(__ANDROID__)
+ {
+ auto appdir = InstallDetect::applicationSupportDirectory();
+ if(!appdir.empty()) {
+ std::filesystem::current_path(appdir);
+ }
+ }
#endif
try {
diff --git a/game/mainwindow.cpp b/game/mainwindow.cpp
index 34985d74e..e59422113 100644
--- a/game/mainwindow.cpp
+++ b/game/mainwindow.cpp
@@ -26,6 +26,8 @@
#include "commandline.h"
#include "gothic.h"
+#include
+
using namespace Tempest;
MainWindow::MainWindow(Device& device)
@@ -281,8 +283,17 @@ void MainWindow::paintEvent(PaintEvent& event) {
void MainWindow::resizeEvent(SizeEvent&) {
for(auto& i:fence)
i.wait();
+
+ auto rectBefore = SystemApi::windowClientRect(hwnd());
+ Tempest::Log::i("MainWindow::resizeEvent: Starting resize - window: ", rectBefore.w, "x", rectBefore.h);
+
swapchain.reset();
renderer.resetSwapchain();
+
+ auto rectAfter = SystemApi::windowClientRect(hwnd());
+ Tempest::Log::i("MainWindow::resizeEvent: After swapchain reset - window: ", rectAfter.w, "x", rectAfter.h);
+ Tempest::Log::i("MainWindow::resizeEvent: Swapchain size: ", swapchain.w(), "x", swapchain.h());
+
if(auto camera = Gothic::inst().camera())
camera->setViewport(swapchain.w(),swapchain.h());
@@ -291,6 +302,8 @@ void MainWindow::resizeEvent(SizeEvent&) {
setCursorPosition(rect.w/2,rect.h/2);
setCursorShape(fs ? CursorShape::Hidden : CursorShape::Arrow);
dMouse = Point();
+
+ Tempest::Log::i("MainWindow::resizeEvent: Resize completed");
}
void MainWindow::mouseDownEvent(MouseEvent &event) {
@@ -369,6 +382,42 @@ void MainWindow::tickMouse(uint64_t dt) {
dMouse = Point();
}
+void MainWindow::tickGamepad() {
+ auto gp = SystemApi::gamepadState();
+ if(!gp.connected)
+ return;
+
+ auto camera = Gothic::inst().camera();
+ if(dialogs.hasContent() || Gothic::inst().isPause() || camera==nullptr || camera->isCutscene())
+ return;
+
+ const float deadzone = 0.15f;
+ const float sensitivity = 15.0f;
+
+ float rx = gp.rightStickX;
+ float ry = gp.rightStickY;
+
+ if(std::abs(rx) < deadzone) rx = 0.0f;
+ if(std::abs(ry) < deadzone) ry = 0.0f;
+
+ if(rx != 0.0f || ry != 0.0f) {
+ PointF dp(ry * sensitivity, -rx * sensitivity);
+ camera->onRotateMouse(dp);
+
+ if(!inventory.isActive()) {
+ player.onRotateMouse(-dp.y, dp.x);
+ }
+ }
+
+ float lx = gp.leftStickX;
+ float ly = gp.leftStickY;
+
+ if(std::abs(lx) < deadzone) lx = 0.0f;
+ if(std::abs(ly) < deadzone) ly = 0.0f;
+
+ player.setGamepadAxis(lx, ly);
+ }
+
void MainWindow::onSettings() {
auto zMaxFps = Gothic::options().fpsLimit;
if(zMaxFps<=0)
@@ -529,6 +578,7 @@ void MainWindow::keyUpEvent(KeyEvent &event) {
if(auto pl = Gothic::inst().player())
rootMenu.setPlayer(*pl);
clearInput();
+ //event.accept();
}
else if(act==KeyCodec::Inventory && !dialogs.isActive()) {
if(inventory.isActive()) {
@@ -892,6 +942,7 @@ uint64_t MainWindow::tick() {
else if(runtimeMode==R_Suspended) {
auto camera = Gothic::inst().camera();
if(camera!=nullptr && camera->isFree()) {
+ tickGamepad();
tickMouse(dt);
}
update();
@@ -907,7 +958,8 @@ uint64_t MainWindow::tick() {
;//clearInput();
if(document.isActive())
clearInput();
- tickMouse(dt);
+ tickMouse();
+ tickGamepad();
player.tickMove(dt);
update();
return dt;
diff --git a/game/mainwindow.h b/game/mainwindow.h
index 833e58894..a5ff720de 100644
--- a/game/mainwindow.h
+++ b/game/mainwindow.h
@@ -89,7 +89,8 @@ class MainWindow : public Tempest::Window {
void setFullscreen(bool fs);
void processMouse(Tempest::MouseEvent& event, bool enable);
- void tickMouse(uint64_t dt);
+ void tickMouse(uint64_t dt = 0);
+ void tickGamepad();
void onSettings();
void setupUi();
diff --git a/game/utils/crashlog.cpp b/game/utils/crashlog.cpp
index 4373f8ce0..f667931d6 100644
--- a/game/utils/crashlog.cpp
+++ b/game/utils/crashlog.cpp
@@ -14,7 +14,7 @@
#include
#endif
-#if defined(__LINUX__) || defined(__APPLE__)
+#if (defined(__LINUX__) || defined(__APPLE__)) && !defined(__ANDROID__)
#include // backtrace
#include // dladdr
#include // __cxa_demangle
@@ -167,7 +167,7 @@ void CrashLog::tracebackStd(std::ostream &out) {
}
void CrashLog::tracebackLinux(std::ostream &out) {
-#if defined(__LINUX__) || defined(__APPLE__)
+#if (defined(__LINUX__) || defined(__APPLE__)) && !defined(__ANDROID__)
// inspired by https://gist.github.com/fmela/591333/36faca4c2f68f7483cd0d3a357e8a8dd5f807edf (BSD)
void *callstack[64] = {};
char **symbols = nullptr;
diff --git a/game/utils/installdetect.cpp b/game/utils/installdetect.cpp
index 9c7f3de39..b15be3b0d 100644
--- a/game/utils/installdetect.cpp
+++ b/game/utils/installdetect.cpp
@@ -1,6 +1,7 @@
#include "installdetect.h"
#include
+#include
#ifdef __WINDOWS__
#include "windows.h"
@@ -8,7 +9,11 @@
#include "shlwapi.h"
#endif
-#include
+#ifdef __ANDROID__
+#include
+extern "C" struct android_app* tempest_android_get_app();
+#endif
+
#include "utils/fileutil.h"
InstallDetect::InstallDetect() {
@@ -16,7 +21,7 @@ InstallDetect::InstallDetect() {
pfiles = programFiles(false);
pfilesX86 = programFiles(true);
#endif
-#if defined(__OSX__) || defined(__IOS__)
+#if defined(__OSX__) || defined(__IOS__) || defined(__ANDROID__)
appDir = applicationSupportDirectory();
#endif
}
@@ -27,6 +32,14 @@ std::u16string InstallDetect::detectG2() {
if(ret.empty())
ret = detectG2(pfilesX86);
return ret;
+#elif defined(__ANDROID__)
+ // Check external storage
+ if(FileUtil::exists(u"/storage/emulated/0/Gothic2/"))
+ return u"/storage/emulated/0/Gothic2/";
+ // First check app's private data directory
+ if(FileUtil::exists(appDir))
+ return appDir;
+ return u"";
#elif defined(__OSX__) || defined(__IOS__)
if(FileUtil::exists(appDir))
return appDir;
@@ -62,3 +75,20 @@ std::u16string InstallDetect::programFiles(bool x86) {
return ret;
}
#endif
+
+#ifdef __ANDROID__
+std::u16string InstallDetect::applicationSupportDirectory() {
+ struct android_app* app = tempest_android_get_app();
+ if(app == nullptr || app->activity == nullptr)
+ return u"";
+
+ // Prefer external data path (accessible without root)
+ const char* path = app->activity->externalDataPath;
+ if(path == nullptr)
+ path = app->activity->internalDataPath;
+ if(path == nullptr)
+ return u"";
+
+ return Tempest::TextCodec::toUtf16(path);
+ }
+#endif
diff --git a/game/utils/installdetect.h b/game/utils/installdetect.h
index 140855660..fdf3709ce 100644
--- a/game/utils/installdetect.h
+++ b/game/utils/installdetect.h
@@ -8,7 +8,7 @@ class InstallDetect final {
InstallDetect();
std::u16string detectG2();
-#if defined(__OSX__) || defined(__IOS__)
+#if defined(__OSX__) || defined(__IOS__) || defined(__ANDROID__)
static std::u16string applicationSupportDirectory();
#endif
@@ -20,7 +20,7 @@ class InstallDetect final {
std::u16string pfiles, pfilesX86;
#endif
-#if defined(__OSX__) || defined(__IOS__)
+#if defined(__OSX__) || defined(__IOS__) || defined(__ANDROID__)
std::u16string appDir;
#endif
};
diff --git a/lib/Tempest b/lib/Tempest
index 4487b10b5..480afd888 160000
--- a/lib/Tempest
+++ b/lib/Tempest
@@ -1 +1 @@
-Subproject commit 4487b10b5991f7e3cc48978a9b5cf376e2546dae
+Subproject commit 480afd888eb4415b2c70e27f1697626feadfddca
diff --git a/shader/CMakeLists.txt b/shader/CMakeLists.txt
index 4eda6621a..461a2d5eb 100644
--- a/shader/CMakeLists.txt
+++ b/shader/CMakeLists.txt
@@ -6,18 +6,18 @@ set(HEADER "${PROJECT_BINARY_DIR}/sprv/shader.h")
set(CPP "${PROJECT_BINARY_DIR}/sprv/shader.cpp")
file(GLOB_RECURSE SOURCES
- "${CMAKE_SOURCE_DIR}/shader/*.vert"
- "${CMAKE_SOURCE_DIR}/shader/*.tesc"
- "${CMAKE_SOURCE_DIR}/shader/*.tese"
- "${CMAKE_SOURCE_DIR}/shader/*.geom"
- "${CMAKE_SOURCE_DIR}/shader/*.frag"
- "${CMAKE_SOURCE_DIR}/shader/*.glsl"
- "${CMAKE_SOURCE_DIR}/shader/*.task"
- "${CMAKE_SOURCE_DIR}/shader/*.mesh"
- "${CMAKE_SOURCE_DIR}/shader/*.comp")
+ "${CMAKE_CURRENT_LIST_DIR}/*.vert"
+ "${CMAKE_CURRENT_LIST_DIR}/*.tesc"
+ "${CMAKE_CURRENT_LIST_DIR}/*.tese"
+ "${CMAKE_CURRENT_LIST_DIR}/*.geom"
+ "${CMAKE_CURRENT_LIST_DIR}/*.frag"
+ "${CMAKE_CURRENT_LIST_DIR}/*.glsl"
+ "${CMAKE_CURRENT_LIST_DIR}/*.task"
+ "${CMAKE_CURRENT_LIST_DIR}/*.mesh"
+ "${CMAKE_CURRENT_LIST_DIR}/*.comp")
file(GLOB_RECURSE GLSL_SOURCES
- "${CMAKE_SOURCE_DIR}/shader/*.glsl")
+ "${CMAKE_CURRENT_LIST_DIR}/*.glsl")
# GLSL to SPIRV compiler
find_program(GLSLANGVALIDATOR glslangValidator "/opt/homebrew/bin")
@@ -27,7 +27,7 @@ endif()
function(add_shader OUTPUT SOURCE)
set(OUTPUT_FILE "${PROJECT_BINARY_DIR}/sprv/${OUTPUT}.sprv")
- set(SOURCE_FILE "${CMAKE_SOURCE_DIR}/shader/${SOURCE}")
+ set(SOURCE_FILE "${CMAKE_CURRENT_LIST_DIR}/${SOURCE}")
set(OPENGOTHIC_SHADERS ${OPENGOTHIC_SHADERS} ${SOURCE_FILE} PARENT_SCOPE)
set(OPENGOTHIC_SHADERS_SPRV ${OPENGOTHIC_SHADERS_SPRV} ${OUTPUT_FILE} PARENT_SCOPE)
@@ -67,7 +67,7 @@ function(add_shader OUTPUT SOURCE)
OUTPUT ${OUTPUT_FILE}
DEPENDS ${SOURCE_FILE} ${GLSL_SOURCES}
COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/sprv/"
- COMMAND ${GLSLANGVALIDATOR} -V ${VARS} -I"${CMAKE_SOURCE_DIR}/shader" "${SOURCE_FILE}" -o ${OUTPUT_FILE}
+ COMMAND ${GLSLANGVALIDATOR} -V ${VARS} -I"${CMAKE_CURRENT_LIST_DIR}" "${SOURCE_FILE}" -o ${OUTPUT_FILE}
)
endfunction(add_shader)
@@ -373,13 +373,13 @@ add_custom_command(
OUTPUT ${HEADER} ${CPP}
DEPENDS ${OPENGOTHIC_SHADERS_SPRV}
COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/sprv/"
- COMMAND ${CMAKE_COMMAND} -P "${CMAKE_SOURCE_DIR}/shader/link_shaders.cmake"
+ COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_LIST_DIR}/link_shaders.cmake"
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
)
add_custom_target(shader
DEPENDS ${HEADER} ${CPP}
- SOURCES ${SOURCES} "${CMAKE_SOURCE_DIR}/shader/link_shaders.cmake")
+ SOURCES ${SOURCES} "${CMAKE_CURRENT_LIST_DIR}/link_shaders.cmake")
add_library(${PROJECT_NAME} STATIC ${HEADER} ${CPP})
add_dependencies(${PROJECT_NAME} shader)