diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 39228dd..64e840a 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -3,7 +3,7 @@ name: Package on: [push, pull_request] jobs: - build-freeimage-android: + build-freeimage-android-unity-2021: runs-on: ubuntu-latest container: image: unityci/editor:ubuntu-2021.3.14f1-android-1.0.1 @@ -21,11 +21,35 @@ jobs: shell: bash - uses: actions/upload-artifact@v3 with: - name: "arm64-v8a" + name: "arm64-v8a-unity-2021" path: build-arm64-v8a/libFreeImage.so - uses: actions/upload-artifact@v3 with: - name: "armeabi-v7a" + name: "armeabi-v7a-unity-2021" + path: build-armeabi-v7a/libFreeImage.so + build-freeimage-android-unity-2022: + runs-on: ubuntu-latest + container: + image: unityci/editor:ubuntu-2022.2.0f1-android-1.0.1 + steps: + - uses: actions/checkout@v1 + with: + submodules: true + - name: Build FreeImage + run: | + apt update -y + apt install cmake -y + apt install build-essential -y + chmod a+x scripts/build-android.py + python scripts/build-android.py /opt/unity/Editor + shell: bash + - uses: actions/upload-artifact@v3 + with: + name: "arm64-v8a-unity-2022" + path: build-arm64-v8a/libFreeImage.so + - uses: actions/upload-artifact@v3 + with: + name: "armeabi-v7a-unity-2022" path: build-armeabi-v7a/libFreeImage.so build-freeimage-ubuntu: runs-on: ubuntu-18.04 @@ -42,3 +66,71 @@ jobs: with: name: "ubuntu-16.04" path: build/libFreeImage.so + package-unity-2021-3: + needs: build-freeimage-android-unity-2021 + runs-on: ubuntu-latest + container: + image: unityci/editor:ubuntu-2021.3.9f1-base-1.0.1 + steps: + - uses: actions/checkout@v1 + with: + submodules: true + - uses: actions/download-artifact@master + with: + name: arm64-v8a-unity-2021 + path: binaries/arm64-v8a + - uses: actions/download-artifact@master + with: + name: armeabi-v7a-unity-2021 + path: binaries/armeabi-v7a + - uses: actions/download-artifact@master + with: + name: ubuntu-16.04 + path: binaries/linux + - name: Package + run: | + chmod a+x scripts/ci/activate-license.sh + ./scripts/ci/activate-license.sh + echo "Packaging..." + python scripts/export-unity-package.py /opt/unity/Editor/Unity -nodisplay + shell: bash + env: + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE_BASE64 }} + - uses: actions/upload-artifact@v3 + with: + name: UnityAsyncTextureImport-Unity-2021.3.unitypackage + path: UnityAsyncTextureImport.unitypackage + package-unity-2022-2: + needs: build-freeimage-android-unity-2022 + runs-on: ubuntu-latest + container: + image: unityci/editor:ubuntu-2022.2.0f1-base-1.0.1 + steps: + - uses: actions/checkout@v1 + with: + submodules: true + - uses: actions/download-artifact@master + with: + name: arm64-v8a-unity-2022 + path: binaries/arm64-v8a + - uses: actions/download-artifact@master + with: + name: armeabi-v7a-unity-2022 + path: binaries/armeabi-v7a + - uses: actions/download-artifact@master + with: + name: ubuntu-16.04 + path: binaries/linux + - name: Package + run: | + chmod a+x scripts/ci/activate-license.sh + ./scripts/ci/activate-license.sh + echo "Packaging..." + python scripts/export-unity-package.py /opt/unity/Editor/Unity -nodisplay + shell: bash + env: + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE_BASE64 }} + - uses: actions/upload-artifact@v3 + with: + name: UnityAsyncTextureImport-Unity-2022.2.unitypackage + path: UnityAsyncTextureImport.unitypackage diff --git a/README.md b/README.md new file mode 100644 index 0000000..7efdfe1 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# Unity Async Texture Importer (automatic builds) + +This repository is simply a set of build scripts and actions for building and packaging unity-async-textureimport for Unity. +See main repo here: https://codeberg.org/matiaslavik/unity-async-textureimport + +This is a faster alternative to [Texture2D.LoadImage](https://docs.unity3d.com/530/Documentation/ScriptReference/Texture2D.LoadImage.html) and , which can only be used on the main thread - and which will block the thread until it's done. + +# How to use +Create a [coroutine](https://docs.unity3d.com/Manual/Coroutines.html), and from there do this: +```csharp +TextureImporter importer = new TextureImporter(); +yield return importer.ImportTexture(texPath, FREE_IMAGE_FORMAT.FIF_JPEG); +Texture2D tex = importer.texture; +``` +See the sample scene for an example. + +# What it does +The TextureImporter class has a public IEnumerator ("ImportTexture") that you can call/yield from a coroutine. It runs a task in a separate thread that loads the texture file, converts it to raw data and generates mipmaps. When the task is done, the IEnumerator will finally upload the raw data by calling [Texture2D.LoadRawTextureData](https://docs.unity3d.com/ScriptReference/Texture2D.LoadRawTextureData.html). +Since the file reading, decompressing and mipmap generation is done in a separate thread, you will be able to load large textures without causing FPS lags/hiccups. +I used [FreeImage](https://freeimage.sourceforge.io/) for the texture loading/conversion. + +# License + MIT License + (See the "LICENSE" file) + + Note: This project uses the FreeImage library. To use this project, you should include a copy of the FreeImage license (GPL or FIPL). See more info here: https://freeimage.sourceforge.io/license.html diff --git a/bin-meta/arm64-v8a.meta b/bin-meta/arm64-v8a.meta new file mode 100644 index 0000000..4814473 --- /dev/null +++ b/bin-meta/arm64-v8a.meta @@ -0,0 +1,70 @@ +fileFormatVersion: 2 +guid: 836091bca52a63137ab87ad521299447 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARM64 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + userData: + assetBundleName: + assetBundleVariant: diff --git a/bin-meta/armeabi-v7a.meta b/bin-meta/armeabi-v7a.meta new file mode 100644 index 0000000..2c7b56f --- /dev/null +++ b/bin-meta/armeabi-v7a.meta @@ -0,0 +1,70 @@ +fileFormatVersion: 2 +guid: e7e092ec832ac5c2fa122b55f4711ca1 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux64: 1 + Exclude OSXUniversal: 1 + Exclude Win: 1 + Exclude Win64: 1 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 0 + settings: + CPU: None + userData: + assetBundleName: + assetBundleVariant: diff --git a/bin-meta/linux.meta b/bin-meta/linux.meta new file mode 100644 index 0000000..4fdc438 --- /dev/null +++ b/bin-meta/linux.meta @@ -0,0 +1,70 @@ +fileFormatVersion: 2 +guid: 50b327450dc276c1bb88b6bb553c63e1 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + : Any + second: + enabled: 0 + settings: + Exclude Android: 1 + Exclude Editor: 0 + Exclude Linux64: 0 + Exclude OSXUniversal: 0 + Exclude Win: 0 + Exclude Win64: 0 + - first: + Android: Android + second: + enabled: 0 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 1 + settings: + CPU: x86_64 + DefaultValueInitialized: true + OS: Linux + - first: + Standalone: Linux64 + second: + enabled: 1 + settings: + CPU: x86_64 + - first: + Standalone: OSXUniversal + second: + enabled: 1 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: None + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: None + userData: + assetBundleName: + assetBundleVariant: diff --git a/scripts/ci/activate-license.sh b/scripts/ci/activate-license.sh new file mode 100644 index 0000000..24e1de4 --- /dev/null +++ b/scripts/ci/activate-license.sh @@ -0,0 +1,6 @@ +apt install coreutils +echo "$UNITY_LICENSE" | base64 -d > unity_license.ulf +ls +ls /opt/unity/Editor/ +echo "Activating unity license..." +/opt/unity/Editor/Unity -batchmode -nographics -quit -manualLicenseFile unity_license.ulf || true diff --git a/scripts/export-unity-package.py b/scripts/export-unity-package.py new file mode 100644 index 0000000..08de012 --- /dev/null +++ b/scripts/export-unity-package.py @@ -0,0 +1,58 @@ +import os, shutil, errno, sys + +def copy_filedir(src, dst): + try: + shutil.copytree(src, dst) + except OSError as exc: # python >2.5 + if exc.errno in (errno.ENOTDIR, errno.EINVAL): + shutil.copy(src, dst) + else: raise + +if len(sys.argv) > 1: + unity_path = str(sys.argv[1]) +else: + print("ERROR: You need to pass the path to Unity editor executable.") + exit() + +nodisplay = "-nodisplay" in sys.argv +package_name = 'UnityAsyncTextureImport.unitypackage' +plugin_folder_name = 'UnityAsyncTextureImport' +unity_project_dir = 'unity-async-textureimport' + +export_project_path = "tmp-package-export" + +if os.path.exists(export_project_path): + shutil.rmtree(export_project_path) +os.mkdir(export_project_path) + +assets = ["Assets", "ACKNOWLEDGEMENTS.txt", "ACKNOWLEDGEMENTS.txt", "LICENSE", "README.md", "FreeImage-license-GPLv3"] + +for asset in assets: + src_asset = os.path.join(unity_project_dir, asset) + dest_asset = os.path.join(export_project_path, "Assets", plugin_folder_name, asset) + copy_filedir(src_asset, dest_asset) + +# Copy binaries +freeImage_bin_dir = os.path.join(export_project_path, "Assets", plugin_folder_name, "Assets", "Plugins", "FreeImage") +os.mkdir(os.path.join(freeImage_bin_dir, "Android")) +os.mkdir(os.path.join(freeImage_bin_dir, "Android", "arm64-v8a")) +copy_filedir(os.path.join("binaries", "arm64-v8a", "libFreeImage.so"), os.path.join(freeImage_bin_dir, "Android", "arm64-v8a", "libFreeImage.so")) +os.mkdir(os.path.join(freeImage_bin_dir, "Android", "armeabi-v7a")) +copy_filedir(os.path.join("binaries", "armeabi-v7a", "libFreeImage.so"), os.path.join(freeImage_bin_dir, "Android", "armeabi-v7a", "libFreeImage.so")) +#os.mkdir(os.path.join(freeImage_bin_dir, "Linux")) +copy_filedir(os.path.join("binaries", "linux", "libFreeImage.so"), os.path.join(freeImage_bin_dir, "Linux", "libFreeImage.so")) +# Copy meta files +shutil.copy(os.path.join("bin-meta", "arm64-v8a.meta"), os.path.join(freeImage_bin_dir, "Android", "arm64-v8a", "libFreeImage.so.meta")) +shutil.copy(os.path.join("bin-meta", "armeabi-v7a.meta"), os.path.join(freeImage_bin_dir, "Android", "armeabi-v7a", "libFreeImage.so.meta")) +shutil.copy(os.path.join("bin-meta", "linux.meta"), os.path.join(freeImage_bin_dir, "Linux", "libFreeImage.so.meta")) + +command_string = "\"{unity_path}\" -projectPath {project_path} -exportPackage Assets {package_name} -batchmode -nographics -silent-crashes -quit".format(unity_path=unity_path, project_path=export_project_path, package_name=package_name) +# Run through cvfb if no display available (building in container, etc.). +if nodisplay: + command_string = "xvfb-run --auto-servernum --server-args=\'-screen 0 640x480x24\' " + command_string +print(command_string) +os.system(command_string) + +shutil.copy(os.path.join(export_project_path, package_name), package_name) + +shutil.rmtree(export_project_path) diff --git a/unity-async-textureimport b/unity-async-textureimport index 183dc52..6abe120 160000 --- a/unity-async-textureimport +++ b/unity-async-textureimport @@ -1 +1 @@ -Subproject commit 183dc52a7b3d048637094426f3ac46c25179d25a +Subproject commit 6abe1205e08f71ec5b1cef2801a9b5e97e1e5f03