Skip to content

Commit

Permalink
Merge pull request #15 from matyalatte/dev
Browse files Browse the repository at this point in the history
v0.5.1 update
  • Loading branch information
matyalatte authored Apr 9, 2023
2 parents 0824973 + 8250737 commit c22d5ed
Show file tree
Hide file tree
Showing 18 changed files with 436 additions and 378 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

env:
ZIP_NAME: UE4-DDS-Tools
GUI_VERSION: v0.2.2
GUI_VERSION: v0.3.0
PYTHON_VERSION: 3.9.12

jobs:
Expand Down
2 changes: 1 addition & 1 deletion bat/_1_export_as_tga.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ REM Export texture assets as tga or hdr. And save the asset path for injection
@if "%~1"=="" goto skip

@pushd %~dp0
python\python.exe src\main.py "%~1" --save_folder=exported --mode=export --export_as=tga
python\python.exe src\main.py "%~1" --save_folder=exported --mode=export --export_as=tga --skip_non_texture
echo %~1> src\_file_path_.txt
@popd

Expand Down
2 changes: 1 addition & 1 deletion bat/_3_inject.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ REM You can specify the asset path with _export_as_tga.bat or _set_asset_path.ba
@if "%~1"=="" goto skip

@pushd %~dp0
python\python.exe src\main.py src\_file_path_.txt "%~1" --save_folder=injected
python\python.exe src\main.py src\_file_path_.txt "%~1" --save_folder=injected --skip_non_texture --image_filter=cubic
@popd

pause
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
![test](https://github.com/matyalatte/UE4-DDS-tools/actions/workflows/test.yml/badge.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

# UE4-DDS-Tools ver0.5.0
# UE4-DDS-Tools ver0.5.1

Texture modding tools for UE games.
You can inject texture files (.dds, .tga, .hdr, etc.) into UE assets.
Expand Down
7 changes: 7 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
ver 0.5.1
- Updated GUI to v0.3.0
- Added tooltips to GUI
- Fixed a bug that max size will be uexp's max size.
- Fixed a bug that ubulk flags won't be updated correctly.
- Enabled "skip_non_texture" option and cubic filter as default.

ver 0.5.0
- Supported Texture2DArray, TextureCubeArray, and VolumeTexture
- Restored the batch file method for injection
Expand Down
18 changes: 15 additions & 3 deletions gui_definition.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"recommended": "0.3.0",
"gui": [
{
"label": "Inject",
Expand Down Expand Up @@ -49,8 +50,14 @@
"type": "check_array",
"label": "Options",
"id": "options_inject",
"items": ["No mipmaps", "Force uncompressed", "Skip non-texture assets", "Use cubic filter for mip generation"],
"values": [" --no_mipmaps", " --force_uncompressed", " --skip_non_texture", " --image_filter=cubic"]
"items": ["No mipmaps", "Force uncompressed", "Skip non-texture assets", "Use cubic filter"],
"values": [" --no_mipmaps", " --force_uncompressed", " --skip_non_texture", " --image_filter=cubic"],
"tooltip": [
"Disable mip generation.",
"Use uncompressed formats instead of BC1 ~ BC7 and ASTC.",
"No error for non-texture assets.",
"Use bicubic interpolation for mip generation."],
"default": [false, false, true, true]
}
]
},
Expand Down Expand Up @@ -104,7 +111,12 @@
"label": "Options",
"id": "options_export",
"items": ["No mipmaps", "Skip non-texture assets"],
"values": [" --no_mipmaps", " --skip_non_texture"]
"values": [" --no_mipmaps", " --skip_non_texture"],
"tooltip": [
"Discard mipmaps.",
"No error for non-texture assets."
],
"default": [false, true]
}
]
},
Expand Down
18 changes: 15 additions & 3 deletions gui_definition_unix.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"recommended": "0.3.0",
"gui": [
{
"label": "Inject",
Expand Down Expand Up @@ -50,8 +51,14 @@
"type": "check_array",
"label": "Options",
"id": "options_inject",
"items": ["No mipmaps", "Force uncompressed", "Skip non-texture assets", "Use cubic filter for mip generation"],
"values": [" --no_mipmaps", " --force_uncompressed", " --skip_non_texture", " --image_filter=cubic"]
"items": ["No mipmaps", "Force uncompressed", "Skip non-texture assets", "Use cubic filter"],
"values": [" --no_mipmaps", " --force_uncompressed", " --skip_non_texture", " --image_filter=cubic"],
"tooltip": [
"Disable mip generation.",
"Use uncompressed formats instead of BC1 ~ BC7 and ASTC.",
"No error for non-texture assets.",
"Use bicubic interpolation for mip generation."],
"default": [false, false, true, true]
}
]
},
Expand Down Expand Up @@ -105,7 +112,12 @@
"label": "Options",
"id": "options_export",
"items": ["No mipmaps", "Skip non-texture assets"],
"values": [" --no_mipmaps", " --skip_non_texture"]
"values": [" --no_mipmaps", " --skip_non_texture"],
"tooltip": [
"Discard mipmaps.",
"No error for non-texture assets."
],
"default": [false, true]
}
]
},
Expand Down
52 changes: 26 additions & 26 deletions src/directx/dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


class PF_FLAGS(IntEnum):
'''dwFlags for DDS_PIXELFORMAT'''
"""dwFlags for DDS_PIXELFORMAT"""
# ALPHAPIXELS = 0x00000001
# ALPHA = 0x00000002
FOURCC = 0x00000004
Expand Down Expand Up @@ -67,7 +67,7 @@ def __init__(self):
self.bit_mask = (c.c_uint32 * 4)((0) * 4)

def get_dxgi(self) -> DXGI_FORMAT:
'''Similar method as GetDXGIFormat in DirectXTex/DDSTextureLoader/DDSTextureLoader12.cpp'''
"""Similar method as GetDXGIFormat in DirectXTex/DDSTextureLoader/DDSTextureLoader12.cpp"""

if not self.is_canonical():
raise RuntimeError(f"Non-standard fourCC detected. ({self.fourCC.decode()})")
Expand Down Expand Up @@ -249,7 +249,7 @@ def is_array(self):


def is_hdr(name: str):
return 'BC6' in name or 'FLOAT' in name or 'INT' in name or 'SNORM' in name
return "BC6" in name or "FLOAT" in name or "INT" in name or "SNORM" in name


def convertible_to_tga(name: str):
Expand All @@ -270,10 +270,10 @@ def read_buffer(f: IOBase, size: int, end_offset: int):


class DDSHeader(c.LittleEndianStructure):
MAGIC = b'DDS '
MAGIC = b"DDS "
_pack_ = 1
_fields_ = [
("magic", c.c_char * 4), # Magic == 'DDS '
("magic", c.c_char * 4), # Magic == "DDS "
("head_size", c.c_uint32), # Size == 124
("flags", c.c_uint32), # DDS_FLAGS
("height", c.c_uint32),
Expand Down Expand Up @@ -334,7 +334,7 @@ def read(f: IOBase) -> "DDSHeader":
@staticmethod
def read_from_file(file_name: str) -> "DDSHeader":
"""Read dds header from a file."""
with open(file_name, 'rb') as f:
with open(file_name, "rb") as f:
head = DDSHeader.read(f)
return head

Expand Down Expand Up @@ -390,16 +390,16 @@ def is_hdr(self):

def is_normals(self):
dxgi = self.get_format_as_str()
return 'BC5' in dxgi or dxgi == 'R8G8_UNORM'
return "BC5" in dxgi or dxgi == "R8G8_UNORM"

def get_format_as_str(self):
return self.dxgi_format.name

def is_srgb(self):
return 'SRGB' in self.dxgi_format.name
return "SRGB" in self.dxgi_format.name

def is_int(self):
return 'UINT' in self.dxgi_format.name or 'SINT' in self.dxgi_format.name
return "UINT" in self.dxgi_format.name or "SINT" in self.dxgi_format.name

def is_canonical(self):
return self.pixel_format.is_canonical()
Expand Down Expand Up @@ -456,24 +456,24 @@ def cail(val, unit):
slice_size += _width * _height * byte_per_pixel
if slice_size != int(slice_size):
raise RuntimeError(
'The size of mipmap data is not int. This is unexpected.'
"The size of mipmap data is not int. This is unexpected."
)
width, height = width // 2, height // 2
width, height = max(block_size, width), max(block_size, height)

return mipmap_size_list, int(slice_size)

def print(self):
print(f' type: {self.get_texture_type()}')
print(f' format: {self.get_format_as_str()}')
print(f' width: {self.width}')
print(f' height: {self.height}')
print(f" type: {self.get_texture_type()}")
print(f" format: {self.get_format_as_str()}")
print(f" width: {self.width}")
print(f" height: {self.height}")
if self.is_3d():
print(f' depth: {self.depth}')
print(f" depth: {self.depth}")
elif self.is_array():
print(f' array_size: {self.get_array_size()}')
print(f" array_size: {self.get_array_size()}")
else:
print(f' mipmaps: {self.mipmap_num}')
print(f" mipmaps: {self.mipmap_num}")

def disassemble(self):
self.update(self.width, self.height, 1, self.mipmap_num, self.dxgi_format, self.is_cube(), 1)
Expand All @@ -493,10 +493,10 @@ def __init__(self, header: DDSHeader, slices: list[bytes] = None, mipmap_sizes:

@staticmethod
def load(file: str, verbose=False):
if file[-3:] not in ['dds', 'DDS']:
raise RuntimeError(f'Not DDS. ({file})')
print('load: ' + file)
with open(file, 'rb') as f:
if file[-3:] not in ["dds", "DDS"]:
raise RuntimeError(f"Not DDS. ({file})")
print("load: " + file)
with open(file, "rb") as f:
end_offset = get_size(f)

# read header
Expand All @@ -521,12 +521,12 @@ def load(file: str, verbose=False):

# save as dds
def save(self, file: str):
print('save: {}'.format(file))
print("save: {}".format(file))
folder = os.path.dirname(file)
if folder not in ['.', ''] and not os.path.exists(folder):
if folder not in [".", ""] and not os.path.exists(folder):
mkdir(folder)

with open(file, 'wb') as f:
with open(file, "wb") as f:
# write header
self.header.write(f)

Expand Down Expand Up @@ -574,6 +574,6 @@ def print(self, verbose):
if verbose:
# print mipmap info
for i, size in zip(range(len(self.mipmap_size_list)), self.mipmap_size_list):
print(f' Mipmap {i}')
print(f" Mipmap {i}")
width, height = size
print(f' size (w, h): ({width}, {height})')
print(f" size (w, h): ({width}, {height})")
28 changes: 14 additions & 14 deletions src/directx/dxgi_format.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'''Constants for DXGI formats
"""Constants for DXGI formats
Notes:
- Official document for DXGI formats
https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format
- Official repo for DDS
https://github.com/microsoft/DirectXTex
'''
"""
from enum import IntEnum


Expand Down Expand Up @@ -302,18 +302,18 @@ def int_to_byte(n):

# Used to detect DXGI format from fourCC
FOURCC_TO_DXGI = [
[[b'DXT1'], DXGI_FORMAT.BC1_UNORM],
[[b'DXT2', b'DXT3'], DXGI_FORMAT.BC2_UNORM],
[[b'DXT4', b'DXT5'], DXGI_FORMAT.BC3_UNORM],
[[b'ATI1', b'BC4U', b'3DC1'], DXGI_FORMAT.BC4_UNORM],
[[b'ATI2', b'BC5U', b'3DC2'], DXGI_FORMAT.BC5_UNORM],
[[b'BC4S'], DXGI_FORMAT.BC4_SNORM],
[[b'BC5S'], DXGI_FORMAT.BC5_SNORM],
[[b'BC6H'], DXGI_FORMAT.BC6H_UF16],
[[b'BC7L', b'BC7'], DXGI_FORMAT.BC7_UNORM],
[[b'RGBG'], DXGI_FORMAT.R8G8_B8G8_UNORM],
[[b'GRGB'], DXGI_FORMAT.G8R8_G8B8_UNORM],
[[b'YUY2', b'UYVY'], DXGI_FORMAT.YUY2],
[[b"DXT1"], DXGI_FORMAT.BC1_UNORM],
[[b"DXT2", b"DXT3"], DXGI_FORMAT.BC2_UNORM],
[[b"DXT4", b"DXT5"], DXGI_FORMAT.BC3_UNORM],
[[b"ATI1", b"BC4U", b"3DC1"], DXGI_FORMAT.BC4_UNORM],
[[b"ATI2", b"BC5U", b"3DC2"], DXGI_FORMAT.BC5_UNORM],
[[b"BC4S"], DXGI_FORMAT.BC4_SNORM],
[[b"BC5S"], DXGI_FORMAT.BC5_SNORM],
[[b"BC6H"], DXGI_FORMAT.BC6H_UF16],
[[b"BC7L", b"BC7"], DXGI_FORMAT.BC7_UNORM],
[[b"RGBG"], DXGI_FORMAT.R8G8_B8G8_UNORM],
[[b"GRGB"], DXGI_FORMAT.G8R8_G8B8_UNORM],
[[b"YUY2", b"UYVY"], DXGI_FORMAT.YUY2],
[[int_to_byte(36)], DXGI_FORMAT.R16G16B16A16_UNORM],
[[int_to_byte(110)], DXGI_FORMAT.R16G16B16A16_SNORM],
[[int_to_byte(111)], DXGI_FORMAT.R16_FLOAT],
Expand Down
Loading

0 comments on commit c22d5ed

Please sign in to comment.