diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 234c3af..af8bc9a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,13 +59,13 @@ jobs: if: runner.os=='Windows' run: | cd external/Texconv-Custom-DLL/batch_files - ./build_small.bat + ./build.bat - name: build shared library (for Unix) if: runner.os!='Windows' run: | cd external/Texconv-Custom-DLL/shell_scripts - bash build_small.sh + bash build.sh - name: Copy files run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b694c7..3ed2770 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,9 +37,9 @@ jobs: fail-fast: false matrix: include: - # Test with 2.83, 3.3, and 3.5 on Windows + # Test with 2.83, 3.3, and 3.6 on Windows - platform: windows-latest - blender-version: '3.5.1' + blender-version: '3.6.5' - platform: windows-latest blender-version: '3.3.7' @@ -66,13 +66,13 @@ jobs: - name: build dll (for Windows) if: runner.os=='Windows' run: | - external/Texconv-Custom-DLL/batch_files/build_small.bat + external/Texconv-Custom-DLL/batch_files/build.bat cp external/Texconv-Custom-DLL/texconv.dll addons/blender_dds_addon/directx - name: build shared library (for Unix) if: runner.os!='Windows' run: | - bash external/Texconv-Custom-DLL/shell_scripts/build_small.sh + bash external/Texconv-Custom-DLL/shell_scripts/build.sh cp external/Texconv-Custom-DLL/libtexconv.* addons/blender_dds_addon/directx - name: Set up Python v${{ env.python-version }} diff --git a/addons/blender_dds_addon/__init__.py b/addons/blender_dds_addon/__init__.py index 886106a..5bb11c2 100644 --- a/addons/blender_dds_addon/__init__.py +++ b/addons/blender_dds_addon/__init__.py @@ -8,7 +8,7 @@ bl_info = { 'name': 'DDS textures', 'author': 'Matyalatte', - 'version': (0, 3, 2), + 'version': (0, 3, 3), 'blender': (2, 83, 20), 'location': 'Image Editor > Sidebar > DDS Tab', 'description': 'Import and export .dds files', diff --git a/addons/blender_dds_addon/directx/texconv.py b/addons/blender_dds_addon/directx/texconv.py index 769057f..414aa3d 100644 --- a/addons/blender_dds_addon/directx/texconv.py +++ b/addons/blender_dds_addon/directx/texconv.py @@ -16,24 +16,34 @@ DLL = None +def get_dll_close_from_lib(lib_name): + """Return dll function to unlaod DLL if the library has it.""" + dlpath = find_library(lib_name) + if dlpath is None: + # DLL not found. + return None + try: + lib = ctypes.CDLL(dlpath) + if hasattr(lib, "dlclose"): + return lib.dlclose + except OSError: + pass + # dlclose not found. + return None + + def get_dll_close(): """Get dll function to unload DLL.""" if util.is_windows(): return ctypes.windll.kernel32.FreeLibrary else: - dlpath = find_library("c") - if dlpath is None: - dlpath = find_library("System") - elif dlpath is None: - # Failed to find the path to stdlib. - return None - - try: - stdlib = ctypes.CDLL(dlpath) - return stdlib.dlclose - except OSError: - # Failed to load stdlib. - return None + # Search libc, libdl, and libSystem + for lib_name in ["c", "dl", "System"]: + dlclose = get_dll_close_from_lib(lib_name) + if dlclose is not None: + return dlclose + # Failed to find dlclose + return None def unload_texconv(): @@ -43,7 +53,7 @@ def unload_texconv(): dll_close = get_dll_close() if dll_close is None: - raise RuntimeError("Failed to unload DLL. Restart Blender if you will remove the addon.") + raise RuntimeError("Failed to unload DLL.") handle = DLL._handle dll_close.argtypes = [ctypes.c_void_p] @@ -74,13 +84,12 @@ def load_dll(self, dll_path=None): raise RuntimeError(f'This OS ({util.get_os_name()}) is unsupported.') dirname = os.path.dirname(file_path) dll_path = os.path.join(dirname, dll_name) - dll_path2 = os.path.join(os.path.dirname(dirname), dll_name) # allow ../texconv.dll + + if util.is_arm(): + raise RuntimeError(f'{dll_name} does NOT support ARM devices') if not os.path.exists(dll_path): - if os.path.exists(dll_path2): - dll_path = dll_path2 - else: - raise RuntimeError(f'texconv not found. ({dll_path})') + raise RuntimeError(f'texconv not found. ({dll_path})') self.dll = ctypes.cdll.LoadLibrary(dll_path) DLL = self.dll @@ -176,6 +185,9 @@ def convert_to_dds(self, file, dds_fmt, out=None, if image_filter != "LINEAR": args += ["-if", image_filter] + if "SRGB" in dds_fmt: + args += ['-srgb'] + if ("BC5" in dds_fmt) and invert_normals: args += ['-inverty'] @@ -203,8 +215,7 @@ def __texconv(self, file, args, out=None, verbose=True, allow_slow_codec=False): if out not in ['.', ''] and not os.path.exists(out): util.mkdir(out) - args += ["-y"] - args += [os.path.normpath(file)] + args += ["-y", "--", os.path.normpath(file)] args_p = [ctypes.c_wchar_p(arg) for arg in args] args_p = (ctypes.c_wchar_p*len(args_p))(*args_p) @@ -233,7 +244,7 @@ def __texassemble(self, file, new_file, args, verbose=True): out = os.path.dirname(new_file) if out not in ['.', ''] and not os.path.exists(out): util.mkdir(out) - args += ["-y", "-o", new_file, file] + args += ["-y", "-o", new_file, "--", file] args_p = [ctypes.c_wchar_p(arg) for arg in args] args_p = (ctypes.c_wchar_p*len(args_p))(*args_p) diff --git a/addons/blender_dds_addon/directx/util.py b/addons/blender_dds_addon/directx/util.py index de87be5..21602e8 100644 --- a/addons/blender_dds_addon/directx/util.py +++ b/addons/blender_dds_addon/directx/util.py @@ -36,3 +36,7 @@ def is_linux(): def is_mac(): return get_os_name() == 'Darwin' + + +def is_arm(): + return 'arm' in platform.machine().lower() diff --git a/addons/blender_dds_addon/ui/export_dds.py b/addons/blender_dds_addon/ui/export_dds.py index 72d0bca..34c4bbc 100644 --- a/addons/blender_dds_addon/ui/export_dds.py +++ b/addons/blender_dds_addon/ui/export_dds.py @@ -13,7 +13,7 @@ import numpy as np from ..directx.dds import is_hdr, DDS -from ..directx.texconv import Texconv +from ..directx.texconv import Texconv, unload_texconv from .bpy_util import save_texture, dds_properties_exist, get_image_editor_space, flush_stdout from .texture_list import draw_texture_list @@ -266,6 +266,10 @@ def execute_base(self, context, file=None, directory=None, is_dir=False): print(traceback.format_exc()) self.report({'ERROR'}, e.args[0]) ret = {'CANCELLED'} + + # release DLL resources + unload_texconv() + return ret diff --git a/addons/blender_dds_addon/ui/import_dds.py b/addons/blender_dds_addon/ui/import_dds.py index 0976d6a..8184f52 100644 --- a/addons/blender_dds_addon/ui/import_dds.py +++ b/addons/blender_dds_addon/ui/import_dds.py @@ -13,7 +13,7 @@ import numpy as np from ..directx.dds import DDSHeader, DDS -from ..directx.texconv import Texconv +from ..directx.texconv import Texconv, unload_texconv from .bpy_util import get_image_editor_space, load_texture, dds_properties_exist, flush_stdout from .custom_properties import DDS_FMT_NAMES @@ -128,13 +128,15 @@ def import_dds(context, file): space.image = tex -def import_dds_rec(context, folder, count=0): +def import_dds_rec(context, folder): """Search a folder recursively, and import found dds files.""" + count = 0 for file in sorted(os.listdir(folder)): - if os.path.isdir(file): - count += import_dds_rec(context, os.path.join(folder, file), count=count) + path = os.path.join(folder, file) + if os.path.isdir(path): + count += import_dds_rec(context, path) elif file.split('.')[-1].lower() == "dds": - import_dds(context, os.path.join(folder, file)) + import_dds(context, path) count += 1 return count @@ -183,6 +185,9 @@ def execute_base(self, context, files=None, directory=None, is_dir=False): self.report({'ERROR'}, e.args[0]) ret = {'CANCELLED'} + # release DLL resources + unload_texconv() + return ret diff --git a/changelog.txt b/changelog.txt index dfe5e3f..ca3767f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,12 @@ +ver 0.3.3 +- Fixed a crash when closing Blender after exporting BC6 or BC7 textures. +- Fixed a bug that sRGB formats make textures brighter when exporting. +- Fixed an error when importing files from some specific directory structures. +- Fixed a bug that the `Import from a Directory` operation can not count DDS files correctly. +- Fixed an error when releasing DLL resources on Linux. +- Made the addon release DLL resources for each operation. +- Added an error for ARM devices. + ver 0.3.2 - Fixed an error when importing dds without image editor opened. - Fixed an error when changing workspace with file picker opened. @@ -36,4 +45,4 @@ ver 0.1.1 - Fixed typo ver 0.1.0 -- Initial release \ No newline at end of file +- Initial release diff --git a/docs/How-To-Build.md b/docs/How-To-Build.md index 59d6b62..6ad7abc 100644 --- a/docs/How-To-Build.md +++ b/docs/How-To-Build.md @@ -41,13 +41,13 @@ It'll download the file and place it in a proper location. ### for Windows Move to `./Blender-DDS-Addon/external/Texconv-Custom-DLL/batch_files`. -Then, type `build_small.bat`. +Then, type `build.bat`. `texconv.dll` will be generated in `./Blender-DDS-Addon/external/Texconv-Custom-DLL/` ### for Unix/Linux Move to `./Blender-DDS-Addon/external/Texconv-Custom-DLL/shell_scripts`. -Then, type `bash build_small.sh`. +Then, type `bash build.sh`. `libtexconv.so` (or `libtexconv.dylib`) will be generated in `./Blender-DDS-Addon/external/Texconv-Custom-DLL/` ## 4. Copy Texconv diff --git a/docs/README.md b/docs/README.md index 532e6c6..d4fff1c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,8 @@ -# Blender-DDS-Addon v0.3.2 +# Blender-DDS-Addon v0.3.3 [![Github All Releases](https://img.shields.io/github/downloads/matyalatte/Blender-DDS-Addon/total.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ![build](https://github.com/matyalatte/Blender-DDS-Addon/actions/workflows/build.yml/badge.svg) -Buy Me A Coffee Blender addon to import and export dds textures @@ -22,11 +21,9 @@ You can download zip files from [the release page](https://github.com/matyalatte - `blender_dds_addon*_Windows.zip` is for Windows. - `blender_dds_addon*_macOS.zip` is for Mac (10.15 or later). -- `blender_dds_addon*_Linux.zip` is for Ubuntu (20.04 or later). +- `blender_dds_addon*_Linux.zip` is for Linux with GLIBC 2.27+ and GLIBCXX 3.4.26+. -> The linux build only supports Ubuntu due to the glibc dependences. -> If you want to use it on other linux distributions, you should get the lib or build [Texconv](https://github.com/matyalatte/Texconv-Custom-DLL) by yourself. -> (But I don't know if it's possible on your platform.) +> The linux build only supports distributions using GLIBC and GLIBCXX. ## Getting Started @@ -118,7 +115,7 @@ Here is a list of supported formats. -## About Non-2D Textures +## Non-2D Textures The addon supports non-2D textures except for partial cubemaps. See wiki pages for the details. diff --git a/external/Texconv-Custom-DLL b/external/Texconv-Custom-DLL index 3b9dc6e..0c92461 160000 --- a/external/Texconv-Custom-DLL +++ b/external/Texconv-Custom-DLL @@ -1 +1 @@ -Subproject commit 3b9dc6eae1e7325b52e9a04b4946e4143d8c4f4a +Subproject commit 0c924612293485000caf5c313e3006f523ed511d diff --git a/tests/test_dds.py b/tests/test_dds.py index 820e464..d46d731 100644 --- a/tests/test_dds.py +++ b/tests/test_dds.py @@ -6,13 +6,16 @@ export_dds, texture_list, custom_properties) -from blender_dds_addon.directx.texconv import unload_texconv +from blender_dds_addon.directx.texconv import Texconv, unload_texconv import bpy bpy.utils.register_class(texture_list.DDSTextureListItem) bpy.utils.register_class(custom_properties.DDSCustomProperties) custom_properties.add_custom_props_for_dds() +texconv = Texconv() +texconv.dll.init_com() + def get_test_dds(): test_file = os.path.join("tests", "2d.dds")