commit f65399ec53c475f41bbe1d4417052a1a19f1f15e Author: Digital Artifex <7929434+DigitalArtifex@users.noreply.github.com> Date: Sun Aug 3 18:41:56 2025 -0400 Initial Commit diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9b5ae0a --- /dev/null +++ b/.clang-format @@ -0,0 +1,95 @@ +--- +# SPDX-FileCopyrightText: 2019 Christoph Cullmann +# SPDX-FileCopyrightText: 2019 Gernot Gebhard +# +# SPDX-License-Identifier: MIT + +# This file got automatically created by ECM, do not edit +# See https://clang.llvm.org/docs/ClangFormatStyleOptions.html for the config options +# and https://community.kde.org/Policies/Frameworks_Coding_Style#Clang-format_automatic_code_formatting +# for clang-format tips & tricks +--- +Language: JavaScript +DisableFormat: true +--- +Language: Json +DisableFormat: false +IndentWidth: 4 +--- + +# Style for C++ +Language: Cpp + +# base is WebKit coding style: https://webkit.org/code-style-guidelines/ +# below are only things set that diverge from this style! +BasedOnStyle: WebKit + +# enforce C++11 (e.g. for std::vector> +Standard: Cpp11 + +# 4 spaces indent +TabWidth: 4 + +# 2 * 80 wide lines +ColumnLimit: 160 + +# sort includes inside line separated groups +SortIncludes: true + +# break before braces on function, namespace and class definitions. +BreakBeforeBraces: Linux + +# CrlInstruction *a; +PointerAlignment: Right + +# horizontally aligns arguments after an open bracket. +AlignAfterOpenBracket: Align + +# don't move all parameters to new line +AllowAllParametersOfDeclarationOnNextLine: false + +# no single line functions +AllowShortFunctionsOnASingleLine: None + +# no single line enums +AllowShortEnumsOnASingleLine: false + +# always break before you encounter multi line strings +AlwaysBreakBeforeMultilineStrings: true + +# don't move arguments to own lines if they are not all on the same +BinPackArguments: false + +# don't move parameters to own lines if they are not all on the same +BinPackParameters: false + +# In case we have an if statement with multiple lines the operator should be at the beginning of the line +# but we do not want to break assignments +BreakBeforeBinaryOperators: NonAssignment + +# format C++11 braced lists like function calls +Cpp11BracedListStyle: true + +# do not put a space before C++11 braced lists +SpaceBeforeCpp11BracedList: false + +# remove empty lines +KeepEmptyLinesAtTheStartOfBlocks: false + +# no namespace indentation to keep indent level low +NamespaceIndentation: None + +# we use template< without space. +SpaceAfterTemplateKeyword: false + +# Always break after template declaration +AlwaysBreakTemplateDeclarations: true + +# macros for which the opening brace stays attached. +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE , wl_resource_for_each, wl_resource_for_each_safe ] + +# keep lambda formatting multi-line if not empty +AllowShortLambdasOnASingleLine: Empty + +# We do not want clang-format to put all arguments on a new line +AllowAllArgumentsOnNextLine: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39b6e4e --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# C++ objects and libs +*.slo +*.lo +*.o +*.a +*.la +*.lai +*.so +*.so.* +*.dll +*.dylib + +# Qt-es +object_script.*.Release +object_script.*.Debug +*_plugin_import.cpp +/.qmake.cache +/.qmake.stash +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +*.qmlc +*.jsc +Makefile* +*build-* +*.qm +*.prl + +# Qt unit tests +target_wrapper.* + +# QtCreator +*.autosave + +# QtCreator Qml +*.qmlproject.user +*.qmlproject.user.* + +# QtCreator CMake +CMakeLists.txt.user* + +# QtCreator 4.8< compilation database +compile_commands.json + +# QtCreator local machine specific files for imported projects +*creator.user* + +*_qmlcache.qrc +build/* diff --git a/.kde-ci.yml b/.kde-ci.yml new file mode 100644 index 0000000..7b4a55a --- /dev/null +++ b/.kde-ci.yml @@ -0,0 +1,9 @@ +Dependencies: + - 'on': ['@all'] + 'require': + 'frameworks/extra-cmake-modules': '@same' + +Options: + test-before-installing: False + require-passing-tests-on: ['Linux', 'FreeBSD'] + cmake-options: -DBUILD_EXAMPLES=OFF diff --git a/.qmlls.ini b/.qmlls.ini new file mode 100644 index 0000000..a569cc0 --- /dev/null +++ b/.qmlls.ini @@ -0,0 +1,5 @@ +[General] +buildDir="/home/parametheus/kde/src/komplex/build/bin" +no-cmake-calls=false +docDir=/usr/share/doc/qt6 +importPaths="/usr/lib/qt6/qml" diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..95316cb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "files.associations": { + "qjsonarray": "cpp", + "qjsonobject": "cpp", + "qaudiodevice": "cpp", + "qjsondocument": "cpp", + "qjsonparseerror": "cpp", + "qmediarecorder": "cpp", + "qobject": "cpp", + "fstream": "cpp", + "array": "cpp", + "qqmlengine": "cpp", + "*.moc": "cpp", + "qeventloop": "cpp", + "qstandardpaths": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..157b491 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,62 @@ +cmake_minimum_required(VERSION 3.16) + +project(komplex VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +set(QT_QML_GENERATE_QMLLS_INI ON) +set(KF_MIN_VERSION "5.68.0") + +set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +if(NOT OpenGL_GL_PREFERENCE) + set(OpenGL_GL_PREFERENCE "GLVND") +endif() + +set(DEFAULT_BUILD_TYPE "RelWithDebInfo") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message( + STATUS + "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.") + set(CMAKE_BUILD_TYPE + "${DEFAULT_BUILD_TYPE}" + CACHE STRING "Choose the type of build." FORCE) +endif() + +find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(FeatureSummary) +include(ECMQtDeclareLoggingCategory) +include(ECMGenerateExportHeader) +include(ECMInstallIcons) +include(KDEPackageAppTemplates) +include(GenerateExportHeader) +include(CMakePackageConfigHelpers) +include(ECMDeprecationSettings) +include(ECMQmlModule) +include(GNUInstallDirs) + +find_package(Qt6 REQUIRED COMPONENTS Quick Core Gui Quick3D Qml Multimedia) + +find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS + CoreAddons # KAboutData + I18n # KLocalizedString + Package +) + +find_package(Plasma REQUIRED) +qt_standard_project_setup(REQUIRES 6.8) + +add_definitions(-DTRANSLATION_DOMAIN=\"plasma_wallpaper_com.github.digitalartifex.komplex\") + +set(QMLPLUGIN_URI "com.github.digitalartifex.komplex") +string(REPLACE "." "/" QMLPLUGIN_INSTALL_URI ${QMLPLUGIN_URI}) + +plasma_install_package(package ${QMLPLUGIN_URI} wallpapers wallpaper) +add_subdirectory(plugin) \ No newline at end of file diff --git a/REAME.md b/REAME.md new file mode 100644 index 0000000..e69de29 diff --git a/convo.txt b/convo.txt new file mode 100644 index 0000000..7a94b8b --- /dev/null +++ b/convo.txt @@ -0,0 +1,92 @@ +For KDE Plasma 6, C++ QML modules should be installed in standard Qt plugin paths so that both your application and QML engine can find them. Typically, you install them to: + +- System-wide: + `/usr/lib/qt6/qml/` + (or `/usr/lib64/qt6/qml/` on some distros) + +- User-local: + `~/.local/lib/qt6/qml/` + +For development, you can also set the `QML_IMPORT_PATH` environment variable to point to your custom module directory. + +If you are packaging for KDE, follow the conventions used by your distribution and KDE packaging guidelines. + +============================================================================================================= + +You can find the KDE packaging guidelines at the KDE Community Wiki: + +https://community.kde.org/Guidelines_and_HOWTOs/Packaging + +For distribution-specific instructions, refer to your distro's packaging documentation or the KDE pages for your distribution + +// +// Example QML plugin for Qt 6 +// + +#include +#include +#include + +class MyPluginClass : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) +public: + explicit MyPluginClass(QObject *parent = nullptr) : QObject(parent), m_message("Hello from plugin!") {} + + QString message() const { return m_message; } + void setMessage(const QString &msg) { + if (m_message != msg) { + m_message = msg; + emit messageChanged(); + } + } + +signals: + void messageChanged(); + +private: + QString m_message; +}; + +class MyPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + void registerTypes(const char *uri) override + { + // uri must match the import statement in QML + qmlRegisterType(uri, 1, 0, "MyPluginClass"); + } +}; + +#include "plugin.moc" + +# CMakeLists.txt for Qt 6 QML plugin + +cmake_minimum_required(VERSION 3.16) +project(MyQmlPlugin LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core Qml) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +add_library(MyQmlPlugin SHARED + plugin.cpp +) + +target_link_libraries(MyQmlPlugin PRIVATE Qt6::Core Qt6::Qml) + +set_target_properties(MyQmlPlugin PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml/MyQmlPlugin" + QT_QML_MODULE_VERSION 1.0 + QT_QML_MODULE_URI MyQmlPlugin +) + +install(TARGETS MyQmlPlugin + LIBRARY DESTINATION ${QT6_INSTALL_QMLDIR}/MyQmlPlugin +) \ No newline at end of file diff --git a/data/cubemaps/Areskutan/negx.jpg b/data/cubemaps/Areskutan/negx.jpg new file mode 100644 index 0000000..de6b047 Binary files /dev/null and b/data/cubemaps/Areskutan/negx.jpg differ diff --git a/data/cubemaps/Areskutan/negy.jpg b/data/cubemaps/Areskutan/negy.jpg new file mode 100644 index 0000000..2e2c49c Binary files /dev/null and b/data/cubemaps/Areskutan/negy.jpg differ diff --git a/data/cubemaps/Areskutan/negz.jpg b/data/cubemaps/Areskutan/negz.jpg new file mode 100644 index 0000000..1644aab Binary files /dev/null and b/data/cubemaps/Areskutan/negz.jpg differ diff --git a/data/cubemaps/Areskutan/posx.jpg b/data/cubemaps/Areskutan/posx.jpg new file mode 100644 index 0000000..96722d8 Binary files /dev/null and b/data/cubemaps/Areskutan/posx.jpg differ diff --git a/data/cubemaps/Areskutan/posy.jpg b/data/cubemaps/Areskutan/posy.jpg new file mode 100644 index 0000000..6c6c325 Binary files /dev/null and b/data/cubemaps/Areskutan/posy.jpg differ diff --git a/data/cubemaps/Areskutan/posz.jpg b/data/cubemaps/Areskutan/posz.jpg new file mode 100644 index 0000000..3bced1b Binary files /dev/null and b/data/cubemaps/Areskutan/posz.jpg differ diff --git a/data/cubemaps/Areskutan/readme.txt b/data/cubemaps/Areskutan/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Areskutan/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Citadella/negx.jpg b/data/cubemaps/Citadella/negx.jpg new file mode 100644 index 0000000..23833d7 Binary files /dev/null and b/data/cubemaps/Citadella/negx.jpg differ diff --git a/data/cubemaps/Citadella/negy.jpg b/data/cubemaps/Citadella/negy.jpg new file mode 100644 index 0000000..2fb87f6 Binary files /dev/null and b/data/cubemaps/Citadella/negy.jpg differ diff --git a/data/cubemaps/Citadella/negz.jpg b/data/cubemaps/Citadella/negz.jpg new file mode 100644 index 0000000..3f41898 Binary files /dev/null and b/data/cubemaps/Citadella/negz.jpg differ diff --git a/data/cubemaps/Citadella/posx.jpg b/data/cubemaps/Citadella/posx.jpg new file mode 100644 index 0000000..dd97e09 Binary files /dev/null and b/data/cubemaps/Citadella/posx.jpg differ diff --git a/data/cubemaps/Citadella/posy.jpg b/data/cubemaps/Citadella/posy.jpg new file mode 100644 index 0000000..3cb483f Binary files /dev/null and b/data/cubemaps/Citadella/posy.jpg differ diff --git a/data/cubemaps/Citadella/posz.jpg b/data/cubemaps/Citadella/posz.jpg new file mode 100644 index 0000000..4ac5a49 Binary files /dev/null and b/data/cubemaps/Citadella/posz.jpg differ diff --git a/data/cubemaps/Citadella/readme.txt b/data/cubemaps/Citadella/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Citadella/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Citadella2/negx.jpg b/data/cubemaps/Citadella2/negx.jpg new file mode 100644 index 0000000..2d85997 Binary files /dev/null and b/data/cubemaps/Citadella2/negx.jpg differ diff --git a/data/cubemaps/Citadella2/negy.jpg b/data/cubemaps/Citadella2/negy.jpg new file mode 100644 index 0000000..509a1dd Binary files /dev/null and b/data/cubemaps/Citadella2/negy.jpg differ diff --git a/data/cubemaps/Citadella2/negz.jpg b/data/cubemaps/Citadella2/negz.jpg new file mode 100644 index 0000000..92a3f43 Binary files /dev/null and b/data/cubemaps/Citadella2/negz.jpg differ diff --git a/data/cubemaps/Citadella2/posx.jpg b/data/cubemaps/Citadella2/posx.jpg new file mode 100644 index 0000000..b62b739 Binary files /dev/null and b/data/cubemaps/Citadella2/posx.jpg differ diff --git a/data/cubemaps/Citadella2/posy.jpg b/data/cubemaps/Citadella2/posy.jpg new file mode 100644 index 0000000..7684782 Binary files /dev/null and b/data/cubemaps/Citadella2/posy.jpg differ diff --git a/data/cubemaps/Citadella2/posz.jpg b/data/cubemaps/Citadella2/posz.jpg new file mode 100644 index 0000000..03a51de Binary files /dev/null and b/data/cubemaps/Citadella2/posz.jpg differ diff --git a/data/cubemaps/Citadella2/readme.txt b/data/cubemaps/Citadella2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Citadella2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/CoitTower/negx.jpg b/data/cubemaps/CoitTower/negx.jpg new file mode 100644 index 0000000..fb8a2b0 Binary files /dev/null and b/data/cubemaps/CoitTower/negx.jpg differ diff --git a/data/cubemaps/CoitTower/negy.jpg b/data/cubemaps/CoitTower/negy.jpg new file mode 100644 index 0000000..8322429 Binary files /dev/null and b/data/cubemaps/CoitTower/negy.jpg differ diff --git a/data/cubemaps/CoitTower/negz.jpg b/data/cubemaps/CoitTower/negz.jpg new file mode 100644 index 0000000..ab5b5f9 Binary files /dev/null and b/data/cubemaps/CoitTower/negz.jpg differ diff --git a/data/cubemaps/CoitTower/posx.jpg b/data/cubemaps/CoitTower/posx.jpg new file mode 100644 index 0000000..245d4db Binary files /dev/null and b/data/cubemaps/CoitTower/posx.jpg differ diff --git a/data/cubemaps/CoitTower/posy.jpg b/data/cubemaps/CoitTower/posy.jpg new file mode 100644 index 0000000..fd2be56 Binary files /dev/null and b/data/cubemaps/CoitTower/posy.jpg differ diff --git a/data/cubemaps/CoitTower/posz.jpg b/data/cubemaps/CoitTower/posz.jpg new file mode 100644 index 0000000..3265f4e Binary files /dev/null and b/data/cubemaps/CoitTower/posz.jpg differ diff --git a/data/cubemaps/CoitTower/readme.txt b/data/cubemaps/CoitTower/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/CoitTower/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/CoitTower2/negx.jpg b/data/cubemaps/CoitTower2/negx.jpg new file mode 100644 index 0000000..98bf035 Binary files /dev/null and b/data/cubemaps/CoitTower2/negx.jpg differ diff --git a/data/cubemaps/CoitTower2/negy.jpg b/data/cubemaps/CoitTower2/negy.jpg new file mode 100644 index 0000000..50952ec Binary files /dev/null and b/data/cubemaps/CoitTower2/negy.jpg differ diff --git a/data/cubemaps/CoitTower2/negz.jpg b/data/cubemaps/CoitTower2/negz.jpg new file mode 100644 index 0000000..c92d4f1 Binary files /dev/null and b/data/cubemaps/CoitTower2/negz.jpg differ diff --git a/data/cubemaps/CoitTower2/posx.jpg b/data/cubemaps/CoitTower2/posx.jpg new file mode 100644 index 0000000..4fb1743 Binary files /dev/null and b/data/cubemaps/CoitTower2/posx.jpg differ diff --git a/data/cubemaps/CoitTower2/posy.jpg b/data/cubemaps/CoitTower2/posy.jpg new file mode 100644 index 0000000..81971ee Binary files /dev/null and b/data/cubemaps/CoitTower2/posy.jpg differ diff --git a/data/cubemaps/CoitTower2/posz.jpg b/data/cubemaps/CoitTower2/posz.jpg new file mode 100644 index 0000000..2822466 Binary files /dev/null and b/data/cubemaps/CoitTower2/posz.jpg differ diff --git a/data/cubemaps/CoitTower2/readme.txt b/data/cubemaps/CoitTower2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/CoitTower2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Colosseum/negx.jpg b/data/cubemaps/Colosseum/negx.jpg new file mode 100644 index 0000000..60d5896 Binary files /dev/null and b/data/cubemaps/Colosseum/negx.jpg differ diff --git a/data/cubemaps/Colosseum/negy.jpg b/data/cubemaps/Colosseum/negy.jpg new file mode 100644 index 0000000..9b8de69 Binary files /dev/null and b/data/cubemaps/Colosseum/negy.jpg differ diff --git a/data/cubemaps/Colosseum/negz.jpg b/data/cubemaps/Colosseum/negz.jpg new file mode 100644 index 0000000..0a13140 Binary files /dev/null and b/data/cubemaps/Colosseum/negz.jpg differ diff --git a/data/cubemaps/Colosseum/posx.jpg b/data/cubemaps/Colosseum/posx.jpg new file mode 100644 index 0000000..86ed8a1 Binary files /dev/null and b/data/cubemaps/Colosseum/posx.jpg differ diff --git a/data/cubemaps/Colosseum/posy.jpg b/data/cubemaps/Colosseum/posy.jpg new file mode 100644 index 0000000..432683c Binary files /dev/null and b/data/cubemaps/Colosseum/posy.jpg differ diff --git a/data/cubemaps/Colosseum/posz.jpg b/data/cubemaps/Colosseum/posz.jpg new file mode 100644 index 0000000..7bc8a81 Binary files /dev/null and b/data/cubemaps/Colosseum/posz.jpg differ diff --git a/data/cubemaps/Colosseum/readme.txt b/data/cubemaps/Colosseum/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Colosseum/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/FishermansBastion/negx.jpg b/data/cubemaps/FishermansBastion/negx.jpg new file mode 100644 index 0000000..72e96bf Binary files /dev/null and b/data/cubemaps/FishermansBastion/negx.jpg differ diff --git a/data/cubemaps/FishermansBastion/negy.jpg b/data/cubemaps/FishermansBastion/negy.jpg new file mode 100644 index 0000000..44ec249 Binary files /dev/null and b/data/cubemaps/FishermansBastion/negy.jpg differ diff --git a/data/cubemaps/FishermansBastion/negz.jpg b/data/cubemaps/FishermansBastion/negz.jpg new file mode 100644 index 0000000..e77c120 Binary files /dev/null and b/data/cubemaps/FishermansBastion/negz.jpg differ diff --git a/data/cubemaps/FishermansBastion/posx.jpg b/data/cubemaps/FishermansBastion/posx.jpg new file mode 100644 index 0000000..8e6c578 Binary files /dev/null and b/data/cubemaps/FishermansBastion/posx.jpg differ diff --git a/data/cubemaps/FishermansBastion/posy.jpg b/data/cubemaps/FishermansBastion/posy.jpg new file mode 100644 index 0000000..54ff8f0 Binary files /dev/null and b/data/cubemaps/FishermansBastion/posy.jpg differ diff --git a/data/cubemaps/FishermansBastion/posz.jpg b/data/cubemaps/FishermansBastion/posz.jpg new file mode 100644 index 0000000..3990bfa Binary files /dev/null and b/data/cubemaps/FishermansBastion/posz.jpg differ diff --git a/data/cubemaps/FishermansBastion/readme.txt b/data/cubemaps/FishermansBastion/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/FishermansBastion/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Fjaderholmarna/negx.jpg b/data/cubemaps/Fjaderholmarna/negx.jpg new file mode 100644 index 0000000..c281415 Binary files /dev/null and b/data/cubemaps/Fjaderholmarna/negx.jpg differ diff --git a/data/cubemaps/Fjaderholmarna/negy.jpg b/data/cubemaps/Fjaderholmarna/negy.jpg new file mode 100644 index 0000000..d7a5767 Binary files /dev/null and b/data/cubemaps/Fjaderholmarna/negy.jpg differ diff --git a/data/cubemaps/Fjaderholmarna/negz.jpg b/data/cubemaps/Fjaderholmarna/negz.jpg new file mode 100644 index 0000000..749270f Binary files /dev/null and b/data/cubemaps/Fjaderholmarna/negz.jpg differ diff --git a/data/cubemaps/Fjaderholmarna/posx.jpg b/data/cubemaps/Fjaderholmarna/posx.jpg new file mode 100644 index 0000000..d5a9882 Binary files /dev/null and b/data/cubemaps/Fjaderholmarna/posx.jpg differ diff --git a/data/cubemaps/Fjaderholmarna/posy.jpg b/data/cubemaps/Fjaderholmarna/posy.jpg new file mode 100644 index 0000000..a6a7ae7 Binary files /dev/null and b/data/cubemaps/Fjaderholmarna/posy.jpg differ diff --git a/data/cubemaps/Fjaderholmarna/posz.jpg b/data/cubemaps/Fjaderholmarna/posz.jpg new file mode 100644 index 0000000..292ed69 Binary files /dev/null and b/data/cubemaps/Fjaderholmarna/posz.jpg differ diff --git a/data/cubemaps/Fjaderholmarna/readme.txt b/data/cubemaps/Fjaderholmarna/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Fjaderholmarna/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/FortPoint/negx.jpg b/data/cubemaps/FortPoint/negx.jpg new file mode 100644 index 0000000..0294b40 Binary files /dev/null and b/data/cubemaps/FortPoint/negx.jpg differ diff --git a/data/cubemaps/FortPoint/negy.jpg b/data/cubemaps/FortPoint/negy.jpg new file mode 100644 index 0000000..c6ae29b Binary files /dev/null and b/data/cubemaps/FortPoint/negy.jpg differ diff --git a/data/cubemaps/FortPoint/negz.jpg b/data/cubemaps/FortPoint/negz.jpg new file mode 100644 index 0000000..07a1b3e Binary files /dev/null and b/data/cubemaps/FortPoint/negz.jpg differ diff --git a/data/cubemaps/FortPoint/posx.jpg b/data/cubemaps/FortPoint/posx.jpg new file mode 100644 index 0000000..b5f683a Binary files /dev/null and b/data/cubemaps/FortPoint/posx.jpg differ diff --git a/data/cubemaps/FortPoint/posy.jpg b/data/cubemaps/FortPoint/posy.jpg new file mode 100644 index 0000000..4764998 Binary files /dev/null and b/data/cubemaps/FortPoint/posy.jpg differ diff --git a/data/cubemaps/FortPoint/posz.jpg b/data/cubemaps/FortPoint/posz.jpg new file mode 100644 index 0000000..baff4d8 Binary files /dev/null and b/data/cubemaps/FortPoint/posz.jpg differ diff --git a/data/cubemaps/FortPoint/readme.txt b/data/cubemaps/FortPoint/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/FortPoint/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/GoldenGateBridge/negx.jpg b/data/cubemaps/GoldenGateBridge/negx.jpg new file mode 100644 index 0000000..a475456 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge/negx.jpg differ diff --git a/data/cubemaps/GoldenGateBridge/negy.jpg b/data/cubemaps/GoldenGateBridge/negy.jpg new file mode 100644 index 0000000..49b6a13 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge/negy.jpg differ diff --git a/data/cubemaps/GoldenGateBridge/negz.jpg b/data/cubemaps/GoldenGateBridge/negz.jpg new file mode 100644 index 0000000..2d6e124 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge/negz.jpg differ diff --git a/data/cubemaps/GoldenGateBridge/posx.jpg b/data/cubemaps/GoldenGateBridge/posx.jpg new file mode 100644 index 0000000..34f3d24 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge/posx.jpg differ diff --git a/data/cubemaps/GoldenGateBridge/posy.jpg b/data/cubemaps/GoldenGateBridge/posy.jpg new file mode 100644 index 0000000..08c335c Binary files /dev/null and b/data/cubemaps/GoldenGateBridge/posy.jpg differ diff --git a/data/cubemaps/GoldenGateBridge/posz.jpg b/data/cubemaps/GoldenGateBridge/posz.jpg new file mode 100644 index 0000000..f8fba17 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge/posz.jpg differ diff --git a/data/cubemaps/GoldenGateBridge/readme.txt b/data/cubemaps/GoldenGateBridge/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/GoldenGateBridge/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/GoldenGateBridge2/negx.jpg b/data/cubemaps/GoldenGateBridge2/negx.jpg new file mode 100644 index 0000000..4a0a2f1 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge2/negx.jpg differ diff --git a/data/cubemaps/GoldenGateBridge2/negy.jpg b/data/cubemaps/GoldenGateBridge2/negy.jpg new file mode 100644 index 0000000..6152352 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge2/negy.jpg differ diff --git a/data/cubemaps/GoldenGateBridge2/negz.jpg b/data/cubemaps/GoldenGateBridge2/negz.jpg new file mode 100644 index 0000000..68120c2 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge2/negz.jpg differ diff --git a/data/cubemaps/GoldenGateBridge2/posx.jpg b/data/cubemaps/GoldenGateBridge2/posx.jpg new file mode 100644 index 0000000..d041ba5 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge2/posx.jpg differ diff --git a/data/cubemaps/GoldenGateBridge2/posy.jpg b/data/cubemaps/GoldenGateBridge2/posy.jpg new file mode 100644 index 0000000..778e123 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge2/posy.jpg differ diff --git a/data/cubemaps/GoldenGateBridge2/posz.jpg b/data/cubemaps/GoldenGateBridge2/posz.jpg new file mode 100644 index 0000000..1ed0c23 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge2/posz.jpg differ diff --git a/data/cubemaps/GoldenGateBridge2/readme.txt b/data/cubemaps/GoldenGateBridge2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/GoldenGateBridge2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/GoldenGateBridge3/negx.jpg b/data/cubemaps/GoldenGateBridge3/negx.jpg new file mode 100644 index 0000000..d518e76 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge3/negx.jpg differ diff --git a/data/cubemaps/GoldenGateBridge3/negy.jpg b/data/cubemaps/GoldenGateBridge3/negy.jpg new file mode 100644 index 0000000..a02946a Binary files /dev/null and b/data/cubemaps/GoldenGateBridge3/negy.jpg differ diff --git a/data/cubemaps/GoldenGateBridge3/negz.jpg b/data/cubemaps/GoldenGateBridge3/negz.jpg new file mode 100644 index 0000000..9e28647 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge3/negz.jpg differ diff --git a/data/cubemaps/GoldenGateBridge3/posx.jpg b/data/cubemaps/GoldenGateBridge3/posx.jpg new file mode 100644 index 0000000..5e8fa40 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge3/posx.jpg differ diff --git a/data/cubemaps/GoldenGateBridge3/posy.jpg b/data/cubemaps/GoldenGateBridge3/posy.jpg new file mode 100644 index 0000000..5762534 Binary files /dev/null and b/data/cubemaps/GoldenGateBridge3/posy.jpg differ diff --git a/data/cubemaps/GoldenGateBridge3/posz.jpg b/data/cubemaps/GoldenGateBridge3/posz.jpg new file mode 100644 index 0000000..d8c1cce Binary files /dev/null and b/data/cubemaps/GoldenGateBridge3/posz.jpg differ diff --git a/data/cubemaps/GoldenGateBridge3/readme.txt b/data/cubemaps/GoldenGateBridge3/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/GoldenGateBridge3/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/HeroesSquare/negx.jpg b/data/cubemaps/HeroesSquare/negx.jpg new file mode 100644 index 0000000..d72ef4e Binary files /dev/null and b/data/cubemaps/HeroesSquare/negx.jpg differ diff --git a/data/cubemaps/HeroesSquare/negy.jpg b/data/cubemaps/HeroesSquare/negy.jpg new file mode 100644 index 0000000..be1f10e Binary files /dev/null and b/data/cubemaps/HeroesSquare/negy.jpg differ diff --git a/data/cubemaps/HeroesSquare/negz.jpg b/data/cubemaps/HeroesSquare/negz.jpg new file mode 100644 index 0000000..79b60fa Binary files /dev/null and b/data/cubemaps/HeroesSquare/negz.jpg differ diff --git a/data/cubemaps/HeroesSquare/posx.jpg b/data/cubemaps/HeroesSquare/posx.jpg new file mode 100644 index 0000000..331988e Binary files /dev/null and b/data/cubemaps/HeroesSquare/posx.jpg differ diff --git a/data/cubemaps/HeroesSquare/posy.jpg b/data/cubemaps/HeroesSquare/posy.jpg new file mode 100644 index 0000000..1d7f861 Binary files /dev/null and b/data/cubemaps/HeroesSquare/posy.jpg differ diff --git a/data/cubemaps/HeroesSquare/posz.jpg b/data/cubemaps/HeroesSquare/posz.jpg new file mode 100644 index 0000000..aeb05ff Binary files /dev/null and b/data/cubemaps/HeroesSquare/posz.jpg differ diff --git a/data/cubemaps/HeroesSquare/readme.txt b/data/cubemaps/HeroesSquare/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/HeroesSquare/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/LancellottiChapel/negx.jpg b/data/cubemaps/LancellottiChapel/negx.jpg new file mode 100644 index 0000000..827515c Binary files /dev/null and b/data/cubemaps/LancellottiChapel/negx.jpg differ diff --git a/data/cubemaps/LancellottiChapel/negy.jpg b/data/cubemaps/LancellottiChapel/negy.jpg new file mode 100644 index 0000000..1ada940 Binary files /dev/null and b/data/cubemaps/LancellottiChapel/negy.jpg differ diff --git a/data/cubemaps/LancellottiChapel/negz.jpg b/data/cubemaps/LancellottiChapel/negz.jpg new file mode 100644 index 0000000..63e39fa Binary files /dev/null and b/data/cubemaps/LancellottiChapel/negz.jpg differ diff --git a/data/cubemaps/LancellottiChapel/posx.jpg b/data/cubemaps/LancellottiChapel/posx.jpg new file mode 100644 index 0000000..797bfcb Binary files /dev/null and b/data/cubemaps/LancellottiChapel/posx.jpg differ diff --git a/data/cubemaps/LancellottiChapel/posy.jpg b/data/cubemaps/LancellottiChapel/posy.jpg new file mode 100644 index 0000000..f3154d6 Binary files /dev/null and b/data/cubemaps/LancellottiChapel/posy.jpg differ diff --git a/data/cubemaps/LancellottiChapel/posz.jpg b/data/cubemaps/LancellottiChapel/posz.jpg new file mode 100644 index 0000000..f9d7717 Binary files /dev/null and b/data/cubemaps/LancellottiChapel/posz.jpg differ diff --git a/data/cubemaps/LancellottiChapel/readme.txt b/data/cubemaps/LancellottiChapel/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/LancellottiChapel/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Lycksele/negx.jpg b/data/cubemaps/Lycksele/negx.jpg new file mode 100644 index 0000000..aa7df6a Binary files /dev/null and b/data/cubemaps/Lycksele/negx.jpg differ diff --git a/data/cubemaps/Lycksele/negy.jpg b/data/cubemaps/Lycksele/negy.jpg new file mode 100644 index 0000000..1f37096 Binary files /dev/null and b/data/cubemaps/Lycksele/negy.jpg differ diff --git a/data/cubemaps/Lycksele/negz.jpg b/data/cubemaps/Lycksele/negz.jpg new file mode 100644 index 0000000..f5f2982 Binary files /dev/null and b/data/cubemaps/Lycksele/negz.jpg differ diff --git a/data/cubemaps/Lycksele/posx.jpg b/data/cubemaps/Lycksele/posx.jpg new file mode 100644 index 0000000..e7949e8 Binary files /dev/null and b/data/cubemaps/Lycksele/posx.jpg differ diff --git a/data/cubemaps/Lycksele/posy.jpg b/data/cubemaps/Lycksele/posy.jpg new file mode 100644 index 0000000..92d04c4 Binary files /dev/null and b/data/cubemaps/Lycksele/posy.jpg differ diff --git a/data/cubemaps/Lycksele/posz.jpg b/data/cubemaps/Lycksele/posz.jpg new file mode 100644 index 0000000..ddc17cf Binary files /dev/null and b/data/cubemaps/Lycksele/posz.jpg differ diff --git a/data/cubemaps/Lycksele/readme.txt b/data/cubemaps/Lycksele/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Lycksele/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Lycksele2/negx.jpg b/data/cubemaps/Lycksele2/negx.jpg new file mode 100644 index 0000000..276154a Binary files /dev/null and b/data/cubemaps/Lycksele2/negx.jpg differ diff --git a/data/cubemaps/Lycksele2/negy.jpg b/data/cubemaps/Lycksele2/negy.jpg new file mode 100644 index 0000000..5042bcc Binary files /dev/null and b/data/cubemaps/Lycksele2/negy.jpg differ diff --git a/data/cubemaps/Lycksele2/negz.jpg b/data/cubemaps/Lycksele2/negz.jpg new file mode 100644 index 0000000..bf3984e Binary files /dev/null and b/data/cubemaps/Lycksele2/negz.jpg differ diff --git a/data/cubemaps/Lycksele2/posx.jpg b/data/cubemaps/Lycksele2/posx.jpg new file mode 100644 index 0000000..904081a Binary files /dev/null and b/data/cubemaps/Lycksele2/posx.jpg differ diff --git a/data/cubemaps/Lycksele2/posy.jpg b/data/cubemaps/Lycksele2/posy.jpg new file mode 100644 index 0000000..ed0e13c Binary files /dev/null and b/data/cubemaps/Lycksele2/posy.jpg differ diff --git a/data/cubemaps/Lycksele2/posz.jpg b/data/cubemaps/Lycksele2/posz.jpg new file mode 100644 index 0000000..3acbe80 Binary files /dev/null and b/data/cubemaps/Lycksele2/posz.jpg differ diff --git a/data/cubemaps/Lycksele2/readme.txt b/data/cubemaps/Lycksele2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Lycksele2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Lycksele3/negx.jpg b/data/cubemaps/Lycksele3/negx.jpg new file mode 100644 index 0000000..1b0257f Binary files /dev/null and b/data/cubemaps/Lycksele3/negx.jpg differ diff --git a/data/cubemaps/Lycksele3/negy.jpg b/data/cubemaps/Lycksele3/negy.jpg new file mode 100644 index 0000000..be1573f Binary files /dev/null and b/data/cubemaps/Lycksele3/negy.jpg differ diff --git a/data/cubemaps/Lycksele3/negz.jpg b/data/cubemaps/Lycksele3/negz.jpg new file mode 100644 index 0000000..7e65e12 Binary files /dev/null and b/data/cubemaps/Lycksele3/negz.jpg differ diff --git a/data/cubemaps/Lycksele3/posx.jpg b/data/cubemaps/Lycksele3/posx.jpg new file mode 100644 index 0000000..a587a2c Binary files /dev/null and b/data/cubemaps/Lycksele3/posx.jpg differ diff --git a/data/cubemaps/Lycksele3/posy.jpg b/data/cubemaps/Lycksele3/posy.jpg new file mode 100644 index 0000000..f87ca16 Binary files /dev/null and b/data/cubemaps/Lycksele3/posy.jpg differ diff --git a/data/cubemaps/Lycksele3/posz.jpg b/data/cubemaps/Lycksele3/posz.jpg new file mode 100644 index 0000000..bdda7a3 Binary files /dev/null and b/data/cubemaps/Lycksele3/posz.jpg differ diff --git a/data/cubemaps/Lycksele3/readme.txt b/data/cubemaps/Lycksele3/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Lycksele3/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/PereaBeach1/negx.jpg b/data/cubemaps/PereaBeach1/negx.jpg new file mode 100644 index 0000000..6e1b59b Binary files /dev/null and b/data/cubemaps/PereaBeach1/negx.jpg differ diff --git a/data/cubemaps/PereaBeach1/negy.jpg b/data/cubemaps/PereaBeach1/negy.jpg new file mode 100644 index 0000000..45e3ff5 Binary files /dev/null and b/data/cubemaps/PereaBeach1/negy.jpg differ diff --git a/data/cubemaps/PereaBeach1/negz.jpg b/data/cubemaps/PereaBeach1/negz.jpg new file mode 100644 index 0000000..a1eee3b Binary files /dev/null and b/data/cubemaps/PereaBeach1/negz.jpg differ diff --git a/data/cubemaps/PereaBeach1/posx.jpg b/data/cubemaps/PereaBeach1/posx.jpg new file mode 100644 index 0000000..aa25d45 Binary files /dev/null and b/data/cubemaps/PereaBeach1/posx.jpg differ diff --git a/data/cubemaps/PereaBeach1/posy.jpg b/data/cubemaps/PereaBeach1/posy.jpg new file mode 100644 index 0000000..f2f92d2 Binary files /dev/null and b/data/cubemaps/PereaBeach1/posy.jpg differ diff --git a/data/cubemaps/PereaBeach1/posz.jpg b/data/cubemaps/PereaBeach1/posz.jpg new file mode 100644 index 0000000..56906f8 Binary files /dev/null and b/data/cubemaps/PereaBeach1/posz.jpg differ diff --git a/data/cubemaps/PereaBeach1/readme.txt b/data/cubemaps/PereaBeach1/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/PereaBeach1/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/PereaBeach2/negx.jpg b/data/cubemaps/PereaBeach2/negx.jpg new file mode 100644 index 0000000..bf7a9c1 Binary files /dev/null and b/data/cubemaps/PereaBeach2/negx.jpg differ diff --git a/data/cubemaps/PereaBeach2/negy.jpg b/data/cubemaps/PereaBeach2/negy.jpg new file mode 100644 index 0000000..ec91662 Binary files /dev/null and b/data/cubemaps/PereaBeach2/negy.jpg differ diff --git a/data/cubemaps/PereaBeach2/negz.jpg b/data/cubemaps/PereaBeach2/negz.jpg new file mode 100644 index 0000000..c840bb6 Binary files /dev/null and b/data/cubemaps/PereaBeach2/negz.jpg differ diff --git a/data/cubemaps/PereaBeach2/posx.jpg b/data/cubemaps/PereaBeach2/posx.jpg new file mode 100644 index 0000000..0b71e3f Binary files /dev/null and b/data/cubemaps/PereaBeach2/posx.jpg differ diff --git a/data/cubemaps/PereaBeach2/posy.jpg b/data/cubemaps/PereaBeach2/posy.jpg new file mode 100644 index 0000000..e0aebb2 Binary files /dev/null and b/data/cubemaps/PereaBeach2/posy.jpg differ diff --git a/data/cubemaps/PereaBeach2/posz.jpg b/data/cubemaps/PereaBeach2/posz.jpg new file mode 100644 index 0000000..bb79d72 Binary files /dev/null and b/data/cubemaps/PereaBeach2/posz.jpg differ diff --git a/data/cubemaps/PereaBeach2/readme.txt b/data/cubemaps/PereaBeach2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/PereaBeach2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/SaintPetersSquare3/negx.jpg b/data/cubemaps/SaintPetersSquare3/negx.jpg new file mode 100644 index 0000000..27e515f Binary files /dev/null and b/data/cubemaps/SaintPetersSquare3/negx.jpg differ diff --git a/data/cubemaps/SaintPetersSquare3/negy.jpg b/data/cubemaps/SaintPetersSquare3/negy.jpg new file mode 100644 index 0000000..0f44e25 Binary files /dev/null and b/data/cubemaps/SaintPetersSquare3/negy.jpg differ diff --git a/data/cubemaps/SaintPetersSquare3/negz.jpg b/data/cubemaps/SaintPetersSquare3/negz.jpg new file mode 100644 index 0000000..50e7bc3 Binary files /dev/null and b/data/cubemaps/SaintPetersSquare3/negz.jpg differ diff --git a/data/cubemaps/SaintPetersSquare3/posx.jpg b/data/cubemaps/SaintPetersSquare3/posx.jpg new file mode 100644 index 0000000..4283cbe Binary files /dev/null and b/data/cubemaps/SaintPetersSquare3/posx.jpg differ diff --git a/data/cubemaps/SaintPetersSquare3/posy.jpg b/data/cubemaps/SaintPetersSquare3/posy.jpg new file mode 100644 index 0000000..2e667b2 Binary files /dev/null and b/data/cubemaps/SaintPetersSquare3/posy.jpg differ diff --git a/data/cubemaps/SaintPetersSquare3/posz.jpg b/data/cubemaps/SaintPetersSquare3/posz.jpg new file mode 100644 index 0000000..0adbf36 Binary files /dev/null and b/data/cubemaps/SaintPetersSquare3/posz.jpg differ diff --git a/data/cubemaps/SaintPetersSquare3/readme.txt b/data/cubemaps/SaintPetersSquare3/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/SaintPetersSquare3/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/SanFrancisco/negx.jpg b/data/cubemaps/SanFrancisco/negx.jpg new file mode 100644 index 0000000..17dbb70 Binary files /dev/null and b/data/cubemaps/SanFrancisco/negx.jpg differ diff --git a/data/cubemaps/SanFrancisco/negy.jpg b/data/cubemaps/SanFrancisco/negy.jpg new file mode 100644 index 0000000..26ce6a8 Binary files /dev/null and b/data/cubemaps/SanFrancisco/negy.jpg differ diff --git a/data/cubemaps/SanFrancisco/negz.jpg b/data/cubemaps/SanFrancisco/negz.jpg new file mode 100644 index 0000000..5d815db Binary files /dev/null and b/data/cubemaps/SanFrancisco/negz.jpg differ diff --git a/data/cubemaps/SanFrancisco/posx.jpg b/data/cubemaps/SanFrancisco/posx.jpg new file mode 100644 index 0000000..ce56f20 Binary files /dev/null and b/data/cubemaps/SanFrancisco/posx.jpg differ diff --git a/data/cubemaps/SanFrancisco/posy.jpg b/data/cubemaps/SanFrancisco/posy.jpg new file mode 100644 index 0000000..4e67f10 Binary files /dev/null and b/data/cubemaps/SanFrancisco/posy.jpg differ diff --git a/data/cubemaps/SanFrancisco/posz.jpg b/data/cubemaps/SanFrancisco/posz.jpg new file mode 100644 index 0000000..7c7dd7a Binary files /dev/null and b/data/cubemaps/SanFrancisco/posz.jpg differ diff --git a/data/cubemaps/SanFrancisco/readme.txt b/data/cubemaps/SanFrancisco/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/SanFrancisco/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/SanFrancisco2/negx.jpg b/data/cubemaps/SanFrancisco2/negx.jpg new file mode 100644 index 0000000..4cd2ac7 Binary files /dev/null and b/data/cubemaps/SanFrancisco2/negx.jpg differ diff --git a/data/cubemaps/SanFrancisco2/negy.jpg b/data/cubemaps/SanFrancisco2/negy.jpg new file mode 100644 index 0000000..97f1123 Binary files /dev/null and b/data/cubemaps/SanFrancisco2/negy.jpg differ diff --git a/data/cubemaps/SanFrancisco2/negz.jpg b/data/cubemaps/SanFrancisco2/negz.jpg new file mode 100644 index 0000000..5cbbb6a Binary files /dev/null and b/data/cubemaps/SanFrancisco2/negz.jpg differ diff --git a/data/cubemaps/SanFrancisco2/posx.jpg b/data/cubemaps/SanFrancisco2/posx.jpg new file mode 100644 index 0000000..a998dd7 Binary files /dev/null and b/data/cubemaps/SanFrancisco2/posx.jpg differ diff --git a/data/cubemaps/SanFrancisco2/posy.jpg b/data/cubemaps/SanFrancisco2/posy.jpg new file mode 100644 index 0000000..25e2542 Binary files /dev/null and b/data/cubemaps/SanFrancisco2/posy.jpg differ diff --git a/data/cubemaps/SanFrancisco2/posz.jpg b/data/cubemaps/SanFrancisco2/posz.jpg new file mode 100644 index 0000000..f0c91d9 Binary files /dev/null and b/data/cubemaps/SanFrancisco2/posz.jpg differ diff --git a/data/cubemaps/SanFrancisco2/readme.txt b/data/cubemaps/SanFrancisco2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/SanFrancisco2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/SanFrancisco3/negx.jpg b/data/cubemaps/SanFrancisco3/negx.jpg new file mode 100644 index 0000000..10c6142 Binary files /dev/null and b/data/cubemaps/SanFrancisco3/negx.jpg differ diff --git a/data/cubemaps/SanFrancisco3/negy.jpg b/data/cubemaps/SanFrancisco3/negy.jpg new file mode 100644 index 0000000..9ceb10e Binary files /dev/null and b/data/cubemaps/SanFrancisco3/negy.jpg differ diff --git a/data/cubemaps/SanFrancisco3/negz.jpg b/data/cubemaps/SanFrancisco3/negz.jpg new file mode 100644 index 0000000..ab6a2e2 Binary files /dev/null and b/data/cubemaps/SanFrancisco3/negz.jpg differ diff --git a/data/cubemaps/SanFrancisco3/posx.jpg b/data/cubemaps/SanFrancisco3/posx.jpg new file mode 100644 index 0000000..3887309 Binary files /dev/null and b/data/cubemaps/SanFrancisco3/posx.jpg differ diff --git a/data/cubemaps/SanFrancisco3/posy.jpg b/data/cubemaps/SanFrancisco3/posy.jpg new file mode 100644 index 0000000..0bce419 Binary files /dev/null and b/data/cubemaps/SanFrancisco3/posy.jpg differ diff --git a/data/cubemaps/SanFrancisco3/posz.jpg b/data/cubemaps/SanFrancisco3/posz.jpg new file mode 100644 index 0000000..a7c77ac Binary files /dev/null and b/data/cubemaps/SanFrancisco3/posz.jpg differ diff --git a/data/cubemaps/SanFrancisco3/readme.txt b/data/cubemaps/SanFrancisco3/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/SanFrancisco3/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/SanFrancisco4/negx.jpg b/data/cubemaps/SanFrancisco4/negx.jpg new file mode 100644 index 0000000..7a3ccda Binary files /dev/null and b/data/cubemaps/SanFrancisco4/negx.jpg differ diff --git a/data/cubemaps/SanFrancisco4/negy.jpg b/data/cubemaps/SanFrancisco4/negy.jpg new file mode 100644 index 0000000..10c61f4 Binary files /dev/null and b/data/cubemaps/SanFrancisco4/negy.jpg differ diff --git a/data/cubemaps/SanFrancisco4/negz.jpg b/data/cubemaps/SanFrancisco4/negz.jpg new file mode 100644 index 0000000..11ad904 Binary files /dev/null and b/data/cubemaps/SanFrancisco4/negz.jpg differ diff --git a/data/cubemaps/SanFrancisco4/posx.jpg b/data/cubemaps/SanFrancisco4/posx.jpg new file mode 100644 index 0000000..67e1202 Binary files /dev/null and b/data/cubemaps/SanFrancisco4/posx.jpg differ diff --git a/data/cubemaps/SanFrancisco4/posy.jpg b/data/cubemaps/SanFrancisco4/posy.jpg new file mode 100644 index 0000000..8a59280 Binary files /dev/null and b/data/cubemaps/SanFrancisco4/posy.jpg differ diff --git a/data/cubemaps/SanFrancisco4/posz.jpg b/data/cubemaps/SanFrancisco4/posz.jpg new file mode 100644 index 0000000..70c5a55 Binary files /dev/null and b/data/cubemaps/SanFrancisco4/posz.jpg differ diff --git a/data/cubemaps/SanFrancisco4/readme.txt b/data/cubemaps/SanFrancisco4/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/SanFrancisco4/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Storforsen/negx.jpg b/data/cubemaps/Storforsen/negx.jpg new file mode 100644 index 0000000..9f0882d Binary files /dev/null and b/data/cubemaps/Storforsen/negx.jpg differ diff --git a/data/cubemaps/Storforsen/negy.jpg b/data/cubemaps/Storforsen/negy.jpg new file mode 100644 index 0000000..a41d558 Binary files /dev/null and b/data/cubemaps/Storforsen/negy.jpg differ diff --git a/data/cubemaps/Storforsen/negz.jpg b/data/cubemaps/Storforsen/negz.jpg new file mode 100644 index 0000000..f38894b Binary files /dev/null and b/data/cubemaps/Storforsen/negz.jpg differ diff --git a/data/cubemaps/Storforsen/posx.jpg b/data/cubemaps/Storforsen/posx.jpg new file mode 100644 index 0000000..cda7da8 Binary files /dev/null and b/data/cubemaps/Storforsen/posx.jpg differ diff --git a/data/cubemaps/Storforsen/posy.jpg b/data/cubemaps/Storforsen/posy.jpg new file mode 100644 index 0000000..a1910be Binary files /dev/null and b/data/cubemaps/Storforsen/posy.jpg differ diff --git a/data/cubemaps/Storforsen/posz.jpg b/data/cubemaps/Storforsen/posz.jpg new file mode 100644 index 0000000..d3c53b0 Binary files /dev/null and b/data/cubemaps/Storforsen/posz.jpg differ diff --git a/data/cubemaps/Storforsen/readme.txt b/data/cubemaps/Storforsen/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Storforsen/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Storforsen2/negx.jpg b/data/cubemaps/Storforsen2/negx.jpg new file mode 100644 index 0000000..aaf583e Binary files /dev/null and b/data/cubemaps/Storforsen2/negx.jpg differ diff --git a/data/cubemaps/Storforsen2/negy.jpg b/data/cubemaps/Storforsen2/negy.jpg new file mode 100644 index 0000000..fcaf862 Binary files /dev/null and b/data/cubemaps/Storforsen2/negy.jpg differ diff --git a/data/cubemaps/Storforsen2/negz.jpg b/data/cubemaps/Storforsen2/negz.jpg new file mode 100644 index 0000000..7704fec Binary files /dev/null and b/data/cubemaps/Storforsen2/negz.jpg differ diff --git a/data/cubemaps/Storforsen2/posx.jpg b/data/cubemaps/Storforsen2/posx.jpg new file mode 100644 index 0000000..f3e7d1d Binary files /dev/null and b/data/cubemaps/Storforsen2/posx.jpg differ diff --git a/data/cubemaps/Storforsen2/posy.jpg b/data/cubemaps/Storforsen2/posy.jpg new file mode 100644 index 0000000..6ede7cb Binary files /dev/null and b/data/cubemaps/Storforsen2/posy.jpg differ diff --git a/data/cubemaps/Storforsen2/posz.jpg b/data/cubemaps/Storforsen2/posz.jpg new file mode 100644 index 0000000..35885b8 Binary files /dev/null and b/data/cubemaps/Storforsen2/posz.jpg differ diff --git a/data/cubemaps/Storforsen2/readme.txt b/data/cubemaps/Storforsen2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Storforsen2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Storforsen3/negx.jpg b/data/cubemaps/Storforsen3/negx.jpg new file mode 100644 index 0000000..8fe881d Binary files /dev/null and b/data/cubemaps/Storforsen3/negx.jpg differ diff --git a/data/cubemaps/Storforsen3/negy.jpg b/data/cubemaps/Storforsen3/negy.jpg new file mode 100644 index 0000000..266aee5 Binary files /dev/null and b/data/cubemaps/Storforsen3/negy.jpg differ diff --git a/data/cubemaps/Storforsen3/negz.jpg b/data/cubemaps/Storforsen3/negz.jpg new file mode 100644 index 0000000..165a759 Binary files /dev/null and b/data/cubemaps/Storforsen3/negz.jpg differ diff --git a/data/cubemaps/Storforsen3/posx.jpg b/data/cubemaps/Storforsen3/posx.jpg new file mode 100644 index 0000000..8394dca Binary files /dev/null and b/data/cubemaps/Storforsen3/posx.jpg differ diff --git a/data/cubemaps/Storforsen3/posy.jpg b/data/cubemaps/Storforsen3/posy.jpg new file mode 100644 index 0000000..65c61bf Binary files /dev/null and b/data/cubemaps/Storforsen3/posy.jpg differ diff --git a/data/cubemaps/Storforsen3/posz.jpg b/data/cubemaps/Storforsen3/posz.jpg new file mode 100644 index 0000000..39624de Binary files /dev/null and b/data/cubemaps/Storforsen3/posz.jpg differ diff --git a/data/cubemaps/Storforsen3/readme.txt b/data/cubemaps/Storforsen3/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Storforsen3/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Storforsen4/negx.jpg b/data/cubemaps/Storforsen4/negx.jpg new file mode 100644 index 0000000..1c3d73d Binary files /dev/null and b/data/cubemaps/Storforsen4/negx.jpg differ diff --git a/data/cubemaps/Storforsen4/negy.jpg b/data/cubemaps/Storforsen4/negy.jpg new file mode 100644 index 0000000..cc7abf4 Binary files /dev/null and b/data/cubemaps/Storforsen4/negy.jpg differ diff --git a/data/cubemaps/Storforsen4/negz.jpg b/data/cubemaps/Storforsen4/negz.jpg new file mode 100644 index 0000000..7284ff3 Binary files /dev/null and b/data/cubemaps/Storforsen4/negz.jpg differ diff --git a/data/cubemaps/Storforsen4/posx.jpg b/data/cubemaps/Storforsen4/posx.jpg new file mode 100644 index 0000000..4ef9821 Binary files /dev/null and b/data/cubemaps/Storforsen4/posx.jpg differ diff --git a/data/cubemaps/Storforsen4/posy.jpg b/data/cubemaps/Storforsen4/posy.jpg new file mode 100644 index 0000000..00f91d1 Binary files /dev/null and b/data/cubemaps/Storforsen4/posy.jpg differ diff --git a/data/cubemaps/Storforsen4/posz.jpg b/data/cubemaps/Storforsen4/posz.jpg new file mode 100644 index 0000000..43f2424 Binary files /dev/null and b/data/cubemaps/Storforsen4/posz.jpg differ diff --git a/data/cubemaps/Storforsen4/readme.txt b/data/cubemaps/Storforsen4/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Storforsen4/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/VancouverConventionCentre/negx.jpg b/data/cubemaps/VancouverConventionCentre/negx.jpg new file mode 100644 index 0000000..3cc01b7 Binary files /dev/null and b/data/cubemaps/VancouverConventionCentre/negx.jpg differ diff --git a/data/cubemaps/VancouverConventionCentre/negy.jpg b/data/cubemaps/VancouverConventionCentre/negy.jpg new file mode 100644 index 0000000..072e209 Binary files /dev/null and b/data/cubemaps/VancouverConventionCentre/negy.jpg differ diff --git a/data/cubemaps/VancouverConventionCentre/negz.jpg b/data/cubemaps/VancouverConventionCentre/negz.jpg new file mode 100644 index 0000000..3ec47a3 Binary files /dev/null and b/data/cubemaps/VancouverConventionCentre/negz.jpg differ diff --git a/data/cubemaps/VancouverConventionCentre/posx.jpg b/data/cubemaps/VancouverConventionCentre/posx.jpg new file mode 100644 index 0000000..c49fdd1 Binary files /dev/null and b/data/cubemaps/VancouverConventionCentre/posx.jpg differ diff --git a/data/cubemaps/VancouverConventionCentre/posy.jpg b/data/cubemaps/VancouverConventionCentre/posy.jpg new file mode 100644 index 0000000..b055686 Binary files /dev/null and b/data/cubemaps/VancouverConventionCentre/posy.jpg differ diff --git a/data/cubemaps/VancouverConventionCentre/posz.jpg b/data/cubemaps/VancouverConventionCentre/posz.jpg new file mode 100644 index 0000000..aa6dc90 Binary files /dev/null and b/data/cubemaps/VancouverConventionCentre/posz.jpg differ diff --git a/data/cubemaps/VancouverConventionCentre/readme.txt b/data/cubemaps/VancouverConventionCentre/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/VancouverConventionCentre/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Yokohama/negx.jpg b/data/cubemaps/Yokohama/negx.jpg new file mode 100644 index 0000000..e0861b1 Binary files /dev/null and b/data/cubemaps/Yokohama/negx.jpg differ diff --git a/data/cubemaps/Yokohama/negy.jpg b/data/cubemaps/Yokohama/negy.jpg new file mode 100644 index 0000000..fc1891b Binary files /dev/null and b/data/cubemaps/Yokohama/negy.jpg differ diff --git a/data/cubemaps/Yokohama/negz.jpg b/data/cubemaps/Yokohama/negz.jpg new file mode 100644 index 0000000..c1ffbb4 Binary files /dev/null and b/data/cubemaps/Yokohama/negz.jpg differ diff --git a/data/cubemaps/Yokohama/posx.jpg b/data/cubemaps/Yokohama/posx.jpg new file mode 100644 index 0000000..2521b8e Binary files /dev/null and b/data/cubemaps/Yokohama/posx.jpg differ diff --git a/data/cubemaps/Yokohama/posy.jpg b/data/cubemaps/Yokohama/posy.jpg new file mode 100644 index 0000000..8980554 Binary files /dev/null and b/data/cubemaps/Yokohama/posy.jpg differ diff --git a/data/cubemaps/Yokohama/posz.jpg b/data/cubemaps/Yokohama/posz.jpg new file mode 100644 index 0000000..f0cb218 Binary files /dev/null and b/data/cubemaps/Yokohama/posz.jpg differ diff --git a/data/cubemaps/Yokohama/readme.txt b/data/cubemaps/Yokohama/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Yokohama/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Yokohama2/negx.jpg b/data/cubemaps/Yokohama2/negx.jpg new file mode 100644 index 0000000..d72ed3b Binary files /dev/null and b/data/cubemaps/Yokohama2/negx.jpg differ diff --git a/data/cubemaps/Yokohama2/negy.jpg b/data/cubemaps/Yokohama2/negy.jpg new file mode 100644 index 0000000..baa2416 Binary files /dev/null and b/data/cubemaps/Yokohama2/negy.jpg differ diff --git a/data/cubemaps/Yokohama2/negz.jpg b/data/cubemaps/Yokohama2/negz.jpg new file mode 100644 index 0000000..088ce34 Binary files /dev/null and b/data/cubemaps/Yokohama2/negz.jpg differ diff --git a/data/cubemaps/Yokohama2/posx.jpg b/data/cubemaps/Yokohama2/posx.jpg new file mode 100644 index 0000000..4416e28 Binary files /dev/null and b/data/cubemaps/Yokohama2/posx.jpg differ diff --git a/data/cubemaps/Yokohama2/posy.jpg b/data/cubemaps/Yokohama2/posy.jpg new file mode 100644 index 0000000..1eeecfb Binary files /dev/null and b/data/cubemaps/Yokohama2/posy.jpg differ diff --git a/data/cubemaps/Yokohama2/posz.jpg b/data/cubemaps/Yokohama2/posz.jpg new file mode 100644 index 0000000..fd27d57 Binary files /dev/null and b/data/cubemaps/Yokohama2/posz.jpg differ diff --git a/data/cubemaps/Yokohama2/readme.txt b/data/cubemaps/Yokohama2/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Yokohama2/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/cubemaps/Yokohama3/negx.jpg b/data/cubemaps/Yokohama3/negx.jpg new file mode 100644 index 0000000..48b37dc Binary files /dev/null and b/data/cubemaps/Yokohama3/negx.jpg differ diff --git a/data/cubemaps/Yokohama3/negy.jpg b/data/cubemaps/Yokohama3/negy.jpg new file mode 100644 index 0000000..0883450 Binary files /dev/null and b/data/cubemaps/Yokohama3/negy.jpg differ diff --git a/data/cubemaps/Yokohama3/negz.jpg b/data/cubemaps/Yokohama3/negz.jpg new file mode 100644 index 0000000..d5b53c9 Binary files /dev/null and b/data/cubemaps/Yokohama3/negz.jpg differ diff --git a/data/cubemaps/Yokohama3/posx.jpg b/data/cubemaps/Yokohama3/posx.jpg new file mode 100644 index 0000000..f457b83 Binary files /dev/null and b/data/cubemaps/Yokohama3/posx.jpg differ diff --git a/data/cubemaps/Yokohama3/posy.jpg b/data/cubemaps/Yokohama3/posy.jpg new file mode 100644 index 0000000..ebee2af Binary files /dev/null and b/data/cubemaps/Yokohama3/posy.jpg differ diff --git a/data/cubemaps/Yokohama3/posz.jpg b/data/cubemaps/Yokohama3/posz.jpg new file mode 100644 index 0000000..3de2360 Binary files /dev/null and b/data/cubemaps/Yokohama3/posz.jpg differ diff --git a/data/cubemaps/Yokohama3/readme.txt b/data/cubemaps/Yokohama3/readme.txt new file mode 100644 index 0000000..d9bd514 --- /dev/null +++ b/data/cubemaps/Yokohama3/readme.txt @@ -0,0 +1,13 @@ +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + + + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ diff --git a/data/shaders/generative/AI_NotIncluded.frag.qsb b/data/shaders/generative/AI_NotIncluded.frag.qsb new file mode 100644 index 0000000..b7d977b Binary files /dev/null and b/data/shaders/generative/AI_NotIncluded.frag.qsb differ diff --git a/data/shaders/generative/Abstract_Glassy_Field.frag.qsb b/data/shaders/generative/Abstract_Glassy_Field.frag.qsb new file mode 100644 index 0000000..4e00869 Binary files /dev/null and b/data/shaders/generative/Abstract_Glassy_Field.frag.qsb differ diff --git a/data/shaders/generative/Abstract_Liquid.frag.qsb b/data/shaders/generative/Abstract_Liquid.frag.qsb new file mode 100644 index 0000000..8f3288b Binary files /dev/null and b/data/shaders/generative/Abstract_Liquid.frag.qsb differ diff --git a/data/shaders/generative/Abstract_Patterns6.frag.qsb b/data/shaders/generative/Abstract_Patterns6.frag.qsb new file mode 100644 index 0000000..354a35d Binary files /dev/null and b/data/shaders/generative/Abstract_Patterns6.frag.qsb differ diff --git a/data/shaders/generative/Abstract_Plane.frag.qsb b/data/shaders/generative/Abstract_Plane.frag.qsb new file mode 100644 index 0000000..fd51bb1 Binary files /dev/null and b/data/shaders/generative/Abstract_Plane.frag.qsb differ diff --git a/data/shaders/generative/Auroras.frag.qsb b/data/shaders/generative/Auroras.frag.qsb new file mode 100644 index 0000000..b766c28 Binary files /dev/null and b/data/shaders/generative/Auroras.frag.qsb differ diff --git a/data/shaders/generative/Balatro.frag.qsb b/data/shaders/generative/Balatro.frag.qsb new file mode 100644 index 0000000..1490491 Binary files /dev/null and b/data/shaders/generative/Balatro.frag.qsb differ diff --git a/data/shaders/generative/BalatroSmooth.frag.qsb b/data/shaders/generative/BalatroSmooth.frag.qsb new file mode 100644 index 0000000..054d9e9 Binary files /dev/null and b/data/shaders/generative/BalatroSmooth.frag.qsb differ diff --git a/data/shaders/generative/BalatroSmoothWider.frag.qsb b/data/shaders/generative/BalatroSmoothWider.frag.qsb new file mode 100644 index 0000000..dedaa12 Binary files /dev/null and b/data/shaders/generative/BalatroSmoothWider.frag.qsb differ diff --git a/data/shaders/generative/Base_Warp.frag.qsb b/data/shaders/generative/Base_Warp.frag.qsb new file mode 100644 index 0000000..b511f47 Binary files /dev/null and b/data/shaders/generative/Base_Warp.frag.qsb differ diff --git a/data/shaders/generative/Biomine.frag.qsb b/data/shaders/generative/Biomine.frag.qsb new file mode 100644 index 0000000..431051b Binary files /dev/null and b/data/shaders/generative/Biomine.frag.qsb differ diff --git a/data/shaders/generative/Booting.frag.qsb b/data/shaders/generative/Booting.frag.qsb new file mode 100644 index 0000000..075b1b4 Binary files /dev/null and b/data/shaders/generative/Booting.frag.qsb differ diff --git a/data/shaders/generative/Bottom_of_Water.frag.qsb b/data/shaders/generative/Bottom_of_Water.frag.qsb new file mode 100644 index 0000000..314fb14 Binary files /dev/null and b/data/shaders/generative/Bottom_of_Water.frag.qsb differ diff --git a/data/shaders/generative/Bouncing_Circle.frag.qsb b/data/shaders/generative/Bouncing_Circle.frag.qsb new file mode 100644 index 0000000..a2da5ab Binary files /dev/null and b/data/shaders/generative/Bouncing_Circle.frag.qsb differ diff --git a/data/shaders/generative/Channel_Soup.frag.qsb b/data/shaders/generative/Channel_Soup.frag.qsb new file mode 100644 index 0000000..e27da4d Binary files /dev/null and b/data/shaders/generative/Channel_Soup.frag.qsb differ diff --git a/data/shaders/generative/Clock.frag.qsb b/data/shaders/generative/Clock.frag.qsb new file mode 100644 index 0000000..a711b21 Binary files /dev/null and b/data/shaders/generative/Clock.frag.qsb differ diff --git a/data/shaders/generative/Clouds.frag.qsb b/data/shaders/generative/Clouds.frag.qsb new file mode 100644 index 0000000..c06a199 Binary files /dev/null and b/data/shaders/generative/Clouds.frag.qsb differ diff --git a/data/shaders/generative/Coastal_Dream.frag.qsb b/data/shaders/generative/Coastal_Dream.frag.qsb new file mode 100644 index 0000000..15fb47d Binary files /dev/null and b/data/shaders/generative/Coastal_Dream.frag.qsb differ diff --git a/data/shaders/generative/Color_Grid.frag.qsb b/data/shaders/generative/Color_Grid.frag.qsb new file mode 100644 index 0000000..03da1d4 Binary files /dev/null and b/data/shaders/generative/Color_Grid.frag.qsb differ diff --git a/data/shaders/generative/Colorful_FBM.frag.qsb b/data/shaders/generative/Colorful_FBM.frag.qsb new file mode 100644 index 0000000..8f57e88 Binary files /dev/null and b/data/shaders/generative/Colorful_FBM.frag.qsb differ diff --git a/data/shaders/generative/Colorful_Lens.frag.qsb b/data/shaders/generative/Colorful_Lens.frag.qsb new file mode 100644 index 0000000..e260a35 Binary files /dev/null and b/data/shaders/generative/Colorful_Lens.frag.qsb differ diff --git a/data/shaders/generative/Computers_MadeForCubes.frag.qsb b/data/shaders/generative/Computers_MadeForCubes.frag.qsb new file mode 100644 index 0000000..783b0a0 Binary files /dev/null and b/data/shaders/generative/Computers_MadeForCubes.frag.qsb differ diff --git a/data/shaders/generative/Cosmic_Cycles.frag.qsb b/data/shaders/generative/Cosmic_Cycles.frag.qsb new file mode 100644 index 0000000..2d7e30d Binary files /dev/null and b/data/shaders/generative/Cosmic_Cycles.frag.qsb differ diff --git a/data/shaders/generative/Craziness.frag.qsb b/data/shaders/generative/Craziness.frag.qsb new file mode 100644 index 0000000..f5d002f Binary files /dev/null and b/data/shaders/generative/Craziness.frag.qsb differ diff --git a/data/shaders/generative/Creation.frag.qsb b/data/shaders/generative/Creation.frag.qsb new file mode 100644 index 0000000..d801b93 Binary files /dev/null and b/data/shaders/generative/Creation.frag.qsb differ diff --git a/data/shaders/generative/CrumpledWave.frag.qsb b/data/shaders/generative/CrumpledWave.frag.qsb new file mode 100644 index 0000000..c537a4c Binary files /dev/null and b/data/shaders/generative/CrumpledWave.frag.qsb differ diff --git a/data/shaders/generative/CubeLines.frag.qsb b/data/shaders/generative/CubeLines.frag.qsb new file mode 100644 index 0000000..40e8662 Binary files /dev/null and b/data/shaders/generative/CubeLines.frag.qsb differ diff --git a/data/shaders/generative/DVD.frag.qsb b/data/shaders/generative/DVD.frag.qsb new file mode 100644 index 0000000..4c60b2e Binary files /dev/null and b/data/shaders/generative/DVD.frag.qsb differ diff --git a/data/shaders/generative/Day_74.frag.qsb b/data/shaders/generative/Day_74.frag.qsb new file mode 100644 index 0000000..f557d1c Binary files /dev/null and b/data/shaders/generative/Day_74.frag.qsb differ diff --git a/data/shaders/generative/Descent3D.frag.qsb b/data/shaders/generative/Descent3D.frag.qsb new file mode 100644 index 0000000..6304476 Binary files /dev/null and b/data/shaders/generative/Descent3D.frag.qsb differ diff --git a/data/shaders/generative/Dez.frag.qsb b/data/shaders/generative/Dez.frag.qsb new file mode 100644 index 0000000..c2c08d1 Binary files /dev/null and b/data/shaders/generative/Dez.frag.qsb differ diff --git a/data/shaders/generative/Digital_Rain.frag.qsb b/data/shaders/generative/Digital_Rain.frag.qsb new file mode 100644 index 0000000..5f0d999 Binary files /dev/null and b/data/shaders/generative/Digital_Rain.frag.qsb differ diff --git a/data/shaders/generative/Discoteq_2.frag.qsb b/data/shaders/generative/Discoteq_2.frag.qsb new file mode 100644 index 0000000..0492a83 Binary files /dev/null and b/data/shaders/generative/Discoteq_2.frag.qsb differ diff --git a/data/shaders/generative/Domain_Warping.frag.qsb b/data/shaders/generative/Domain_Warping.frag.qsb new file mode 100644 index 0000000..4200073 Binary files /dev/null and b/data/shaders/generative/Domain_Warping.frag.qsb differ diff --git a/data/shaders/generative/E1M1.frag.qsb b/data/shaders/generative/E1M1.frag.qsb new file mode 100644 index 0000000..dfffd97 Binary files /dev/null and b/data/shaders/generative/E1M1.frag.qsb differ diff --git a/data/shaders/generative/Earthbound.frag.qsb b/data/shaders/generative/Earthbound.frag.qsb new file mode 100644 index 0000000..80ec7ab Binary files /dev/null and b/data/shaders/generative/Earthbound.frag.qsb differ diff --git a/data/shaders/generative/Earthbound2.frag.qsb b/data/shaders/generative/Earthbound2.frag.qsb new file mode 100644 index 0000000..928d6dc Binary files /dev/null and b/data/shaders/generative/Earthbound2.frag.qsb differ diff --git a/data/shaders/generative/Earthbound3.frag.qsb b/data/shaders/generative/Earthbound3.frag.qsb new file mode 100644 index 0000000..8faf8eb Binary files /dev/null and b/data/shaders/generative/Earthbound3.frag.qsb differ diff --git a/data/shaders/generative/ElectricEel_Universe.frag.qsb b/data/shaders/generative/ElectricEel_Universe.frag.qsb new file mode 100644 index 0000000..e3e66f5 Binary files /dev/null and b/data/shaders/generative/ElectricEel_Universe.frag.qsb differ diff --git a/data/shaders/generative/Electric_Sinusoid.frag.qsb b/data/shaders/generative/Electric_Sinusoid.frag.qsb new file mode 100644 index 0000000..458af33 Binary files /dev/null and b/data/shaders/generative/Electric_Sinusoid.frag.qsb differ diff --git a/data/shaders/generative/Electro.frag.qsb b/data/shaders/generative/Electro.frag.qsb new file mode 100644 index 0000000..1b6f403 Binary files /dev/null and b/data/shaders/generative/Electro.frag.qsb differ diff --git a/data/shaders/generative/Endless_Creature.frag.qsb b/data/shaders/generative/Endless_Creature.frag.qsb new file mode 100644 index 0000000..d996f43 Binary files /dev/null and b/data/shaders/generative/Endless_Creature.frag.qsb differ diff --git a/data/shaders/generative/Ether.frag.qsb b/data/shaders/generative/Ether.frag.qsb new file mode 100644 index 0000000..9d405f8 Binary files /dev/null and b/data/shaders/generative/Ether.frag.qsb differ diff --git a/data/shaders/generative/Flickering_Stars.frag.qsb b/data/shaders/generative/Flickering_Stars.frag.qsb new file mode 100644 index 0000000..1b1d5ac Binary files /dev/null and b/data/shaders/generative/Flickering_Stars.frag.qsb differ diff --git a/data/shaders/generative/Floating_Color_Bubbles.frag.qsb b/data/shaders/generative/Floating_Color_Bubbles.frag.qsb new file mode 100644 index 0000000..26f1541 Binary files /dev/null and b/data/shaders/generative/Floating_Color_Bubbles.frag.qsb differ diff --git a/data/shaders/generative/Flow_Cells.frag.qsb b/data/shaders/generative/Flow_Cells.frag.qsb new file mode 100644 index 0000000..a4a3a6f Binary files /dev/null and b/data/shaders/generative/Flow_Cells.frag.qsb differ diff --git a/data/shaders/generative/Fluorescent_Light_Digits.frag.qsb b/data/shaders/generative/Fluorescent_Light_Digits.frag.qsb new file mode 100644 index 0000000..7a49f29 Binary files /dev/null and b/data/shaders/generative/Fluorescent_Light_Digits.frag.qsb differ diff --git a/data/shaders/generative/FlyOnBuckaroo.frag.qsb b/data/shaders/generative/FlyOnBuckaroo.frag.qsb new file mode 100644 index 0000000..0e6ea21 Binary files /dev/null and b/data/shaders/generative/FlyOnBuckaroo.frag.qsb differ diff --git a/data/shaders/generative/Fractal_Flythrough.frag.qsb b/data/shaders/generative/Fractal_Flythrough.frag.qsb new file mode 100644 index 0000000..42049c4 Binary files /dev/null and b/data/shaders/generative/Fractal_Flythrough.frag.qsb differ diff --git a/data/shaders/generative/Galaxy_Spirals.frag.qsb b/data/shaders/generative/Galaxy_Spirals.frag.qsb new file mode 100644 index 0000000..b0790a5 Binary files /dev/null and b/data/shaders/generative/Galaxy_Spirals.frag.qsb differ diff --git a/data/shaders/generative/Geodesic_Tiling.frag.qsb b/data/shaders/generative/Geodesic_Tiling.frag.qsb new file mode 100644 index 0000000..ce7b9d0 Binary files /dev/null and b/data/shaders/generative/Geodesic_Tiling.frag.qsb differ diff --git a/data/shaders/generative/Glow-City.frag.qsb b/data/shaders/generative/Glow-City.frag.qsb new file mode 100644 index 0000000..065e938 Binary files /dev/null and b/data/shaders/generative/Glow-City.frag.qsb differ diff --git a/data/shaders/generative/Grey_Liquid.frag.qsb b/data/shaders/generative/Grey_Liquid.frag.qsb new file mode 100644 index 0000000..e26ccbd Binary files /dev/null and b/data/shaders/generative/Grey_Liquid.frag.qsb differ diff --git a/data/shaders/generative/Grid_Landscape.frag.qsb b/data/shaders/generative/Grid_Landscape.frag.qsb new file mode 100644 index 0000000..6cd660e Binary files /dev/null and b/data/shaders/generative/Grid_Landscape.frag.qsb differ diff --git a/data/shaders/generative/HSV_to_RGB.frag.qsb b/data/shaders/generative/HSV_to_RGB.frag.qsb new file mode 100644 index 0000000..ffba2cc Binary files /dev/null and b/data/shaders/generative/HSV_to_RGB.frag.qsb differ diff --git a/data/shaders/generative/Halftone_Experiment.frag.qsb b/data/shaders/generative/Halftone_Experiment.frag.qsb new file mode 100644 index 0000000..f83acf0 Binary files /dev/null and b/data/shaders/generative/Halftone_Experiment.frag.qsb differ diff --git a/data/shaders/generative/Holotech_Voronoi.frag.qsb b/data/shaders/generative/Holotech_Voronoi.frag.qsb new file mode 100644 index 0000000..cfd0d3c Binary files /dev/null and b/data/shaders/generative/Holotech_Voronoi.frag.qsb differ diff --git a/data/shaders/generative/Hypnoferromagnetism.frag.qsb b/data/shaders/generative/Hypnoferromagnetism.frag.qsb new file mode 100644 index 0000000..06e0f17 Binary files /dev/null and b/data/shaders/generative/Hypnoferromagnetism.frag.qsb differ diff --git a/data/shaders/generative/IFS.frag.qsb b/data/shaders/generative/IFS.frag.qsb new file mode 100644 index 0000000..f5b41f9 Binary files /dev/null and b/data/shaders/generative/IFS.frag.qsb differ diff --git a/data/shaders/generative/IO.frag.qsb b/data/shaders/generative/IO.frag.qsb new file mode 100644 index 0000000..0dbf2bb Binary files /dev/null and b/data/shaders/generative/IO.frag.qsb differ diff --git a/data/shaders/generative/Ice_Block.frag.qsb b/data/shaders/generative/Ice_Block.frag.qsb new file mode 100644 index 0000000..98f3d7c Binary files /dev/null and b/data/shaders/generative/Ice_Block.frag.qsb differ diff --git a/data/shaders/generative/Ice_Fire.frag.qsb b/data/shaders/generative/Ice_Fire.frag.qsb new file mode 100644 index 0000000..7a2132e Binary files /dev/null and b/data/shaders/generative/Ice_Fire.frag.qsb differ diff --git a/data/shaders/generative/Industry_II.frag.qsb b/data/shaders/generative/Industry_II.frag.qsb new file mode 100644 index 0000000..f01415b Binary files /dev/null and b/data/shaders/generative/Industry_II.frag.qsb differ diff --git a/data/shaders/generative/Inercia_IntendedOne.frag.qsb b/data/shaders/generative/Inercia_IntendedOne.frag.qsb new file mode 100644 index 0000000..5db3315 Binary files /dev/null and b/data/shaders/generative/Inercia_IntendedOne.frag.qsb differ diff --git a/data/shaders/generative/Infinite_Pinballs.frag.qsb b/data/shaders/generative/Infinite_Pinballs.frag.qsb new file mode 100644 index 0000000..eafbc43 Binary files /dev/null and b/data/shaders/generative/Infinite_Pinballs.frag.qsb differ diff --git a/data/shaders/generative/Inside_Matrix.frag.qsb b/data/shaders/generative/Inside_Matrix.frag.qsb new file mode 100644 index 0000000..f04565c Binary files /dev/null and b/data/shaders/generative/Inside_Matrix.frag.qsb differ diff --git a/data/shaders/generative/Interstellar.frag.qsb b/data/shaders/generative/Interstellar.frag.qsb new file mode 100644 index 0000000..093c6c2 Binary files /dev/null and b/data/shaders/generative/Interstellar.frag.qsb differ diff --git a/data/shaders/generative/Introduction.frag.qsb b/data/shaders/generative/Introduction.frag.qsb new file mode 100644 index 0000000..90724a2 Binary files /dev/null and b/data/shaders/generative/Introduction.frag.qsb differ diff --git a/data/shaders/generative/Introduction_2.frag.qsb b/data/shaders/generative/Introduction_2.frag.qsb new file mode 100644 index 0000000..acb5ce0 Binary files /dev/null and b/data/shaders/generative/Introduction_2.frag.qsb differ diff --git a/data/shaders/generative/Jelly.frag.qsb b/data/shaders/generative/Jelly.frag.qsb new file mode 100644 index 0000000..79e6e01 Binary files /dev/null and b/data/shaders/generative/Jelly.frag.qsb differ diff --git a/data/shaders/generative/Kaleidoscope.frag.qsb b/data/shaders/generative/Kaleidoscope.frag.qsb new file mode 100644 index 0000000..414a810 Binary files /dev/null and b/data/shaders/generative/Kaleidoscope.frag.qsb differ diff --git a/data/shaders/generative/Kirby.frag.qsb b/data/shaders/generative/Kirby.frag.qsb new file mode 100644 index 0000000..1828557 Binary files /dev/null and b/data/shaders/generative/Kirby.frag.qsb differ diff --git a/data/shaders/generative/Kitties.frag.qsb b/data/shaders/generative/Kitties.frag.qsb new file mode 100644 index 0000000..3d68402 Binary files /dev/null and b/data/shaders/generative/Kitties.frag.qsb differ diff --git a/data/shaders/generative/LOVE.frag.qsb b/data/shaders/generative/LOVE.frag.qsb new file mode 100644 index 0000000..9641c1c Binary files /dev/null and b/data/shaders/generative/LOVE.frag.qsb differ diff --git a/data/shaders/generative/Laserworld.frag.qsb b/data/shaders/generative/Laserworld.frag.qsb new file mode 100644 index 0000000..fe0f031 Binary files /dev/null and b/data/shaders/generative/Laserworld.frag.qsb differ diff --git a/data/shaders/generative/Liberation.frag.qsb b/data/shaders/generative/Liberation.frag.qsb new file mode 100644 index 0000000..ac2a5ca Binary files /dev/null and b/data/shaders/generative/Liberation.frag.qsb differ diff --git a/data/shaders/generative/Light_Clock.frag.qsb b/data/shaders/generative/Light_Clock.frag.qsb new file mode 100644 index 0000000..3af0eed Binary files /dev/null and b/data/shaders/generative/Light_Clock.frag.qsb differ diff --git a/data/shaders/generative/Mandelbrot_Pattern_Decoration.frag.qsb b/data/shaders/generative/Mandelbrot_Pattern_Decoration.frag.qsb new file mode 100644 index 0000000..e5ed677 Binary files /dev/null and b/data/shaders/generative/Mandelbrot_Pattern_Decoration.frag.qsb differ diff --git a/data/shaders/generative/Metaball.frag.qsb b/data/shaders/generative/Metaball.frag.qsb new file mode 100644 index 0000000..26f34ca Binary files /dev/null and b/data/shaders/generative/Metaball.frag.qsb differ diff --git a/data/shaders/generative/Minkowski_Tube.frag.qsb b/data/shaders/generative/Minkowski_Tube.frag.qsb new file mode 100644 index 0000000..46583a7 Binary files /dev/null and b/data/shaders/generative/Minkowski_Tube.frag.qsb differ diff --git a/data/shaders/generative/Neon_Parallax.frag.qsb b/data/shaders/generative/Neon_Parallax.frag.qsb new file mode 100644 index 0000000..651b6ef Binary files /dev/null and b/data/shaders/generative/Neon_Parallax.frag.qsb differ diff --git a/data/shaders/generative/Net-2D.frag.qsb b/data/shaders/generative/Net-2D.frag.qsb new file mode 100644 index 0000000..226a19f Binary files /dev/null and b/data/shaders/generative/Net-2D.frag.qsb differ diff --git a/data/shaders/generative/Night_Sky.frag.qsb b/data/shaders/generative/Night_Sky.frag.qsb new file mode 100644 index 0000000..7fabff0 Binary files /dev/null and b/data/shaders/generative/Night_Sky.frag.qsb differ diff --git a/data/shaders/generative/Noise_Electric.frag.qsb b/data/shaders/generative/Noise_Electric.frag.qsb new file mode 100644 index 0000000..924ea31 Binary files /dev/null and b/data/shaders/generative/Noise_Electric.frag.qsb differ diff --git a/data/shaders/generative/OpArt_2.frag.qsb b/data/shaders/generative/OpArt_2.frag.qsb new file mode 100644 index 0000000..81936a3 Binary files /dev/null and b/data/shaders/generative/OpArt_2.frag.qsb differ diff --git a/data/shaders/generative/Paint_1.frag.qsb b/data/shaders/generative/Paint_1.frag.qsb new file mode 100644 index 0000000..f4cf112 Binary files /dev/null and b/data/shaders/generative/Paint_1.frag.qsb differ diff --git a/data/shaders/generative/Paint_Archipelago.frag.qsb b/data/shaders/generative/Paint_Archipelago.frag.qsb new file mode 100644 index 0000000..208f4a6 Binary files /dev/null and b/data/shaders/generative/Paint_Archipelago.frag.qsb differ diff --git a/data/shaders/generative/Painting_CodeDemo.frag.qsb b/data/shaders/generative/Painting_CodeDemo.frag.qsb new file mode 100644 index 0000000..216da40 Binary files /dev/null and b/data/shaders/generative/Painting_CodeDemo.frag.qsb differ diff --git a/data/shaders/generative/Perspex_Web_Lattice.frag.qsb b/data/shaders/generative/Perspex_Web_Lattice.frag.qsb new file mode 100644 index 0000000..5e61dd2 Binary files /dev/null and b/data/shaders/generative/Perspex_Web_Lattice.frag.qsb differ diff --git a/data/shaders/generative/Pixelated_RGB.frag.qsb b/data/shaders/generative/Pixelated_RGB.frag.qsb new file mode 100644 index 0000000..e489139 Binary files /dev/null and b/data/shaders/generative/Pixelated_RGB.frag.qsb differ diff --git a/data/shaders/generative/Planet.frag.qsb b/data/shaders/generative/Planet.frag.qsb new file mode 100644 index 0000000..a66d741 Binary files /dev/null and b/data/shaders/generative/Planet.frag.qsb differ diff --git a/data/shaders/generative/Plasma_Storm.frag.qsb b/data/shaders/generative/Plasma_Storm.frag.qsb new file mode 100644 index 0000000..4f3c2ba Binary files /dev/null and b/data/shaders/generative/Plasma_Storm.frag.qsb differ diff --git a/data/shaders/generative/Power_ChainsawMan.frag.qsb b/data/shaders/generative/Power_ChainsawMan.frag.qsb new file mode 100644 index 0000000..1d49285 Binary files /dev/null and b/data/shaders/generative/Power_ChainsawMan.frag.qsb differ diff --git a/data/shaders/generative/Pretty_Hip.frag.qsb b/data/shaders/generative/Pretty_Hip.frag.qsb new file mode 100644 index 0000000..7bf3675 Binary files /dev/null and b/data/shaders/generative/Pretty_Hip.frag.qsb differ diff --git a/data/shaders/generative/Procgen_Planet.frag.qsb b/data/shaders/generative/Procgen_Planet.frag.qsb new file mode 100644 index 0000000..884b90a Binary files /dev/null and b/data/shaders/generative/Procgen_Planet.frag.qsb differ diff --git a/data/shaders/generative/Ps3menu.frag.qsb b/data/shaders/generative/Ps3menu.frag.qsb new file mode 100644 index 0000000..1db984f Binary files /dev/null and b/data/shaders/generative/Ps3menu.frag.qsb differ diff --git a/data/shaders/generative/Psychedelic_Curlnoise.frag.qsb b/data/shaders/generative/Psychedelic_Curlnoise.frag.qsb new file mode 100644 index 0000000..147b2bb Binary files /dev/null and b/data/shaders/generative/Psychedelic_Curlnoise.frag.qsb differ diff --git a/data/shaders/generative/RGB_Noise_in_Movement.frag.qsb b/data/shaders/generative/RGB_Noise_in_Movement.frag.qsb new file mode 100644 index 0000000..ad4d86f Binary files /dev/null and b/data/shaders/generative/RGB_Noise_in_Movement.frag.qsb differ diff --git a/data/shaders/generative/Rainbow_AlienNoise.frag.qsb b/data/shaders/generative/Rainbow_AlienNoise.frag.qsb new file mode 100644 index 0000000..51d9348 Binary files /dev/null and b/data/shaders/generative/Rainbow_AlienNoise.frag.qsb differ diff --git a/data/shaders/generative/Rainbow_Twister.frag.qsb b/data/shaders/generative/Rainbow_Twister.frag.qsb new file mode 100644 index 0000000..6594a77 Binary files /dev/null and b/data/shaders/generative/Rainbow_Twister.frag.qsb differ diff --git a/data/shaders/generative/Rainier_Mood.frag.qsb b/data/shaders/generative/Rainier_Mood.frag.qsb new file mode 100644 index 0000000..a6282bb Binary files /dev/null and b/data/shaders/generative/Rainier_Mood.frag.qsb differ diff --git a/data/shaders/generative/Raymarched_Reflections.frag.qsb b/data/shaders/generative/Raymarched_Reflections.frag.qsb new file mode 100644 index 0000000..03ecce5 Binary files /dev/null and b/data/shaders/generative/Raymarched_Reflections.frag.qsb differ diff --git a/data/shaders/generative/Raymarching_Basic.frag.qsb b/data/shaders/generative/Raymarching_Basic.frag.qsb new file mode 100644 index 0000000..dd2758f Binary files /dev/null and b/data/shaders/generative/Raymarching_Basic.frag.qsb differ diff --git a/data/shaders/generative/Rorschach_Test.frag.qsb b/data/shaders/generative/Rorschach_Test.frag.qsb new file mode 100644 index 0000000..d9b7dc7 Binary files /dev/null and b/data/shaders/generative/Rorschach_Test.frag.qsb differ diff --git a/data/shaders/generative/SIG2014.frag.qsb b/data/shaders/generative/SIG2014.frag.qsb new file mode 100644 index 0000000..5297aed Binary files /dev/null and b/data/shaders/generative/SIG2014.frag.qsb differ diff --git a/data/shaders/generative/Seascape_Sailing.frag.qsb b/data/shaders/generative/Seascape_Sailing.frag.qsb new file mode 100644 index 0000000..001a0f6 Binary files /dev/null and b/data/shaders/generative/Seascape_Sailing.frag.qsb differ diff --git a/data/shaders/generative/Sin_Wave.frag.qsb b/data/shaders/generative/Sin_Wave.frag.qsb new file mode 100644 index 0000000..daa6ad6 Binary files /dev/null and b/data/shaders/generative/Sin_Wave.frag.qsb differ diff --git a/data/shaders/generative/Sine_Animation.frag.qsb b/data/shaders/generative/Sine_Animation.frag.qsb new file mode 100644 index 0000000..2a940e7 Binary files /dev/null and b/data/shaders/generative/Sine_Animation.frag.qsb differ diff --git a/data/shaders/generative/Sine_Dunes.frag.qsb b/data/shaders/generative/Sine_Dunes.frag.qsb new file mode 100644 index 0000000..e134bc9 Binary files /dev/null and b/data/shaders/generative/Sine_Dunes.frag.qsb differ diff --git a/data/shaders/generative/Slug_Ring.frag.qsb b/data/shaders/generative/Slug_Ring.frag.qsb new file mode 100644 index 0000000..56d0dbb Binary files /dev/null and b/data/shaders/generative/Slug_Ring.frag.qsb differ diff --git a/data/shaders/generative/Slushher.frag.qsb b/data/shaders/generative/Slushher.frag.qsb new file mode 100644 index 0000000..2953c2f Binary files /dev/null and b/data/shaders/generative/Slushher.frag.qsb differ diff --git a/data/shaders/generative/Space_Curvature.frag.qsb b/data/shaders/generative/Space_Curvature.frag.qsb new file mode 100644 index 0000000..19d3347 Binary files /dev/null and b/data/shaders/generative/Space_Curvature.frag.qsb differ diff --git a/data/shaders/generative/StarField_Practice.frag.qsb b/data/shaders/generative/StarField_Practice.frag.qsb new file mode 100644 index 0000000..1cffb37 Binary files /dev/null and b/data/shaders/generative/StarField_Practice.frag.qsb differ diff --git a/data/shaders/generative/Star_Nest.frag.qsb b/data/shaders/generative/Star_Nest.frag.qsb new file mode 100644 index 0000000..66b7bba Binary files /dev/null and b/data/shaders/generative/Star_Nest.frag.qsb differ diff --git a/data/shaders/generative/Starleidoscope.frag.qsb b/data/shaders/generative/Starleidoscope.frag.qsb new file mode 100644 index 0000000..ff1c9a5 Binary files /dev/null and b/data/shaders/generative/Starleidoscope.frag.qsb differ diff --git a/data/shaders/generative/Supah_Relax.frag.qsb b/data/shaders/generative/Supah_Relax.frag.qsb new file mode 100644 index 0000000..5e22d29 Binary files /dev/null and b/data/shaders/generative/Supah_Relax.frag.qsb differ diff --git a/data/shaders/generative/SuperPlumber.frag.qsb b/data/shaders/generative/SuperPlumber.frag.qsb new file mode 100644 index 0000000..39b500c Binary files /dev/null and b/data/shaders/generative/SuperPlumber.frag.qsb differ diff --git a/data/shaders/generative/Tetragrammaton.frag.qsb b/data/shaders/generative/Tetragrammaton.frag.qsb new file mode 100644 index 0000000..f226265 Binary files /dev/null and b/data/shaders/generative/Tetragrammaton.frag.qsb differ diff --git a/data/shaders/generative/UV_Manipulation.frag.qsb b/data/shaders/generative/UV_Manipulation.frag.qsb new file mode 100644 index 0000000..d41f6eb Binary files /dev/null and b/data/shaders/generative/UV_Manipulation.frag.qsb differ diff --git a/data/shaders/generative/VDJ.frag.qsb b/data/shaders/generative/VDJ.frag.qsb new file mode 100644 index 0000000..dd13e6a Binary files /dev/null and b/data/shaders/generative/VDJ.frag.qsb differ diff --git a/data/shaders/generative/Voxel_Tunnel.frag.qsb b/data/shaders/generative/Voxel_Tunnel.frag.qsb new file mode 100644 index 0000000..f2cd75f Binary files /dev/null and b/data/shaders/generative/Voxel_Tunnel.frag.qsb differ diff --git a/data/shaders/generative/Warped_LiquidMetal.frag.qsb b/data/shaders/generative/Warped_LiquidMetal.frag.qsb new file mode 100644 index 0000000..1ca6282 Binary files /dev/null and b/data/shaders/generative/Warped_LiquidMetal.frag.qsb differ diff --git a/data/shaders/generative/Waves.frag.qsb b/data/shaders/generative/Waves.frag.qsb new file mode 100644 index 0000000..57d78f1 Binary files /dev/null and b/data/shaders/generative/Waves.frag.qsb differ diff --git a/data/shaders/generative/Waves221.frag.qsb b/data/shaders/generative/Waves221.frag.qsb new file mode 100644 index 0000000..9e4f1eb Binary files /dev/null and b/data/shaders/generative/Waves221.frag.qsb differ diff --git a/data/shaders/generative/Waves_Portrait.frag.qsb b/data/shaders/generative/Waves_Portrait.frag.qsb new file mode 100644 index 0000000..9349dd3 Binary files /dev/null and b/data/shaders/generative/Waves_Portrait.frag.qsb differ diff --git a/data/shaders/generative/Wiggle_Worm.frag.qsb b/data/shaders/generative/Wiggle_Worm.frag.qsb new file mode 100644 index 0000000..21c62c6 Binary files /dev/null and b/data/shaders/generative/Wiggle_Worm.frag.qsb differ diff --git a/data/shaders/generative/Wolfenstein.frag.qsb b/data/shaders/generative/Wolfenstein.frag.qsb new file mode 100644 index 0000000..555ecfb Binary files /dev/null and b/data/shaders/generative/Wolfenstein.frag.qsb differ diff --git a/data/shaders/generative/X_and_Circles.frag.qsb b/data/shaders/generative/X_and_Circles.frag.qsb new file mode 100644 index 0000000..66e47c2 Binary files /dev/null and b/data/shaders/generative/X_and_Circles.frag.qsb differ diff --git a/data/shaders/generative/wave_propagation.frag.qsb b/data/shaders/generative/wave_propagation.frag.qsb new file mode 100644 index 0000000..864befa Binary files /dev/null and b/data/shaders/generative/wave_propagation.frag.qsb differ diff --git a/data/shaders/generative/wave_propagation_bufferA.frag.qsb b/data/shaders/generative/wave_propagation_bufferA.frag.qsb new file mode 100644 index 0000000..dd9f137 Binary files /dev/null and b/data/shaders/generative/wave_propagation_bufferA.frag.qsb differ diff --git a/data/shaders/manipulative/chromakey.frag.qsb b/data/shaders/manipulative/chromakey.frag.qsb new file mode 100644 index 0000000..5a4bde8 Binary files /dev/null and b/data/shaders/manipulative/chromakey.frag.qsb differ diff --git a/data/shaders/manipulative/edge-detect-2.frag.qsb b/data/shaders/manipulative/edge-detect-2.frag.qsb new file mode 100644 index 0000000..dff534b Binary files /dev/null and b/data/shaders/manipulative/edge-detect-2.frag.qsb differ diff --git a/data/shaders/manipulative/edge-detect-greyscale.frag.qsb b/data/shaders/manipulative/edge-detect-greyscale.frag.qsb new file mode 100644 index 0000000..352928a Binary files /dev/null and b/data/shaders/manipulative/edge-detect-greyscale.frag.qsb differ diff --git a/data/shaders/manipulative/edge-detect.frag.qsb b/data/shaders/manipulative/edge-detect.frag.qsb new file mode 100644 index 0000000..2e506cb Binary files /dev/null and b/data/shaders/manipulative/edge-detect.frag.qsb differ diff --git a/data/shaders/manipulative/video-glitch-extra.frag.qsb b/data/shaders/manipulative/video-glitch-extra.frag.qsb new file mode 100644 index 0000000..969bdda Binary files /dev/null and b/data/shaders/manipulative/video-glitch-extra.frag.qsb differ diff --git a/data/shaders/manipulative/video-glitch.frag.qsb b/data/shaders/manipulative/video-glitch.frag.qsb new file mode 100644 index 0000000..4920128 Binary files /dev/null and b/data/shaders/manipulative/video-glitch.frag.qsb differ diff --git a/metainfo.yaml b/metainfo.yaml new file mode 100644 index 0000000..18fd45c --- /dev/null +++ b/metainfo.yaml @@ -0,0 +1,15 @@ +description: Complex Shader Wallpaper Arrangements +tier: 1 +type: solution +platforms: + - name: Linux + - name: FreeBSD +portingAid: false +deprecated: false +release: true +libraries: +cmakename: komplex + +public_lib: true +group: Frameworks +subgroup: Tier 1 diff --git a/pack.json b/pack.json new file mode 100644 index 0000000..a2233f7 --- /dev/null +++ b/pack.json @@ -0,0 +1,36 @@ +{ + "author": "DigitalArtifex", + "name": "Test", + "version": "1.0.0", + "description": "Test", + "license": "GPLv3+", + "engine": "shadertoys", + "id": "sdE3sx", + + "type": 2, + "source": "/home/parametheus/Projects/Code/ControlsTest/shaders/video-glitch-extra.frag.qsb", + + "channel0": + { + "type": 2, + "source": "/home/parametheus/Projects/Code/ControlsTest/shaders/edge-detect-greyscale.frag.qsb", + + "resolution_x": 1920, + "resolution_y": 1080, + "resolution_scale": 1.0, + "time_scale": 1.0, + "mouse_scale": 1.0, + + "channel0": + { + "type": 2, + "source": "/home/parametheus/kde/src/komplex/package/contents/ui/Shaders/Generative/Glow-City.frag.qsb", + + "resolution_x": 1920, + "resolution_y": 1080, + "resolution_scale": 1.0, + "time_scale": 1.0, + "mouse_scale": 1.0 + } + } +} diff --git a/package/contents/config/main.xml b/package/contents/config/main.xml new file mode 100644 index 0000000..bede8a2 --- /dev/null +++ b/package/contents/config/main.xml @@ -0,0 +1,218 @@ + + + + + + + + Shaders6/Ps3menu.frag.qsb + + + + + + + + 0 + + + + false + + + + 1.0 + + + + true + + + + false + + + + 1.0 + + + + ./Resources/wallpaper2.png + + + + 0 + + + + 1920 + + + + 1080 + + + + 1 + + + + true + + + + 1.0 + + + + ./Resources/wallpaper2.png + + + + 0 + + + + 1920 + + + + 1080 + + + + 1 + + + + true + + + + 1.0 + + + + ./Resources/Shadertoy_Organic_2.jpg + + + + 0 + + + + 1920 + + + + 1080 + + + + 1 + + + + true + + + + 1.0 + + + + ./Resources/Shadertoy_Organic_2.jpg + + + + 0 + + + + 1920 + + + + 1080 + + + + 1 + + + + false + + + + 1.0 + + + + 1920 + + + + 1080 + + + + 1.0 + + + + 60 + + + + + + + + 0 + + + + false + + + + false + + + + false + + + + false + + + + false + + + + false + + + + 0 + + + + true + + + + + + + + diff --git a/package/contents/ui/KomplexModel.qml b/package/contents/ui/KomplexModel.qml new file mode 100644 index 0000000..a86f0cf --- /dev/null +++ b/package/contents/ui/KomplexModel.qml @@ -0,0 +1,207 @@ +/* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * WallpaperModel.qml + * + * This component provides a model for parsing and managing wallpaper configurations from + * a JSON file, specifically designed for the Komplex Wallpaper Engine. + * + * This enables infinite complexity in shader configurations + * + * This program 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. + * + * This program 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 this program. If not, see + */ + +import QtQuick + +import com.github.digitalartifex.komplex 1.0 as Komplex + +Item +{ + property real pixelRatio: 1 //This will (hopefully) be set to PlasmaCore.Units.devicePixelRatio in onCompleted + property vector3d iResolution: Qt.vector3d(wallpaper.configuration.resolution_x ? wallpaper.configuration.resolution_x : 1920, wallpaper.configuration.resolution_y ? wallpaper.configuration.resolution_y : 1080, 1)//width, height, pixel aspect ratio + property real iTime: 0 //used by most motion shaders + property real iTimeDelta: iTime + property var iChannelTime: [iTime, iTime, iTime, iTime] //individual channel time values + property real iSampleRate: 44100 //used by audio shaders + property int iFrame: 0 + property real iFrameRate: wallpaper.configuration.framerate_limit ? wallpaper.configuration.framerate_limit : 60 // Default frame rate for the shader + property vector4d iMouse + property var iDate + property bool running: true + + // Individual channel resolutions to customize performance and quality + property var iChannelResolution: [Qt.vector3d(wallpaper.configuration.iChannel0_resolution_x, wallpaper.configuration.iChannel0_resolution_y, pixelRatio), + Qt.vector3d(wallpaper.configuration.iChannel1_resolution_x, wallpaper.configuration.iChannel1_resolution_y, pixelRatio), + Qt.vector3d(wallpaper.configuration.iChannel2_resolution_x, wallpaper.configuration.iChannel2_resolution_y, pixelRatio), + Qt.vector3d(wallpaper.configuration.iChannel3_resolution_x, wallpaper.configuration.iChannel3_resolution_y, pixelRatio)] + + property string iChannel0: "" + property string iChannel1: "" + property string iChannel2: "" + property string iChannel3: "" + + id: mainItem + + Komplex.ShaderPackModel + { + id: shaderPackModel + onJsonChanged: + { + // Handle the JSON change if needed + console.log("Shader pack JSON changed:", shaderPackModel.json); + mainItem.parsePack(shaderPackModel.json); + } + } + + // The WindowModel is used to manage the interaction with the desktop environment + WindowModel + { + id: windowModel + screenGeometry: mainItem.parent.screenGeometry + } + + Rectangle + { + anchors.fill: parent + color: "black" + + // The output channel that combines all the input channels and displays the final shader output + // This channel must be set to a shader source file that has been pre-compiled to a QSB Fragment Shader + ShaderChannel + { + iTime: mainItem.iTime + iMouse: mainItem.iMouse + iResolution: mainItem.iResolution + + id: channelOutput + anchors.fill: parent + type: ShaderChannel.Type.ShaderChannel + + visible: true // Set to true to display the output + z: 9000 + } + + // To save on performance, just use one timer for all channels and shaders + // they will need to be bound to the mainItem properties they need to access + Timer + { + id: channelTimer + + //Not entirely sure if this will actually limit the frame rate + interval: (1 / mainItem.iFrameRate) * 1000 //fps to ms cycles :: fps = 60 = 1 / 60 = 0.01666 * 1000 = 16 + repeat: true + + running: true //wallpaper.configuration.running ? mainItem.running : true + + triggeredOnStart: true + onTriggered: + { + var date = new Date(); + var startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); + var secondsSinceMidnight = (date - startOfDay) / 1000; + + mainItem.iTime += (interval / 1000) * (wallpaper.configuration.shaderSpeed ? wallpaper.configuration.shaderSpeed : 1.0) + mainItem.iDate = Qt.vector4d(date.getFullYear(), date.getMonth() + 1, date.getDate(), secondsSinceMidnight) + } + } + } + + // Setup the connection to shader pack model for updates + Connections + { + target: shaderPackModel + + function onJsonChanged() + { + // Parse the JSON configuration and set the properties of the ShaderChannel + // mainItem.parsePack(shaderPackModel.json); + } + } + + // Load the default shader pack configuration on component completion + Component.onCompleted: + { + if(wallpaper.configuration.shader_package) + shaderPackModel.loadJson(wallpaper.configuration.shader_package); + else + shaderPackModel.loadJson("/home/parametheus/kde/src/komplex/pack.json"); // Load a default shader pack if none is specified + } + + // Function to parse the pack.json file and set the properties of the ShaderChannel + function parsePack(json) + { + var pack = JSON.parse(json); + var currentChannel = null; + + if (pack.channel0) + channelOutput.iChannel0 = parseChannel(pack.channel0); + if (pack.channel1) + channelOutput.iChannel1 = parseChannel(pack.channel1); + if (pack.channel2) + channelOutput.iChannel2 = parseChannel(pack.channel2); + if (pack.channel3) + channelOutput.iChannel3 = parseChannel(pack.channel3); + + var source + + // Ensure the source path is correctly resolved for relative paths + if(!pack.source.startsWith("/") && !pack.source.startsWith("file://")) + source = Qt.resolvedUrl(shaderPackModel.shaderPackPath + "/" + pack.source); + else if(!pack.source.startsWith("file://")) + source = Qt.resolvedUrl("file://" + pack.source); + + channelOutput.source = "file://" + (source || ""); // Set the shader source file + channelOutput.type = ShaderChannel.Type.ShaderChannel; // Set the shader + } + + // Recursive helper function to parse channels + function parseChannel(channel) + { + if (!channel) return; + + var source + + // Ensure the source path is correctly resolved for relative paths + if(!channel.source.startsWith("/") && !channel.source.startsWith("file://")) + source = Qt.resolvedUrl(shaderPackModel.shaderPackPath + "/" + channel.source); + else if(!channel.source.startsWith("file://")) + source = Qt.resolvedUrl("file://" + channel.source); + + var result = Qt.createQmlObject(`ShaderChannel + { + z: 0 + iTimeScale: ${channel.time_scale || 1.0} + iResolutionScale: ${channel.resolution_scale || 1.0} + visible: false + anchors.fill: parent + source: "file://" + "${source || ''}" + type: ${channel.type || 0} + iTime: mainItem.iTime * ${channel.time_scale || 1.0} + iMouse: mainItem.iMouse + iResolution: Qt.vector3d(${(channel.resolution_x || mainItem.width) * (channel.resolution_scale || 1.0)}, ${(channel.resolution_y || mainItem.width) * (channel.resolution_scale || 1.0)}, pixelRatio) + }`, mainItem); + + if (channel.channel0) + result.iChannel0 = parseChannel(channel.channel0); + if (channel.channel1) + result.iChannel1 = parseChannel(channel.channel1); + if (channel.channel2) + result.iChannel2 = parseChannel(channel.channel2); + if (channel.channel3) + result.iChannel3 = parseChannel(channel.channel3); + + return result; + } +} diff --git a/package/contents/ui/ShaderChannel.qml b/package/contents/ui/ShaderChannel.qml new file mode 100644 index 0000000..c052ee6 --- /dev/null +++ b/package/contents/ui/ShaderChannel.qml @@ -0,0 +1,422 @@ +/* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * ShaderChannel.qml + * + * This component provides a configurable channel type to more closely resemble how ShaderToys + * works. It can be configured to be an Image, Video, Shader, Audio, or CubeMap that can be + * used as the input channel of another ShaderChannel, allowing for more complex shader compositions. + * + * It would also appear that in order to support the audio channel, we will need to + * implement a way to capture the desktop audio in C++, as the MediaPlayer component does not support this. + * This will have to come later. + * + * Volumetric shaders do not seem to be widely used in ShaderToys, so it has not been implemented here. + * + * This program 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. + * + * This program 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 this program. If not, see + */ +pragma ComponentBehavior: Bound + +import QtQuick +import QtMultimedia +import QtQuick3D + +import com.github.digitalartifex.komplex 1.0 as Komplex + +Item +{ + enum Type + { + ImageChannel, + VideoChannel, + ShaderChannel, + CubeMapChannel + // AudioChannel + } + + property int type: ShaderChannel.Type.ImageChannel + property string source: "" + + property int fillMode: Image.PreserveAspectCrop + + property var iChannel0: null + property var iChannel1: null + property var iChannel2: null + property var iChannel3: null + + property vector3d iResolution + property real iResolutionScale: 1 // This is used to scale the resolution of the shader, allowing for performance optimizations + property real iTime: 0 //used by most motion shaders + property real lastITime: 0 + property real iTimeDelta: 0 + property var iChannelTime: [iTimeActual, iTimeActual, iTimeActual, iTimeActual] //individual channel time values + property real iSampleRate: 44100 //used by audio shaders + property int iFrame: 0 + property var iFrameRate: 60 + property vector4d iMouse + property var iDate + property real iTimeActual: 0 // This is used to track the actual time for the shader, according to the time scale + property real iTimeScale: 1 // This is used to scale the time for the shader, allowing for slow motion or fast forward effects per channel + + property var iChannelResolution: [Qt.vector3d(channel.width * iResolutionScale, channel.height * iResolutionScale, 1), Qt.vector3d(channel.width * iResolutionScale, channel.height * iResolutionScale, 1), Qt.vector3d(channel.width * iResolutionScale, channel.height * iResolutionScale, 1)] + + onITimeChanged: + { + iTimeDelta = iTime - lastITime + lastITime = iTime + iTimeActual += iTimeDelta * iTimeScale + } + + id: channel + visible: false // Set to false by default, main shader needs be set to true in MainWindow.qml + + // This is used to dynamically load the appropriate channel type based on the `type` property of the channel + Loader + { + id: loader + anchors.fill: parent + + sourceComponent: channelImage + + states:[ + State + { + when: channel.type === ShaderChannel.Type.ImageChannel + PropertyChanges + { + loader.sourceComponent: channelImage + } + }, + State + { + when: channel.type === ShaderChannel.Type.VideoChannel + PropertyChanges + { + loader.sourceComponent: channelVideo + } + }, + State + { + when: channel.type === ShaderChannel.Type.CubeMapChannel + PropertyChanges + { + loader.sourceComponent: channelCubeMap + } + }, + State + { + when: channel.type === ShaderChannel.Type.ShaderChannel + PropertyChanges + { + loader.sourceComponent: channelShader + } + } + // State + // { + // when: channel.type === ShaderChannel.Type.AudioChannel + // PropertyChanges + // { + // loader.sourceComponent: channelAudio + // } + // } + ] + } + + //The image channel will be the default channel type for backwards compatability + Component + { + id: channelImage + + Image + { + anchors.fill: parent + source: Qt.resolvedUrl(channel.source) + fillMode: channel.fillMode + } + } + + //Video channel + Component + { + id: channelVideo + + VideoOutput + { + property alias duration: mediaPlayer.duration + property alias mediaSource: mediaPlayer.source + property alias metaData: mediaPlayer.metaData + property alias playbackRate: mediaPlayer.playbackRate + property alias position: mediaPlayer.position + property alias seekable: mediaPlayer.seekable + property alias volume: audioOutput.volume + + signal sizeChanged + signal fatalError + + id: videoOutput + + visible: true + anchors.fill: parent + fillMode: channel.fillMode + + onHeightChanged: this.sizeChanged() + + MediaPlayer + { + id: mediaPlayer + videoOutput: videoOutput + loops: MediaPlayer.Infinite + source: Qt.resolvedUrl(channel.source) + + audioOutput: AudioOutput + { + id: audioOutput + volume: 0 + } + + onErrorOccurred: function(error, errorString) + { + if (MediaPlayer.NoError !== error) + { + console.log("[qmlvideo] VideoItem.onError error " + error + " errorString " + errorString) + videoOutput.fatalError() + } + } + + onSourceChanged: + { + if(mediaPlayer.source != "") + mediaPlayer.play() + else + mediaPlayer.stop() + } + } + + function start() { mediaPlayer.play() } + function stop() { mediaPlayer.stop() } + function seek(position) { mediaPlayer.setPosition(position); } + } + } + + // A shader channel can be a shader + Component + { + id: channelShader + + Item + { + // Setup the shader effect sources for each channel + // These are needed to provide the uniform data to the shader channel buffers + ShaderEffectSource + { + id: channelSource0 + sourceItem: channel.iChannel0 ? channel.iChannel0 : null + live: true + smooth: true + sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + } + + ShaderEffectSource + { + id: channelSource1 + sourceItem: channel.iChannel1 ? channel.iChannel1 : null + live: true + smooth: true + sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + } + + ShaderEffectSource + { + id: channelSource2 + sourceItem: channel.iChannel2 ? channel.iChannel2 : null + live: true + smooth: true + sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + } + + ShaderEffectSource + { + id: channelSource3 + sourceItem: channel.iChannel3 ? channel.iChannel3 : null + live: true + smooth: true + sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) + } + + // The shader effect that will be used to render the shader + ShaderEffect + { + property var iChannel0: channelSource0 + property var iChannel1: channelSource1 + property var iChannel2: channelSource2 + property var iChannel3: channelSource3 + + property var iResolution: channel.iResolution + property var iTime: channel.iTimeActual + property var iTimeDelta: channel.iTimeDelta + property var iChannelTime: channel.iChannelTime + property var iSampleRate: channel.iSampleRate + property var iFrame: channel.iFrame + property var iFrameRate: channel.iFrameRate + property var iMouse: channel.iMouse + property var iDate: channel.iDate + + property var iChannelResolution: channel.iResolution + + fragmentShader: Qt.resolvedUrl(channel.source) + anchors.fill: parent + } + } + } + + //In order to support CubeMaps, we will need to select a folder that contains a series of JPGs, named as described + //in the CubeMapTexture documentation ie "posx.jpg;negx.jpg;posy.jpg;negy.jpg;posz.jpg;negz.jpg" + Component + { + id: channelCubeMap + + View3D + { + id: view3d + anchors.fill: parent + + property real lastX: 0 + property real lastY: 0 + property bool mousePressed: false + property real yaw: 0 + property real pitch: 0 + + environment: SceneEnvironment + { + backgroundMode: SceneEnvironment.SkyBoxCubeMap + skyBoxCubeMap: CubeMapTexture + { + source: channel.source !== "" ? Qt.resolvedUrl(channel.source) + "/%p.jpg" : "" + } + } + + camera: PerspectiveCamera + { + id: camera + position: Qt.vector3d(0, 0, 10) + } + + function updateCamera() + { + yaw -= (channel.iMouse.x - lastX) * 0.5 + pitch -= (channel.iMouse.y - lastY) * -0.5 + pitch = Math.max(-89, Math.min(89, pitch)) + lastX = channel.iMouse.x + lastY = channel.iMouse.y + + var radYaw = yaw * Math.PI / 180 + var radPitch = pitch * Math.PI / 180 + var x = Math.cos(radPitch) * Math.sin(radYaw) + var y = Math.sin(radPitch) + var z = Math.cos(radPitch) * Math.cos(radYaw) + + camera.eulerRotation = Qt.vector3d((radPitch * 180 / Math.PI), (radYaw * 180 / Math.PI), 0) + } + + Connections + { + target: channel + function onIMouseChanged() + { + view3d.updateCamera() + } + } + } + } + + // Supporting this as an mp3 feels kinda silly. Should really figure out how to capture desktop audio with qml + // UPDATE: This is not currently supported in QML, so we will need to implement this in C++ later + // Component + // { + // id: channelAudio + // Rectangle + // { + // anchors.fill: parent + // color: "black" + + // property var audioData: new Array(512).fill(0) + // property alias texture: audioTexture + + // MediaDevices + // { + // id: devices + // } + + // AudioInput + // { + // id: audioInput + // device: devices.defaultAudioInput + // } + + // CaptureSession + // { + // id: captureSession + // audioInput: audioInput + // } + + // Timer + // { + // interval: 16 // ~60fps update + // running: true + // repeat: true + // onTriggered: + // { + // // Get audio levels and update texture + // // let buffer = audioInput.probe.audioBuffer() + // // if (buffer) + // // { + // // for (let i = 0; i < Math.min(buffer.length, 512); i++) { + // // audioData[i] = Math.abs(buffer[i]) + // // } + // // audioTexture.update() + // // } + // } + // } + + // ShaderEffectSource + // { + // id: audioTexture + // width: 512 + // height: 1 + // format: ShaderEffectSource.Alpha + // smooth: false + // hideSource: true + // sourceItem: Row + // { + // Repeater + // { + // model: 512 + // Rectangle + // { + // width: 1 + // height: 1 + // color: Qt.rgba(1, 1, 1, root.audioData[index]) + // } + // } + // } + // } + + // Component.onCompleted: + // { + // //captureSession.start() + // } + // } + // } +} \ No newline at end of file diff --git a/package/contents/ui/ShaderChannelConfiguration.qml b/package/contents/ui/ShaderChannelConfiguration.qml new file mode 100644 index 0000000..78de2d7 --- /dev/null +++ b/package/contents/ui/ShaderChannelConfiguration.qml @@ -0,0 +1,623 @@ +/* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * ShaderChannelConfiguration.qml + * + * This component is used to configure the shader channels for the output shader. + * It allows the user to select a file or folder for each channel type (Image, + * Video, Shader, Audio, CubeMap) and sets the appropriate properties on the + * ShaderChannel component. + * + * -------------------------------------------------------------------------------------------------------- + * + * This program 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. + * + * This program 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 this program. If not, see + */ +pragma ComponentBehavior: Bound + +import QtCore +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import org.kde.plasma.core as PlasmaCore +import QtCore +import Qt.labs.folderlistmodel 2.15 + +import QtQuick.Dialogs as Dialogs +import com.github.digitalartifex.komplex 1.0 as Komplex + +Item +{ + signal accepted() + signal rejected() + + property bool file: true + property string selectionTitle: "Select a file" + property var selectionFilter: ["All Files (*)"] + + // The current folder is used to set the initial folder for the file and folder dialogs + property string currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] + + // Individual folders for each channel type + property string shaderFolder: shaderPackModel.shadersPath + property string imageFolder: shaderPackModel.imagesPath + property string videoFolder: shaderPackModel.videosPath + property string cubemapFolder: shaderPackModel.cubeMapsPath + + property alias tmp_source: sourceEdit.text + property int tmp_type: 1 + property alias tmp_timeScale: speedSlider.value + property alias tmp_resolution_scale: resolutionScaleSlider.value + property alias tmp_resolution_x: resolutionXEdit.value + property alias tmp_resolution_y: resolutionYEdit.value + property bool tmp_enabled: tmp_source !== "" + property Palette palette + + property string source + property int type + property real timeScale + property real resolution_scale + property int resolution_x + property int resolution_y + property bool enabled + + id: window + + Komplex.ShaderPackModel + { + id: shaderPackModel + } + + // The selection model contains the list of available shader channel types + // and their respective properties. + ListModel + { + id: selectionModel + + // Commented out Audio channel as it is not implemented yet + // ListElement + // { + // file: true + // name: "Audio" + // icon: "qrc:/icons/audio.svg" + // title: "Select an Audio File" + // filter: "MP3 Files (*.mp3):WAV Files (*.wav)" + // type: ShaderChannel.Type.AudioChannel + // } + + ListElement + { + file: false + name: "Cubemap" + icon: "./icons/cube.svg" + title: "Select a CubeMap folder" + filter: "" + type: ShaderChannel.Type.CubeMapChannel + } + + ListElement + { + file: true + name: "Image" + icon: "./icons/image.svg" + title: "Select an Image File" + filter: "Image Files (*.jpg, *.jpeg, *.png, *.svg)" + type: ShaderChannel.Type.ImageChannel + } + + ListElement + { + file: true + name: "Shader" + icon: "./icons/3d-glasses.svg" + title: "Select a Shader File" + filter: "Shader Files (*frag.qsb)" + type: ShaderChannel.Type.ShaderChannel + } + + ListElement + { + file: true + name: "Video" + icon: "./icons/video.svg" + title: "Select a Video File" + filter: "Video Files (*.mov, *.avi, *.mkv, *.mp4)" + type: ShaderChannel.Type.VideoChannel + } + + function indexOf(type) + { + for(var i = 0; i < count; ++i) if (get(i).type == type) + return i + + return -1 + } + } + + Component + { + id: selectionDelegate + + Item + { + required property int index + required property int type + required property string name + required property string icon + required property string title + required property var filter + required property bool file + + width: 100 + height: 75 + + ColumnLayout + { + anchors.fill: parent + Image + { + source: icon + + Layout.preferredHeight: 50 + Layout.preferredWidth: 50 + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + } + + Text + { + id: label + text: name + color: "white" + + horizontalAlignment: Text.AlignHCenter + + Layout.fillHeight: false + Layout.fillWidth: true + Layout.alignment: Qt.AlignBottom + } + } + + MouseArea + { + hoverEnabled: true + anchors.fill: parent + z: 9000 // this is dumb but I can't get the mouse area to propogate without it + + onClicked: + { + list.currentIndex = parent.index + window.tmp_type = parent.type + window.selectionFilter = parent.filter.split(':') + window.selectionTitle = parent.title + window.file = parent.file + + switch(parent.type) + { + // case ShaderChannel.Type.AudioChannel: + // break; + case ShaderChannel.Type.CubeMapChannel: + window.currentFolder = window.cubemapFolder + break; + case ShaderChannel.Type.ImageChannel: + window.currentFolder = window.imageFolder + break; + case ShaderChannel.Type.ShaderChannel: + window.currentFolder = window.shaderFolder + break; + case ShaderChannel.Type.VideoChannel: + window.currentFolder = window.videoFolder + break; + } + } + } + } + } + + Component + { + id: highlight + Rectangle + { + width: list.currentItem.width; height: list.currentItem.height + color: "lightsteelblue"; radius: 5 + y: list.currentItem.y + Behavior on y + { + SpringAnimation + { + spring: 2 + damping: 0.1 + } + } + } + } + + ColumnLayout + { + anchors.fill: parent + spacing: 10 + + ListView + { + id: list + model: selectionModel + + Layout.fillWidth: true + Layout.preferredHeight: 100 + Layout.alignment: Qt.AlignTop + + delegate: selectionDelegate + orientation: Qt.Horizontal + clip: true + + highlight: highlight + highlightFollowsCurrentItem: true + focus: true + } + + RowLayout + { + Layout.alignment: Qt.AlignTop + + Label + { + color: palette.text + verticalAlignment: Text.AlignVCenter + text: i18nd("@option:shader_source_label", "Source") + + Layout.preferredWidth: Kirigami.Units.gridUnit * 6 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + } + + TextField + { + id: sourceEdit + Layout.fillWidth: true + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + } + + Button + { + icon.name: "folder-symbolic" + Layout.preferredWidth: Kirigami.Units.gridUnit * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + + onClicked: + { + if(window.file === true) + fileDialog.open() + else + folderDialog.open() + } + } + } + + RowLayout + { + Layout.alignment: Qt.AlignTop + id: speedLayout + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Shader speed:") + + Label + { + color: palette.text + verticalAlignment: Qt.AlignVCenter + Layout.preferredWidth: Kirigami.Units.gridUnit * 6 + + text: i18nd("@option:time_scale_label", "Shader Speed") + } + + Slider + { + id: speedSlider + Layout.fillWidth: true + from: 0 + to: 16 + stepSize: 0.1 + onValueChanged: shaderSpeedField.text = String(value.toFixed(2)); + } + + TextField + { + id: shaderSpeedField + inputMethodHints: Qt.ImhFormattedNumbersOnly + horizontalAlignment: Text.AlignRight + Layout.preferredWidth: Kirigami.Units.gridUnit * 4 + onEditingFinished: () => + { + let inputValue = parseFloat(text); + + if (isNaN(inputValue) || inputValue < speedSlider.from) + inputValue = speedSlider.from; + else if (inputValue > speedSlider.to) + inputValue = speedSlider.to; + + text = inputValue.toFixed(2); + speedSlider.value = inputValue; + } + + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + shaderSpeedField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + + background: Rectangle + { + color: shaderSpeedField.activeFocus ? palette.base : "transparent" + border.color: shaderSpeedField.activeFocus ? palette.highlight : "transparent" + border.width: 1 + radius: 4 + anchors.fill: shaderSpeedField + anchors.margins: -2 + } + } + } + + RowLayout + { + Layout.alignment: Qt.AlignTop + id: resolutionScaleLayout + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Shader speed:") + + Label + { + color: palette.text + verticalAlignment: Qt.AlignVCenter + text: i18nd("@option:time_scale_label", "Resolution Scale") + Layout.preferredWidth: Kirigami.Units.gridUnit * 6 + } + + Slider + { + id: resolutionScaleSlider + Layout.fillWidth: true + from: 0.125 + to: 1 + stepSize: 0.01 + onValueChanged: resolutionScaleField.text = String(value.toFixed(3)); + } + + TextField + { + id: resolutionScaleField + inputMethodHints: Qt.ImhFormattedNumbersOnly + horizontalAlignment: Text.AlignRight + + Layout.preferredWidth: Kirigami.Units.gridUnit * 4 + + onEditingFinished: () => + { + let inputValue = parseFloat(text); + + if (isNaN(inputValue) || inputValue < resolutionScaleSlider.from) + inputValue = resolutionScaleSlider.from; + else if (inputValue > resolutionScaleSlider.to) + inputValue = resolutionScaleSlider.to; + + text = inputValue.toFixed(3); + resolutionScaleSlider.value = inputValue; + } + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + resolutionScaleField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + background: Rectangle + { + color: resolutionScaleField.activeFocus ? palette.base : "transparent" + border.color: resolutionScaleField.activeFocus ? palette.highlight : "transparent" + border.width: 1 + radius: 4 + anchors.fill: resolutionScaleField + anchors.margins: -2 + } + } + } + + RowLayout + { + Layout.alignment: Qt.AlignTop + Layout.fillWidth: true + + Label + { + color: palette.text + text: i18nd("@option:resolution_label_x", "Resolution X") + Layout.preferredWidth: Kirigami.Units.gridUnit * 6 + } + + TextField + { + property int value + + Layout.preferredHeight: 35 + Layout.fillWidth: true + + id: resolutionXEdit + text: value + onEditingFinished: () => + { + var inputValue = parseInt(text); + + if (isNaN(inputValue) || inputValue < 0) + inputValue = 0 + + value = inputValue; + } + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + resolutionScaleField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + } + Label + { + color: palette.text + text: i18nd("@option:resolution_label_y", "Resolution Y") + Layout.preferredWidth: Kirigami.Units.gridUnit * 6 + } + + TextField + { + property int value + + Layout.preferredHeight: 35 + Layout.fillWidth: true + + id: resolutionYEdit + text: value + onEditingFinished: () => + { + var inputValue = parseInt(text); + + if (isNaN(inputValue) || inputValue < 0) + inputValue = 0 + + value = inputValue; + } + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + resolutionScaleField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + } + } + RowLayout + { + Layout.fillWidth: true + Layout.alignment: Qt.AlignBottom | Qt.AlignRight + Layout.bottomMargin: 5 + + + Button + { + id: okayButton + text: "Okay" + onClicked: window.accept() + + Layout.alignment: Qt.AlignRight + } + + Button + { + id: cancelButton + text: "Cancel" + onClicked: window.reject() + + Layout.alignment: Qt.AlignRight + } + } + } + + // FileDialog is used to select a file for the Image, Shader, and Video channels + Dialogs.FileDialog + { + id: fileDialog + currentFolder: "file://" + window.currentFolder + nameFilters: window.selectionFilter + title: window.selectionTitle + + onAccepted: window.tmp_source = selectedFile + } + + // FolderDialog is used to select a folder for the CubeMap channel + Dialogs.FolderDialog + { + id: folderDialog + currentFolder: window.cubemapFolder + title: window.selectionTitle + + onAccepted: window.tmp_source = selectedFolder + } + + function accept() + { + // copy over temp values + source = tmp_source + type = tmp_type + timeScale = tmp_timeScale + resolution_scale = tmp_resolution_scale + resolution_x = tmp_resolution_x + resolution_y = tmp_resolution_y + enabled = tmp_enabled + + // Emit the accepted signal and reset the selection + window.accepted() + } + + function reject() + { + // Emit the rejected signal and reset the selection + resetSelection() + window.rejected() + } + + function configureChannel() + { + resetSelection() + } + + // Function to update the current selection based on the channel type + function updateCurrentSelection() + { + // Set the dialog properties based on the channel properties + switch(type) + { + case ShaderChannel.Type.CubeMapChannel: + window.currentFolder = window.cubemapFolder + break; + case ShaderChannel.Type.ImageChannel: + window.currentFolder = window.imageFolder + break; + case ShaderChannel.Type.ShaderChannel: + window.currentFolder = window.shaderFolder + break; + case ShaderChannel.Type.VideoChannel: + window.currentFolder = window.videoFolder + break; + } + + // Set the current selection index + list.currentIndex = selectionModel.indexOf(type) + } + + // Function to reset the selection to default values + function resetSelection() + { + tmp_source = source + tmp_timeScale = timeScale + tmp_resolution_scale = resolution_scale + tmp_resolution_x = resolution_x + tmp_resolution_y = resolution_y + + tmp_type = type + updateCurrentSelection() + } +} \ No newline at end of file diff --git a/package/contents/ui/ShaderToyModel.qml b/package/contents/ui/ShaderToyModel.qml new file mode 100644 index 0000000..9611df5 --- /dev/null +++ b/package/contents/ui/ShaderToyModel.qml @@ -0,0 +1,226 @@ + /* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * This was originally part of the KDE Shader Wallpaper Project, which was the inspiration for this project. + * It has been modified to use the new channel structure and is being used to support + * ShaderToy imports. + * + * -------------------------------------------------------------------------------------------------------- + * + * This program 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. + * + * This program 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 this program. If not, see . + * + * This software uses some of the QML code from JaredTao/jared2020@163.com's ToyShader for Android. + * See: https://github.com/jaredtao/TaoShaderToy/ + */ +pragma ComponentBehavior: Bound + +import QtCore +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs as Dialogs + +import org.kde.plasma.core as PlasmaCore + +Item +{ + property real pixelRatio: 1 //This will (hopefully) be set to PlasmaCore.Units.devicePixelRatio in onCompleted + property vector3d iResolution: Qt.vector3d(wallpaper.configuration.resolution_x,wallpaper.configuration.resolution_y,1)//width, height, pixel aspect ratio + property real iTime: 0 //used by most motion shaders + property real iTimeDelta: iTime + property var iChannelTime: [iTime, iTime, iTime, iTime] //individual channel time values + property real iSampleRate: 44100 //used by audio shaders + property int iFrame: 0 + property real iFrameRate: wallpaper.configuration.framerate_limit // Default frame rate for the shader + property vector4d iMouse + property var iDate + property bool running: windowModel.runShader // Controls whether the wallpaper is running or paused + + // Individual channel resolutions to customize performance and quality + property var iChannelResolution: [Qt.vector3d(wallpaper.configuration.iChannel0_resolution_x, wallpaper.configuration.iChannel0_resolution_y, pixelRatio), + Qt.vector3d(wallpaper.configuration.iChannel1_resolution_x, wallpaper.configuration.iChannel1_resolution_y, pixelRatio), + Qt.vector3d(wallpaper.configuration.iChannel2_resolution_x, wallpaper.configuration.iChannel2_resolution_y, pixelRatio), + Qt.vector3d(wallpaper.configuration.iChannel3_resolution_x, wallpaper.configuration.iChannel3_resolution_y, pixelRatio)] + + id: mainItem + + // The WindowModel is used to manage the interaction with the desktop environment + WindowModel + { + id: windowModel + screenGeometry: mainItem.parent.screenGeometry + } + + Rectangle + { + anchors.fill: parent + color: "black" + + Text + { + color: "white" + text: "

" + wallpaper.configuration.selectedShaderPath + "

" + } + + // Setup the shader channels (iChannel0, iChannel1, iChannel2, iChannel3) + // These channels are used to pass channel data to the shader sources and can + // be configured to use different types of media (Image, Video, Shader, Audio, CubeMap) + ShaderChannel + { + //Fallback to a channel if the output channel is not set or there was an error loading the shader + visible: wallpaper.configuration.iChannel0_flag && (channelOutput.source === "" || channelOutput.source === undefined) + iTime: mainItem.iTime + iMouse: mainItem.iMouse + iResolution: mainItem.iChannelResolution[0] + + id: channel0 + anchors.fill: parent + type: wallpaper.configuration.iChannel0_flag ? wallpaper.configuration.iChannel0_type : 0 + + source: wallpaper.configuration.iChannel0_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel0) : "" + } + + ShaderChannel + { + //Fallback to a channel if the output channel is not set or there was an error loading the shader + visible: wallpaper.configuration.iChannel1_flag && (channelOutput.source === "" || channelOutput.source === undefined) + iTime: mainItem.iTime + iResolution: mainItem.iChannelResolution[1] + + id: channel1 + anchors.fill: parent + type: wallpaper.configuration.iChannel1_flag ? wallpaper.configuration.iChannel1_type : 0 + + source: wallpaper.configuration.iChannel1_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel1) : "" + } + + ShaderChannel + { + //Fallback to a channel if the output channel is not set or there was an error loading the shader + visible: wallpaper.configuration.iChannel2_flag && (channelOutput.source === "" || channelOutput.source === undefined) + iTime: mainItem.iTime + iResolution: mainItem.iChannelResolution[2] + + id: channel2 + anchors.fill: parent + type: wallpaper.configuration.iChannel2_flag ? wallpaper.configuration.iChannel2_type : 0 + + source: wallpaper.configuration.iChannel2_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel2) : "" + } + + ShaderChannel + { + //Fallback to a channel if the output channel is not set or there was an error loading the shader + visible: wallpaper.configuration.iChannel3_flag && (channelOutput.source === "" || channelOutput.source === undefined) + iTime: mainItem.iTime + iChannelTime: [mainItem.iTime, mainItem.iTime, mainItem.iTime, mainItem.iTime] + iResolution: mainItem.iChannelResolution[3] + iDate: mainItem.iDate + + id: channel3 + anchors.fill: parent + type: wallpaper.configuration.iChannel3_flag ? wallpaper.configuration.iChannel3_type : 0 + + source: wallpaper.configuration.iChannel3_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel3) : "" + } + + // The output channel that combines all the input channels and displays the final shader output + // This channel must be set to a shader source file that has been pre-compiled to a QSB Fragment Shader + ShaderChannel + { + iTime: mainItem.iTime + iMouse: mainItem.iMouse + iResolution: mainItem.iResolution + + id: channelOutput + anchors.fill: parent + type: ShaderChannel.Type.ShaderChannel + source: wallpaper.configuration.selectedShaderPath ? wallpaper.configuration.selectedShaderPath : "" + + iChannel0: channel0 + iChannel1: channel1 + iChannel2: channel2 + iChannel3: channel3 + + visible: true // Set to true to display the output + } + + // To save on performance, just use one timer for all channels + Timer + { + id: channelTimer + + //Not entirely sure if this will actually limit the frame rate + interval: (1 / mainItem.iFrameRate) * 1000 //fps to ms cycles :: fps = 60 = 1 / 60 = 0.01666 * 1000 = 16 + repeat: true + + running: mainItem.running + + triggeredOnStart: true + onTriggered: + { + var date = new Date(); + var startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); + var secondsSinceMidnight = (date - startOfDay) / 1000; + + mainItem.iTime += (interval / 1000) * (wallpaper.configuration.shaderSpeed ? wallpaper.configuration.shaderSpeed : 1.0) + mainItem.iDate = Qt.vector4d(date.getFullYear(), date.getMonth() + 1, date.getDate(), secondsSinceMidnight) + } + } + } + + Component.onCompleted: + { + Qt.createQmlObject(`import QtQuick + MouseArea + { + id: mouseTrackingArea + propagateComposedEvents: true + preventStealing: false + enabled: wallpaper.configuration.mouseAllowed + anchors.fill: parent + hoverEnabled: true + onPositionChanged: (mouse) => { + mouse.accepted = false + mainItem.iMouse.x = mouse.x * wallpaper.configuration.mouseSpeedBias + mainItem.iMouse.y = -mouse.y * wallpaper.configuration.mouseSpeedBias + } + onClicked:(mouse) => { + mouse.accepted = false + mainItem.iMouse.z = mouse.x + mainItem.iMouse.w = mouse.y + } + // this still doesnt work... guess a C++ wrapper is all that can be done? + onPressed:(mouse) => { + mouse.accepted = false + } + onPressAndHold:(mouse) => { + mouse.accepted = false + } + onDoubleClicked:(mouse) => { + mouse.accepted = false + } + //cancelled, entered, and exited do not pass mouse events, so we can remove them + onReleased:(mouse) => { + mouse.accepted = false + } + onWheel: (mouse) => { + mouse.accepted = false + } + }`, parent.parent, "mouseTrackerArea"); + + // Initialize pixelRatio for shader use + pixelRatio = 1 //PlasmaCore.Units.devicePixelRatio was removed in Plasma6 + } +} diff --git a/package/contents/ui/WindowModel.qml b/package/contents/ui/WindowModel.qml new file mode 100644 index 0000000..e06771b --- /dev/null +++ b/package/contents/ui/WindowModel.qml @@ -0,0 +1,178 @@ + /* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * WindowModel.qml + * + * Copyright 2018 Rog131 + * Copyright 2019 adhe + * Copyright 2024 Luis Bocanegra + * + * This file was part of the KDE Shader Wallpaper project and is used to track the + * desktop state. + * + * -------------------------------------------------------------------------------------------------------- + * + * This program 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. + * + * This program 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 this program. If not, see . + * + * This software uses some of the QML code from JaredTao/jared2020@163.com's ToyShader for Android. + * See: https://github.com/jaredtao/TaoShaderToy/ + */ + +pragma ComponentBehavior: Bound + +import QtQuick +import org.kde.taskmanager 0.1 as TaskManager +import org.kde.kwindowsystem + +import com.github.digitalartifex.komplex as Komplex + +Item +{ + id: wModel + property var screenGeometry + property int pauseMode: wallpaper.configuration.pauseMode + property bool runShader: false + property bool maximizedExists: false + property bool visibleExists: false + property bool activeExists: false + property var abstractTasksModel: TaskManager.AbstractTasksModel + property var appId: abstractTasksModel.AppId + property var isWindow: abstractTasksModel.IsWindow + property var isMinimized: abstractTasksModel.IsMinimized + property var isMaximized: abstractTasksModel.IsMaximized + property var isFullScreen: abstractTasksModel.IsFullScreen + property var isActive: abstractTasksModel.IsActive + property var isHidden: abstractTasksModel.IsHidden + property bool activeScreenOnly: wallpaper.configuration.checkActiveScreen + property var excludeWindows: wallpaper.configuration.excludeWindows + + Komplex.ShaderPackModel + { + id: shaderPackModel + } + + Connections + { + target: wallpaper.configuration + function onValueChanged() + { + wModel.updateWindowsInfo(); + } + } + + Connections + { + target: KWindowSystem + function onShowingDesktopChanged() + { + wModel.updateWindowsInfo(); + } + } + + onPauseModeChanged: + { + updateWindowsInfo(); + } + + function updateRun() + { + let shouldRun = true; + switch (pauseMode) + { + case 0: + shouldRun = !maximizedExists; + break; + case 1: + shouldRun = !activeExists; + break; + case 2: + shouldRun = !visibleExists; + break; + case 3: + shouldRun = true; + } + runShader = shouldRun; + } + + TaskManager.VirtualDesktopInfo + { + id: virtualDesktopInfo + } + + TaskManager.ActivityInfo + { + id: activityInfo + readonly property string nullUuid: "00000000-0000-0000-0000-000000000000" + } + + TaskManager.TasksModel + { + id: tasksModel + sortMode: TaskManager.TasksModel.SortVirtualDesktop + groupMode: TaskManager.TasksModel.GroupDisabled + virtualDesktop: virtualDesktopInfo.currentDesktop + activity: activityInfo.currentActivity + screenGeometry: wModel.screenGeometry + filterByVirtualDesktop: true + filterByScreen: parent.activeScreenOnly + filterByActivity: true + filterMinimized: true + + onActiveTaskChanged: + { + updateWindowsInfo(); + } + + onDataChanged: + { + updateWindowsInfo(); + } + + onCountChanged: + { + updateWindowsInfo(); + } + } + + function updateWindowsInfo() + { + let activeCount = 0; + let visibleCount = 0; + let maximizedCount = 0; + + if (!KWindowSystem.showingDesktop) + { + for (var i = 0; i < tasksModel.count; i++) + { + const currentTask = tasksModel.index(i, 0); + + // Long line + if (currentTask === undefined || excludeWindows.includes(tasksModel.data(currentTask, appId).replace(/\.desktop$/, "")) || tasksModel.data(currentTask, isHidden) || !tasksModel.data(currentTask, isWindow) || tasksModel.data(currentTask, isMinimized)) + continue; + + visibleCount += 1; + if (tasksModel.data(currentTask, isMaximized) || tasksModel.data(currentTask, isFullScreen)) + maximizedCount += 1; + if (tasksModel.data(currentTask, isActive)) + activeCount += 1; + } + } + + visibleExists = visibleCount > 0; + maximizedExists = maximizedCount > 0; + activeExists = activeCount > 0; + updateRun(); + } +} diff --git a/package/contents/ui/config.qml b/package/contents/ui/config.qml new file mode 100644 index 0000000..4fc76b0 --- /dev/null +++ b/package/contents/ui/config.qml @@ -0,0 +1,740 @@ +/* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * config.qml + * + * This component provides a configuration interface for the Komplex Wallpaper Engine, + * allowing users to customize shader settings, channel configurations, and other + * parameters related to the wallpaper engine. + * + * This program 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. + * + * This program 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 this program. If not, see + */ +// pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Controls +import QtQuick.Dialogs +import QtQuick.Layouts +import org.kde.kirigami as Kirigami +import org.kde.plasma.core as PlasmaCore +import QtCore +import Qt.labs.folderlistmodel 2.15 + +import com.github.digitalartifex.komplex 1.0 as Komplex + +Kirigami.FormLayout +{ + id: root + twinFormLayouts: parentLayout // required by parent + property alias formLayout: root // required by parent + property alias cfg_pauseMode: pauseModeCombo.currentIndex + property alias cfg_isPaused: runningCombo.checked + property alias cfg_selectedShaderIndex: selectedShader.currentIndex + property alias cfg_selectedShaderPath: selectedShader.shader + property alias cfg_iChannel0: shaderChannelConfig0.source + property alias cfg_iChannel1: shaderChannelConfig1.source + property alias cfg_iChannel2: shaderChannelConfig2.source + property alias cfg_iChannel3: shaderChannelConfig3.source + property alias cfg_iChannel0_flag: shaderChannelConfig0.enabled + property alias cfg_iChannel1_flag: shaderChannelConfig1.enabled + property alias cfg_iChannel2_flag: shaderChannelConfig2.enabled + property alias cfg_iChannel3_flag: shaderChannelConfig3.enabled + property alias cfg_iChannel0_type: shaderChannelConfig0.type + property alias cfg_iChannel1_type: shaderChannelConfig1.type + property alias cfg_iChannel2_type: shaderChannelConfig2.type + property alias cfg_iChannel3_type: shaderChannelConfig3.type + property alias cfg_iChannel0_timeScale: shaderChannelConfig0.timeScale + property alias cfg_iChannel1_timeScale: shaderChannelConfig1.timeScale + property alias cfg_iChannel2_timeScale: shaderChannelConfig2.timeScale + property alias cfg_iChannel3_timeScale: shaderChannelConfig3.timeScale + property alias cfg_iChannel0_resolution_scale: shaderChannelConfig0.resolution_scale + property alias cfg_iChannel1_resolution_scale: shaderChannelConfig1.resolution_scale + property alias cfg_iChannel2_resolution_scale: shaderChannelConfig2.resolution_scale + property alias cfg_iChannel3_resolution_scale: shaderChannelConfig3.resolution_scale + property alias cfg_iChannel0_resolution_x: shaderChannelConfig0.resolution_x + property alias cfg_iChannel0_resolution_y: shaderChannelConfig0.resolution_y + property alias cfg_iChannel1_resolution_x: shaderChannelConfig1.resolution_x + property alias cfg_iChannel1_resolution_y: shaderChannelConfig1.resolution_y + property alias cfg_iChannel2_resolution_x: shaderChannelConfig2.resolution_x + property alias cfg_iChannel2_resolution_y: shaderChannelConfig2.resolution_y + property alias cfg_iChannel3_resolution_x: shaderChannelConfig3.resolution_x + property alias cfg_iChannel3_resolution_y: shaderChannelConfig3.resolution_y + property alias cfg_shaderSpeed: speedSlider.value + property alias cfg_mouseSpeedBias: mouseBiasSlider.value + property alias cfg_mouseAllowed: mouseEnableButton.checked + property bool cfg_infoPlasma6Preview_dismissed + property bool cfg_warningResources_dismissed + property bool cfg_emergencyHelp_dismissed + property bool cfg_infoiChannelSettings_dismissed + property alias cfg_checkActiveScreen: activeScreenOnlyCheckbox.checked + property alias cfg_excludeWindows: excludeWindows.windows + property alias cfg_running: runningCombo.checked + + property alias cfg_shader_package: selectedShaderPack.shader + property alias cfg_shader_package_index: selectedShaderPack.currentIndex + property alias cfg_komplex_mode: engineModeSelect.currentIndex + + Palette + { + id: palette + } + + Komplex.ShaderPackModel + { + id: shaderPackModel + onJsonChanged: + { + // Handle the JSON change if needed + console.log("Shader pack JSON changed:", shaderPackModel.json); + root.cfg_shader_package = shaderPackModel.shaderPackPath + "/" + shaderPackModel.shaderPackName + "/pack.json" + } + } + + // Engine Mode Selection + + RowLayout + { + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Engine Mode:") + ComboBox + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + id: engineModeSelect + currentIndex: root.cfg_komplex_mode + onCurrentIndexChanged: root.cfg_komplex_mode = currentIndex + textRole: "label" + model: [ + { "label": i18nd("@option:komplex_mode", "ShaderToys") }, + { "label": i18nd("@option:komplex_mode", "Komplex") } + ] + } + } + TabBar + { + Layout.fillWidth: true + id: navBar + width: parent.width + TabButton { + text: qsTr("Shader") + } + TabButton { + text: qsTr("Shader Settings") + } + TabButton { + text: qsTr("Extra Settings") + } + } + RowLayout + { + Layout.fillWidth: true + Kirigami.InlineMessage + { + id: warningResources + Layout.fillWidth: true + type: Kirigami.MessageType.Warning + text: qsTr("Some shaders might consume more power and resources than others, beware!") + showCloseButton: true + visible: !root.cfg_warningResources_dismissed + onVisibleChanged: () => + { + root.cfg_warningResources_dismissed = true; + } + } + } + RowLayout + { + visible: root.cfg_komplex_mode === 0 && navBar.currentIndex === 0 + + id: shaderOutputLayout + spacing: Kirigami.Units.smallSpacing + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Output Shader:") + + ComboBox + { + property string shader + + id: selectedShader + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + model: FolderListModel + { + id: folderListModel + showDirs: false + showFiles: true + showHidden: true + nameFilters: ["*.frag.qsb"] + folder: "file://" + shaderPackModel.shadersPath + "/generative" + } + delegate: Component + { + id: folderListDelegate + ItemDelegate + { + width: parent ? parent.width : 0 + text: fileBaseName.replace("_", " ").charAt(0).toUpperCase() + fileBaseName.replace("_", " ").slice(1) + } + } + + textRole: "fileBaseName" + currentIndex: root.cfg_selectedShaderIndex + displayText: currentIndex === -1 ? "Custom File" : currentText.replace("_", " ").charAt(0).toUpperCase() + currentText.replace("_", " ").slice(1) + + onCurrentTextChanged: + { + root.cfg_selectedShaderIndex = currentIndex; + + if (root.cfg_selectedShaderIndex === -1) + return; + + var source = model.get(currentIndex, "fileUrl"); + shader = source; + } + } + + Button + { + id: shaderFileButton + icon.name: "folder-symbolic" + text: i18nd("@button:toggle_select_shader", "Select File") + Layout.preferredWidth: Kirigami.Units.gridUnit * 9 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + onClicked: + { + fileDialog.currentFolder = "file://" + shaderPackModel.shadersPath + "/generative"; + fileDialog.open(); + } + } + + FileDialog + { + id: fileDialog + fileMode: FileDialog.OpenFile + title: i18nd("@dialog_title:choose_shader", "Choose a shader") + // will accept and auto convert .frag in the near future + nameFilters: ["Shader files (*.frag.qsb)", "All files (*)"] + visible: false + currentFolder: `${StandardPaths.writableLocation(StandardPaths.HomeLocation)}/.local/share/komplex/shaders/` + onAccepted: + { + root.cfg_selectedShaderIndex = -1; + root.cfg_selectedShaderPath = selectedFile; + } + } + } + + // iChannel0 Configuration + RowLayout + { + visible: root.cfg_komplex_mode === 0 && navBar.currentIndex === 0 + id: channel0ConfigLayout + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Channel 1:") + + spacing: Kirigami.Units.smallSpacing + + Text + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + + color: palette.text + text: i18nd("@iChannel0_source", root.cfg_iChannel0 ? root.cfg_iChannel0 : "No source selected") + verticalAlignment: Text.AlignVCenter + elide: Text.ElideLeft + } + + Button + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + icon.name: "configure-symbolic" + onClicked: () => + { + shaderChannelConfig0.configureChannel(); + shaderChannelOverlay0.open(); + } + } + } + + Kirigami.OverlaySheet + { + id: shaderChannelOverlay0 + parent: applicationWindow().overlay + implicitHeight: 400 + + ShaderChannelConfiguration + { + id: shaderChannelConfig0 + palette: palette + height: 350 + onAccepted: shaderChannelOverlay0.close(); // Close the overlay after configuration + onRejected: shaderChannelOverlay0.close(); + } + } + + // iChannel1 Configuration + RowLayout + { + visible: root.cfg_komplex_mode === 0 && navBar.currentIndex === 0 + id: channel1ConfigLayout + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Channel 2:") + + Text + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + color: palette.text + text: i18nd("@iChannel1_source", root.cfg_iChannel1 ? root.cfg_iChannel1 : "No source selected") + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + Button + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + icon.name: "configure-symbolic" + onClicked: () => + { + shaderChannelConfig1.configureChannel(); + shaderChannelOverlay1.open(); + } + } + } + + Kirigami.OverlaySheet + { + id: shaderChannelOverlay1 + parent: applicationWindow().overlay + implicitHeight: 400 + + ShaderChannelConfiguration + { + id: shaderChannelConfig1 + height: 350 + onAccepted: shaderChannelOverlay1.close(); // Close the overlay after configuration + onRejected: shaderChannelOverlay1.close(); + } + } + + // iChannel2 Configuration + RowLayout + { + visible: root.cfg_komplex_mode === 0 && navBar.currentIndex === 0 + id: channel2ConfigLayout + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Channel 3:") + + Text + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + color: palette.text + text: i18nd("@iChannel2_source", root.cfg_iChannel2 ? root.cfg_iChannel2 : "No source selected") + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + Button + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + icon.name: "configure-symbolic" + onClicked: () => + { + shaderChannelConfig2.configureChannel(); + shaderChannelOverlay2.open(); + } + } + } + + Kirigami.OverlaySheet + { + id: shaderChannelOverlay2 + parent: applicationWindow().overlay + implicitHeight: 400 + + ShaderChannelConfiguration + { + id: shaderChannelConfig2 + height: 350 + onAccepted: shaderChannelOverlay2.close(); // Close the overlay after configuration + onRejected: shaderChannelOverlay2.close(); + } + } + + // iChannel3 Configuration + RowLayout + { + visible: root.cfg_komplex_mode === 0 && navBar.currentIndex === 0 + Layout.fillWidth: true + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Channel 4:") + + Text + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + color: palette.text + text: i18nd("@iChannel0_source", root.cfg_iChannel3 ? root.cfg_iChannel3 : "No source selected") + verticalAlignment: Text.AlignVCenter + elide: Text.ElideLeft + } + + Button + { + Layout.preferredWidth: Kirigami.Units.gridUnit * 2 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + icon.name: "configure-symbolic" + onClicked: () => + { + shaderChannelConfig3.configureChannel(); + shaderChannelOverlay3.open(); + } + } + } + + Kirigami.OverlaySheet + { + id: shaderChannelOverlay3 + parent: applicationWindow().overlay + implicitHeight: 400 + + ShaderChannelConfiguration + { + id: shaderChannelConfig3 + height: 350 + onAccepted: shaderChannelOverlay3.close(); // Close the overlay after configuration + onRejected: shaderChannelOverlay3.close(); + } + } + + RowLayout + { + visible: navBar.currentIndex === 1 + id: speedLayout + Layout.fillWidth: true + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Shader speed:") + + Slider + { + id: speedSlider + Layout.fillWidth: true + from: -10.0 + to: 10.0 + stepSize: 0.01 + onValueChanged: shaderSpeedField.text = String(value.toFixed(2)); + } + + TextField + { + id: shaderSpeedField + inputMethodHints: Qt.ImhFormattedNumbersOnly + horizontalAlignment: Text.AlignRight + Layout.preferredWidth: Kirigami.Units.gridUnit * 4 + onEditingFinished: () => + { + let inputValue = parseFloat(text); + + if (isNaN(inputValue) || inputValue < speedSlider.from) + inputValue = speedSlider.from; + else if (inputValue > speedSlider.to) + inputValue = speedSlider.to; + + text = inputValue.toFixed(2); + speedSlider.value = inputValue; + } + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + shaderSpeedField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + background: Rectangle + { + color: shaderSpeedField.activeFocus ? palette.base : "transparent" + border.color: shaderSpeedField.activeFocus ? palette.highlight : "transparent" + border.width: 1 + radius: 4 + anchors.fill: shaderSpeedField + anchors.margins: -2 + } + } + + } + ComboBox + { + visible: navBar.currentIndex === 1 + id: pauseModeCombo + + Kirigami.FormData.label: i18nd("@buttonGroup:pause_mode", "Pause:") + model: [ + { + 'label': i18nd("@option:pause_mode", "Maximized or full-screen windows") + }, + { + 'label': i18nd("@option:pause_mode", "Active window is present") + }, + { + 'label': i18nd("@option:pause_mode", "At least one window is shown") + }, + { + 'label': i18nd("@option:pause_mode", "Never") + } + ] + textRole: "label" + onCurrentIndexChanged: root.cfg_pauseMode = currentIndex + currentIndex: root.cfg_pauseMode + } + + CheckBox + { + visible: navBar.currentIndex === 1 + id: activeScreenOnlyCheckbox + + Kirigami.FormData.label: i18nd("@checkbox:screen_filter", "Filter:") + text: i18n("Only check for windows in active screen") + } + + TextField + { + visible: navBar.currentIndex === 1 + id: excludeWindows + property var windows: [] + width: Kirigami.Units.gridUnit * 11 + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Exclude windows:") + text: windows.join(",") + onEditingFinished: () => + { + windows = excludeWindows.text.trim().replace(/\s+/g, "").split(","); + } + ToolTip.visible: hovered + ToolTip.text: qsTr("A comma-separated list of fully-qualified App-IDs to exclude their windows from triggering pause mode.") + } + + CheckBox + { + visible: navBar.currentIndex === 1 + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", cfg_isPaused ? "Playing" : "Paused") + + id: runningCombo + checked: root.cfg_running + text: i18n("Play/Pause the shader") + onCheckedChanged: () => + { + wallpaper.configuration.running = checked; + root.cfg_running = checked; + } + } + + RowLayout + { + visible: navBar.currentIndex === 1 + id: mouseLayout + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Mouse allowed:") + Button + { + id: mouseEnableButton + icon.name: checked ? "followmouse-symbolic" : "hidemouse-symbolic" + text: i18nd("@button:toggle_use_mouse", checked ? "Enabled" : "Disabled") + checkable: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Enabling this will allow the shader to interact with the cursor but will prevent interaction with desktop elements") + } + } + + RowLayout + { + id: mouseBiasLayout + visible: root.cfg_mouseAllowed && navBar.currentIndex === 1 + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Mouse bias:") + ColumnLayout + { + Slider + { + id: mouseBiasSlider + Layout.preferredWidth: Kirigami.Units.gridUnit * 16 + from: -10.0 + to: 10.0 + stepSize: 0.01 + value: root.cfg_mouseSpeedBias ? root.cfg_mouseSpeedBias : 1.0 + onValueChanged: () => + { + mouseBiasField.text = String(value.toFixed(2)); + wallpaper.configuration.mouseBias = mouseBiasField.text; + root.cfg_mouseSpeedBias = mouseBiasField.text; + } + } + } + ColumnLayout + { + visible: navBar.currentIndex === 1 + TextField + { + id: mouseBiasField + text: root.cfg_mouseSpeedBias ? String(root.cfg_mouseSpeedBias.toFixed(2)) : "1.00" + inputMethodHints: Qt.ImhFormattedNumbersOnly + Layout.preferredWidth: Kirigami.Units.gridUnit * 3 + onEditingFinished: () => + { + let inputValue = parseFloat(text); + + if (isNaN(inputValue) || inputValue < mouseBiasSlider.from) + inputValue = mouseBiasSlider.from; + else if (inputValue > mouseBiasSlider.to) + inputValue = mouseBiasSlider.to; + + text = inputValue.toFixed(2); + mouseBiasSlider.value = inputValue; + wallpaper.configuration.mouseBias = inputValue; + root.cfg_mouseSpeedBias = inputValue; + } + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + mouseBiasField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + background: Rectangle + { + color: mouseBiasField.activeFocus ? palette.base : "transparent" + border.color: mouseBiasField.activeFocus ? palette.highlight : "transparent" + border.width: 1 + radius: 4 + anchors.fill: mouseBiasField + anchors.margins: -2 + } + } + } + } + + Button + { + visible: navBar.currentIndex === 1 + id: kofiButton + Layout.preferredWidth: Kirigami.Units.gridUnit * 5 + Layout.preferredHeight: Kirigami.Units.gridUnit * 3 + + contentItem: RowLayout + { + AnimatedImage + { + source: "icons/kofi.gif" + sourceSize.width: 36 + sourceSize.height: 36 + fillMode: Image.Pad + horizontalAlignment: Image.AlignLeft + transform: Translate + { + x: 8 + } + } + Text + { + text: i18nd("@button:kofi", "Kofi") + horizontalAlignment: Text.AlignHCenter + color: palette.text + transform: Translate + { + x: -8 + } + } + } + onClicked: () => + { + Qt.openUrlExternally("https://ko-fi.com/digitalartifex"); + } + } + + RowLayout + { + visible: root.cfg_komplex_mode === 1 && navBar.currentIndex === 0 + + spacing: Kirigami.Units.smallSpacing + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Shader Pack:") + + ComboBox + { + property string shader + + id: selectedShaderPack + Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + model: FolderListModel + { + id: packListModel + showDirs: true + showFiles: false + showHidden: false + nameFilters: ["*.frag.qsb"] + folder: "file://" + shaderPackModel.shadersPath + "/generative" + } + delegate: Component + { + id: packListDelegate + ItemDelegate + { + width: parent ? parent.width : 0 + text: fileBaseName.replace("_", " ").charAt(0).toUpperCase() + fileBaseName.replace("_", " ").slice(1) + } + } + + textRole: "fileBaseName" + currentIndex: root.cfg_shader_package + displayText: currentIndex === -1 ? "Custom File" : currentText.replace("_", " ").charAt(0).toUpperCase() + currentText.replace("_", " ").slice(1) + + onCurrentTextChanged: + { + root.cfg_selectedShaderIndex = currentIndex; + + if (root.cfg_selectedShaderIndex === -1) + return; + + var source = model.get(currentIndex, "fileUrl"); + shader = source; + } + } + + Button + { + id: packFileButton + icon.name: "folder-symbolic" + text: i18nd("@button:toggle_select_shader", "Select File") + Layout.preferredWidth: Kirigami.Units.gridUnit * 9 + Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + onClicked: + { + packDialog.currentFolder = "file://" + shaderPackModel.shaderPackInstallPath; + packDialog.open(); + } + } + + FileDialog + { + id: packDialog + fileMode: FileDialog.OpenFile + title: i18nd("@dialog_title:choose_shader", "Choose a shader") + // will accept and auto convert .frag in the near future + nameFilters: ["Shader Package files (*.json)", "All files (*)"] + visible: false + currentFolder: "file://" + shaderPackModel.shaderPackInstallPath + onAccepted: + { + root.cfg_shader_package_index = -1; + root.cfg_shader_package = selectedFile; + } + } + } +} diff --git a/package/contents/ui/icons/3d-glasses.svg b/package/contents/ui/icons/3d-glasses.svg new file mode 100644 index 0000000..ed7f2fc --- /dev/null +++ b/package/contents/ui/icons/3d-glasses.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/icons/3d-model.svg b/package/contents/ui/icons/3d-model.svg new file mode 100644 index 0000000..31c2fe3 --- /dev/null +++ b/package/contents/ui/icons/3d-model.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/icons/audio.svg b/package/contents/ui/icons/audio.svg new file mode 100644 index 0000000..5aca53c --- /dev/null +++ b/package/contents/ui/icons/audio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/icons/codepen.svg b/package/contents/ui/icons/codepen.svg new file mode 100644 index 0000000..8c53d89 --- /dev/null +++ b/package/contents/ui/icons/codepen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/icons/cube.svg b/package/contents/ui/icons/cube.svg new file mode 100644 index 0000000..4c211c9 --- /dev/null +++ b/package/contents/ui/icons/cube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/icons/image.svg b/package/contents/ui/icons/image.svg new file mode 100644 index 0000000..755d7db --- /dev/null +++ b/package/contents/ui/icons/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/icons/kofi.gif b/package/contents/ui/icons/kofi.gif new file mode 100644 index 0000000..2e0a81d Binary files /dev/null and b/package/contents/ui/icons/kofi.gif differ diff --git a/package/contents/ui/icons/video.svg b/package/contents/ui/icons/video.svg new file mode 100644 index 0000000..c5362d0 --- /dev/null +++ b/package/contents/ui/icons/video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/contents/ui/main.qml b/package/contents/ui/main.qml new file mode 100644 index 0000000..3803e07 --- /dev/null +++ b/package/contents/ui/main.qml @@ -0,0 +1,63 @@ +import QtCore +import QtQuick +import QtQml + +import org.kde.plasma.core +import org.kde.plasma.components as PlasmaComponents +import org.kde.plasma.extras as PlasmaExtras +import org.kde.plasma.plasmoid + +WallpaperItem +{ + Item + { + anchors.fill: parent + + Loader + { + id: pageLoader + anchors.fill: parent + active: true + sourceComponent: shaderToysContent + + states: [ + State + { + when: wallpaper.komplex_mode === 0 + PropertyChanges + { + pageLoader.sourceComponent: shaderToysContent + } + }, + State + { + when: wallpaper.komplex_mode === 1 + PropertyChanges + { + pageLoader.sourceComponent: packContent + } + } + ] + } + + Component + { + id: shaderToysContent + + ShaderToyModel + { + anchors.fill: parent + } + } + + Component + { + id: packContent + + KomplexModel + { + anchors.fill: parent + } + } + } +} \ No newline at end of file diff --git a/package/metadata.json b/package/metadata.json new file mode 100644 index 0000000..a57388b --- /dev/null +++ b/package/metadata.json @@ -0,0 +1,22 @@ +{ + "KPackageStructure": "Plasma/Wallpaper", + "KPlugin": { + "Authors": [ + { + "Name": "DigitalArtifex" + } + ], + "Category": "", + "Description": "Allows you to use Shaders as your wallpaper", + "Icon": "preferences-desktop-wallpaper", + "Id": "com.github.digitalartifex.komplex", + "License": "GPLv3+", + "Version": "1.0.0", + "Name": "Komplex Wallpaper Engine", + "ServiceTypes": [ + "Plasma/Wallpaper" + ] + }, + "X-KDE-ParentApp": "org.kde.plasmashell", + "X-Plasma-MainScript": "ui/main.qml" +} \ No newline at end of file diff --git a/plugin/.qmlls.ini b/plugin/.qmlls.ini new file mode 100644 index 0000000..a569cc0 --- /dev/null +++ b/plugin/.qmlls.ini @@ -0,0 +1,5 @@ +[General] +buildDir="/home/parametheus/kde/src/komplex/build/bin" +no-cmake-calls=false +docDir=/usr/share/doc/qt6 +importPaths="/usr/lib/qt6/qml" diff --git a/plugin/AudioModel.cpp b/plugin/AudioModel.cpp new file mode 100644 index 0000000..83b5f60 --- /dev/null +++ b/plugin/AudioModel.cpp @@ -0,0 +1,72 @@ +#include "AudioModel.h" + +#ifdef AUDIOMODEL_H + +AudioModel::AudioModel(QObject *parent) + : QObject(parent), m_deviceString(QString()) +{ +} + +AudioModel::~AudioModel() +{ + if (m_recorder) + { + m_recorder->stop(); + delete m_recorder; + } + + if (m_audioInput) + delete m_audioInput; + + if (m_captureSession) + delete m_captureSession; +} + +QByteArray AudioModel::frame() const +{ + // This function should return the current audio frame. + // For now, we return an empty QByteArray. + return QByteArray(); +} + +QString AudioModel::device() const +{ + return m_deviceString; +} + +QStringList AudioModel::availableDevices() const +{ + QStringList devices; + + // Assuming QAudioDeviceInfo is used to get available audio devices + for (const auto &device : QMediaDevices::audioInputs()) + { + devices.append(QString::fromLatin1(device.id())); + } + + return devices; +} + +void AudioModel::setDeviceName(const QString &device) +{ + if (m_deviceString == device) + return; + + m_deviceString = device; + + // if (m_audioInput) + // { + // m_audioInput->setDevice(QAudioInput(device)); + // getAudioFrame(); + // } +} + +void AudioModel::getAudioFrame() +{ + // This function should be implemented to retrieve the audio frame + // from the audio input device and emit the frameChanged signal. + // For now, we will just emit the signal to indicate that the frame is ready. + Q_EMIT frameChanged(); +} + +#endif \ No newline at end of file diff --git a/plugin/AudioModel.h b/plugin/AudioModel.h new file mode 100644 index 0000000..9f57e7e --- /dev/null +++ b/plugin/AudioModel.h @@ -0,0 +1,107 @@ +/* + * Komplex Wallpaper Engine + * Copyright (C) 2025 @DigitalArtifex | github.com/DigitalArtifex + * + * AudioModel.h + * + * This program 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. + * + * This program 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 this program. If not, see + */ + +#ifndef AUDIOMODEL_H +#define AUDIOMODEL_H +#include "Komplex_global.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + class KOMPLEX_EXPORT AudioModel : public QObject + { + Q_OBJECT + QML_ELEMENT + public: + explicit AudioModel(QObject *parent = nullptr); + ~AudioModel(); + + /**! + * @brief frame + * This function returns the current audio frame as a QString. + * It is expected to be called periodically to update the audio frame for the shader. + * + * @return QString containing the current audio frame. + */ + QByteArray frame() const; + + /**! + * @brief device + * This function returns the currently set audio device name. + * + * @return QString containing the name of the audio device. + */ + QString device() const; + + /**! + * @brief availableDevices + * This function returns a list of available audio devices on the system. + * + * @return QStringList containing the names of available audio devices. + */ + QStringList availableDevices() const; + + /**! + * @brief setDeviceName + * This function sets the audio device to be used for capturing audio frames. + * + * @param device The name of the audio device to set. + */ + Q_INVOKABLE void setDeviceName(const QString &device); + + /**! + * @brief getAudioFrame + * This function retrieves the current audio frame from the specified audio device. + * It is expected to be called periodically to update the audio frame for the shader. + * + * It is an asynchronous fuction and will emit the frameChanged signal when the audio frame is ready. + */ + Q_INVOKABLE void getAudioFrame(); + + Q_SIGNALS: + void frameChanged(); + + private: + QString m_deviceString; + + QMediaCaptureSession *m_captureSession = nullptr; + QAudioInput *m_audioInput = nullptr; + QMediaRecorder *m_recorder = nullptr; + + Q_PROPERTY(QByteArray frame READ frame NOTIFY frameChanged) + Q_PROPERTY(QString device READ device WRITE setDeviceName NOTIFY frameChanged) + }; + + +Q_DECLARE_METATYPE(AudioModel) + +#endif \ No newline at end of file diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt new file mode 100644 index 0000000..f648092 --- /dev/null +++ b/plugin/CMakeLists.txt @@ -0,0 +1,65 @@ +set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/plugin ${CMAKE_BINARY_DIR}/imports CACHE STRING "" FORCE) + +set(BUILD_QML ON CACHE BOOL "") + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +add_library( + ${PROJECT_NAME} + SHARED + plugin.cpp + ShaderPackModel.cpp + AudioModel.cpp +) + +qt_add_qml_module( + ${PROJECT_NAME} + URI + ${QMLPLUGIN_URI} + VERSION + 1.0 + PLUGIN_TARGET + ${PROJECT_NAME} + CLASS_NAME + KomplexPlugin + SOURCES + plugin.cpp + ShaderPackModel.cpp + AudioModel.cpp + NO_GENERATE_PLUGIN_SOURCE +) + +target_link_libraries( + ${PROJECT_NAME} + PRIVATE + Qt6::Quick + Qt6::Core + Qt6::Gui + Qt6::Quick3D + Qt6::Multimedia + Qt6::Qml + KF6::CoreAddons + KF6::I18n + KF6::Package +) + +target_compile_definitions( + ${PROJECT_NAME} + PUBLIC + KOMPLEX_PLUGIN +) + +ecm_finalize_qml_module(komplex) + +install( + TARGETS + ${PROJECT_NAME} + + DESTINATION + ${KDE_INSTALL_QMLDIR}/${QMLPLUGIN_INSTALL_URI} +) + +set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) +set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-Wl,--exclude-libs,ALL") \ No newline at end of file diff --git a/plugin/Komplex_global.h b/plugin/Komplex_global.h new file mode 100644 index 0000000..86c539e --- /dev/null +++ b/plugin/Komplex_global.h @@ -0,0 +1,10 @@ +#ifndef KOMPLEX_GLOBAL_H +#define KOMPLEX_GLOBAL_H + +#ifdef KOMPLEX_PLUGIN +#define KOMPLEX_EXPORT Q_DECL_EXPORT +#else +#define KOMPLEX_EXPORT Q_DECL_IMPORT +#endif + +#endif // KOMPLEX_GLOBAL_H \ No newline at end of file diff --git a/plugin/ShaderPackModel.cpp b/plugin/ShaderPackModel.cpp new file mode 100644 index 0000000..2a89447 --- /dev/null +++ b/plugin/ShaderPackModel.cpp @@ -0,0 +1,269 @@ +#include "ShaderPackModel.h" + +ShaderPackModel::ShaderPackModel(QObject *parent) + : QObject(parent), + m_shaderPackPath(QString("%1/.local/share/komplex/packs/default").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))), + m_shaderPackInstallPath(QString("%1/.local/share/komplex/packs").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))), + m_shadersPath(QString("%1/.local/share/komplex/shaders").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))), + m_imagesPath(QString("%1/.local/share/komplex/images").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))), + m_cubeMapsPath(QString("%1/.local/share/komplex/cubemaps").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))), + m_videosPath(QString("%1/.local/share/komplex/videos").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))), + m_json(QString()) +{ +} + +void ShaderPackModel::loadJson(const QString &filePath) +{ + if (filePath.isEmpty()) + return; + + setState(Loading); // Set the state to Loading + + // Open the file and read its contents + QFile file(filePath); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + setState(Idle); // Reset state to Idle + qWarning("Could not open file %s for reading", qPrintable(filePath)); + return; + } + + QByteArray fileData = file.readAll(); + file.close(); + + // Parse the JSON data to validate it + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(fileData, &error); + + if(error.error != QJsonParseError::NoError) + { + setState(Idle); // Reset state to Idle + qWarning("JSON parse error: %s at offset %d", qPrintable(error.errorString()), error.offset); + return; + } + + // Minify the JSON document to a QString + QString json = QString::fromLatin1(document.toJson(QJsonDocument::Compact)); + + // Check if the JSON content has changed + if (json != m_json) + { + m_json = json; + Q_EMIT jsonChanged(); + + setShaderPackPath(filePath); // Update the shader pack path + } + + setState(Idle); // Reset state to Idle +} + +QString ShaderPackModel::json() const +{ + return m_json; +} + +QStringList ShaderPackModel::availableShaderPacks() const +{ + return m_availableShaderPacks.keys(); +} + +void ShaderPackModel::refreshShaderPacks() +{ + setState(Loading); + + // check for and create the directory if it doesn't exist + QDir dir(m_shaderPackPath); + + if (!dir.exists()) + { + if (!dir.mkpath(m_shaderPackPath)) + { + setState(Idle); // Reset state to Idle + qWarning("Failed to create shader pack directory: %s", qPrintable(m_shaderPackPath)); + return; + } + } + + // Get a list of directories in the shader pack path + QStringList shaderPacks = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + QMap verifiedShaderPacks; + + // Only keep shader packs that contain a valid pack.json file + for(const QString &pack : std::as_const(shaderPacks)) + { + QDir packDir(dir.absoluteFilePath(pack)); + bool valid = false; + + // Check if the pack directory contains a pack.json file + if(packDir.exists("pack.json")) + { + // Load the pack.json data + QFile packFile(packDir.absoluteFilePath("pack.json")); + if (packFile.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QByteArray packData = packFile.readAll(); + packFile.close(); // close the file immediately after reading + + // Parse the JSON data to validate it + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(packData, &error); + if (error.error != QJsonParseError::NoError) + { + qWarning("Shader pack %s has invalid JSON: %s at offset %d", + qPrintable(pack), qPrintable(error.errorString()), error.offset); + } + else + valid = true; // JSON is valid + } + } + + // If valid, add to the list of verified shader packs + if(valid) + verifiedShaderPacks.insert(pack, packDir.absoluteFilePath("pack.json")); // Store the path to the pack.json file + // Otherwise, log a warning + else + qWarning("Shader pack %s does not contain a valid pack.json file", qPrintable(pack)); + } + + if(m_availableShaderPacks != verifiedShaderPacks) + { + m_availableShaderPacks = verifiedShaderPacks; + Q_EMIT shaderPacksChanged(); // Emit signal to notify that the list has changed + } + + setState(Idle); // Reset state to Idle +} + +void ShaderPackModel::loadShaderPack(const QString &name) +{ + setState(Loading); + + if (name.isEmpty() || !m_availableShaderPacks.contains(name)) + { + qWarning("Shader pack '%s' not found", qPrintable(name)); + return; + } + + QString filePath = m_availableShaderPacks.value(name); + loadJson(filePath); // Load the JSON content of the shader pack +} + +// This may be replaced with Quazip and something similar for tarballs in the future +void ShaderPackModel::importShaderPack(const QString &filePath) +{ + if (filePath.isEmpty()) + { + qWarning("File path is empty"); + return; + } + + QFileInfo file(filePath); + if (!file.exists()) + { + qWarning("File does not exist: %s", qPrintable(filePath)); + return; + } + + QProcess process; + QString command; + + setState(Importing); // Set the state to Importing + + // Check if the file is a zip or tarball + if(filePath.endsWith(".zip", Qt::CaseInsensitive)) + command = QString("unzip -o %1 -d %2/%3").arg(file.absoluteFilePath(), m_shaderPackInstallPath, file.baseName()); + else if(filePath.endsWith(".tar.gz", Qt::CaseInsensitive) || filePath.endsWith(".tar", Qt::CaseInsensitive)) + command = QString("tar -xf %1 -C %2/%3").arg(file.absoluteFilePath(), m_shaderPackInstallPath, file.baseName()); + else + { + setState(Idle); // Reset state to Idle + qWarning("Unsupported file format for shader pack import: %s", qPrintable(filePath)); + return; + } + + // Connect to the process finished signal to refresh shader packs and so the event loop can exit + connect(&process, &QProcess::finished, this, [this](int exitCode, QProcess::ExitStatus exitStatus) + { + // Check if the process exited normally and with a success code + if (exitStatus == QProcess::NormalExit && exitCode == 0) + refreshShaderPacks(); // Refresh the list of shader packs + else + { + setState(Idle); // Reset state to Idle + qWarning("Failed to import shader pack: Exit code %d, Status %d", exitCode, exitStatus); + return; + } + }); + + // Start the process + process.start(command); + + // Make sure the process started successfully + if (!process.waitForStarted()) + { + setState(Idle); // Reset state to Idle + qWarning("Failed to start process for importing shader pack: %s", qPrintable(process.errorString())); + return; + } +} + +ShaderPackModel::State ShaderPackModel::state() const +{ + return m_state; +} + +void ShaderPackModel::setState(State state) +{ + if (m_state != state) + { + m_state = state; + Q_EMIT stateChanged(); + } +} + +QString ShaderPackModel::shaderPackPath() const +{ + return m_shaderPackPath; +} + +void ShaderPackModel::setShaderPackPath(const QString &filePath) +{ + QFileInfo fileInfo(filePath); + + if (m_shaderPackPath != fileInfo.absolutePath()) + { + m_shaderPackPath = filePath; + Q_EMIT shaderPackPathChanged(); + } +} + +QString ShaderPackModel::shaderPackName() const +{ + return m_shaderPackName; +} + +QString ShaderPackModel::shaderPackInstallPath() const +{ + return m_shaderPackInstallPath; +} + +QString ShaderPackModel::shadersPath() const +{ + return m_shadersPath; +} + +QString ShaderPackModel::imagesPath() const +{ + return m_imagesPath; +} + +QString ShaderPackModel::cubeMapsPath() const +{ + return m_cubeMapsPath; +} + +QString ShaderPackModel::videosPath() const +{ + return m_videosPath; +} \ No newline at end of file diff --git a/plugin/ShaderPackModel.h b/plugin/ShaderPackModel.h new file mode 100644 index 0000000..b996c84 --- /dev/null +++ b/plugin/ShaderPackModel.h @@ -0,0 +1,154 @@ +#ifndef SHADERPACKMODEL_H +#define SHADERPACKMODEL_H + +#include "Komplex_global.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class KOMPLEX_EXPORT ShaderPackModel : public QObject +{ + Q_OBJECT + QML_ELEMENT +public: + explicit ShaderPackModel(QObject *parent = nullptr); + ~ShaderPackModel() override = default; + + // State enum to represent the current state of the model + // for the UI and configuration + enum State + { + Idle, + Loading, + Importing + }; + Q_ENUM(State) + + /**! + * @brief json + * This function returns the current JSON content as a QString. + * It is expected to be called to retrieve the shader pack's JSON data, + * after loadJson() has been called to load the shader pack. + * + * @return QString containing the JSON data. + */ + QString json() const; + + /**! + * @brief loadJson + * This function loads a JSON file from the specified path and updates + * the model. It emits jsonChanged() signal if the JSON content changes. + * + * @param filePath The path to the JSON file to load. + */ + Q_INVOKABLE void loadJson(const QString &filePath); + + /**! + * @brief availableShaderPacks + * This function returns a list of available shader packs. + * It is expected to be called to retrieve the list of shader packs. + * + * @return QStringList containing the names of available shader packs. + */ + QStringList availableShaderPacks() const; + + /**! + * @brief refreshShaderPacks + * This function refreshes the list of available shader packs by checking + * the shader pack directory for valid packs. It emits the shaderPacksChanged() + * signal if the list of available shader packs changes. + */ + Q_INVOKABLE void refreshShaderPacks(); + + /**! + * @brief loadShaderPack + * This function loads a shader pack from the specified file path. + * It is expected to be called to load a specific shader pack. + * + * @param name The name of the shader pack file to load. + */ + Q_INVOKABLE void loadShaderPack(const QString &name); + + /**! + * @brief importShaderPack + * This function imports a shader pack from the specified file path. + * It is expected to be called to be either a zip or tarball structured + * as described in the wiki. + * + * @param filePath The path to the shader pack file to import. + */ + Q_INVOKABLE void importShaderPack(const QString &filePath); + + /**! + * @brief state + * This function returns the current state of the model. + * It is expected to be called to retrieve the current state. + * + * @return State representing the current state of the model. + */ + State state() const; + + QString shaderPackPath() const; + QString shaderPackName() const; + QString shaderPackInstallPath() const; + + QString shadersPath() const; + QString imagesPath() const; + QString cubeMapsPath() const; + QString videosPath() const; + + protected: + void setState(State state); + void setShaderPackPath(const QString &filePath); + +Q_SIGNALS: + void shaderPackPathChanged(); + void shaderPackNameChanged(); + void shaderPackInstallPathChanged(); + void jsonChanged(); + void shaderPacksChanged(); + void stateChanged(); + void error(const QString &errorString); + +private: + QString m_shaderPackPath; + QString m_shaderPackName; + const QString m_shaderPackInstallPath; + + const QString m_shadersPath; + const QString m_imagesPath; + const QString m_cubeMapsPath; + const QString m_videosPath; + + QString m_json; + QMap m_availableShaderPacks; // Maps shader pack names to their file paths + State m_state = Idle; + + Q_PROPERTY(QString json READ json WRITE loadJson NOTIFY jsonChanged) + Q_PROPERTY(QStringList availableShaderPacks READ availableShaderPacks NOTIFY shaderPacksChanged) + Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(QString shaderPackPath READ shaderPackPath NOTIFY shaderPackPathChanged) + Q_PROPERTY(QString shaderPackName READ shaderPackName NOTIFY shaderPackNameChanged) + Q_PROPERTY(QString shaderPackInstallPath READ shaderPackInstallPath NOTIFY shaderPackInstallPathChanged) + + Q_PROPERTY(QString shadersPath READ shadersPath CONSTANT) + Q_PROPERTY(QString imagesPath READ imagesPath CONSTANT) + Q_PROPERTY(QString cubeMapsPath READ cubeMapsPath CONSTANT) + Q_PROPERTY(QString videosPath READ videosPath CONSTANT) +}; + +Q_DECLARE_METATYPE(ShaderPackModel) + +#endif // SHADERPACKMODEL_H \ No newline at end of file diff --git a/plugin/plugin.cpp b/plugin/plugin.cpp new file mode 100644 index 0000000..5a0d60c --- /dev/null +++ b/plugin/plugin.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +#include "AudioModel.h" +#include "ShaderPackModel.h" +#include "Komplex_global.h" + +class KOMPLEX_EXPORT KomplexPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid FILE "plugin.json") +public: + void registerTypes(const char *uri) override + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("com.github.digitalartifex.komplex")); + + qmlRegisterType(uri, 1, 0, "AudioModel"); + qmlRegisterType(uri, 1, 0, "ShaderPackModel"); + } +}; + +#include "plugin.moc" \ No newline at end of file diff --git a/plugin/plugin.json b/plugin/plugin.json new file mode 100644 index 0000000..c555782 --- /dev/null +++ b/plugin/plugin.json @@ -0,0 +1,18 @@ +{ + "Id" : "komplex", + "Name" : "Komplex Wallpaper Plugin", + "Version" : "1.0.0", + "CompatVersion" : "1.0.0", + "VendorId" : "digitalartifex", + "Vendor" : "Digital Artifex", + "Copyright" : "(C) 2025 Digital Artifex", + "License" : [ + "GLPL-3.0-or-later" + ], + "Category" : "Wallpaper Plugins", + "Description" : [ + "This plugin enables functionality for the Komplex wallpaper, allowing users to set and manage complex shader arrangements as wallpapers in their KDE environment." + ], + "Url" : "http://www.github.com/digitalartifex/komplex", + "DocumentationUrl" : "http://www.github.com/digitalartifex/komplex/wiki" +} \ No newline at end of file diff --git a/plugin/qmldir b/plugin/qmldir new file mode 100644 index 0000000..c42d0e8 --- /dev/null +++ b/plugin/qmldir @@ -0,0 +1,4 @@ +module com.github.digitalartifex.komplex +plugin komplex +classname AudioModel +classname ShaderPackModel \ No newline at end of file diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..46ed7a7 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,96 @@ +# Shader Dev Guide + +`ShaderCompiler.py` and `ShaderProcessor.py` are from the KDE Shader Wallpaper project + +## Automated Shader Import + +### Prerequisite +To compile shaders, you must use QT6's qsb, by default it isn't in your PATH. +qsb can be found in `/usr/lib/qt6/bin` +add it to your path like this: `export PATH:$PATH:/usr/lib/qt6/bin` and now we can call it from anywhere + +### Processing & Compiling +Currently, kde-shader-wallpaper doesn't support shaders that uses buffers + +Place the .frag shaders you want to convert here: `package/contents/ui/Shaders/ConvertMe` + +Run: +- `python ShaderProcessor.py` to add the required code to the shader files and process it (!!! it's probably a good idea to manually verify as it's not perfect!!! ) +- `python ShaderCompiler.py` to compile it to the `Shaders6` folder + +### Install the package +- `kpackagetool6 -t Plasma/Wallpaper -i package` + + ( You may need to remove the previously installed package first, which can be found here: `~/.local/share/plasma/wallpapers/online.knowmad.shaderwallpaper` ) + + +## Manual Shader Import + +### Processing + +Add this to your shader .frag file: + +```hlsl +// add this at the top of the file +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float iTime; + float iTimeDelta; + float iFrameRate; + float iSampleRate; + int iFrame; + vec4 iDate; + vec4 iMouse; + vec3 iResolution; + float iChannelTime[4]; + vec3 iChannelResolution[4]; +} ubuf; + +layout(binding = 1) uniform sampler2D iChannel0; +layout(binding = 2) uniform sampler2D iChannel1; +layout(binding = 3) uniform sampler2D iChannel2; +layout(binding = 4) uniform sampler2D iChannel3; + +vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy; + +// either rename them in the frag or add this (probably costs some performance) + +// int iFrame = ubuf.iFrame; +// float iTime = ubuf.iTime; +// float iTimeDelta = ubuf.iTimeDelta; +// vec3 iResolution = ubuf.iResolution; +// vec4 iMouse = ubuf.iMouse; +// etc... + +// these must be modified as you cant do that with arrays afaik: +// float iChannelTime[4]; +// vec3 iChannelResolution[4]; + +// add this at the end +void main() { + vec4 color = vec4(0.0); + mainImage(color, fragCoord); + fragColor = color; +} +``` + +### Compile +`qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o MYSHADER.frag.qsb MYSHADER.frag` + + +### Install the package +You may need to remove the previously installed package in your `~/.local/share/plasma/wallpapers/online.knowmad.shaderwallpaper` +`kpackagetool6 -t Plasma/Wallpaper -i package` + + + +## Reference + +- https://doc.qt.io/qt-6/qtshadertools-qsb.html +- https://invent.kde.org/plasma/libplasma diff --git a/tools/ShaderCompiler.py b/tools/ShaderCompiler.py new file mode 100644 index 0000000..941f8b3 --- /dev/null +++ b/tools/ShaderCompiler.py @@ -0,0 +1,42 @@ +import os +import subprocess + +# If they fail to convert, try only converting for 120,150 or 150 instead of 100 es +# otherwise, debug the shader it self + +# Paths +source_directory = 'processed' +output_directory = 'build' + +# Ensure output directory exists +os.makedirs(output_directory, exist_ok=True) + +# THIS WILL DELETE YOUR ORIGINAL FRAG AFTER COMPILING IF SET TO TRUE +DELETE_AFTER_COMPILATION = False + +# Iterate over all .frag files in the source directory +for root, dirs, files in os.walk(source_directory): + for file in files: + if file.endswith('.frag'): + # Construct the full path to the source file + source_file_path = os.path.join(root, file) + # Construct the output file path + output_file_name = file.replace('.frag', '.frag.qsb') + output_file_path = os.path.join(output_directory, output_file_name) + # Construct and execute the command + cmd = [ + 'qsb', '--glsl', '100 es,120,150', '--hlsl', '50', '--msl', '12', + '-o', output_file_path, source_file_path + ] + + try: + subprocess.run(cmd, check=True) + # If the command was successful, delete the source file + if (DELETE_AFTER_COMPILATION): + os.remove(source_file_path) + print(f"Successfully converted and deleted: {file}") + else: + print(f"Successfully converted: {file}") + except subprocess.CalledProcessError: + # If the command failed, do not delete the source file + print(f"Conversion failed for: {file}") diff --git a/tools/ShaderProcessor.py b/tools/ShaderProcessor.py new file mode 100644 index 0000000..2285fb5 --- /dev/null +++ b/tools/ShaderProcessor.py @@ -0,0 +1,82 @@ +import os +import re +import shutil + +# Specify the directory where your .frag files are located +directory_path = 'src' +output_directory = 'processed' + +# List of variables to update +variables_to_update = [ + 'iTime', 'iTimeDelta', 'iFrameRate', 'iSampleRate', + 'iFrame', 'iDate', 'iMouse', 'iResolution', + r'iChannelTime', r'iChannelResolution' +] + +# Header and footer to append +header = ''' +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float iTime; + float iTimeDelta; + float iFrameRate; + float iSampleRate; + int iFrame; + vec4 iDate; + vec4 iMouse; + vec3 iResolution; + float iChannelTime[4]; + vec3 iChannelResolution[4]; +} ubuf; + +layout(binding = 1) uniform sampler2D iChannel0; +layout(binding = 2) uniform sampler2D iChannel1; +layout(binding = 3) uniform sampler2D iChannel2; +layout(binding = 4) uniform sampler2D iChannel3; + +vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy; +''' + +footer = ''' + +void main() { + vec4 color = vec4(0.0); + mainImage(color, fragCoord); + fragColor = color; +} +''' + +for root, dirs, files in os.walk(directory_path): + for file in files: + if file.endswith('.frag'): + file_path = os.path.join(root, file) + + with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + + # Replace variable names + for var in variables_to_update: + content = re.sub(r'\b' + re.escape(var) + r'\b', 'ubuf.' + var, content) + + # Insert header after first empty line + insert_index = content.find('\n\n') + 1 + content = content[:insert_index] + header + content[insert_index:] + + # Append footer + content += footer + + # Construct new output path + relative_path = os.path.relpath(root, directory_path) + new_root = os.path.join(output_directory, relative_path) + os.makedirs(new_root, exist_ok=True) + new_file_path = os.path.join(new_root, file) + + # Write to the new file + with open(new_file_path, 'w', encoding='utf-8') as f: + f.write(content) diff --git a/tools/processed/002-Blue.frag b/tools/processed/002-Blue.frag new file mode 100644 index 0000000..95567c6 --- /dev/null +++ b/tools/processed/002-Blue.frag @@ -0,0 +1,141 @@ +// https://www.shadertoy.com/view/WldSRn +// credits to haquxx + +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float iTime; + float iTimeDelta; + float iFrameRate; + float iSampleRate; + int iFrame; + vec4 iDate; + vec4 iMouse; + vec3 iResolution; + float iChannelTime[4]; + vec3 iChannelResolution[4]; +} ubuf; + +layout(binding = 1) uniform sampler2D iChannel0; +layout(binding = 2) uniform sampler2D iChannel1; +layout(binding = 3) uniform sampler2D iChannel2; +layout(binding = 4) uniform sampler2D iChannel3; + +vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy; + +float sdSphere(vec3 pos, float size) +{ + return length(pos) - size; +} + +float sdBox(vec3 pos, vec3 size) +{ + pos = abs(pos) - vec3(size); + return max(max(pos.x, pos.y), pos.z); +} + +float sdOctahedron(vec3 p, float s) +{ + p = abs(p); + float m = p.x+p.y+p.z-s; + vec3 q; + if( 3.0*p.x < m ) q = p.xyz; + else if( 3.0*p.y < m ) q = p.yzx; + else if( 3.0*p.z < m ) q = p.zxy; + else return m*0.57735027; + + float k = clamp(0.5*(q.z-q.y+s),0.0,s); + return length(vec3(q.x,q.y-s+k,q.z-k)); +} + +float sdPlane(vec3 pos) +{ + return pos.y; +} + +mat2 rotate(float a) +{ + float s = sin(a); + float c = cos(a); + return mat2(c, s, -s, c); +} + +vec3 repeat(vec3 pos, vec3 span) +{ + return abs(mod(pos, span)) - span * 0.5; +} + +float getDistance(vec3 pos, vec2 uv) +{ + vec3 originalPos = pos; + + for(int i = 0; i < 3; i++) + { + pos = abs(pos) - 4.5; + pos.xz *= rotate(1.0); + pos.yz *= rotate(1.0); + } + + pos = repeat(pos, vec3(4.0)); + + float d0 = abs(originalPos.x) - 0.1; + float d1 = sdBox(pos, vec3(0.8)); + + pos.xy *= rotate(mix(1.0, 2.0, abs(sin(ubuf.iTime)))); + float size = mix(1.1, 1.3, (abs(uv.y) * abs(uv.x))); + float d2 = sdSphere(pos, size); + float dd2 = sdOctahedron(pos, 1.8); + float ddd2 = mix(d2, dd2, abs(sin(ubuf.iTime))); + + return max(max(d1, -ddd2), -d0); +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 p = (fragCoord.xy * 2.0 - ubuf.iResolution.xy) / min(ubuf.iResolution.x, ubuf.iResolution.y); + + // camera + vec3 cameraOrigin = vec3(0.0, 0.0, -10.0 + ubuf.iTime * 4.0); + vec3 cameraTarget = vec3(cos(ubuf.iTime) + sin(ubuf.iTime / 2.0) * 10.0, exp(sin(ubuf.iTime)) * 2.0, 3.0 + ubuf.iTime * 4.0); + vec3 upDirection = vec3(0.0, 1.0, 0.0); + vec3 cameraDir = normalize(cameraTarget - cameraOrigin); + vec3 cameraRight = normalize(cross(upDirection, cameraOrigin)); + vec3 cameraUp = cross(cameraDir, cameraRight); + vec3 rayDirection = normalize(cameraRight * p.x + cameraUp * p.y + cameraDir); + + float depth = 0.0; + float ac = 0.0; + vec3 rayPos = vec3(0.0); + float d = 0.0; + + for(int i = 0; i < 80; i++) + { + rayPos = cameraOrigin + rayDirection * depth; + d = getDistance(rayPos, p); + + if(abs(d) < 0.0001) + { + break; + } + + ac += exp(-d * mix(5.0, 10.0, abs(sin(ubuf.iTime)))); + depth += d; + } + + vec3 col = vec3(0.0, 0.3, 0.7); + ac *= 1.2 * (ubuf.iResolution.x/ubuf.iResolution.y - abs(p.x)) ; + vec3 finalCol = col * ac * 0.06; + fragColor = vec4(finalCol, 1.0); + fragColor.w = 1.0 - depth * 0.1; +} + +void main() { + vec4 color = vec4(0.0); + mainImage(color, fragCoord); + fragColor = color; +} diff --git a/tools/src/002-Blue.frag b/tools/src/002-Blue.frag new file mode 100644 index 0000000..09ffca5 --- /dev/null +++ b/tools/src/002-Blue.frag @@ -0,0 +1,108 @@ +// https://www.shadertoy.com/view/WldSRn +// credits to haquxx + +float sdSphere(vec3 pos, float size) +{ + return length(pos) - size; +} + +float sdBox(vec3 pos, vec3 size) +{ + pos = abs(pos) - vec3(size); + return max(max(pos.x, pos.y), pos.z); +} + +float sdOctahedron(vec3 p, float s) +{ + p = abs(p); + float m = p.x+p.y+p.z-s; + vec3 q; + if( 3.0*p.x < m ) q = p.xyz; + else if( 3.0*p.y < m ) q = p.yzx; + else if( 3.0*p.z < m ) q = p.zxy; + else return m*0.57735027; + + float k = clamp(0.5*(q.z-q.y+s),0.0,s); + return length(vec3(q.x,q.y-s+k,q.z-k)); +} + +float sdPlane(vec3 pos) +{ + return pos.y; +} + +mat2 rotate(float a) +{ + float s = sin(a); + float c = cos(a); + return mat2(c, s, -s, c); +} + +vec3 repeat(vec3 pos, vec3 span) +{ + return abs(mod(pos, span)) - span * 0.5; +} + +float getDistance(vec3 pos, vec2 uv) +{ + vec3 originalPos = pos; + + for(int i = 0; i < 3; i++) + { + pos = abs(pos) - 4.5; + pos.xz *= rotate(1.0); + pos.yz *= rotate(1.0); + } + + pos = repeat(pos, vec3(4.0)); + + float d0 = abs(originalPos.x) - 0.1; + float d1 = sdBox(pos, vec3(0.8)); + + pos.xy *= rotate(mix(1.0, 2.0, abs(sin(iTime)))); + float size = mix(1.1, 1.3, (abs(uv.y) * abs(uv.x))); + float d2 = sdSphere(pos, size); + float dd2 = sdOctahedron(pos, 1.8); + float ddd2 = mix(d2, dd2, abs(sin(iTime))); + + return max(max(d1, -ddd2), -d0); +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 p = (fragCoord.xy * 2.0 - iResolution.xy) / min(iResolution.x, iResolution.y); + + // camera + vec3 cameraOrigin = vec3(0.0, 0.0, -10.0 + iTime * 4.0); + vec3 cameraTarget = vec3(cos(iTime) + sin(iTime / 2.0) * 10.0, exp(sin(iTime)) * 2.0, 3.0 + iTime * 4.0); + vec3 upDirection = vec3(0.0, 1.0, 0.0); + vec3 cameraDir = normalize(cameraTarget - cameraOrigin); + vec3 cameraRight = normalize(cross(upDirection, cameraOrigin)); + vec3 cameraUp = cross(cameraDir, cameraRight); + vec3 rayDirection = normalize(cameraRight * p.x + cameraUp * p.y + cameraDir); + + float depth = 0.0; + float ac = 0.0; + vec3 rayPos = vec3(0.0); + float d = 0.0; + + for(int i = 0; i < 80; i++) + { + rayPos = cameraOrigin + rayDirection * depth; + d = getDistance(rayPos, p); + + if(abs(d) < 0.0001) + { + break; + } + + ac += exp(-d * mix(5.0, 10.0, abs(sin(iTime)))); + depth += d; + } + + vec3 col = vec3(0.0, 0.3, 0.7); + ac *= 1.2 * (iResolution.x/iResolution.y - abs(p.x)) ; + vec3 finalCol = col * ac * 0.06; + fragColor = vec4(finalCol, 1.0); + fragColor.w = 1.0 - depth * 0.1; +} \ No newline at end of file