|
65 | 65 | //! |
66 | 66 | //! ### Encoding |
67 | 67 | //! |
68 | | -//! Since the data of a DDS file is determined by the header, the first step to |
69 | | -//! encoding a DDS file is to create a header. See the documentation of |
70 | | -//! the [`dds::header`](crate::header) module for more details. |
| 68 | +//! [`Encoder`] defines the high-level interface for encoding DDS images. |
| 69 | +//! |
| 70 | +//! A single texture can be encoded as follows: |
71 | 71 | //! |
72 | 72 | //! ```no_run |
73 | | -//! use dds::{*, header::*}; |
| 73 | +//! use dds::*; |
74 | 74 | //! use std::fs::File; |
75 | 75 | //! |
76 | 76 | //! fn save_rgba_image( |
77 | 77 | //! file: &mut File, |
78 | 78 | //! image_data: &[u8], |
79 | 79 | //! width: u32, |
80 | 80 | //! height: u32, |
| 81 | +//! mipmaps: bool, |
81 | 82 | //! ) -> Result<(), EncodingError> { |
82 | | -//! let format = Format::BC1_UNORM; |
83 | | -//! let header = Header::new_image(width, height, format); |
84 | | -//! |
85 | | -//! let mut encoder = Encoder::new(file, format, &header)?; |
| 83 | +//! let size = Size::new(width, height); |
| 84 | +//! let mut encoder = Encoder::new_image(file, size, Format::BC7_UNORM, mipmaps)?; |
| 85 | +//! // lower quality for faster encoding |
86 | 86 | //! encoder.encoding.quality = CompressionQuality::Fast; |
87 | 87 | //! |
88 | | -//! let view = ImageView::new(image_data, Size::new(width, height), ColorFormat::RGBA_U8) |
| 88 | +//! let view = ImageView::new(image_data, size, ColorFormat::RGBA_U8) |
89 | 89 | //! .expect("invalid image data"); |
90 | 90 | //! encoder.write_surface(view)?; |
91 | 91 | //! encoder.finish()?; |
92 | 92 | //! Ok(()) |
93 | 93 | //! } |
94 | 94 | //! ``` |
95 | 95 | //! |
96 | | -//! Note the use of [`Encoder::finish()`]. This method will verify that the |
97 | | -//! file has been created correctly and contains all necessary data. Always |
98 | | -//! use [`Encoder::finish()`] instead of dropping the encoder. |
99 | | -//! |
100 | | -//! To create DDS files with mipmaps, we simply create a header with mipmaps and |
101 | | -//! enable automatic mipmap generation in the encoder: |
| 96 | +//! Mipmaps are automatically generated if requested (by default). How mipmaps |
| 97 | +//! are generated can be configured using [`Encoder::mipmaps`]. |
102 | 98 | //! |
103 | | -//! ```no_run |
104 | | -//! use dds::{*, header::*}; |
105 | | -//! use std::fs::File; |
| 99 | +//! Most formats also support encoding options to change the encoded image data |
| 100 | +//! in some way. These can be set using the [`Encoder::encoding`] field. E.g. |
| 101 | +//! most formats support [dithering](EncodeOptions::dithering) and compressed |
| 102 | +//! formats support different [quality levels](EncodeOptions::quality) among |
| 103 | +//! others. |
106 | 104 | //! |
107 | | -//! fn save_rgba_image_with_mipmaps( |
108 | | -//! file: &mut File, |
109 | | -//! image_data: &[u8], |
110 | | -//! width: u32, |
111 | | -//! height: u32, |
112 | | -//! ) -> Result<(), EncodingError> { |
113 | | -//! let format = Format::BC1_UNORM; |
114 | | -//! // Create a header with mipmaps |
115 | | -//! let header = Header::new_image(width, height, format).with_mipmaps(); |
116 | | -//! |
117 | | -//! let mut encoder = Encoder::new(file, format, &header)?; |
118 | | -//! encoder.encoding.quality = CompressionQuality::Fast; |
119 | | -//! encoder.mipmaps.generate = true; // Enable automatic mipmap generation |
120 | | -//! |
121 | | -//! let view = ImageView::new(image_data, Size::new(width, height), ColorFormat::RGBA_U8) |
122 | | -//! .expect("invalid image data"); |
123 | | -//! encoder.write_surface(view)?; |
124 | | -//! encoder.finish()?; |
125 | | -//! Ok(()) |
126 | | -//! } |
127 | | -//! ``` |
| 105 | +//! Also note the use of [`Encoder::finish()`]. This method verifies that the |
| 106 | +//! DDS file contains all necessary data and is valid. ALWAYS use |
| 107 | +//! [`Encoder::finish()`] instead of dropping the encoder. |
128 | 108 | //! |
129 | | -//! Note: If the header does not specify mipmaps, no mipmaps will be generated |
130 | | -//! even if automatic mipmap generation is enabled. |
| 109 | +//! #### Texture arrays, cube maps, and volumes |
131 | 110 | //! |
132 | | -//! For other types of data: |
| 111 | +//! Other types of data work slightly differently. You need to create a |
| 112 | +//! [`Header`](crate::header::Header) for them manually and pass it to |
| 113 | +//! [`Encoder::new`]. After the encoder has been created, the process is |
| 114 | +//! similar: |
133 | 115 | //! |
134 | 116 | //! - Texture arrays can be encoded using [`Encoder::write_surface`] for each |
135 | 117 | //! texture in the array. |
136 | 118 | //! - Cube maps, like texture arrays, can be encoded using [`Encoder::write_surface`] |
137 | 119 | //! for each face. The order of the faces must be +X, -X, +Y, -Y, +Z, -Z. |
138 | | -//! Writing whole cube maps at once is not supported. |
139 | 120 | //! - Volumes can be encoded one depth slice at a time using |
140 | 121 | //! [`Encoder::write_surface`]. |
141 | 122 | //! |
142 | | -//! Automatic mipmap generation is **not** supported for volumes. If enabled, |
143 | | -//! the options will be silently ignored and no mipmaps will be generated. |
| 123 | +//! Automatic mipmap generation is **not** supported for volumes. If automatic |
| 124 | +//! mipmap generation is enabled, it will silently do nothing. Use |
| 125 | +//! [`Encoder::finish()`] to prevent the creation of invalid DDS files. |
144 | 126 | //! |
145 | 127 | //! ### Progress reporting |
146 | 128 | //! |
|
0 commit comments