Skip to content

Commit

Permalink
[CMake] Refactor basis encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
past-due committed Sep 7, 2023
1 parent 78f2bfa commit 92de36a
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 15 deletions.
172 changes: 172 additions & 0 deletions cmake/WZBasisEncode.cmake
@@ -0,0 +1,172 @@
#
# _WZ_BASIS_ENCODE_GET_UNIQUE_TARGET_NAME is adapted from
# _GETTEXT_GET_UNIQUE_TARGET_NAME in: https://github.com/Kitware/CMake/blob/master/Modules/FindGettext.cmake
#
# Original license:
# -------------------------------------------------------------------
# CMake - Cross Platform Makefile Generator
# Copyright 2000-2023 Kitware, Inc. and Contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of Kitware, Inc. nor the names of Contributors
# may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# -------------------------------------------------------------------

function(_WZ_BASIS_ENCODE_GET_UNIQUE_TARGET_NAME _name _unique_name)
set(propertyName "_WZ_BASIS_ENCODE_UNIQUE_COUNTER_${_name}")
get_property(currentCounter GLOBAL PROPERTY "${propertyName}")
if(NOT currentCounter)
set(currentCounter 1)
endif()
set(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE)
math(EXPR currentCounter "${currentCounter} + 1")
set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} )
endfunction()

########################################################################
#
# WZ_BASIS_ENCODE_TEXTURES(OUTPUT_DIR outputDir
# TYPE <TEXTURE, NORMALMAP, SPECULARMAP, ALPHAMASK>
# [RESIZE <512 | 1024 | 2048 ...>]
# [UASTC_LEVEL <0 | 1 | 2 | 3 | 4> = 2]
# [RDO]
# FILES [files...]
# ENCODING_TARGET [target name]
# [TARGET_FOLDER <folder>]
# [ALL])
#
# Basis-encode a list of texture files, into the output folder <outputDir>.
#
# TYPE must be specified, and must be one of "TEXTURE", "NORMALMAP", "SPECULARMAP", or "ALPHAMASK".
#
# Notes on expected input formats:
# - For "SPECULARMAP": a single-channel (grayscale) PNG. Only the first channel is extracted and used.
# - For "ALPHAMASK": an RGBA PNG. Only the alpha channel is extracted and used.
#
# If RESIZE is specified, the texture images will be resized to RESIZE x RESIZE dimensions (if they aren't already) as a first step.
#
# If UASTC_LEVEL is specified, the -uastc_level parameter will be specified to set the UASTC encoding level:
# > Range is [0,4], default is 2, higher=slower but higher quality.
# > 0=fastest/lowest quality, 3=slowest practical option, 4=impractically slow/highest achievable quality
#
function(WZ_BASIS_ENCODE_TEXTURES)

if(NOT DEFINED BASIS_UNIVERSAL_CLI)
message(FATAL_ERROR "No basisu tool has been provided - set BASIS_UNIVERSAL_CLI to the path to basisu or disable WZ_ENABLE_BASIS_UNIVERSAL!")
endif()

set(_options ALL RDO)
set(_oneValueArgs OUTPUT_DIR TYPE RESIZE ENCODING_TARGET TARGET_FOLDER UASTC_LEVEL)
set(_multiValueArgs FILES)

CMAKE_PARSE_ARGUMENTS(_parsedArguments "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})

# Check that mandatory parameters were provided
if(NOT _parsedArguments_OUTPUT_DIR)
message( FATAL_ERROR "Missing required OUTPUT_DIR parameter" )
endif()
if(NOT _parsedArguments_TYPE OR NOT _parsedArguments_TYPE MATCHES "^(TEXTURE|NORMALMAP|SPECULARMAP|ALPHAMASK)$")
message( FATAL_ERROR "Missing valid TYPE parameter" )
endif()
if(NOT _parsedArguments_ENCODING_TARGET)
message( FATAL_ERROR "Missing required ENCODING_TARGET parameter" )
endif()
if(NOT _parsedArguments_FILES)
message( FATAL_ERROR "Missing required FILES parameter" )
endif()

# Optional arguments with defaults
if(DEFINED _parsedArguments_UASTC_LEVEL)
if (NOT _parsedArguments_UASTC_LEVEL MATCHES "^(0|1|2|3|4)$")
message( FATAL_ERROR "Invalid UASTC_LEVEL value: ${_parsedArguments_UASTC_LEVEL}" )
endif()
set(_uastc_level ${_parsedArguments_UASTC_LEVEL})
else()
set(_uastc_level 2)
endif()

# Construct variable encoding arguments
unset(_resample_arguments)
if(_parsedArguments_RESIZE)
set(_resample_arguments "-resample" "${_parsedArguments_RESIZE}" "${_parsedArguments_RESIZE}")
endif()
unset(_rdo_arguments)
unset(_type_dependent_arguments)
if(_parsedArguments_TYPE STREQUAL "TEXTURE")
set(_type_dependent_arguments -mipmap)
if (_parsedArguments_RDO)
set(_rdo_arguments -uastc_rdo_l 1.0)
endif()
elseif(_parsedArguments_TYPE STREQUAL "NORMALMAP")
set(_type_dependent_arguments -mipmap -normal_map -mip_filter mitchell)
if (_parsedArguments_RDO)
set(_rdo_arguments -uastc_rdo_l 1.0)
endif()
elseif(_parsedArguments_TYPE STREQUAL "SPECULARMAP")
set(_type_dependent_arguments -mipmap -linear -mip_linear -no_selector_rdo -no_endpoint_rdo -swizzle rrra -no_alpha -mip_filter mitchell)
if (_parsedArguments_RDO)
set(_rdo_arguments -uastc_rdo_l 1.0)
endif()
elseif(_parsedArguments_TYPE STREQUAL "ALPHAMASK")
set(_type_dependent_arguments -mipmap -linear -mip_linear -no_selector_rdo -no_endpoint_rdo -swizzle aaaa -no_alpha)
endif()

file(MAKE_DIRECTORY "${_parsedArguments_OUTPUT_DIR}")

foreach(TEXTURE ${_parsedArguments_FILES})
get_filename_component(TEXTURE_FILE_PATH ${TEXTURE} DIRECTORY)
get_filename_component(TEXTURE_FILE_NAME_WE ${TEXTURE} NAME_WE)
set(_output_name "${TEXTURE_FILE_NAME_WE}.ktx2")
add_custom_command(OUTPUT "${_parsedArguments_OUTPUT_DIR}/${_output_name}"
COMMAND "${BASIS_UNIVERSAL_CLI}"
ARGS -ktx2 -uastc -uastc_level ${_uastc_level} ${_rdo_arguments} -uastc_rdo_m ${_type_dependent_arguments} ${_resample_arguments} -output_file "${_parsedArguments_OUTPUT_DIR}/${_output_name}" -file "${TEXTURE}"
DEPENDS "${TEXTURE}"
VERBATIM
)
list(APPEND TEXTURE_LIST "${_parsedArguments_OUTPUT_DIR}/${_output_name}")
endforeach()

if(NOT TARGET ${_parsedArguments_ENCODING_TARGET})
add_custom_target(${_parsedArguments_ENCODING_TARGET})
set_property(TARGET ${_parsedArguments_ENCODING_TARGET} PROPERTY FOLDER "data")
endif()

_WZ_BASIS_ENCODE_GET_UNIQUE_TARGET_NAME("${_parsedArguments_ENCODING_TARGET}" uniqueTargetName)

if(_parsedArguments_ALL)
add_custom_target(${uniqueTargetName} ALL DEPENDS ${TEXTURE_LIST})
else()
add_custom_target(${uniqueTargetName} DEPENDS ${TEXTURE_LIST})
endif()

if (DEFINED _parsedArguments_TARGET_FOLDER)
set_property(TARGET ${uniqueTargetName} PROPERTY FOLDER "${_parsedArguments_TARGET_FOLDER}")
endif()

add_dependencies(${_parsedArguments_ENCODING_TARGET} ${uniqueTargetName})

endfunction()
18 changes: 3 additions & 15 deletions data/CMakeLists.txt
Expand Up @@ -99,6 +99,8 @@ endif()
#########################################
# Texture pages basis-universal encoding

include(WZBasisEncode)

# default texpages path
set(_texpages_PATHS
PATHS
Expand Down Expand Up @@ -145,22 +147,8 @@ if(WZ_ENABLE_BASIS_UNIVERSAL AND NOT WZ_CI_DISABLE_BASIS_COMPRESS_TEXTURES)
set(_output_dir "${CMAKE_CURRENT_BINARY_DIR}/base/texpages")
file(MAKE_DIRECTORY "${_output_dir}")
set(_terrain_max_size 1024)
foreach(TEXTURE ${TEXPAGES_TERRAIN})
get_filename_component(TEXTURE_FILE_PATH ${TEXTURE} DIRECTORY)
get_filename_component(TEXTURE_FILE_NAME_WE ${TEXTURE} NAME_WE)
set(_output_name "${TEXTURE_FILE_NAME_WE}.ktx2")
add_custom_command(OUTPUT "${_output_dir}/${_output_name}"
COMMAND "${BASIS_UNIVERSAL_CLI}"
ARGS -ktx2 -uastc -uastc_level 2 -uastc_rdo_l 1.0 -uastc_rdo_m -mipmap -resample ${_terrain_max_size} ${_terrain_max_size} -output_file "${_output_dir}/${_output_name}" -file "${TEXTURE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/base/texpages"
DEPENDS "${TEXTURE}"
VERBATIM
)
list(APPEND TEXTURE_LIST "${_output_dir}/${_output_name}")
endforeach()
add_custom_target(texture_encoding DEPENDS ${TEXTURE_LIST})
set_property(TARGET texture_encoding PROPERTY FOLDER "data")

WZ_BASIS_ENCODE_TEXTURES(OUTPUT_DIR "${_output_dir}" TYPE "TEXTURE" RESIZE "${_terrain_max_size}" RDO ENCODING_TARGET texture_encoding TARGET_FOLDER data ALL FILES ${TEXPAGES_TERRAIN})
set(PROCESSED_TEXTURE_FILES ${TEXPAGES_TERRAIN})

file(GLOB_RECURSE ALL_TEXPAGES LIST_DIRECTORIES false CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/base/texpages/*.png" "${CMAKE_CURRENT_SOURCE_DIR}/base/texpages/compression_overrides.txt" "${CMAKE_CURRENT_SOURCE_DIR}/base/texpages/*.radar")
Expand Down

0 comments on commit 92de36a

Please sign in to comment.