diff --git a/basis-universal-sys/generate_bindings.sh b/basis-universal-sys/generate_bindings.sh index a6c3eff..cc0edc0 100755 --- a/basis-universal-sys/generate_bindings.sh +++ b/basis-universal-sys/generate_bindings.sh @@ -94,12 +94,14 @@ bindgen vendor/encoding_wrapper.cpp -o src/encoding_bindings.rs \ --allowlist-function compressor_params_set_generate_mipmaps \ --allowlist-function compressor_params_set_mip_smallest_dimension \ --allowlist-function compressor_params_set_userdata \ + --allowlist-function compressor_params_set_create_ktx2_file \ \ --allowlist-function compressor_new \ --allowlist-function compressor_delete \ --allowlist-function compressor_init \ --allowlist-function compressor_process \ --allowlist-function compressor_get_output_basis_file \ + --allowlist-function compressor_get_output_ktx2_file \ \ --allowlist-function compressor_get_basis_file_size \ --allowlist-function compressor_get_basis_bits_per_texel \ diff --git a/basis-universal-sys/src/encoding_bindings.rs b/basis-universal-sys/src/encoding_bindings.rs index 1e23f5d..e4f59c0 100644 --- a/basis-universal-sys/src/encoding_bindings.rs +++ b/basis-universal-sys/src/encoding_bindings.rs @@ -140,7 +140,7 @@ fn bindgen_test_layout_basisu_image() { ); } extern "C" { - #[link_name = "\u{1}?debug_text@image@basisu@@QEAAXIIIIAEBVcolor_rgba@2@PEBV32@_NPEBDZZ"] + #[link_name = "\u{1}__ZN6basisu5image10debug_textEjjjjRKNS_10color_rgbaEPS2_bPKcz"] pub fn basisu_image_debug_text( this: *mut basisu_image, x_ofs: u32, @@ -585,6 +585,12 @@ extern "C" { userdata1: u32, ); } +extern "C" { + pub fn compressor_params_set_create_ktx2_file( + params: *mut CompressorParams, + create_ktx2_file: bool, + ); +} #[repr(C)] #[repr(align(8))] #[derive(Debug, Copy, Clone)] @@ -663,6 +669,9 @@ fn bindgen_test_layout_CompressorBasisFile() { extern "C" { pub fn compressor_get_output_basis_file(compressor: *mut Compressor) -> CompressorBasisFile; } +extern "C" { + pub fn compressor_get_output_ktx2_file(compressor: *mut Compressor) -> CompressorBasisFile; +} extern "C" { pub fn compressor_get_basis_file_size(compressor: *const Compressor) -> u32; } diff --git a/basis-universal-sys/vendor/encoding_wrapper.cpp b/basis-universal-sys/vendor/encoding_wrapper.cpp index 8af431d..f898db9 100644 --- a/basis-universal-sys/vendor/encoding_wrapper.cpp +++ b/basis-universal-sys/vendor/encoding_wrapper.cpp @@ -233,6 +233,10 @@ extern "C" { params->pParams->m_userdata1 = userdata1; } + void compressor_params_set_create_ktx2_file(CompressorParams *params, bool create_ktx2_file) { + params->pParams->m_create_ktx2_file = create_ktx2_file; + } + // compressor_params_set_multithreaded is not implemented because this parameter is controlled by thread count // passed to compressor_new() @@ -289,6 +293,14 @@ extern "C" { return file; } + CompressorBasisFile compressor_get_output_ktx2_file(Compressor *compressor) { + CompressorBasisFile file; + const basisu::uint8_vec &basis_file = compressor->pCompressor->get_output_ktx2_file(); + file.pData = basis_file.data(); + file.length = basis_file.size(); + return file; + } + // Not implemented: // const std::vector &compressor_get_stats(); diff --git a/basis-universal/examples/example.rs b/basis-universal/examples/example.rs index b99a7cd..c27c40e 100644 --- a/basis-universal/examples/example.rs +++ b/basis-universal/examples/example.rs @@ -54,6 +54,7 @@ pub fn main() { // let mut compressor_params = CompressorParams::new(); compressor_params.set_generate_mipmaps(true); + // compressor_params.set_create_ktx2_file(true); compressor_params.set_basis_format(BasisTextureFormat::UASTC4x4); compressor_params.set_uastc_quality_level(basis_universal::UASTC_QUALITY_DEFAULT); compressor_params.set_print_status_to_stdout(false); @@ -91,6 +92,11 @@ pub fn main() { let basis_file = compressor.basis_file(); // std::fs::write("example_encoded_image.basis", basis_file).unwrap(); + // Or maybe prefer KTX2 format + // You will need to uncomment the above `set_create_ktx2_file` line first + // let ktx2_file = compressor.ktx2_file(); + // std::fs::write("example_encoded_image.ktx2", ktx2_file).unwrap(); + let mut transcoder = Transcoder::new(); let mip_level_count = transcoder.image_level_count(basis_file, 0); println!( diff --git a/basis-universal/src/encoding/compressor.rs b/basis-universal/src/encoding/compressor.rs index 78657f1..b021ded 100644 --- a/basis-universal/src/encoding/compressor.rs +++ b/basis-universal/src/encoding/compressor.rs @@ -88,6 +88,15 @@ impl Compressor { } } + /// Access the KTX2 compressed data. May be empty if `process()` was not yet called + /// or `create_ktx2_file` parameter is false (default). + pub fn ktx2_file(&self) -> &[u8] { + unsafe { + let result = sys::compressor_get_output_ktx2_file(self.0); + std::slice::from_raw_parts(result.pData, result.length as usize) + } + } + /// Return the size of the encoded basis-universal data pub fn basis_file_size(&self) -> u32 { unsafe { sys::compressor_get_basis_file_size(self.0) } diff --git a/basis-universal/src/encoding/compressor_params.rs b/basis-universal/src/encoding/compressor_params.rs index f8b3984..3daec2d 100644 --- a/basis-universal/src/encoding/compressor_params.rs +++ b/basis-universal/src/encoding/compressor_params.rs @@ -309,6 +309,17 @@ impl CompressorParams { } } + /// Set if also create compressed data in KTX2 format + /// + /// By default this is set to false and calling [Compressor::ktx2_file](crate::Compressor::ktx2_file) + /// will return an empty result. + pub fn set_create_ktx2_file( + &mut self, + create_ktx2_file: bool, + ) { + unsafe { sys::compressor_params_set_create_ktx2_file(self.0, create_ktx2_file) } + } + /// The `basisu` command line compressor offers a -normal_map parameter that sets several /// values automatically. This convenience function mimics that parameter. /// diff --git a/basis-universal/src/encoding/encoding_tests.rs b/basis-universal/src/encoding/encoding_tests.rs index 163e154..27a656b 100644 --- a/basis-universal/src/encoding/encoding_tests.rs +++ b/basis-universal/src/encoding/encoding_tests.rs @@ -38,6 +38,7 @@ fn test_compressor_params_smoketest_bindings() { compressor_params.set_uastc_quality_level(crate::UASTC_QUALITY_DEFAULT); compressor_params.set_basis_format(BasisTextureFormat::UASTC4x4); compressor_params.set_generate_mipmaps(true); + compressor_params.set_create_ktx2_file(true); compressor_params.reset(); } @@ -82,6 +83,7 @@ fn test_encode_image() { let mut compressor_params = CompressorParams::new(); compressor_params.set_generate_mipmaps(true); + compressor_params.set_create_ktx2_file(true); // // Set up the source image in the params @@ -113,8 +115,13 @@ fn test_encode_image() { // By default the test shouldn't write to disk, but this is a quick way to put it on disk to // check that it works with basisu - let _basis_file = compressor.basis_file(); + let basis_file = compressor.basis_file(); + assert!(!basis_file.is_empty()); //std::fs::write("test_assets/test_encode_image.basis", basis_file).unwrap(); + let ktx2_file = compressor.ktx2_file(); + assert!(!ktx2_file.is_empty()); + // std::fs::write("test_assets/test_encode_image.ktx2", ktx2_file).unwrap(); + std::mem::drop(compressor); }