├── .gitignore
├── LICENSE
├── README.md
├── ctexview
├── compile-shaders.bat
├── ctexview.c
├── ctexview.ico
├── quad.frag
├── quad.vert
├── quad_cubemap_glsl.frag.h
├── quad_cubemap_hlsl.frag.h
├── quad_cubemap_metal.frag.h
├── quad_glsl.frag.h
├── quad_glsl.vert.h
├── quad_hlsl.frag.h
├── quad_hlsl.vert.h
├── quad_metal.frag.h
├── quad_metal.vert.h
├── sokol_app.h
├── sokol_debugtext.h
├── sokol_gfx.h
└── sokol_glue.h
└── dds-ktx.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # External junk
2 | .DS_Store
3 | _ReSharper*
4 | *.opensdf
5 | *.sdf
6 | *.dir
7 | *.suo
8 | *.user
9 | *.bak
10 | *.scor
11 | *.scor.*
12 | Win32
13 | Win64
14 | Debug
15 | Release
16 | Profile
17 | Development
18 | Obj
19 | Bin
20 | Build
21 | Lib
22 | .tags
23 | .tags_sorted_by_file
24 | *.lnk
25 | ipch
26 | __pycache__
27 | Thumbs.db
28 | .build*
29 | .downloads
30 | .clangd
31 | *.obj
32 | *.exe
33 | *.pdb
34 | *.dll
35 | *.o
36 | .vs
37 | xcuserdata
38 | *imgui.ini
39 | *.tmp
40 | /*.ini
41 | .cache
42 |
43 | # build analyzer
44 | .vcperf
45 | *.etl
46 | StructLayoutSettings.json
47 |
48 |
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2018, Sepehr Taghdisian
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## dds-ktx: Portable single header DDS/KTX reader for C/C++
2 | [@septag](https://twitter.com/septagh)
3 |
4 | - Parses from memory blob. No allocations
5 | - No dependencies
6 | - Single-header for easy integration
7 | - Overridable libc functions
8 |
9 | ### Build Example (ctexview)
10 | [**ctexview**](ctexview/ctexview.c) is a tiny ddx-ktx viewer that can be built on linux/mac and windows. To build it just compile the single file with your compiler.
11 |
12 | **Windows:**
13 | ```
14 | cl ctexview.c /O2
15 | ```
16 |
17 | **Linuxx**
18 | ```
19 | gcc ctexview.c -O2 -lGL -ldl -lX11 -lXi -lXcursor -lm -o ctexview
20 | ```
21 |
22 | **MacOS**
23 | ```
24 | clang -framework Foundation -framework CoreServices -framework CoreFoundation -O2 -fobjc-arc -x objective-c -fmodules -x objective-c ctexview.c -o ./ctexview
25 | ```
26 |
27 | to view images just provide the image path as an argument:
28 |
29 | ```
30 | ctexview [dds_or_ktx_image_file_path]
31 | ```
32 |
33 | Used open-source libraries for app creation/graphics: [**Sokol**](https://github.com/floooh/sokol)
34 |
35 | **Keys:**
36 |
37 | - UP/DOWN: change current mipmap
38 | - Apostrophe: change text color
39 | - F: Next cube-map face
40 | - R: Toggle Red channel
41 | - G: Toggle Green channel
42 | - B: Toggle Blue channel
43 | - A: Toggle Alpha channel
44 |
45 | ### Usage
46 | In this example, a simple 2D texture is parsed and created using OpenGL
47 |
48 | ```c
49 | #define DDSKTX_IMPLEMENT
50 | #include "dds-ktx.h"
51 |
52 | int size;
53 | void* dds_data = load_file("test.dds", &size);
54 | assert(dds_data);
55 | ddsktx_texture_info tc = {0};
56 | GLuint tex = 0;
57 | if (ddsktx_parse(&tc, dds_data, size, NULL)) {
58 | assert(tc.depth == 1);
59 | assert(!(tc.flags & STC_TEXTURE_FLAG_CUBEMAP));
60 | assert(tc.num_layers == 1);
61 |
62 | //Create GPU texture from tc data
63 | glGenTextures(1, &tex);
64 | glActiveTexture(GL_TEXTURE0);
65 | glBindTexture(img->gl_target, tex);
66 |
67 | for (int mip = 0; mip < tc->num_mips; mip++) {
68 | ddsktx_sub_data sub_data;
69 | ddsktx_get_sub(&tc, &sub_data, dds_data, size, 0, 0, mip);
70 | // Fill/Set texture sub resource data (mips in this case)
71 | if (ddsktx_format_compressed(tc.format))
72 | glCompressedTexImage2D(..);
73 | else
74 | glTexImage2D(..);
75 | }
76 |
77 | // Now we can delete file data
78 | free(dds_data);
79 | }
80 | ```
81 |
82 | ### Links
83 | - [DdsKtxSharp](https://github.com/rds1983/DdsKtxSharp): C# port of dds-ktx by [Roman Shapiro](https://github.com/rds1983)
84 |
85 | ### TODO
86 |
87 | - Write KTX/DDS
88 | - Read KTX metadata. currently it just stores the offset/size to the metadata block
89 |
90 | ### Others
91 |
92 | - [stb_image](https://github.com/nothings/stb/blob/master/stb_image.h) - Single header library that loads images (.png, .jpg, .bmp, etc)
93 | - [bimg](https://github.com/bkaradzic/bimg) - Extensive C++ image library
94 |
95 | **NOTE**: Many parts of the code is taken from _bimg_ library.
96 |
97 |
98 | [License (BSD 2-clause)](https://github.com/septag/dds-ktx/blob/master/LICENSE)
99 | --------------------------------------------------------------------------
100 |
101 |
102 |
103 |
104 |
105 | Copyright 2018 Sepehr Taghdisian. All rights reserved.
106 |
107 | https://github.com/septag/dds-ktx
108 |
109 | Redistribution and use in source and binary forms, with or without
110 | modification, are permitted provided that the following conditions are met:
111 |
112 | 1. Redistributions of source code must retain the above copyright notice,
113 | this list of conditions and the following disclaimer.
114 |
115 | 2. Redistributions in binary form must reproduce the above copyright notice,
116 | this list of conditions and the following disclaimer in the documentation
117 | and/or other materials provided with the distribution.
118 |
119 | THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
120 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
121 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
122 | EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
123 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
124 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
125 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
126 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
127 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
128 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129 |
--------------------------------------------------------------------------------
/ctexview/compile-shaders.bat:
--------------------------------------------------------------------------------
1 | glslcc -i quad.vert --lang hlsl --bin -o quad_hlsl.vert.h --cvar quad
2 | glslcc -i quad.vert --lang glsl --flatten-ubos --profile 330 -o quad_glsl.vert.h --cvar quad
3 | glslcc -i quad.vert --lang metal -o quad_metal.vert.h --cvar quad
4 |
5 | glslcc -i quad.frag --lang hlsl --bin -o quad_hlsl.frag.h --cvar quad
6 | glslcc -i quad.frag --lang glsl --flatten-ubos --profile 330 -o quad_glsl.frag.h --cvar quad
7 | glslcc -i quad.frag --lang metal -o quad_metal.frag.h --cvar quad
8 |
9 | glslcc -i quad.frag --lang hlsl --bin -o quad_cubemap_hlsl.frag.h --cvar quad_cubemap --defines CUBEMAP
10 | glslcc -i quad.frag --lang glsl --flatten-ubos --profile 330 -o quad_cubemap_glsl.frag.h --cvar quad_cubemap --defines CUBEMAP
11 | glslcc -i quad.frag --lang metal -o quad_cubemap_metal.frag.h --cvar quad_cubemap --defines CUBEMAP
12 |
--------------------------------------------------------------------------------
/ctexview/ctexview.c:
--------------------------------------------------------------------------------
1 |
2 | #if defined(_WIN32) || defined(_WIN64)
3 | # define SOKOL_D3D11
4 | # define _CRT_SECURE_NO_WARNINGS
5 | # include "quad_hlsl.vert.h"
6 | # include "quad_hlsl.frag.h"
7 | # include "quad_cubemap_hlsl.frag.h"
8 | # define SOKOL_LOG(s) OutputDebugStringA(s)
9 | #elif defined(__linux__)
10 | # include "quad_glsl.vert.h"
11 | # include "quad_glsl.frag.h"
12 | # include "quad_cubemap_glsl.frag.h"
13 | # define SOKOL_GLCORE33
14 | #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
15 | # include "quad_metal.vert.h"
16 | # include "quad_metal.frag.h"
17 | # include "quad_cubemap_metal.frag.h"
18 | # define SOKOL_METAL
19 | #endif
20 |
21 | #define SOKOL_IMPL
22 | #define DDSKTX_IMPLEMENT
23 |
24 | #define SOKOL_API_DECL static
25 | #include "sokol_app.h"
26 | #include "sokol_gfx.h"
27 | #include "sokol_glue.h"
28 |
29 | #define DDSKTX_API static
30 | #include "../dds-ktx.h"
31 |
32 | #ifndef __APPLE__
33 | # include
34 | #endif
35 | #include
36 | #include
37 | #include
38 |
39 | #define SOKOL_DEBUGTEXT_IMPL
40 | #include "sokol_debugtext.h"
41 |
42 | #define FONT_SCALE 1.1f
43 | #define CHECKER_SIZE 8
44 |
45 | typedef struct uniforms_fs
46 | {
47 | float color[4];
48 | float args[4];
49 | } uniforms_fs;
50 |
51 | typedef struct uniforms_vs
52 | {
53 | float proj_mat[16];
54 | } uniforms_vs;
55 |
56 | typedef struct vertex
57 | {
58 | float x;
59 | float y;
60 | float u;
61 | float v;
62 | float w; // reserved for cubemapping
63 | } vertex;
64 |
65 |
66 | typedef struct ctexview_state
67 | {
68 | sg_pass_action pass_action;
69 | void* file_data;
70 | int file_size;
71 | ddsktx_texture_info texinfo;
72 | sg_image tex;
73 | sg_shader shader;
74 | sg_shader shader_cubemap;
75 | sg_pipeline pip;
76 | sg_pipeline pip_cubemap;
77 | sg_pipeline pip_checker;
78 | sg_buffer vb;
79 | sg_buffer ib;
80 | sg_buffer vb_checker;
81 | sg_image checker;
82 | bool inv_text_color;
83 | uniforms_fs vars_fs;
84 | int cur_mip;
85 | int cur_slice;
86 | int cube_face;
87 | } ctexview_state;
88 |
89 | ctexview_state g_state;
90 |
91 | static const vertex k_vertices[] = {
92 | { -1.0f, -1.0f, 0.0f, 1.0f, 0 },
93 | { 1.0f, -1.0f, 1.0f, 1.0f, 0 },
94 | { 1.0f, 1.0f, 1.0f, 0.0f, 0 },
95 | { -1.0f, 1.0f, 0.0f, 0.0f, 0 },
96 | };
97 |
98 | static const uint16_t k_indices[] = { 0, 2, 1, 2, 0, 3 };
99 |
100 | static const char* k_cube_face_names[DDSKTX_CUBE_FACE_COUNT] = {
101 | "X+",
102 | "X-",
103 | "Y+",
104 | "Y-",
105 | "Z+",
106 | "Z-"
107 | };
108 |
109 | #if defined(_WIN32) || defined(_WIN64)
110 | static desktop_size(int* width, int* height)
111 | {
112 | RECT desktop;
113 | const HWND hDesktop = GetDesktopWindow();
114 | GetWindowRect(hDesktop, &desktop);
115 | *width = desktop.right;
116 | *height = desktop.bottom;
117 | }
118 | #endif
119 |
120 | static int nearest_pow2(int n)
121 | {
122 | n--;
123 | n |= n >> 1;
124 | n |= n >> 2;
125 | n |= n >> 4;
126 | n |= n >> 8;
127 | n |= n >> 16;
128 | n++;
129 | return n;
130 | }
131 |
132 | // https://en.wikipedia.org/wiki/Cube_mapping
133 | static void convert_cube_uv_to_xyz(int index, float u, float v, float* x, float* y, float* z)
134 | {
135 | // convert range 0 to 1 to -1 to 1
136 | float uc = 2.0f * u - 1.0f;
137 | float vc = 2.0f * v - 1.0f;
138 | switch (index) {
139 | case 0: *x = 1.0f; *y = vc; *z = -uc; break; // POSITIVE X
140 | case 1: *x = -1.0f; *y = vc; *z = uc; break; // NEGATIVE X
141 | case 2: *x = uc; *y = 1.0f; *z = -vc; break; // POSITIVE Y
142 | case 3: *x = uc; *y = -1.0f; *z = vc; break; // NEGATIVE Y
143 | case 4: *x = uc; *y = vc; *z = 1.0f; break; // POSITIVE Z
144 | case 5: *x = -uc; *y = vc; *z = -1.0f; break; // NEGATIVE Z
145 | }
146 | }
147 |
148 | static void set_cube_face(int index)
149 | {
150 | if (g_state.texinfo.flags & DDSKTX_TEXTURE_FLAG_CUBEMAP) {
151 | assert(index >= 0 && index < DDSKTX_CUBE_FACE_COUNT);
152 |
153 | vertex vertices[4];
154 | memcpy(vertices, k_vertices, sizeof(k_vertices));
155 |
156 | for (int i = 0; i < 4; i++) {
157 | float x, y, z;
158 | convert_cube_uv_to_xyz(index, vertices[i].u, vertices[i].v, &x, &y, &z);
159 | vertices[i].u = x;
160 | vertices[i].v = y;
161 | vertices[i].w = z;
162 | }
163 |
164 | sg_update_buffer(g_state.vb, vertices, sizeof(vertices));
165 | }
166 | }
167 |
168 | static void adjust_checker_coords(int width, int height)
169 | {
170 | int count_x = width/CHECKER_SIZE;
171 | int count_y = height/CHECKER_SIZE;
172 |
173 | float ratio = (float)width / (float)height;
174 | float u, v;
175 | if (width > height) {
176 | u = (float)count_x;
177 | v = (float)count_y * ratio;
178 | }
179 | else {
180 | v = (float)count_y;
181 | u = (float)count_x / ratio;
182 | }
183 |
184 | vertex vertices[4];
185 | memcpy(vertices, k_vertices, sizeof(k_vertices));
186 |
187 | for (int i = 0; i < 4; i++) {
188 | vertices[i].u = vertices[i].u != 0 ? u : 0;
189 | vertices[i].v = vertices[i].v != 0 ? v : 0;
190 | }
191 | sg_update_buffer(g_state.vb_checker, vertices, sizeof(vertices));
192 | }
193 |
194 | static void sx_mat4_ortho(float mat[16], float width, float height, float zn, float zf, float offset, bool ogl_ndc)
195 | {
196 | const float d = zf - zn;
197 | const float cc = (ogl_ndc ? 2.0f : 1.0f) / d;
198 | const float ff = ogl_ndc ? -(zn + zf) / d : -zn / d;
199 |
200 | mat[0] = 2.0f / width;
201 | mat[1] = 0;
202 | mat[2] = 0;
203 | mat[3] = 0;
204 |
205 | mat[4] = 0;
206 | mat[5] = 2.0f / height;
207 | mat[6] = 0;
208 | mat[7] = 0;
209 |
210 | mat[8] = 0;
211 | mat[9] = 0;
212 | mat[10] = -cc;
213 | mat[11] = 0;
214 |
215 | mat[12] = offset;
216 | mat[13] = 0;
217 | mat[14] = ff;
218 | mat[15] = 1.0f;
219 | }
220 |
221 | static void sx_mat4_ident(float mat[16])
222 | {
223 | mat[0] = 1.0f;
224 | mat[1] = 0;
225 | mat[2] = 0;
226 | mat[3] = 0;
227 |
228 | mat[4] = 0;
229 | mat[5] = 1.0f;
230 | mat[6] = 0;
231 | mat[7] = 0;
232 |
233 | mat[8] = 0;
234 | mat[9] = 0;
235 | mat[10] = 1.0f;
236 | mat[11] = 0;
237 |
238 | mat[12] = 0;
239 | mat[13] = 0;
240 | mat[14] = 0;
241 | mat[15] = 1.0f;
242 | }
243 |
244 |
245 | static sg_image create_checker_texture(int checker_size, int size, uint32_t colors[2])
246 | {
247 | assert(size % 4 == 0 && "size must be multiple of four");
248 | assert(size % checker_size == 0 && "checker_size must be dividable by size");
249 |
250 | int size_bytes = size * size * sizeof(uint32_t);
251 | uint32_t* pixels = malloc(size_bytes);
252 | assert(pixels);
253 |
254 | // split into tiles and color them
255 | int tiles_x = size / checker_size;
256 | int tiles_y = size / checker_size;
257 | int num_tiles = tiles_x * tiles_y;
258 |
259 | int* poss = malloc(sizeof(int) * 2 * num_tiles);
260 | assert(poss);
261 | int _x = 0, _y = 0;
262 | for (int i = 0; i < num_tiles; i++) {
263 | poss[i*2] = _x;
264 | poss[i*2 + 1] = _y;
265 | _x += checker_size;
266 | if (_x >= size) {
267 | _x = 0;
268 | _y += checker_size;
269 | }
270 | }
271 |
272 | int color_idx = 0;
273 | for (int i = 0; i < num_tiles; i++) {
274 | int* p = poss + i*2;
275 | uint32_t c = colors[color_idx];
276 | if (i == 0 || ((i + 1) % tiles_x) != 0)
277 | color_idx = !color_idx;
278 | int end_x = p[0] + checker_size;
279 | int end_y = p[1] + checker_size;
280 | for (int y = p[1]; y < end_y; y++) {
281 | for (int x = p[0]; x < end_x; x++) {
282 | int pixel = x + y * size;
283 | pixels[pixel] = c;
284 | }
285 | }
286 | }
287 |
288 | sg_image tex = sg_make_image(&(sg_image_desc) {
289 | .width = size,
290 | .height = size,
291 | .num_mipmaps = 1,
292 | .pixel_format = SG_PIXELFORMAT_RGBA8,
293 | .content = (sg_image_content){.subimage[0][0].ptr = pixels,
294 | .subimage[0][0].size = size_bytes }
295 | });
296 |
297 | free(poss);
298 | free(pixels);
299 |
300 | return tex;
301 | }
302 |
303 |
304 | static void print_msg(const char* fmt, ...)
305 | {
306 | char msg[1024];
307 | va_list args;
308 | va_start(args, fmt);
309 | vsnprintf(msg, sizeof(msg), fmt, args);
310 | va_end(args);
311 |
312 | #if defined(_WIN32) || defined(_WIN64)
313 | MessageBoxA(NULL, msg, "DDS/KTX viewer", MB_OK);
314 | #else
315 | puts(msg);
316 | #endif
317 | }
318 |
319 | static sg_shader_desc get_shader_desc(const void* vs_data, uint32_t vs_size, const void* fs_data,
320 | uint32_t fs_size, sg_image_type imgtype)
321 | {
322 | return (sg_shader_desc){
323 | .attrs = {
324 | [0] = {.name = "a_pos", .sem_name = "POSITION" },
325 | [1] = {.name = "a_uv", .sem_name = "TEXCOORD" }
326 | },
327 | .vs = {
328 | #ifdef SOKOL_D3D11
329 | .byte_code = (const uint8_t*)vs_data,
330 | .byte_code_size = vs_size,
331 | #else
332 | .source = (const char*)vs_data,
333 | #endif
334 | #ifdef SOKOL_METAL
335 | .entry = "main0",
336 | #endif
337 | .uniform_blocks[0] = {
338 | .size = sizeof(uniforms_vs),
339 | .uniforms = {
340 | [0] = {.name = "proj_mat", .type = SG_UNIFORMTYPE_MAT4 },
341 | }
342 | }
343 | },
344 | .fs = {
345 | #ifdef SOKOL_D3D11
346 | .byte_code = (const uint8_t*)fs_data,
347 | .byte_code_size = fs_size,
348 | #else
349 | .source = (const char*)fs_data,
350 | #endif
351 | #ifdef SOKOL_METAL
352 | .entry = "main0",
353 | #endif
354 | .images[0] = {
355 | .name = "tex_image",
356 | .type = imgtype
357 | },
358 | .uniform_blocks[0] = {
359 | .size = sizeof(uniforms_fs),
360 | .uniforms = {
361 | [0] = {.name = "color", .type = SG_UNIFORMTYPE_FLOAT4 },
362 | [1] = {.name = "target_lod", SG_UNIFORMTYPE_FLOAT4 }
363 | }
364 | }
365 | }
366 | };
367 | }
368 |
369 | static void init(void)
370 | {
371 | sg_setup(&(sg_desc) {
372 | .context = sapp_sgcontext()
373 | });
374 |
375 | sg_image_type imgtype = (g_state.texinfo.flags & DDSKTX_TEXTURE_FLAG_CUBEMAP) ? SG_IMAGETYPE_CUBE : SG_IMAGETYPE_2D;
376 |
377 | g_state.pass_action = (sg_pass_action) {
378 | .colors[0] = { .action = SG_ACTION_CLEAR, .val = {0, 0, 0, 1.0f} }
379 | };
380 |
381 | g_state.vb = sg_make_buffer(&(sg_buffer_desc) {
382 | .usage = SG_USAGE_DYNAMIC,
383 | .type = SG_BUFFERTYPE_VERTEXBUFFER,
384 | .size = sizeof(k_vertices)
385 | });
386 |
387 | g_state.vb_checker = sg_make_buffer(&(sg_buffer_desc) {
388 | .usage = SG_USAGE_DYNAMIC,
389 | .type = SG_BUFFERTYPE_VERTEXBUFFER,
390 | .size = sizeof(k_vertices)
391 | });
392 |
393 | g_state.ib = sg_make_buffer(&(sg_buffer_desc) {
394 | .usage = SG_USAGE_IMMUTABLE,
395 | .type = SG_BUFFERTYPE_INDEXBUFFER,
396 | .size = sizeof(k_indices),
397 | .content = k_indices
398 | });
399 |
400 |
401 | {
402 | sg_shader_desc desc = get_shader_desc(quad_vs_data, quad_vs_size, quad_fs_data, quad_fs_size,
403 | SG_IMAGETYPE_2D);
404 | g_state.shader = sg_make_shader(&desc);
405 | }
406 |
407 | {
408 | sg_shader_desc desc = get_shader_desc(quad_vs_data, quad_vs_size, quad_cubemap_fs_data,
409 | quad_cubemap_fs_size, SG_IMAGETYPE_CUBE);
410 | g_state.shader_cubemap = sg_make_shader(&desc);
411 | }
412 |
413 | sg_pipeline_desc pip_desc = (sg_pipeline_desc) {
414 | .layout = {
415 | .buffers[0] = {
416 | .stride = sizeof(vertex),
417 | },
418 | .attrs = {
419 | [0] = {.offset = 0, .format = SG_VERTEXFORMAT_FLOAT2 },
420 | [1] = {.offset = 8, .format = SG_VERTEXFORMAT_FLOAT3 }
421 | }
422 | },
423 | .primitive_type = SG_PRIMITIVETYPE_TRIANGLES,
424 | .index_type = SG_INDEXTYPE_UINT16,
425 | .rasterizer = {
426 | .cull_mode = SG_CULLMODE_BACK
427 | },
428 | .blend = {
429 | .enabled = true,
430 | .src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
431 | .dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
432 | }
433 | };
434 |
435 | {
436 | pip_desc.shader = g_state.shader;
437 | g_state.pip = sg_make_pipeline(&pip_desc);
438 | }
439 |
440 | {
441 | pip_desc.shader = g_state.shader_cubemap;
442 | g_state.pip_cubemap = sg_make_pipeline(&pip_desc);
443 | }
444 |
445 | // main texture (dds-ktx)
446 | if (imgtype == SG_IMAGETYPE_CUBE) {
447 | set_cube_face(0);
448 | } else {
449 | sg_update_buffer(g_state.vb, k_vertices, sizeof(k_vertices));
450 | }
451 |
452 | adjust_checker_coords(sapp_width(), sapp_height());
453 |
454 | sg_image_desc desc = {
455 | .type = imgtype,
456 | .width = g_state.texinfo.width,
457 | .height = g_state.texinfo.height,
458 | .depth = 1,
459 | .num_mipmaps = g_state.texinfo.num_mips,
460 | .min_filter = SG_FILTER_NEAREST,
461 | .mag_filter = SG_FILTER_NEAREST
462 | };
463 |
464 | switch (g_state.texinfo.format) {
465 | case DDSKTX_FORMAT_BC1: desc.pixel_format = SG_PIXELFORMAT_BC1_RGBA; break;
466 | case DDSKTX_FORMAT_BC2: desc.pixel_format = SG_PIXELFORMAT_BC2_RGBA; break;
467 | case DDSKTX_FORMAT_BC3: desc.pixel_format = SG_PIXELFORMAT_BC3_RGBA; break;
468 | case DDSKTX_FORMAT_BC4: desc.pixel_format = SG_PIXELFORMAT_BC4_R; break;
469 | case DDSKTX_FORMAT_BC5: desc.pixel_format = SG_PIXELFORMAT_BC5_RG; break;
470 | case DDSKTX_FORMAT_BC6H: desc.pixel_format = SG_PIXELFORMAT_BC6H_RGBF; break;
471 | case DDSKTX_FORMAT_BC7: desc.pixel_format = SG_PIXELFORMAT_BC7_RGBA; break;
472 | case DDSKTX_FORMAT_A8:
473 | case DDSKTX_FORMAT_R8: desc.pixel_format = SG_PIXELFORMAT_R8; break;
474 | case DDSKTX_FORMAT_RGBA8:
475 | case DDSKTX_FORMAT_RGBA8S: desc.pixel_format = SG_PIXELFORMAT_RGBA8; break;
476 | case DDSKTX_FORMAT_RG16: desc.pixel_format = SG_PIXELFORMAT_RG16; break;
477 | case DDSKTX_FORMAT_RGB8: desc.pixel_format = SG_PIXELFORMAT_RGBA8; break;
478 | case DDSKTX_FORMAT_R16: desc.pixel_format = SG_PIXELFORMAT_R16; break;
479 | case DDSKTX_FORMAT_R32F: desc.pixel_format = SG_PIXELFORMAT_R32F; break;
480 | case DDSKTX_FORMAT_R16F: desc.pixel_format = SG_PIXELFORMAT_R16F; break;
481 | case DDSKTX_FORMAT_RG16F: desc.pixel_format = SG_PIXELFORMAT_RG16F; break;
482 | case DDSKTX_FORMAT_RG16S: desc.pixel_format = SG_PIXELFORMAT_RG16; break;
483 | case DDSKTX_FORMAT_RGBA16F: desc.pixel_format = SG_PIXELFORMAT_RGBA16F; break;
484 | case DDSKTX_FORMAT_RGBA16: desc.pixel_format = SG_PIXELFORMAT_RGBA16; break;
485 | case DDSKTX_FORMAT_BGRA8: desc.pixel_format = SG_PIXELFORMAT_BGRA8; break;
486 | case DDSKTX_FORMAT_RGB10A2: desc.pixel_format = SG_PIXELFORMAT_RGB10A2; break;
487 | case DDSKTX_FORMAT_RG11B10F: desc.pixel_format = SG_PIXELFORMAT_RG11B10F; break;
488 | case DDSKTX_FORMAT_RG8: desc.pixel_format = SG_PIXELFORMAT_RG8; break;
489 | case DDSKTX_FORMAT_RG8S: desc.pixel_format = SG_PIXELFORMAT_RG8; break;
490 | default: assert(0); exit(-1);
491 | }
492 |
493 | int num_faces = imgtype == SG_IMAGETYPE_CUBE ? 6 : 1;
494 | for (int face = 0; face < num_faces; face++) {
495 | for (int mip = 0; mip < g_state.texinfo.num_mips; mip++) {
496 | ddsktx_sub_data subdata;
497 | ddsktx_get_sub(&g_state.texinfo, &subdata, g_state.file_data, g_state.file_size, 0, face, mip);
498 | desc.content.subimage[face][mip].ptr = subdata.buff;
499 | desc.content.subimage[face][mip].size = subdata.size_bytes;
500 | }
501 | }
502 |
503 | g_state.tex = sg_make_image(&desc);
504 |
505 | sdtx_setup(&(sdtx_desc_t) {
506 | .fonts = {
507 | [0] = sdtx_font_c64(),
508 | },
509 | });
510 | sdtx_set_context(SDTX_DEFAULT_CONTEXT);
511 | sdtx_canvas((float)sapp_width() * (1.0f/FONT_SCALE), (float)sapp_height() * (1.0f/FONT_SCALE));
512 |
513 | uint32_t checker_colors[] = { 0xff999999, 0xff666666 };
514 |
515 | g_state.checker = create_checker_texture(8, 16, checker_colors);
516 |
517 | g_state.vars_fs.color[0] = g_state.vars_fs.color[1] = g_state.vars_fs.color[2] = g_state.vars_fs.color[3] = 1.0f;
518 | }
519 |
520 | static const char* texture_type_info()
521 | {
522 | static char info[128];
523 |
524 | const char* type = "2D";
525 | if (g_state.texinfo.flags & DDSKTX_TEXTURE_FLAG_CUBEMAP) {
526 | snprintf(info, sizeof(info), "Cube (%s)", k_cube_face_names[g_state.cube_face]);
527 | } else if (g_state.texinfo.depth > 1) {
528 | snprintf(info, sizeof(info), "3D (%d/%d)", g_state.cur_slice, g_state.texinfo.depth);
529 | } else {
530 | strcpy(info, "2D");
531 | }
532 |
533 | return info;
534 |
535 | }
536 |
537 | static void frame(void)
538 | {
539 | sdtx_home();
540 | sdtx_origin(1, 1);
541 | sdtx_pos(0, 0);
542 | sdtx_color3b(!g_state.inv_text_color ? 255 : 0, !g_state.inv_text_color ? 255 : 0, 0);
543 |
544 | sdtx_printf("%s\t%dx%d (mip %d/%d)",
545 | ddsktx_format_str(g_state.texinfo.format), g_state.texinfo.width,
546 | g_state.texinfo.height, g_state.cur_mip + 1, g_state.texinfo.num_mips);
547 | sdtx_crlf();
548 | sdtx_printf("%s\tmask: %c%c%c%c\t",
549 | texture_type_info(),
550 | g_state.vars_fs.color[0] == 1.0f ? 'R' : 'X',
551 | g_state.vars_fs.color[1] == 1.0f ? 'G' : 'X',
552 | g_state.vars_fs.color[2] == 1.0f ? 'B' : 'X',
553 | g_state.vars_fs.color[3] == 1.0f ? 'A' : 'X');
554 | sdtx_crlf();
555 |
556 | g_state.vars_fs.args[0] = (float)g_state.cur_mip;
557 |
558 | sg_begin_default_pass(&g_state.pass_action, sapp_width(), sapp_height());
559 | if (g_state.tex.id) {
560 | sg_bindings bindings = {
561 | .index_buffer = g_state.ib,
562 | };
563 |
564 | if (g_state.checker.id) {
565 | bindings.fs_images[0] = g_state.checker;
566 | bindings.vertex_buffers[0] = g_state.vb_checker;
567 | uniforms_fs ufs = {
568 | {1.0f, 1.0f, 1.0f, 1.0f},
569 | {0, 0, 0, 0}
570 | };
571 |
572 | uniforms_vs uvs;
573 |
574 | float ratio = (float)sapp_width() / (float)sapp_height();
575 | float w = 1.0f, h = 1.0f;
576 | if (sapp_width() > sapp_height()) {
577 | h = w/ratio;
578 | } else {
579 | w = h*ratio;
580 | }
581 | sx_mat4_ortho(uvs.proj_mat, w, h, -1.0f, 1.0f, 0, false);
582 |
583 | sg_apply_pipeline(g_state.pip);
584 | sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &uvs, sizeof(uvs));
585 | sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, &ufs, sizeof(ufs));
586 | sg_apply_bindings(&bindings);
587 | sg_draw(0, 6, 1);
588 | }
589 |
590 |
591 | uniforms_vs uvs;
592 | sx_mat4_ident(uvs.proj_mat);
593 | bindings.fs_images[0] = g_state.tex;
594 | bindings.vertex_buffers[0] = g_state.vb;
595 |
596 | // for the image to the window and keep the ratio
597 | int w = g_state.texinfo.width;
598 | int h = g_state.texinfo.height;
599 | {
600 | float ratio_outer = (float)sapp_width() / (float)sapp_height();
601 | float ratio_inner = (float)w / (float)h;
602 | float scale = (ratio_inner >= ratio_outer) ?
603 | ((float)sapp_width()/(float)w) :
604 | ((float)sapp_height()/(float)h);
605 | w = (int)((float)w * scale);
606 | h = (int)((float)h * scale);
607 | }
608 |
609 | sg_apply_viewport((sapp_width() - w)/2, (sapp_height() - h)/2, w, h, true);
610 |
611 | sg_apply_pipeline((g_state.texinfo.flags & DDSKTX_TEXTURE_FLAG_CUBEMAP) ? g_state.pip_cubemap : g_state.pip);
612 | sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &uvs, sizeof(uvs));
613 | sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, &g_state.vars_fs, sizeof(g_state.vars_fs));
614 | sg_apply_bindings(&bindings);
615 | sg_draw(0, 6, 1);
616 | }
617 |
618 | sg_apply_viewport(0, 0, sapp_width(), sapp_height(), true);
619 | sdtx_draw();
620 |
621 | sg_end_pass();
622 | sg_commit();
623 | }
624 |
625 | static void release(void)
626 | {
627 | free(g_state.file_data);
628 | sg_destroy_pipeline(g_state.pip);
629 | sg_destroy_pipeline(g_state.pip_checker);
630 | sg_destroy_pipeline(g_state.pip_cubemap);
631 | sg_destroy_shader(g_state.shader);
632 | sg_destroy_shader(g_state.shader_cubemap);
633 | sg_destroy_buffer(g_state.vb);
634 | sg_destroy_buffer(g_state.vb_checker);
635 | sg_destroy_buffer(g_state.ib);
636 | sg_destroy_image(g_state.tex);
637 | sg_destroy_image(g_state.checker);
638 | sdtx_shutdown();
639 | sg_shutdown();
640 | }
641 |
642 | static void on_events(const sapp_event* e)
643 | {
644 | switch (e->type) {
645 | case SAPP_EVENTTYPE_RESIZED:
646 | sdtx_canvas((float)sapp_width() * (1.0f/FONT_SCALE), (float)sapp_height() * (1.0f/FONT_SCALE));
647 | adjust_checker_coords(e->window_width, e->window_height);
648 | break;
649 |
650 | case SAPP_EVENTTYPE_KEY_DOWN:
651 | if (e->key_code == SAPP_KEYCODE_GRAVE_ACCENT) {
652 | g_state.inv_text_color = !g_state.inv_text_color;
653 | }
654 | if (e->key_code == SAPP_KEYCODE_A) {
655 | g_state.vars_fs.color[3] = g_state.vars_fs.color[3] == 1.0f ? 0 : 1.0f;
656 | }
657 | if (e->key_code == SAPP_KEYCODE_R) {
658 | g_state.vars_fs.color[0] = g_state.vars_fs.color[0] == 1.0f ? 0 : 1.0f;
659 | }
660 | if (e->key_code == SAPP_KEYCODE_G) {
661 | g_state.vars_fs.color[1] = g_state.vars_fs.color[1] == 1.0f ? 0 : 1.0f;
662 | }
663 | if (e->key_code == SAPP_KEYCODE_B) {
664 | g_state.vars_fs.color[2] = g_state.vars_fs.color[2] == 1.0f ? 0 : 1.0f;
665 | }
666 | if (e->key_code == SAPP_KEYCODE_UP) {
667 | g_state.cur_mip = (g_state.cur_mip + 1) >= g_state.texinfo.num_mips ? (g_state.texinfo.num_mips - 1) : g_state.cur_mip + 1;
668 | }
669 | if (e->key_code == SAPP_KEYCODE_DOWN) {
670 | g_state.cur_mip = (g_state.cur_mip > 0) ? g_state.cur_mip - 1 : 0;
671 | }
672 |
673 | if (e->key_code == SAPP_KEYCODE_ESCAPE) {
674 | sapp_request_quit();
675 | }
676 |
677 | if (e->key_code == SAPP_KEYCODE_F) {
678 | g_state.cube_face = (g_state.cube_face + 1) % DDSKTX_CUBE_FACE_COUNT;
679 | set_cube_face(g_state.cube_face);
680 | }
681 |
682 | break;
683 | }
684 | }
685 |
686 | sapp_desc sokol_main(int argc, char* argv[])
687 | {
688 | if (argc <= 1) {
689 | print_msg("Provide a file to load as argument");
690 | exit(-1);
691 | }
692 |
693 | FILE* f = fopen(argv[1], "rb");
694 | if (!f) {
695 | print_msg("Error: could not open file: %s\n", argv[1]);
696 | exit(-1);
697 | }
698 |
699 | fseek(f, 0, SEEK_END);
700 | int size = (int)ftell(f);
701 | if (size == 0) {
702 | print_msg("Error: file '%s' is empty\n", argv[1]);
703 | exit(-1);
704 | }
705 | fseek(f, 0, SEEK_SET);
706 |
707 | void* data = malloc(size);
708 | if (!data) {
709 | print_msg("out of memory: requested size: %d\n", (int)size);
710 | exit(-1);
711 | }
712 |
713 | if (fread(data, 1, size, f) != size) {
714 | print_msg("could not read file data : %s\n", argv[1]);
715 | exit(-1);
716 | }
717 |
718 | g_state.file_data = data;
719 | g_state.file_size = size;
720 |
721 | fclose(f);
722 |
723 | ddsktx_texture_info tc = {0};
724 | ddsktx_error img_err;
725 | if (!ddsktx_parse(&tc, data, size, &img_err)) {
726 | print_msg("Loading image '%s' failed: %s", argv[1], img_err.msg);
727 | exit(-1);
728 | }
729 |
730 | g_state.texinfo = tc;
731 |
732 | int window_w = tc.width;
733 | int window_h = tc.height;
734 | #if defined(_WIN32) || defined(_WIN64)
735 | int desktop_w, desktop_h;
736 | desktop_size(&desktop_w, &desktop_h);
737 | float ratio = (float)tc.width / (float)tc.height;
738 | if (window_w > (desktop_w - 50)) {
739 | window_w = desktop_w - 50;
740 | window_h = (int)((float)window_w / ratio);
741 | }
742 | if (window_h > (desktop_h - 50)) {
743 | window_h = desktop_h - 50;
744 | window_w = (int)((float)window_h * ratio);
745 | }
746 | #endif
747 |
748 | return (sapp_desc) {
749 | .init_cb = init,
750 | .frame_cb = frame,
751 | .cleanup_cb = release,
752 | .event_cb = on_events,
753 | .width = window_w,
754 | .height = window_h,
755 | .window_title = "DDS/KTX viewer",
756 | .swap_interval = 2,
757 | .sample_count = 1
758 | };
759 | }
760 |
--------------------------------------------------------------------------------
/ctexview/ctexview.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/septag/dds-ktx/c3ca8febc2457ab5c581604f3236a8a511fc2e45/ctexview/ctexview.ico
--------------------------------------------------------------------------------
/ctexview/quad.frag:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | precision mediump float;
4 |
5 |
6 | layout (location = TEXCOORD0) in vec3 f_uv;
7 | layout (location = SV_Target0) out vec4 frag_color;
8 |
9 | #ifdef CUBEMAP
10 | layout (binding = 0) uniform samplerCube tex_image;
11 | #else
12 | layout (binding = 0) uniform sampler2D tex_image;
13 | #endif
14 |
15 | layout (binding = 0, std140) uniform globals {
16 | vec4 color;
17 | vec4 target_lod;
18 | };
19 |
20 | void main()
21 | {
22 | #ifdef CUBEMAP
23 | frag_color = textureLod(tex_image, f_uv, target_lod.x) * vec4(color.xyz, 1.0);
24 | #else
25 | frag_color = textureLod(tex_image, f_uv.xy, target_lod.x) * vec4(color.rgb, 1.0);
26 | #endif
27 | frag_color.a = color.a < 1.0 ? 1.0 : frag_color.a;
28 | }
29 |
--------------------------------------------------------------------------------
/ctexview/quad.vert:
--------------------------------------------------------------------------------
1 | #version 450
2 |
3 | layout (location = POSITION) in vec2 a_pos;
4 | layout (location = TEXCOORD0) in vec3 a_uv;
5 |
6 | layout (location = TEXCOORD0) out vec3 f_uv;
7 |
8 | layout (binding = 0, std140) uniform globals {
9 | mat4 proj_mat;
10 | };
11 |
12 | void main() {
13 | gl_Position = proj_mat * vec4(a_pos, 0, 1.0);
14 | f_uv = a_uv;
15 | }
--------------------------------------------------------------------------------
/ctexview/quad_cubemap_glsl.frag.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_cubemap_fs_size = 381;
7 | static const unsigned int quad_cubemap_fs_data[384/4] = {
8 | 0x72657623, 0x6e6f6973, 0x30333320, 0x6e750a0a, 0x726f6669, 0x6576206d, 0x67203463, 0x61626f6c,
9 | 0x325b736c, 0x750a3b5d, 0x6f66696e, 0x73206d72, 0x6c706d61, 0x75437265, 0x74206562, 0x695f7865,
10 | 0x6567616d, 0x6c0a0a3b, 0x756f7961, 0x6f6c2874, 0x69746163, 0x3d206e6f, 0x20293020, 0x2074756f,
11 | 0x34636576, 0x61726620, 0x6f635f67, 0x3b726f6c, 0x206e690a, 0x33636576, 0x755f6620, 0x0a0a3b76,
12 | 0x64696f76, 0x69616d20, 0x0a29286e, 0x20200a7b, 0x72662020, 0x635f6761, 0x726f6c6f, 0x74203d20,
13 | 0x75747865, 0x6f4c6572, 0x65742864, 0x6d695f78, 0x2c656761, 0x755f6620, 0x67202c76, 0x61626f6c,
14 | 0x315b736c, 0x29782e5d, 0x76202a20, 0x28346365, 0x626f6c67, 0x5b736c61, 0x782e5d30, 0x202c7a79,
15 | 0x29302e31, 0x20200a3b, 0x6c662020, 0x2074616f, 0x3b37345f, 0x2020200a, 0x20666920, 0x6f6c6728,
16 | 0x736c6162, 0x2e5d305b, 0x203c2077, 0x29302e31, 0x2020200a, 0x200a7b20, 0x20202020, 0x5f202020,
17 | 0x3d203734, 0x302e3120, 0x20200a3b, 0x0a7d2020, 0x20202020, 0x65736c65, 0x2020200a, 0x200a7b20,
18 | 0x20202020, 0x5f202020, 0x3d203734, 0x61726620, 0x6f635f67, 0x2e726f6c, 0x200a3b77, 0x7d202020,
19 | 0x2020200a, 0x61726620, 0x6f635f67, 0x2e726f6c, 0x203d2077, 0x3b37345f, 0x0a0a7d0a, 0x00000000 };
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ctexview/quad_cubemap_hlsl.frag.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_cubemap_fs_size = 988;
7 | static const unsigned int quad_cubemap_fs_data[988/4] = {
8 | 0x43425844, 0xdcce51ee, 0x91aaa444, 0x1f1ddd8b, 0x4bd76050, 0x00000001, 0x000003dc, 0x00000005,
9 | 0x00000034, 0x000001d8, 0x0000020c, 0x00000240, 0x00000340, 0x46454452, 0x0000019c, 0x00000001,
10 | 0x000000c4, 0x00000003, 0x0000003c, 0xffff0500, 0x00008100, 0x00000173, 0x31314452, 0x0000003c,
11 | 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x0000009c, 0x00000003,
12 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000af, 0x00000002,
13 | 0x00000005, 0x00000009, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000b9, 0x00000000,
14 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x7865745f, 0x616d695f,
15 | 0x735f6567, 0x6c706d61, 0x74007265, 0x695f7865, 0x6567616d, 0x6f6c6700, 0x736c6162, 0xababab00,
16 | 0x000000b9, 0x00000002, 0x000000dc, 0x00000020, 0x00000000, 0x00000000, 0x0000012c, 0x00000000,
17 | 0x00000010, 0x00000002, 0x00000140, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
18 | 0x00000164, 0x00000010, 0x00000010, 0x00000002, 0x00000140, 0x00000000, 0xffffffff, 0x00000000,
19 | 0xffffffff, 0x00000000, 0x5f31325f, 0x6f6c6f63, 0x6c660072, 0x3474616f, 0xababab00, 0x00030001,
20 | 0x00040001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000136,
21 | 0x5f31325f, 0x67726174, 0x6c5f7465, 0x4d00646f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
22 | 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x30312072, 0xab00312e, 0x4e475349, 0x0000002c,
23 | 0x00000001, 0x00000008, 0x00000020, 0x00000002, 0x00000000, 0x00000003, 0x00000000, 0x00000707,
24 | 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
25 | 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074,
26 | 0x58454853, 0x000000f8, 0x00000050, 0x0000003e, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000,
27 | 0x00000002, 0x0300005a, 0x00106000, 0x00000000, 0x04003058, 0x00107000, 0x00000000, 0x00005555,
28 | 0x03001062, 0x00101072, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002,
29 | 0x08000031, 0x00100012, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x00004001, 0x3f800000,
30 | 0x8e000048, 0x80000182, 0x00155543, 0x001000f2, 0x00000001, 0x00101246, 0x00000000, 0x00107936,
31 | 0x00000000, 0x00106000, 0x00000000, 0x0020800a, 0x00000000, 0x00000001, 0x08000038, 0x00102072,
32 | 0x00000000, 0x00100796, 0x00000001, 0x00208246, 0x00000000, 0x00000000, 0x09000037, 0x00102082,
33 | 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0010000a, 0x00000001, 0x0100003e,
34 | 0x54415453, 0x00000094, 0x00000005, 0x00000002, 0x00000000, 0x00000002, 0x00000002, 0x00000000,
35 | 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
36 | 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
37 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
38 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
39 |
40 |
--------------------------------------------------------------------------------
/ctexview/quad_cubemap_metal.frag.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_cubemap_fs_size = 738;
7 | static const unsigned int quad_cubemap_fs_data[740/4] = {
8 | 0x636e6923, 0x6564756c, 0x656d3c20, 0x5f6c6174, 0x6c647473, 0x0a3e6269, 0x636e6923, 0x6564756c,
9 | 0x69733c20, 0x732f646d, 0x2e646d69, 0x0a0a3e68, 0x6e697375, 0x616e2067, 0x7073656d, 0x20656361,
10 | 0x6174656d, 0x0a0a3b6c, 0x75727473, 0x67207463, 0x61626f6c, 0x7b0a736c, 0x2020200a, 0x6f6c6620,
11 | 0x20347461, 0x6f6c6f63, 0x200a3b72, 0x66202020, 0x74616f6c, 0x61742034, 0x74656772, 0x646f6c5f,
12 | 0x3b7d0a3b, 0x74730a0a, 0x74637572, 0x69616d20, 0x6f5f306e, 0x7b0a7475, 0x2020200a, 0x6f6c6620,
13 | 0x20347461, 0x67617266, 0x6c6f635f, 0x5b20726f, 0x6c6f635b, 0x3028726f, 0x3b5d5d29, 0x0a3b7d0a,
14 | 0x7274730a, 0x20746375, 0x6e69616d, 0x6e695f30, 0x200a7b0a, 0x66202020, 0x74616f6c, 0x5f662033,
15 | 0x5b207675, 0x6573755b, 0x6f6c2872, 0x29326e63, 0x0a3b5d5d, 0x0a0a3b7d, 0x67617266, 0x746e656d,
16 | 0x69616d20, 0x6f5f306e, 0x6d207475, 0x306e6961, 0x69616d28, 0x695f306e, 0x6e69206e, 0x735b5b20,
17 | 0x65676174, 0x5d6e695f, 0x63202c5d, 0x74736e6f, 0x20746e61, 0x626f6c67, 0x26736c61, 0x31325f20,
18 | 0x625b5b20, 0x65666675, 0x29302872, 0x202c5d5d, 0x74786574, 0x63657275, 0x3c656275, 0x616f6c66,
19 | 0x74203e74, 0x695f7865, 0x6567616d, 0x745b5b20, 0x75747865, 0x30286572, 0x2c5d5d29, 0x6d617320,
20 | 0x72656c70, 0x78657420, 0x616d695f, 0x6d536567, 0x20726c70, 0x61735b5b, 0x656c706d, 0x29302872,
21 | 0x0a295d5d, 0x20200a7b, 0x616d2020, 0x5f306e69, 0x2074756f, 0x2074756f, 0x7d7b203d, 0x20200a3b,
22 | 0x756f2020, 0x72662e74, 0x635f6761, 0x726f6c6f, 0x74203d20, 0x695f7865, 0x6567616d, 0x6d61732e,
23 | 0x28656c70, 0x5f786574, 0x67616d69, 0x706d5365, 0x202c726c, 0x662e6e69, 0x2c76755f, 0x76656c20,
24 | 0x5f286c65, 0x742e3132, 0x65677261, 0x6f6c5f74, 0x29782e64, 0x202a2029, 0x616f6c66, 0x5f283474,
25 | 0x632e3132, 0x726f6c6f, 0x7a79782e, 0x2e31202c, 0x0a3b2930, 0x20202020, 0x616f6c66, 0x345f2074,
26 | 0x200a3b37, 0x69202020, 0x5f282066, 0x632e3132, 0x726f6c6f, 0x3c20772e, 0x302e3120, 0x20200a29,
27 | 0x0a7b2020, 0x20202020, 0x20202020, 0x2037345f, 0x2e31203d, 0x200a3b30, 0x7d202020, 0x2020200a,
28 | 0x736c6520, 0x20200a65, 0x0a7b2020, 0x20202020, 0x20202020, 0x2037345f, 0x756f203d, 0x72662e74,
29 | 0x635f6761, 0x726f6c6f, 0x0a3b772e, 0x20202020, 0x20200a7d, 0x756f2020, 0x72662e74, 0x635f6761,
30 | 0x726f6c6f, 0x3d20772e, 0x37345f20, 0x20200a3b, 0x65722020, 0x6e727574, 0x74756f20, 0x0a7d0a3b,
31 | 0x0000000a };
32 |
33 |
--------------------------------------------------------------------------------
/ctexview/quad_glsl.frag.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_fs_size = 382;
7 | static const unsigned int quad_fs_data[384/4] = {
8 | 0x72657623, 0x6e6f6973, 0x30333320, 0x6e750a0a, 0x726f6669, 0x6576206d, 0x67203463, 0x61626f6c,
9 | 0x325b736c, 0x750a3b5d, 0x6f66696e, 0x73206d72, 0x6c706d61, 0x44327265, 0x78657420, 0x616d695f,
10 | 0x0a3b6567, 0x79616c0a, 0x2874756f, 0x61636f6c, 0x6e6f6974, 0x30203d20, 0x756f2029, 0x65762074,
11 | 0x66203463, 0x5f676172, 0x6f6c6f63, 0x690a3b72, 0x6576206e, 0x66203363, 0x3b76755f, 0x6f760a0a,
12 | 0x6d206469, 0x286e6961, 0x0a7b0a29, 0x20202020, 0x67617266, 0x6c6f635f, 0x3d20726f, 0x78657420,
13 | 0x65727574, 0x28646f4c, 0x5f786574, 0x67616d69, 0x66202c65, 0x2e76755f, 0x202c7978, 0x626f6c67,
14 | 0x5b736c61, 0x782e5d31, 0x202a2029, 0x34636576, 0x6f6c6728, 0x736c6162, 0x2e5d305b, 0x2c7a7978,
15 | 0x302e3120, 0x200a3b29, 0x66202020, 0x74616f6c, 0x39345f20, 0x20200a3b, 0x66692020, 0x6c672820,
16 | 0x6c61626f, 0x5d305b73, 0x3c20772e, 0x302e3120, 0x20200a29, 0x0a7b2020, 0x20202020, 0x20202020,
17 | 0x2039345f, 0x2e31203d, 0x200a3b30, 0x7d202020, 0x2020200a, 0x736c6520, 0x20200a65, 0x0a7b2020,
18 | 0x20202020, 0x20202020, 0x2039345f, 0x7266203d, 0x635f6761, 0x726f6c6f, 0x0a3b772e, 0x20202020,
19 | 0x20200a7d, 0x72662020, 0x635f6761, 0x726f6c6f, 0x3d20772e, 0x39345f20, 0x0a7d0a3b, 0x0000000a };
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ctexview/quad_glsl.vert.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_vs_size = 257;
7 | static const unsigned int quad_vs_data[260/4] = {
8 | 0x72657623, 0x6e6f6973, 0x30333320, 0x6e750a0a, 0x726f6669, 0x6576206d, 0x67203463, 0x61626f6c,
9 | 0x345b736c, 0x6c0a3b5d, 0x756f7961, 0x6f6c2874, 0x69746163, 0x3d206e6f, 0x20293020, 0x76206e69,
10 | 0x20326365, 0x6f705f61, 0x6f0a3b73, 0x76207475, 0x20336365, 0x76755f66, 0x616c0a3b, 0x74756f79,
11 | 0x636f6c28, 0x6f697461, 0x203d206e, 0x69202932, 0x6576206e, 0x61203363, 0x3b76755f, 0x6f760a0a,
12 | 0x6d206469, 0x286e6961, 0x0a7b0a29, 0x20202020, 0x505f6c67, 0x7469736f, 0x206e6f69, 0x616d203d,
13 | 0x67283474, 0x61626f6c, 0x305b736c, 0x67202c5d, 0x61626f6c, 0x315b736c, 0x67202c5d, 0x61626f6c,
14 | 0x325b736c, 0x67202c5d, 0x61626f6c, 0x335b736c, 0x2a20295d, 0x63657620, 0x5f612834, 0x2c736f70,
15 | 0x302e3020, 0x2e31202c, 0x0a3b2930, 0x20202020, 0x76755f66, 0x61203d20, 0x3b76755f, 0x0a0a7d0a,
16 | 0x00000000 };
17 |
18 |
--------------------------------------------------------------------------------
/ctexview/quad_hlsl.frag.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_fs_size = 988;
7 | static const unsigned int quad_fs_data[988/4] = {
8 | 0x43425844, 0x1f031d00, 0xb00294b3, 0x863dd79d, 0x353015d5, 0x00000001, 0x000003dc, 0x00000005,
9 | 0x00000034, 0x000001d8, 0x0000020c, 0x00000240, 0x00000340, 0x46454452, 0x0000019c, 0x00000001,
10 | 0x000000c4, 0x00000003, 0x0000003c, 0xffff0500, 0x00008100, 0x00000173, 0x31314452, 0x0000003c,
11 | 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x0000009c, 0x00000003,
12 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000af, 0x00000002,
13 | 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x000000b9, 0x00000000,
14 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x7865745f, 0x616d695f,
15 | 0x735f6567, 0x6c706d61, 0x74007265, 0x695f7865, 0x6567616d, 0x6f6c6700, 0x736c6162, 0xababab00,
16 | 0x000000b9, 0x00000002, 0x000000dc, 0x00000020, 0x00000000, 0x00000000, 0x0000012c, 0x00000000,
17 | 0x00000010, 0x00000002, 0x00000140, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
18 | 0x00000164, 0x00000010, 0x00000010, 0x00000002, 0x00000140, 0x00000000, 0xffffffff, 0x00000000,
19 | 0xffffffff, 0x00000000, 0x5f33325f, 0x6f6c6f63, 0x6c660072, 0x3474616f, 0xababab00, 0x00030001,
20 | 0x00040001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000136,
21 | 0x5f33325f, 0x67726174, 0x6c5f7465, 0x4d00646f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
22 | 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x30312072, 0xab00312e, 0x4e475349, 0x0000002c,
23 | 0x00000001, 0x00000008, 0x00000020, 0x00000002, 0x00000000, 0x00000003, 0x00000000, 0x00000307,
24 | 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
25 | 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074,
26 | 0x58454853, 0x000000f8, 0x00000050, 0x0000003e, 0x0100086a, 0x04000059, 0x00208e46, 0x00000000,
27 | 0x00000002, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
28 | 0x03001062, 0x00101032, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002,
29 | 0x08000031, 0x00100012, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x00004001, 0x3f800000,
30 | 0x8e000048, 0x800000c2, 0x00155543, 0x001000f2, 0x00000001, 0x00101046, 0x00000000, 0x00107936,
31 | 0x00000000, 0x00106000, 0x00000000, 0x0020800a, 0x00000000, 0x00000001, 0x08000038, 0x00102072,
32 | 0x00000000, 0x00100796, 0x00000001, 0x00208246, 0x00000000, 0x00000000, 0x09000037, 0x00102082,
33 | 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0010000a, 0x00000001, 0x0100003e,
34 | 0x54415453, 0x00000094, 0x00000005, 0x00000002, 0x00000000, 0x00000002, 0x00000002, 0x00000000,
35 | 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
36 | 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
37 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
38 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
39 |
40 |
--------------------------------------------------------------------------------
/ctexview/quad_hlsl.vert.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_vs_size = 876;
7 | static const unsigned int quad_vs_data[876/4] = {
8 | 0x43425844, 0x850b49a2, 0x1c1eb79a, 0x88cec8a9, 0xac646615, 0x00000001, 0x0000036c, 0x00000005,
9 | 0x00000034, 0x00000144, 0x00000198, 0x000001f0, 0x000002d0, 0x46454452, 0x00000108, 0x00000001,
10 | 0x00000064, 0x00000001, 0x0000003c, 0xfffe0500, 0x00008100, 0x000000e0, 0x31314452, 0x0000003c,
11 | 0x00000018, 0x00000020, 0x00000028, 0x00000024, 0x0000000c, 0x00000000, 0x0000005c, 0x00000000,
12 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x626f6c67, 0x00736c61,
13 | 0x0000005c, 0x00000001, 0x0000007c, 0x00000040, 0x00000000, 0x00000000, 0x000000a4, 0x00000000,
14 | 0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
15 | 0x5f39315f, 0x6a6f7270, 0x74616d5f, 0x6f6c6600, 0x78347461, 0xabab0034, 0x00030002, 0x00040004,
16 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000b1, 0x7263694d,
17 | 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x31207265,
18 | 0x00312e30, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000,
19 | 0x00000003, 0x00000000, 0x00000303, 0x00000041, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
20 | 0x00000707, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044, 0x4e47534f, 0x00000050,
21 | 0x00000002, 0x00000008, 0x00000038, 0x00000002, 0x00000000, 0x00000003, 0x00000000, 0x00000807,
22 | 0x00000041, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x0000000f, 0x43584554, 0x44524f4f,
23 | 0x5f565300, 0x69736f50, 0x6e6f6974, 0xababab00, 0x58454853, 0x000000d8, 0x00010050, 0x00000036,
24 | 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f, 0x00101032, 0x00000000,
25 | 0x0300005f, 0x00101072, 0x00000001, 0x03000065, 0x00102072, 0x00000000, 0x04000067, 0x001020f2,
26 | 0x00000001, 0x00000001, 0x02000068, 0x00000001, 0x05000036, 0x00102072, 0x00000000, 0x00101246,
27 | 0x00000001, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46, 0x00000000,
28 | 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006, 0x00000000, 0x00208e46, 0x00000000,
29 | 0x00000000, 0x00100e46, 0x00000000, 0x08000000, 0x001020f2, 0x00000001, 0x00100e46, 0x00000000,
30 | 0x00208e46, 0x00000000, 0x00000003, 0x0100003e, 0x54415453, 0x00000094, 0x00000005, 0x00000001,
31 | 0x00000000, 0x00000004, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
32 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
33 | 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
34 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
35 | 0x00000000, 0x00000000, 0x00000000 };
36 |
37 |
--------------------------------------------------------------------------------
/ctexview/quad_metal.frag.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_fs_size = 739;
7 | static const unsigned int quad_fs_data[740/4] = {
8 | 0x636e6923, 0x6564756c, 0x656d3c20, 0x5f6c6174, 0x6c647473, 0x0a3e6269, 0x636e6923, 0x6564756c,
9 | 0x69733c20, 0x732f646d, 0x2e646d69, 0x0a0a3e68, 0x6e697375, 0x616e2067, 0x7073656d, 0x20656361,
10 | 0x6174656d, 0x0a0a3b6c, 0x75727473, 0x67207463, 0x61626f6c, 0x7b0a736c, 0x2020200a, 0x6f6c6620,
11 | 0x20347461, 0x6f6c6f63, 0x200a3b72, 0x66202020, 0x74616f6c, 0x61742034, 0x74656772, 0x646f6c5f,
12 | 0x3b7d0a3b, 0x74730a0a, 0x74637572, 0x69616d20, 0x6f5f306e, 0x7b0a7475, 0x2020200a, 0x6f6c6620,
13 | 0x20347461, 0x67617266, 0x6c6f635f, 0x5b20726f, 0x6c6f635b, 0x3028726f, 0x3b5d5d29, 0x0a3b7d0a,
14 | 0x7274730a, 0x20746375, 0x6e69616d, 0x6e695f30, 0x200a7b0a, 0x66202020, 0x74616f6c, 0x5f662033,
15 | 0x5b207675, 0x6573755b, 0x6f6c2872, 0x29326e63, 0x0a3b5d5d, 0x0a0a3b7d, 0x67617266, 0x746e656d,
16 | 0x69616d20, 0x6f5f306e, 0x6d207475, 0x306e6961, 0x69616d28, 0x695f306e, 0x6e69206e, 0x735b5b20,
17 | 0x65676174, 0x5d6e695f, 0x63202c5d, 0x74736e6f, 0x20746e61, 0x626f6c67, 0x26736c61, 0x33325f20,
18 | 0x625b5b20, 0x65666675, 0x29302872, 0x202c5d5d, 0x74786574, 0x32657275, 0x6c663c64, 0x3e74616f,
19 | 0x78657420, 0x616d695f, 0x5b206567, 0x7865745b, 0x65727574, 0x5d293028, 0x73202c5d, 0x6c706d61,
20 | 0x74207265, 0x695f7865, 0x6567616d, 0x6c706d53, 0x5b5b2072, 0x706d6173, 0x2872656c, 0x5d5d2930,
21 | 0x0a7b0a29, 0x20202020, 0x6e69616d, 0x756f5f30, 0x756f2074, 0x203d2074, 0x0a3b7d7b, 0x20202020,
22 | 0x2e74756f, 0x67617266, 0x6c6f635f, 0x3d20726f, 0x78657420, 0x616d695f, 0x732e6567, 0x6c706d61,
23 | 0x65742865, 0x6d695f78, 0x53656761, 0x726c706d, 0x6e69202c, 0x755f662e, 0x79782e76, 0x656c202c,
24 | 0x286c6576, 0x2e33325f, 0x67726174, 0x6c5f7465, 0x782e646f, 0x2a202929, 0x6f6c6620, 0x28347461,
25 | 0x2e33325f, 0x6f6c6f63, 0x79782e72, 0x31202c7a, 0x3b29302e, 0x2020200a, 0x6f6c6620, 0x5f207461,
26 | 0x0a3b3934, 0x20202020, 0x28206669, 0x2e33325f, 0x6f6c6f63, 0x20772e72, 0x2e31203c, 0x200a2930,
27 | 0x7b202020, 0x2020200a, 0x20202020, 0x39345f20, 0x31203d20, 0x0a3b302e, 0x20202020, 0x20200a7d,
28 | 0x6c652020, 0x200a6573, 0x7b202020, 0x2020200a, 0x20202020, 0x39345f20, 0x6f203d20, 0x662e7475,
29 | 0x5f676172, 0x6f6c6f63, 0x3b772e72, 0x2020200a, 0x200a7d20, 0x6f202020, 0x662e7475, 0x5f676172,
30 | 0x6f6c6f63, 0x20772e72, 0x345f203d, 0x200a3b39, 0x72202020, 0x72757465, 0x756f206e, 0x7d0a3b74,
31 | 0x00000a0a };
32 |
33 |
--------------------------------------------------------------------------------
/ctexview/quad_metal.vert.h:
--------------------------------------------------------------------------------
1 | // This file is automatically created by glslcc v1.7.3
2 | // http://www.github.com/septag/glslcc
3 | //
4 | #pragma once
5 |
6 | static const unsigned int quad_vs_size = 521;
7 | static const unsigned int quad_vs_data[524/4] = {
8 | 0x636e6923, 0x6564756c, 0x656d3c20, 0x5f6c6174, 0x6c647473, 0x0a3e6269, 0x636e6923, 0x6564756c,
9 | 0x69733c20, 0x732f646d, 0x2e646d69, 0x0a0a3e68, 0x6e697375, 0x616e2067, 0x7073656d, 0x20656361,
10 | 0x6174656d, 0x0a0a3b6c, 0x75727473, 0x67207463, 0x61626f6c, 0x7b0a736c, 0x2020200a, 0x6f6c6620,
11 | 0x78347461, 0x72702034, 0x6d5f6a6f, 0x0a3b7461, 0x0a0a3b7d, 0x75727473, 0x6d207463, 0x306e6961,
12 | 0x74756f5f, 0x200a7b0a, 0x66202020, 0x74616f6c, 0x5f662033, 0x5b207675, 0x6573755b, 0x6f6c2872,
13 | 0x29326e63, 0x0a3b5d5d, 0x20202020, 0x616f6c66, 0x67203474, 0x6f505f6c, 0x69746973, 0x5b206e6f,
14 | 0x736f705b, 0x6f697469, 0x3b5d5d6e, 0x0a3b7d0a, 0x7274730a, 0x20746375, 0x6e69616d, 0x6e695f30,
15 | 0x200a7b0a, 0x66202020, 0x74616f6c, 0x5f612032, 0x20736f70, 0x74615b5b, 0x62697274, 0x28657475,
16 | 0x5d5d2930, 0x20200a3b, 0x6c662020, 0x3374616f, 0x755f6120, 0x5b5b2076, 0x72747461, 0x74756269,
17 | 0x29312865, 0x0a3b5d5d, 0x0a0a3b7d, 0x74726576, 0x6d207865, 0x306e6961, 0x74756f5f, 0x69616d20,
18 | 0x6d28306e, 0x306e6961, 0x206e695f, 0x5b206e69, 0x6174735b, 0x695f6567, 0x2c5d5d6e, 0x6e6f6320,
19 | 0x6e617473, 0x6c672074, 0x6c61626f, 0x5f202673, 0x5b203931, 0x6675625b, 0x28726566, 0x5d5d2930,
20 | 0x0a7b0a29, 0x20202020, 0x6e69616d, 0x756f5f30, 0x756f2074, 0x203d2074, 0x0a3b7d7b, 0x20202020,
21 | 0x2e74756f, 0x505f6c67, 0x7469736f, 0x206e6f69, 0x315f203d, 0x72702e39, 0x6d5f6a6f, 0x2a207461,
22 | 0x6f6c6620, 0x28347461, 0x612e6e69, 0x736f705f, 0x2e30202c, 0x31202c30, 0x3b29302e, 0x2020200a,
23 | 0x74756f20, 0x755f662e, 0x203d2076, 0x612e6e69, 0x3b76755f, 0x2020200a, 0x74657220, 0x206e7275,
24 | 0x3b74756f, 0x0a0a7d0a, 0x00000000 };
25 |
26 |
--------------------------------------------------------------------------------
/ctexview/sokol_glue.h:
--------------------------------------------------------------------------------
1 | #ifndef SOKOL_GLUE_INCLUDED
2 | /*
3 | sokol_glue.h -- glue helper functions for sokol headers
4 |
5 | Project URL: https://github.com/floooh/sokol
6 |
7 | Do this:
8 | #define SOKOL_IMPL
9 | before you include this file in *one* C or C++ file to create the
10 | implementation.
11 |
12 | ...optionally provide the following macros to override defaults:
13 |
14 | SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
15 | SOKOL_API_DECL - public function declaration prefix (default: extern)
16 | SOKOL_API_IMPL - public function implementation prefix (default: -)
17 |
18 | If sokol_glue.h is compiled as a DLL, define the following before
19 | including the declaration or implementation:
20 |
21 | SOKOL_DLL
22 |
23 | On Windows, SOKOL_DLL will define SOKOL_API_DECL as __declspec(dllexport)
24 | or __declspec(dllimport) as needed.
25 |
26 | OVERVIEW
27 | ========
28 | The sokol core headers should not depend on each other, but sometimes
29 | it's useful to have a set of helper functions as "glue" between
30 | two or more sokol headers.
31 |
32 | This is what sokol_glue.h is for. Simply include the header after other
33 | sokol headers (both for the implementation and declaration), and
34 | depending on what headers have been included before, sokol_glue.h
35 | will make available "glue functions".
36 |
37 | PROVIDED FUNCTIONS
38 | ==================
39 |
40 | - if sokol_app.h and sokol_gfx.h is included:
41 |
42 | sg_context_desc sapp_sgcontext(void):
43 |
44 | Returns an initialized sg_context_desc function initialized
45 | by calling sokol_app.h functions.
46 |
47 | LICENSE
48 | =======
49 | zlib/libpng license
50 |
51 | Copyright (c) 2018 Andre Weissflog
52 |
53 | This software is provided 'as-is', without any express or implied warranty.
54 | In no event will the authors be held liable for any damages arising from the
55 | use of this software.
56 |
57 | Permission is granted to anyone to use this software for any purpose,
58 | including commercial applications, and to alter it and redistribute it
59 | freely, subject to the following restrictions:
60 |
61 | 1. The origin of this software must not be misrepresented; you must not
62 | claim that you wrote the original software. If you use this software in a
63 | product, an acknowledgment in the product documentation would be
64 | appreciated but is not required.
65 |
66 | 2. Altered source versions must be plainly marked as such, and must not
67 | be misrepresented as being the original software.
68 |
69 | 3. This notice may not be removed or altered from any source
70 | distribution.
71 | */
72 | #define SOKOL_GLUE_INCLUDED
73 |
74 | #ifndef SOKOL_API_DECL
75 | #if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_IMPL)
76 | #define SOKOL_API_DECL __declspec(dllexport)
77 | #elif defined(_WIN32) && defined(SOKOL_DLL)
78 | #define SOKOL_API_DECL __declspec(dllimport)
79 | #else
80 | #define SOKOL_API_DECL extern
81 | #endif
82 | #endif
83 |
84 | #ifdef __cplusplus
85 | extern "C" {
86 | #endif
87 |
88 | #if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
89 | SOKOL_API_DECL sg_context_desc sapp_sgcontext(void);
90 | #endif
91 |
92 | #ifdef __cplusplus
93 | } /* extern "C" */
94 | #endif
95 | #endif /* SOKOL_GLUE_INCLUDED */
96 |
97 | /*-- IMPLEMENTATION ----------------------------------------------------------*/
98 | #ifdef SOKOL_IMPL
99 | #define SOKOL_GLUE_IMPL_INCLUDED (1)
100 | #include /* memset */
101 |
102 | #ifndef SOKOL_API_IMPL
103 | #define SOKOL_API_IMPL
104 | #endif
105 |
106 | #if defined(SOKOL_GFX_INCLUDED) && defined(SOKOL_APP_INCLUDED)
107 | SOKOL_API_IMPL sg_context_desc sapp_sgcontext(void) {
108 | sg_context_desc desc;
109 | memset(&desc, 0, sizeof(desc));
110 | desc.color_format = (sg_pixel_format) sapp_color_format();
111 | desc.depth_format = (sg_pixel_format) sapp_depth_format();
112 | desc.sample_count = sapp_sample_count();
113 | desc.gl.force_gles2 = sapp_gles2();
114 | desc.metal.device = sapp_metal_get_device();
115 | desc.metal.renderpass_descriptor_cb = sapp_metal_get_renderpass_descriptor;
116 | desc.metal.drawable_cb = sapp_metal_get_drawable;
117 | desc.d3d11.device = sapp_d3d11_get_device();
118 | desc.d3d11.device_context = sapp_d3d11_get_device_context();
119 | desc.d3d11.render_target_view_cb = sapp_d3d11_get_render_target_view;
120 | desc.d3d11.depth_stencil_view_cb = sapp_d3d11_get_depth_stencil_view;
121 | desc.wgpu.device = sapp_wgpu_get_device();
122 | desc.wgpu.render_view_cb = sapp_wgpu_get_render_view;
123 | desc.wgpu.resolve_view_cb = sapp_wgpu_get_resolve_view;
124 | desc.wgpu.depth_stencil_view_cb = sapp_wgpu_get_depth_stencil_view;
125 | return desc;
126 | }
127 | #endif
128 |
129 | #endif /* SOKOL_IMPL */
130 |
--------------------------------------------------------------------------------
/dds-ktx.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2018 Sepehr Taghdisian (septag@github). All rights reserved.
3 | // License: https://github.com/septag/dds-ktx#license-bsd-2-clause
4 | //
5 | // Many parts of this code is taken from bimg library:
6 | // https://github.com/bkaradzic/bimg
7 | //
8 | // Copyright 2011-2019 Branimir Karadzic. All rights reserved.
9 | // License: https://github.com/bkaradzic/bimg#license-bsd-2-clause
10 | //
11 | // dds-ktx.h - v1.1.0 - Reader/Writer for DDS/KTX formats
12 | // Parses DDS and KTX files from a memory blob, written in C99
13 | //
14 | // Supported formats:
15 | // For supported formats, see ddsktx_format enum.
16 | // Both KTX/DDS parser supports all formats defined in ddsktx_format
17 | //
18 | // Overriable macros:
19 | // DDSKTX_API Define any function specifier for public functions (default: extern)
20 | // ddsktx_memcpy default: memcpy(dst, src, size)
21 | // ddsktx_memset default: memset(dst, v, size)
22 | // ddsktx_assert default: assert(a)
23 | // ddsktx_strcpy default: strcpy(dst, src)
24 | // ddsktx_memcmp default: memcmp(ptr1, ptr2, size)
25 | //
26 | // API:
27 | // bool ddsktx_parse(ddsktx_texture_info* tc, const void* file_data, int size, ddsktx_error* err);
28 | // Parses texture file and fills the ddsktx_texture_info struct
29 | // Returns true if successfully parsed, false if failed with an error message inside ddsktx_error parameter (optional)
30 | // After format is parsed, you can read the contents of ddsktx_format and create your GPU texture
31 | // To get pointer to mips and slices see ddsktx_get_sub function
32 | //
33 | // void ddsktx_get_sub(const ddsktx_texture_info* tex, ddsktx_sub_data* buff,
34 | // const void* file_data, int size,
35 | // int array_idx, int slice_face_idx, int mip_idx);
36 | // Gets sub-image data, form a parsed texture file
37 | // user must provided the container object and the original file data which was passed to ddsktx_parse
38 | // array_idx: array index (0..num_layers)
39 | // slice_face_idx: depth-slice or cube-face index.
40 | // if 'flags' have DDSKTX_TEXTURE_FLAG_CUBEMAP bit, then this value represents cube-face-index (0..DDSKTX_CUBE_FACE_COUNT)
41 | // else it represents depth slice index (0..depth)
42 | // mip_idx: mip index (0..num_mips-1 in ddsktx_texture_info)
43 | //
44 | // const char* ddsktx_format_str(ddsktx_format format);
45 | // Converts a format enumeration to string
46 | //
47 | // bool ddsktx_format_compressed(ddsktx_format format);
48 | // Returns true if format is compressed
49 | //
50 | // Example (for 2D textures only):
51 | // int size;
52 | // void* dds_data = load_file("test.dds", &size);
53 | // assert(dds_data);
54 | // ddsktx_texture_info tc = {0};
55 | // if (ddsktx_parse(&tc, dds_data, size, NULL)) {
56 | // assert(tc.depth == 1);
57 | // assert(!(tc.flags & DDSKTX_TEXTURE_FLAG_CUBEMAP));
58 | // assert(tc.num_layers == 1);
59 | // // Create GPU texture from tc data
60 | // for (int mip = 0; mip < tc.num_mips; mip++) {
61 | // ddsktx_sub_data sub_data;
62 | // ddsktx_get_sub(&tc, &sub_data, dds_data, size, 0, 0, mip);
63 | // // Fill/Set texture sub resource data (mips in this case)
64 | // }
65 | // }
66 | // free(dds_data); // memory must be valid during stc_ calls
67 | //
68 | // Version history:
69 | // 0.9.0 Initial release, ktx is incomplete
70 | // 1.0.0 Api change: ddsktx_sub_data
71 | // Added KTX support
72 | // 1.0.1 Fixed major bugs in KTX parsing
73 | // 1.1.0 Fixed bugs in get_sub routine, refactored some parts, image-viewer example
74 | //
75 | // TODO
76 | // Write KTX/DDS
77 | // Read KTX metadata. currently it just stores the offset/size to the metadata block
78 | //
79 |
80 | #pragma once
81 |
82 | #include
83 | #include
84 | #include
85 |
86 | #ifndef DDSKTX_API
87 | # ifdef __cplusplus
88 | # define DDSKTX_API extern "C"
89 | # else
90 | # define DDSKTX_API
91 | # endif
92 | #endif
93 |
94 | typedef struct ddsktx_sub_data
95 | {
96 | const void* buff;
97 | int width;
98 | int height;
99 | int size_bytes;
100 | int row_pitch_bytes;
101 | } ddsktx_sub_data;
102 |
103 | typedef enum ddsktx_format
104 | {
105 | DDSKTX_FORMAT_BC1, // DXT1
106 | DDSKTX_FORMAT_BC2, // DXT3
107 | DDSKTX_FORMAT_BC3, // DXT5
108 | DDSKTX_FORMAT_BC4, // ATI1
109 | DDSKTX_FORMAT_BC5, // ATI2
110 | DDSKTX_FORMAT_BC6H, // BC6H
111 | DDSKTX_FORMAT_BC7, // BC7
112 | DDSKTX_FORMAT_ETC1, // ETC1 RGB8
113 | DDSKTX_FORMAT_ETC2, // ETC2 RGB8
114 | DDSKTX_FORMAT_ETC2A, // ETC2 RGBA8
115 | DDSKTX_FORMAT_ETC2A1, // ETC2 RGB8A1
116 | DDSKTX_FORMAT_PTC12, // PVRTC1 RGB 2bpp
117 | DDSKTX_FORMAT_PTC14, // PVRTC1 RGB 4bpp
118 | DDSKTX_FORMAT_PTC12A, // PVRTC1 RGBA 2bpp
119 | DDSKTX_FORMAT_PTC14A, // PVRTC1 RGBA 4bpp
120 | DDSKTX_FORMAT_PTC22, // PVRTC2 RGBA 2bpp
121 | DDSKTX_FORMAT_PTC24, // PVRTC2 RGBA 4bpp
122 | DDSKTX_FORMAT_ATC, // ATC RGB 4BPP
123 | DDSKTX_FORMAT_ATCE, // ATCE RGBA 8 BPP explicit alpha
124 | DDSKTX_FORMAT_ATCI, // ATCI RGBA 8 BPP interpolated alpha
125 | DDSKTX_FORMAT_ASTC4x4, // ASTC 4x4 8.0 BPP
126 | DDSKTX_FORMAT_ASTC5x5, // ASTC 5x5 5.12 BPP
127 | DDSKTX_FORMAT_ASTC6x6, // ASTC 6x6 3.56 BPP
128 | DDSKTX_FORMAT_ASTC8x5, // ASTC 8x5 3.20 BPP
129 | DDSKTX_FORMAT_ASTC8x6, // ASTC 8x6 2.67 BPP
130 | DDSKTX_FORMAT_ASTC10x5, // ASTC 10x5 2.56 BPP
131 | _DDSKTX_FORMAT_COMPRESSED,
132 | DDSKTX_FORMAT_A8,
133 | DDSKTX_FORMAT_R8,
134 | DDSKTX_FORMAT_RGBA8,
135 | DDSKTX_FORMAT_RGBA8S,
136 | DDSKTX_FORMAT_RG16,
137 | DDSKTX_FORMAT_RGB8,
138 | DDSKTX_FORMAT_R16,
139 | DDSKTX_FORMAT_R32F,
140 | DDSKTX_FORMAT_R16F,
141 | DDSKTX_FORMAT_RG16F,
142 | DDSKTX_FORMAT_RG16S,
143 | DDSKTX_FORMAT_RGBA16F,
144 | DDSKTX_FORMAT_RGBA16,
145 | DDSKTX_FORMAT_BGRA8,
146 | DDSKTX_FORMAT_RGB10A2,
147 | DDSKTX_FORMAT_RG11B10F,
148 | DDSKTX_FORMAT_RG8,
149 | DDSKTX_FORMAT_RG8S,
150 | _DDSKTX_FORMAT_COUNT
151 | } ddsktx_format;
152 |
153 | typedef enum ddsktx_texture_flags
154 | {
155 | DDSKTX_TEXTURE_FLAG_CUBEMAP = 0x01,
156 | DDSKTX_TEXTURE_FLAG_SRGB = 0x02,
157 | DDSKTX_TEXTURE_FLAG_ALPHA = 0x04, // Has alpha channel
158 | DDSKTX_TEXTURE_FLAG_DDS = 0x08, // container was DDS file
159 | DDSKTX_TEXTURE_FLAG_KTX = 0x10, // container was KTX file
160 | DDSKTX_TEXTURE_FLAG_VOLUME = 0x20, // 3D volume
161 | } ddsktx_texture_flags;
162 |
163 | typedef struct ddsktx_texture_info
164 | {
165 | int data_offset; // start offset of pixel data
166 | int size_bytes;
167 | ddsktx_format format;
168 | unsigned int flags; // ddsktx_texture_flags
169 | int width;
170 | int height;
171 | int depth;
172 | int num_layers;
173 | int num_mips;
174 | int bpp;
175 | int metadata_offset; // ktx only
176 | int metadata_size; // ktx only
177 | } ddsktx_texture_info;
178 |
179 | typedef enum ddsktx_cube_face
180 | {
181 | DDSKTX_CUBE_FACE_X_POSITIVE = 0,
182 | DDSKTX_CUBE_FACE_X_NEGATIVE,
183 | DDSKTX_CUBE_FACE_Y_POSITIVE,
184 | DDSKTX_CUBE_FACE_Y_NEGATIVE,
185 | DDSKTX_CUBE_FACE_Z_POSITIVE,
186 | DDSKTX_CUBE_FACE_Z_NEGATIVE,
187 | DDSKTX_CUBE_FACE_COUNT
188 | } ddsktx_cube_face;
189 |
190 | typedef struct ddsktx_error
191 | {
192 | char msg[256];
193 | } ddsktx_error;
194 |
195 | #ifdef __cplusplus
196 | # define ddsktx_default(_v) =_v
197 | #else
198 | # define ddsktx_default(_v)
199 | #endif
200 |
201 | DDSKTX_API bool ddsktx_parse(ddsktx_texture_info* tc, const void* file_data, int size, ddsktx_error* err ddsktx_default(NULL));
202 | DDSKTX_API void ddsktx_get_sub(const ddsktx_texture_info* tex, ddsktx_sub_data* buff,
203 | const void* file_data, int size,
204 | int array_idx, int slice_face_idx, int mip_idx);
205 | DDSKTX_API const char* ddsktx_format_str(ddsktx_format format);
206 | DDSKTX_API bool ddsktx_format_compressed(ddsktx_format format);
207 |
208 | ////////////////////////////////////////////////////////////////////////////////////////////////////
209 | // Implementation
210 | #ifdef DDSKTX_IMPLEMENT
211 |
212 | #define stc__makefourcc(_a, _b, _c, _d) ( ( (uint32_t)(_a) | ( (uint32_t)(_b) << 8) | \
213 | ( (uint32_t)(_c) << 16) | ( (uint32_t)(_d) << 24) ) )
214 |
215 | // DDS: https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dx-graphics-dds-pguide
216 | #define DDSKTX__DDS_HEADER_SIZE 124
217 | #define DDSKTX__DDS_MAGIC stc__makefourcc('D', 'D', 'S', ' ')
218 | #define DDSKTX__DDS_DXT1 stc__makefourcc('D', 'X', 'T', '1')
219 | #define DDSKTX__DDS_DXT2 stc__makefourcc('D', 'X', 'T', '2')
220 | #define DDSKTX__DDS_DXT3 stc__makefourcc('D', 'X', 'T', '3')
221 | #define DDSKTX__DDS_DXT4 stc__makefourcc('D', 'X', 'T', '4')
222 | #define DDSKTX__DDS_DXT5 stc__makefourcc('D', 'X', 'T', '5')
223 | #define DDSKTX__DDS_ATI1 stc__makefourcc('A', 'T', 'I', '1')
224 | #define DDSKTX__DDS_BC4U stc__makefourcc('B', 'C', '4', 'U')
225 | #define DDSKTX__DDS_ATI2 stc__makefourcc('A', 'T', 'I', '2')
226 | #define DDSKTX__DDS_BC5U stc__makefourcc('B', 'C', '5', 'U')
227 | #define DDSKTX__DDS_DX10 stc__makefourcc('D', 'X', '1', '0')
228 |
229 | #define DDSKTX__DDS_ETC1 stc__makefourcc('E', 'T', 'C', '1')
230 | #define DDSKTX__DDS_ETC2 stc__makefourcc('E', 'T', 'C', '2')
231 | #define DDSKTX__DDS_ET2A stc__makefourcc('E', 'T', '2', 'A')
232 | #define DDSKTX__DDS_PTC2 stc__makefourcc('P', 'T', 'C', '2')
233 | #define DDSKTX__DDS_PTC4 stc__makefourcc('P', 'T', 'C', '4')
234 | #define DDSKTX__DDS_ATC stc__makefourcc('A', 'T', 'C', ' ')
235 | #define DDSKTX__DDS_ATCE stc__makefourcc('A', 'T', 'C', 'E')
236 | #define DDSKTX__DDS_ATCI stc__makefourcc('A', 'T', 'C', 'I')
237 | #define DDSKTX__DDS_ASTC4x4 stc__makefourcc('A', 'S', '4', '4')
238 | #define DDSKTX__DDS_ASTC5x5 stc__makefourcc('A', 'S', '5', '5')
239 | #define DDSKTX__DDS_ASTC6x6 stc__makefourcc('A', 'S', '6', '6')
240 | #define DDSKTX__DDS_ASTC8x5 stc__makefourcc('A', 'S', '8', '5')
241 | #define DDSKTX__DDS_ASTC8x6 stc__makefourcc('A', 'S', '8', '6')
242 | #define DDSKTX__DDS_ASTC10x5 stc__makefourcc('A', 'S', ':', '5')
243 |
244 | #define DDSKTX__DDS_R8G8B8 20
245 | #define DDSKTX__DDS_A8R8G8B8 21
246 | #define DDSKTX__DDS_R5G6B5 23
247 | #define DDSKTX__DDS_A1R5G5B5 25
248 | #define DDSKTX__DDS_A4R4G4B4 26
249 | #define DDSKTX__DDS_A2B10G10R10 31
250 | #define DDSKTX__DDS_G16R16 34
251 | #define DDSKTX__DDS_A2R10G10B10 35
252 | #define DDSKTX__DDS_A16B16G16R16 36
253 | #define DDSKTX__DDS_A8L8 51
254 | #define DDSKTX__DDS_R16F 111
255 | #define DDSKTX__DDS_G16R16F 112
256 | #define DDSKTX__DDS_A16B16G16R16F 113
257 | #define DDSKTX__DDS_R32F 114
258 | #define DDSKTX__DDS_G32R32F 115
259 | #define DDSKTX__DDS_A32B32G32R32F 116
260 |
261 | #define DDSKTX__DDS_FORMAT_R32G32B32A32_FLOAT 2
262 | #define DDSKTX__DDS_FORMAT_R32G32B32A32_UINT 3
263 | #define DDSKTX__DDS_FORMAT_R16G16B16A16_FLOAT 10
264 | #define DDSKTX__DDS_FORMAT_R16G16B16A16_UNORM 11
265 | #define DDSKTX__DDS_FORMAT_R16G16B16A16_UINT 12
266 | #define DDSKTX__DDS_FORMAT_R32G32_FLOAT 16
267 | #define DDSKTX__DDS_FORMAT_R32G32_UINT 17
268 | #define DDSKTX__DDS_FORMAT_R10G10B10A2_UNORM 24
269 | #define DDSKTX__DDS_FORMAT_R11G11B10_FLOAT 26
270 | #define DDSKTX__DDS_FORMAT_R8G8B8A8_UNORM 28
271 | #define DDSKTX__DDS_FORMAT_R8G8B8A8_UNORM_SRGB 29
272 | #define DDSKTX__DDS_FORMAT_R16G16_FLOAT 34
273 | #define DDSKTX__DDS_FORMAT_R16G16_UNORM 35
274 | #define DDSKTX__DDS_FORMAT_R32_FLOAT 41
275 | #define DDSKTX__DDS_FORMAT_R32_UINT 42
276 | #define DDSKTX__DDS_FORMAT_R8G8_UNORM 49
277 | #define DDSKTX__DDS_FORMAT_R16_FLOAT 54
278 | #define DDSKTX__DDS_FORMAT_R16_UNORM 56
279 | #define DDSKTX__DDS_FORMAT_R8_UNORM 61
280 | #define DDSKTX__DDS_FORMAT_R1_UNORM 66
281 | #define DDSKTX__DDS_FORMAT_BC1_UNORM 71
282 | #define DDSKTX__DDS_FORMAT_BC1_UNORM_SRGB 72
283 | #define DDSKTX__DDS_FORMAT_BC2_UNORM 74
284 | #define DDSKTX__DDS_FORMAT_BC2_UNORM_SRGB 75
285 | #define DDSKTX__DDS_FORMAT_BC3_UNORM 77
286 | #define DDSKTX__DDS_FORMAT_BC3_UNORM_SRGB 78
287 | #define DDSKTX__DDS_FORMAT_BC4_UNORM 80
288 | #define DDSKTX__DDS_FORMAT_BC5_UNORM 83
289 | #define DDSKTX__DDS_FORMAT_B5G6R5_UNORM 85
290 | #define DDSKTX__DDS_FORMAT_B5G5R5A1_UNORM 86
291 | #define DDSKTX__DDS_FORMAT_B8G8R8A8_UNORM 87
292 | #define DDSKTX__DDS_FORMAT_B8G8R8A8_UNORM_SRGB 91
293 | #define DDSKTX__DDS_FORMAT_BC6H_SF16 96
294 | #define DDSKTX__DDS_FORMAT_BC7_UNORM 98
295 | #define DDSKTX__DDS_FORMAT_BC7_UNORM_SRGB 99
296 | #define DDSKTX__DDS_FORMAT_B4G4R4A4_UNORM 115
297 |
298 | #define DDSKTX__DDS_DX10_DIMENSION_TEXTURE2D 3
299 | #define DDSKTX__DDS_DX10_DIMENSION_TEXTURE3D 4
300 | #define DDSKTX__DDS_DX10_MISC_TEXTURECUBE 4
301 |
302 | #define DDSKTX__DDSD_CAPS 0x00000001
303 | #define DDSKTX__DDSD_HEIGHT 0x00000002
304 | #define DDSKTX__DDSD_WIDTH 0x00000004
305 | #define DDSKTX__DDSD_PITCH 0x00000008
306 | #define DDSKTX__DDSD_PIXELFORMAT 0x00001000
307 | #define DDSKTX__DDSD_MIPMAPCOUNT 0x00020000
308 | #define DDSKTX__DDSD_LINEARSIZE 0x00080000
309 | #define DDSKTX__DDSD_DEPTH 0x00800000
310 |
311 | #define DDSKTX__DDPF_ALPHAPIXELS 0x00000001
312 | #define DDSKTX__DDPF_ALPHA 0x00000002
313 | #define DDSKTX__DDPF_FOURCC 0x00000004
314 | #define DDSKTX__DDPF_INDEXED 0x00000020
315 | #define DDSKTX__DDPF_RGB 0x00000040
316 | #define DDSKTX__DDPF_YUV 0x00000200
317 | #define DDSKTX__DDPF_LUMINANCE 0x00020000
318 | #define DDSKTX__DDPF_BUMPDUDV 0x00080000
319 |
320 | #define DDSKTX__DDSCAPS_COMPLEX 0x00000008
321 | #define DDSKTX__DDSCAPS_TEXTURE 0x00001000
322 | #define DDSKTX__DDSCAPS_MIPMAP 0x00400000
323 |
324 | #define DDSKTX__DDSCAPS2_VOLUME 0x00200000
325 | #define DDSKTX__DDSCAPS2_CUBEMAP 0x00000200
326 | #define DDSKTX__DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
327 | #define DDSKTX__DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
328 | #define DDSKTX__DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
329 | #define DDSKTX__DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
330 | #define DDSKTX__DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
331 | #define DDSKTX__DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
332 |
333 | #define DDSKTX__DDSCAPS2_CUBEMAP_ALLSIDES (0 \
334 | | DDSKTX__DDSCAPS2_CUBEMAP_POSITIVEX \
335 | | DDSKTX__DDSCAPS2_CUBEMAP_NEGATIVEX \
336 | | DDSKTX__DDSCAPS2_CUBEMAP_POSITIVEY \
337 | | DDSKTX__DDSCAPS2_CUBEMAP_NEGATIVEY \
338 | | DDSKTX__DDSCAPS2_CUBEMAP_POSITIVEZ \
339 | | DDSKTX__DDSCAPS2_CUBEMAP_NEGATIVEZ )
340 |
341 | #pragma pack(push, 1)
342 | typedef struct ddsktx__dds_pixel_format
343 | {
344 | uint32_t size;
345 | uint32_t flags;
346 | uint32_t fourcc;
347 | uint32_t rgb_bit_count;
348 | uint32_t bit_mask[4];
349 | } ddsktx__dds_pixel_format;
350 |
351 | // https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dds-header
352 | typedef struct ddsktx__dds_header
353 | {
354 | uint32_t size;
355 | uint32_t flags;
356 | uint32_t height;
357 | uint32_t width;
358 | uint32_t pitch_lin_size;
359 | uint32_t depth;
360 | uint32_t mip_count;
361 | uint32_t reserved1[11];
362 | ddsktx__dds_pixel_format pixel_format;
363 | uint32_t caps1;
364 | uint32_t caps2;
365 | uint32_t caps3;
366 | uint32_t caps4;
367 | uint32_t reserved2;
368 | } ddsktx__dds_header;
369 |
370 | // https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dds-header-dxt10
371 | typedef struct ddsktx__dds_header_dxgi
372 | {
373 | uint32_t dxgi_format;
374 | uint32_t dimension;
375 | uint32_t misc_flags;
376 | uint32_t array_size;
377 | uint32_t misc_flags2;
378 | } ddsktx__dds_header_dxgi;
379 |
380 | typedef struct ddsktx__ktx_header
381 | {
382 | uint8_t id[8];
383 | uint32_t endianess;
384 | uint32_t type;
385 | uint32_t type_size;
386 | uint32_t format;
387 | uint32_t internal_format;
388 | uint32_t base_internal_format;
389 | uint32_t width;
390 | uint32_t height;
391 | uint32_t depth;
392 | uint32_t array_count;
393 | uint32_t face_count;
394 | uint32_t mip_count;
395 | uint32_t metadata_size;
396 | } ddsktx__ktx_header;
397 | #pragma pack(pop)
398 |
399 | typedef struct ddsktx__dds_translate_fourcc_format
400 | {
401 | uint32_t dds_format;
402 | ddsktx_format format;
403 | bool srgb;
404 | } ddsktx__dds_translate_fourcc_format;
405 |
406 | typedef struct ddsktx__dds_translate_pixel_format
407 | {
408 | uint32_t bit_count;
409 | uint32_t flags;
410 | uint32_t bit_mask[4];
411 | ddsktx_format format;
412 | } ddsktx__dds_translate_pixel_format;
413 |
414 | typedef struct ddsktx__mem_reader
415 | {
416 | const uint8_t* buff;
417 | int total;
418 | int offset;
419 | } ddsktx__mem_reader;
420 |
421 | typedef struct ddsktx__block_info
422 | {
423 | uint8_t bpp;
424 | uint8_t block_width;
425 | uint8_t block_height;
426 | uint8_t block_size;
427 | uint8_t min_block_x;
428 | uint8_t min_block_y;
429 | uint8_t depth_bits;
430 | uint8_t stencil_bits;
431 | uint8_t r_bits;
432 | uint8_t g_bits;
433 | uint8_t b_bits;
434 | uint8_t a_bits;
435 | uint8_t encoding;
436 | } ddsktx__block_info;
437 |
438 | #ifndef ddsktx_memcpy
439 | # include
440 | # define ddsktx_memcpy(_dst, _src, _size) memcpy((_dst), (_src), (_size))
441 | #endif
442 |
443 | #ifndef ddsktx_memset
444 | # include
445 | # define ddsktx_memset(_dst, _v, _size) memset((_dst), (_v), (_size))
446 | #endif
447 |
448 | #ifndef ddsktx_assert
449 | # include
450 | # define ddsktx_assert(_a) assert(_a)
451 | #endif
452 |
453 | #ifndef ddsktx_strcpy
454 | # include
455 | # ifdef _MSC_VER
456 | # define ddsktx_strcpy(_dst, _src) strcpy_s((_dst), sizeof(_dst), (_src))
457 | # else
458 | # define ddsktx_strcpy(_dst, _src) strcpy((_dst), (_src))
459 | # endif
460 | #endif
461 |
462 | #ifndef ddsktx_memcmp
463 | # include
464 | # define ddsktx_memcmp(_ptr1, _ptr2, _num) memcmp((_ptr1), (_ptr2), (_num))
465 | #endif
466 |
467 | #define ddsktx__max(a, b) ((a) > (b) ? (a) : (b))
468 | #define ddsktx__min(a, b) ((a) < (b) ? (a) : (b))
469 | #define ddsktx__align_mask(_value, _mask) (((_value)+(_mask)) & ((~0)&(~(_mask))))
470 | #define ddsktx__err(_err, _msg) if (_err) ddsktx_strcpy(_err->msg, _msg); return false
471 |
472 | static const ddsktx__dds_translate_fourcc_format k__translate_dds_fourcc[] = {
473 | { DDSKTX__DDS_DXT1, DDSKTX_FORMAT_BC1, false },
474 | { DDSKTX__DDS_DXT2, DDSKTX_FORMAT_BC2, false },
475 | { DDSKTX__DDS_DXT3, DDSKTX_FORMAT_BC2, false },
476 | { DDSKTX__DDS_DXT4, DDSKTX_FORMAT_BC3, false },
477 | { DDSKTX__DDS_DXT5, DDSKTX_FORMAT_BC3, false },
478 | { DDSKTX__DDS_ATI1, DDSKTX_FORMAT_BC4, false },
479 | { DDSKTX__DDS_BC4U, DDSKTX_FORMAT_BC4, false },
480 | { DDSKTX__DDS_ATI2, DDSKTX_FORMAT_BC5, false },
481 | { DDSKTX__DDS_BC5U, DDSKTX_FORMAT_BC5, false },
482 | { DDSKTX__DDS_ETC1, DDSKTX_FORMAT_ETC1, false },
483 | { DDSKTX__DDS_ETC2, DDSKTX_FORMAT_ETC2, false },
484 | { DDSKTX__DDS_ET2A, DDSKTX_FORMAT_ETC2A, false },
485 | { DDSKTX__DDS_PTC2, DDSKTX_FORMAT_PTC12A, false },
486 | { DDSKTX__DDS_PTC4, DDSKTX_FORMAT_PTC14A, false },
487 | { DDSKTX__DDS_ATC , DDSKTX_FORMAT_ATC, false },
488 | { DDSKTX__DDS_ATCE, DDSKTX_FORMAT_ATCE, false },
489 | { DDSKTX__DDS_ATCI, DDSKTX_FORMAT_ATCI, false },
490 | { DDSKTX__DDS_ASTC4x4, DDSKTX_FORMAT_ASTC4x4, false },
491 | { DDSKTX__DDS_ASTC5x5, DDSKTX_FORMAT_ASTC5x5, false },
492 | { DDSKTX__DDS_ASTC6x6, DDSKTX_FORMAT_ASTC6x6, false },
493 | { DDSKTX__DDS_ASTC8x5, DDSKTX_FORMAT_ASTC8x5, false },
494 | { DDSKTX__DDS_ASTC8x6, DDSKTX_FORMAT_ASTC8x6, false },
495 | { DDSKTX__DDS_ASTC10x5, DDSKTX_FORMAT_ASTC10x5, false },
496 | { DDSKTX__DDS_A16B16G16R16, DDSKTX_FORMAT_RGBA16, false },
497 | { DDSKTX__DDS_A16B16G16R16F, DDSKTX_FORMAT_RGBA16F, false },
498 | { DDSKTX__DDPF_RGB|DDSKTX__DDPF_ALPHAPIXELS, DDSKTX_FORMAT_BGRA8, false },
499 | { DDSKTX__DDPF_INDEXED, DDSKTX_FORMAT_R8, false },
500 | { DDSKTX__DDPF_LUMINANCE, DDSKTX_FORMAT_R8, false },
501 | { DDSKTX__DDPF_ALPHA, DDSKTX_FORMAT_R8, false },
502 | { DDSKTX__DDS_R16F, DDSKTX_FORMAT_R16F, false },
503 | { DDSKTX__DDS_R32F, DDSKTX_FORMAT_R32F, false },
504 | { DDSKTX__DDS_A8L8, DDSKTX_FORMAT_RG8, false },
505 | { DDSKTX__DDS_G16R16, DDSKTX_FORMAT_RG16, false },
506 | { DDSKTX__DDS_G16R16F, DDSKTX_FORMAT_RG16F, false },
507 | { DDSKTX__DDS_R8G8B8, DDSKTX_FORMAT_RGB8, false },
508 | { DDSKTX__DDS_A8R8G8B8, DDSKTX_FORMAT_BGRA8, false },
509 | { DDSKTX__DDS_A16B16G16R16, DDSKTX_FORMAT_RGBA16, false },
510 | { DDSKTX__DDS_A16B16G16R16F, DDSKTX_FORMAT_RGBA16F, false },
511 | { DDSKTX__DDS_A2B10G10R10, DDSKTX_FORMAT_RGB10A2, false },
512 | };
513 |
514 | static const ddsktx__dds_translate_fourcc_format k__translate_dxgi[] = {
515 | { DDSKTX__DDS_FORMAT_BC1_UNORM, DDSKTX_FORMAT_BC1, false },
516 | { DDSKTX__DDS_FORMAT_BC1_UNORM_SRGB, DDSKTX_FORMAT_BC1, true },
517 | { DDSKTX__DDS_FORMAT_BC2_UNORM, DDSKTX_FORMAT_BC2, false },
518 | { DDSKTX__DDS_FORMAT_BC2_UNORM_SRGB, DDSKTX_FORMAT_BC2, true },
519 | { DDSKTX__DDS_FORMAT_BC3_UNORM, DDSKTX_FORMAT_BC3, false },
520 | { DDSKTX__DDS_FORMAT_BC3_UNORM_SRGB, DDSKTX_FORMAT_BC3, true },
521 | { DDSKTX__DDS_FORMAT_BC4_UNORM, DDSKTX_FORMAT_BC4, false },
522 | { DDSKTX__DDS_FORMAT_BC5_UNORM, DDSKTX_FORMAT_BC5, false },
523 | { DDSKTX__DDS_FORMAT_BC6H_SF16, DDSKTX_FORMAT_BC6H, false },
524 | { DDSKTX__DDS_FORMAT_BC7_UNORM, DDSKTX_FORMAT_BC7, false },
525 | { DDSKTX__DDS_FORMAT_BC7_UNORM_SRGB, DDSKTX_FORMAT_BC7, true },
526 |
527 | { DDSKTX__DDS_FORMAT_R8_UNORM, DDSKTX_FORMAT_R8, false },
528 | { DDSKTX__DDS_FORMAT_R16_UNORM, DDSKTX_FORMAT_R16, false },
529 | { DDSKTX__DDS_FORMAT_R16_FLOAT, DDSKTX_FORMAT_R16F, false },
530 | { DDSKTX__DDS_FORMAT_R32_FLOAT, DDSKTX_FORMAT_R32F, false },
531 | { DDSKTX__DDS_FORMAT_R8G8_UNORM, DDSKTX_FORMAT_RG8, false },
532 | { DDSKTX__DDS_FORMAT_R16G16_UNORM, DDSKTX_FORMAT_RG16, false },
533 | { DDSKTX__DDS_FORMAT_R16G16_FLOAT, DDSKTX_FORMAT_RG16F, false },
534 | { DDSKTX__DDS_FORMAT_B8G8R8A8_UNORM, DDSKTX_FORMAT_BGRA8, false },
535 | { DDSKTX__DDS_FORMAT_B8G8R8A8_UNORM_SRGB, DDSKTX_FORMAT_BGRA8, true },
536 | { DDSKTX__DDS_FORMAT_R8G8B8A8_UNORM, DDSKTX_FORMAT_RGBA8, false },
537 | { DDSKTX__DDS_FORMAT_R8G8B8A8_UNORM_SRGB, DDSKTX_FORMAT_RGBA8, true },
538 | { DDSKTX__DDS_FORMAT_R16G16B16A16_UNORM, DDSKTX_FORMAT_RGBA16, false },
539 | { DDSKTX__DDS_FORMAT_R16G16B16A16_FLOAT, DDSKTX_FORMAT_RGBA16F, false },
540 | { DDSKTX__DDS_FORMAT_R10G10B10A2_UNORM, DDSKTX_FORMAT_RGB10A2, false },
541 | { DDSKTX__DDS_FORMAT_R11G11B10_FLOAT, DDSKTX_FORMAT_RG11B10F, false },
542 | };
543 |
544 | static const ddsktx__dds_translate_pixel_format k__translate_dds_pixel[] = {
545 | { 8, DDSKTX__DDPF_LUMINANCE, { 0x000000ff, 0x00000000, 0x00000000, 0x00000000 }, DDSKTX_FORMAT_R8 },
546 | { 16, DDSKTX__DDPF_BUMPDUDV, { 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000 }, DDSKTX_FORMAT_RG8S },
547 | { 24, DDSKTX__DDPF_RGB, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }, DDSKTX_FORMAT_RGB8 },
548 | { 24, DDSKTX__DDPF_RGB, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 }, DDSKTX_FORMAT_RGB8 },
549 | { 32, DDSKTX__DDPF_RGB, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }, DDSKTX_FORMAT_BGRA8 },
550 | { 32, DDSKTX__DDPF_RGB|DDSKTX__DDPF_ALPHAPIXELS, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }, DDSKTX_FORMAT_RGBA8 },
551 | { 32, DDSKTX__DDPF_BUMPDUDV, { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }, DDSKTX_FORMAT_RGBA8S },
552 | { 32, DDSKTX__DDPF_RGB, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSKTX_FORMAT_BGRA8 },
553 | { 32, DDSKTX__DDPF_RGB|DDSKTX__DDPF_ALPHAPIXELS, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSKTX_FORMAT_BGRA8 }, // D3DFMT_A8R8G8B8
554 | { 32, DDSKTX__DDPF_RGB|DDSKTX__DDPF_ALPHAPIXELS, { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }, DDSKTX_FORMAT_BGRA8 }, // D3DFMT_X8R8G8B8
555 | { 32, DDSKTX__DDPF_RGB|DDSKTX__DDPF_ALPHAPIXELS, { 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000 }, DDSKTX_FORMAT_RGB10A2 },
556 | { 32, DDSKTX__DDPF_RGB, { 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }, DDSKTX_FORMAT_RG16 },
557 | { 32, DDSKTX__DDPF_BUMPDUDV, { 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }, DDSKTX_FORMAT_RG16S }
558 | };
559 |
560 | typedef enum ddsktx__encode_type
561 | {
562 | DDSKTX__ENCODE_UNORM,
563 | DDSKTX__ENCODE_SNORM,
564 | DDSKTX__ENCODE_FLOAT,
565 | DDSKTX__ENCODE_INT,
566 | DDSKTX__ENCODE_UINT,
567 | DDSKTX__ENCODE_COUNT
568 | } ddsktx__encode_type;
569 |
570 | static const ddsktx__block_info k__block_info[] =
571 | {
572 | // +-------------------------------------------- bits per pixel
573 | // | +----------------------------------------- block width
574 | // | | +-------------------------------------- block height
575 | // | | | +---------------------------------- block size
576 | // | | | | +------------------------------- min blocks x
577 | // | | | | | +---------------------------- min blocks y
578 | // | | | | | | +------------------------ depth bits
579 | // | | | | | | | +--------------------- stencil bits
580 | // | | | | | | | | +---+---+---+----- r, g, b, a bits
581 | // | | | | | | | | r g b a +-- encoding type
582 | // | | | | | | | | | | | | |
583 | { 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BC1
584 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BC2
585 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BC3
586 | { 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BC4
587 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BC5
588 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_FLOAT) }, // BC6H
589 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BC7
590 | { 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ETC1
591 | { 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ETC2
592 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ETC2A
593 | { 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ETC2A1
594 | { 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // PTC12
595 | { 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // PTC14
596 | { 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // PTC12A
597 | { 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // PTC14A
598 | { 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // PTC22
599 | { 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // PTC24
600 | { 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ATC
601 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ATCE
602 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ATCI
603 | { 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ASTC4x4
604 | { 6, 5, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ASTC5x5
605 | { 4, 6, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ASTC6x6
606 | { 4, 8, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ASTC8x5
607 | { 3, 8, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ASTC8x6
608 | { 3, 10, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // ASTC10x5
609 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_COUNT) }, // Unknown
610 | { 8, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 8, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // A8
611 | { 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // R8
612 | { 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RGBA8
613 | { 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, (uint8_t)(DDSKTX__ENCODE_SNORM) }, // RGBA8S
614 | { 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RG16
615 | { 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RGB8
616 | { 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // R16
617 | { 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_FLOAT) }, // R32F
618 | { 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, (uint8_t)(DDSKTX__ENCODE_FLOAT) }, // R16F
619 | { 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, (uint8_t)(DDSKTX__ENCODE_FLOAT) }, // RG16F
620 | { 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, (uint8_t)(DDSKTX__ENCODE_SNORM) }, // RG16S
621 | { 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, (uint8_t)(DDSKTX__ENCODE_FLOAT) }, // RGBA16F
622 | { 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RGBA16
623 | { 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // BGRA8
624 | { 32, 1, 1, 4, 1, 1, 0, 0, 10, 10, 10, 2, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RGB10A2
625 | { 32, 1, 1, 4, 1, 1, 0, 0, 11, 11, 10, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RG11B10F
626 | { 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, (uint8_t)(DDSKTX__ENCODE_UNORM) }, // RG8
627 | { 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, (uint8_t)(DDSKTX__ENCODE_SNORM) } // RG8S
628 | };
629 |
630 | // KTX: https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
631 | #define DDSKTX__KTX_MAGIC stc__makefourcc(0xAB, 'K', 'T', 'X')
632 | #define DDSKTX__KTX_HEADER_SIZE 60 // actual header size is 64, but we read 4 bytes for the 'magic'
633 |
634 | #define DDSKTX__KTX_ETC1_RGB8_OES 0x8D64
635 | #define DDSKTX__KTX_COMPRESSED_R11_EAC 0x9270
636 | #define DDSKTX__KTX_COMPRESSED_SIGNED_R11_EAC 0x9271
637 | #define DDSKTX__KTX_COMPRESSED_RG11_EAC 0x9272
638 | #define DDSKTX__KTX_COMPRESSED_SIGNED_RG11_EAC 0x9273
639 | #define DDSKTX__KTX_COMPRESSED_RGB8_ETC2 0x9274
640 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ETC2 0x9275
641 | #define DDSKTX__KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
642 | #define DDSKTX__KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
643 | #define DDSKTX__KTX_COMPRESSED_RGBA8_ETC2_EAC 0x9278
644 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
645 | #define DDSKTX__KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
646 | #define DDSKTX__KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
647 | #define DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
648 | #define DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
649 | #define DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
650 | #define DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
651 | #define DDSKTX__KTX_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
652 | #define DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
653 | #define DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
654 | #define DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
655 | #define DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
656 | #define DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
657 | #define DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
658 | #define DDSKTX__KTX_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
659 | #define DDSKTX__KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
660 | #define DDSKTX__KTX_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
661 | #define DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
662 | #define DDSKTX__KTX_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
663 | #define DDSKTX__KTX_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
664 | #define DDSKTX__KTX_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
665 | #define DDSKTX__KTX_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
666 | #define DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
667 | #define DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
668 | #define DDSKTX__KTX_ATC_RGB_AMD 0x8C92
669 | #define DDSKTX__KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
670 | #define DDSKTX__KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
671 | #define DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_4x4_KHR 0x93B0
672 | #define DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_5x5_KHR 0x93B2
673 | #define DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_6x6_KHR 0x93B4
674 | #define DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_8x5_KHR 0x93B5
675 | #define DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_8x6_KHR 0x93B6
676 | #define DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_10x5_KHR 0x93B8
677 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_4x4_KHR 0x93D0
678 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_5x5_KHR 0x93D2
679 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_6x6_KHR 0x93D4
680 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_8x5_KHR 0x93D5
681 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_8x6_KHR 0x93D6
682 | #define DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_10x5_KHR 0x93D8
683 |
684 | #define DDSKTX__KTX_A8 0x803C
685 | #define DDSKTX__KTX_R8 0x8229
686 | #define DDSKTX__KTX_R16 0x822A
687 | #define DDSKTX__KTX_RG8 0x822B
688 | #define DDSKTX__KTX_RG16 0x822C
689 | #define DDSKTX__KTX_R16F 0x822D
690 | #define DDSKTX__KTX_R32F 0x822E
691 | #define DDSKTX__KTX_RG16F 0x822F
692 | #define DDSKTX__KTX_RG32F 0x8230
693 | #define DDSKTX__KTX_RGBA8 0x8058
694 | #define DDSKTX__KTX_RGBA16 0x805B
695 | #define DDSKTX__KTX_RGBA16F 0x881A
696 | #define DDSKTX__KTX_R32UI 0x8236
697 | #define DDSKTX__KTX_RG32UI 0x823C
698 | #define DDSKTX__KTX_RGBA32UI 0x8D70
699 | #define DDSKTX__KTX_RGBA32F 0x8814
700 | #define DDSKTX__KTX_RGB565 0x8D62
701 | #define DDSKTX__KTX_RGBA4 0x8056
702 | #define DDSKTX__KTX_RGB5_A1 0x8057
703 | #define DDSKTX__KTX_RGB10_A2 0x8059
704 | #define DDSKTX__KTX_R8I 0x8231
705 | #define DDSKTX__KTX_R8UI 0x8232
706 | #define DDSKTX__KTX_R16I 0x8233
707 | #define DDSKTX__KTX_R16UI 0x8234
708 | #define DDSKTX__KTX_R32I 0x8235
709 | #define DDSKTX__KTX_R32UI 0x8236
710 | #define DDSKTX__KTX_RG8I 0x8237
711 | #define DDSKTX__KTX_RG8UI 0x8238
712 | #define DDSKTX__KTX_RG16I 0x8239
713 | #define DDSKTX__KTX_RG16UI 0x823A
714 | #define DDSKTX__KTX_RG32I 0x823B
715 | #define DDSKTX__KTX_RG32UI 0x823C
716 | #define DDSKTX__KTX_R8_SNORM 0x8F94
717 | #define DDSKTX__KTX_RG8_SNORM 0x8F95
718 | #define DDSKTX__KTX_RGB8_SNORM 0x8F96
719 | #define DDSKTX__KTX_RGBA8_SNORM 0x8F97
720 | #define DDSKTX__KTX_R16_SNORM 0x8F98
721 | #define DDSKTX__KTX_RG16_SNORM 0x8F99
722 | #define DDSKTX__KTX_RGB16_SNORM 0x8F9A
723 | #define DDSKTX__KTX_RGBA16_SNORM 0x8F9B
724 | #define DDSKTX__KTX_SRGB8 0x8C41
725 | #define DDSKTX__KTX_SRGB8_ALPHA8 0x8C43
726 | #define DDSKTX__KTX_RGBA32UI 0x8D70
727 | #define DDSKTX__KTX_RGB32UI 0x8D71
728 | #define DDSKTX__KTX_RGBA16UI 0x8D76
729 | #define DDSKTX__KTX_RGB16UI 0x8D77
730 | #define DDSKTX__KTX_RGBA8UI 0x8D7C
731 | #define DDSKTX__KTX_RGB8UI 0x8D7D
732 | #define DDSKTX__KTX_RGBA32I 0x8D82
733 | #define DDSKTX__KTX_RGB32I 0x8D83
734 | #define DDSKTX__KTX_RGBA16I 0x8D88
735 | #define DDSKTX__KTX_RGB16I 0x8D89
736 | #define DDSKTX__KTX_RGBA8I 0x8D8E
737 | #define DDSKTX__KTX_RGB8 0x8051
738 | #define DDSKTX__KTX_RGB8I 0x8D8F
739 | #define DDSKTX__KTX_RGB9_E5 0x8C3D
740 | #define DDSKTX__KTX_R11F_G11F_B10F 0x8C3A
741 |
742 | #define DDSKTX__KTX_ZERO 0
743 | #define DDSKTX__KTX_RED 0x1903
744 | #define DDSKTX__KTX_ALPHA 0x1906
745 | #define DDSKTX__KTX_RGB 0x1907
746 | #define DDSKTX__KTX_RGBA 0x1908
747 | #define DDSKTX__KTX_BGRA 0x80E1
748 | #define DDSKTX__KTX_RG 0x8227
749 |
750 | #define DDSKTX__KTX_BYTE 0x1400
751 | #define DDSKTX__KTX_UNSIGNED_BYTE 0x1401
752 | #define DDSKTX__KTX_SHORT 0x1402
753 | #define DDSKTX__KTX_UNSIGNED_SHORT 0x1403
754 | #define DDSKTX__KTX_INT 0x1404
755 | #define DDSKTX__KTX_UNSIGNED_INT 0x1405
756 | #define DDSKTX__KTX_FLOAT 0x1406
757 | #define DDSKTX__KTX_HALF_FLOAT 0x140B
758 | #define DDSKTX__KTX_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
759 | #define DDSKTX__KTX_UNSIGNED_SHORT_5_6_5 0x8363
760 | #define DDSKTX__KTX_UNSIGNED_SHORT_4_4_4_4 0x8033
761 | #define DDSKTX__KTX_UNSIGNED_SHORT_5_5_5_1 0x8034
762 | #define DDSKTX__KTX_UNSIGNED_INT_2_10_10_10_REV 0x8368
763 | #define DDSKTX__KTX_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
764 |
765 | typedef struct ddsktx__ktx_format_info
766 | {
767 | uint32_t internal_fmt;
768 | uint32_t internal_fmt_srgb;
769 | uint32_t fmt;
770 | uint32_t type;
771 | } ddsktx__ktx_format_info;
772 |
773 | typedef struct ddsktx__ktx_format_info2
774 | {
775 | uint32_t internal_fmt;
776 | ddsktx_format format;
777 | } ddsktx__ktx_format_info2;
778 |
779 | static const ddsktx__ktx_format_info k__translate_ktx_fmt[] = {
780 | { DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT, DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT, DDSKTX__KTX_ZERO, }, // BC1
781 | { DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT, DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT, DDSKTX__KTX_ZERO, }, // BC2
782 | { DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT, DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, DDSKTX__KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT, DDSKTX__KTX_ZERO, }, // BC3
783 | { DDSKTX__KTX_COMPRESSED_LUMINANCE_LATC1_EXT, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_LUMINANCE_LATC1_EXT, DDSKTX__KTX_ZERO, }, // BC4
784 | { DDSKTX__KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, DDSKTX__KTX_ZERO, }, // BC5
785 | { DDSKTX__KTX_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, DDSKTX__KTX_ZERO, }, // BC6H
786 | { DDSKTX__KTX_COMPRESSED_RGBA_BPTC_UNORM_ARB, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_RGBA_BPTC_UNORM_ARB, DDSKTX__KTX_ZERO, }, // BC7
787 | { DDSKTX__KTX_ETC1_RGB8_OES, DDSKTX__KTX_ZERO, DDSKTX__KTX_ETC1_RGB8_OES, DDSKTX__KTX_ZERO, }, // ETC1
788 | { DDSKTX__KTX_COMPRESSED_RGB8_ETC2, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_RGB8_ETC2, DDSKTX__KTX_ZERO, }, // ETC2
789 | { DDSKTX__KTX_COMPRESSED_RGBA8_ETC2_EAC, DDSKTX__KTX_COMPRESSED_SRGB8_ETC2, DDSKTX__KTX_COMPRESSED_RGBA8_ETC2_EAC, DDSKTX__KTX_ZERO, }, // ETC2A
790 | { DDSKTX__KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, DDSKTX__KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, DDSKTX__KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, DDSKTX__KTX_ZERO, }, // ETC2A1
791 | { DDSKTX__KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, DDSKTX__KTX_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, DDSKTX__KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, DDSKTX__KTX_ZERO, }, // PTC12
792 | { DDSKTX__KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, DDSKTX__KTX_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, DDSKTX__KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, DDSKTX__KTX_ZERO, }, // PTC14
793 | { DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, DDSKTX__KTX_ZERO, }, // PTC12A
794 | { DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, DDSKTX__KTX_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, DDSKTX__KTX_ZERO, }, // PTC14A
795 | { DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, DDSKTX__KTX_ZERO, }, // PTC22
796 | { DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, DDSKTX__KTX_ZERO, DDSKTX__KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, DDSKTX__KTX_ZERO, }, // PTC24
797 | { DDSKTX__KTX_ATC_RGB_AMD, DDSKTX__KTX_ZERO, DDSKTX__KTX_ATC_RGB_AMD, DDSKTX__KTX_ZERO, }, // ATC
798 | { DDSKTX__KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, DDSKTX__KTX_ZERO, DDSKTX__KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, DDSKTX__KTX_ZERO, }, // ATCE
799 | { DDSKTX__KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, DDSKTX__KTX_ZERO, DDSKTX__KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, DDSKTX__KTX_ZERO, }, // ATCI
800 | { DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_4x4_KHR, DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_4x4_KHR, DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_4x4_KHR, DDSKTX__KTX_ZERO, }, // ASTC4x4
801 | { DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_5x5_KHR, DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_5x5_KHR, DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_5x5_KHR, DDSKTX__KTX_ZERO, }, // ASTC5x5
802 | { DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_6x6_KHR, DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_6x6_KHR, DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_6x6_KHR, DDSKTX__KTX_ZERO, }, // ASTC6x6
803 | { DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_8x5_KHR, DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_8x5_KHR, DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_8x5_KHR, DDSKTX__KTX_ZERO, }, // ASTC8x5
804 | { DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_8x6_KHR, DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_8x6_KHR, DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_8x6_KHR, DDSKTX__KTX_ZERO, }, // ASTC8x6
805 | { DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_10x5_KHR, DDSKTX__KTX_COMPRESSED_SRGB8_ALPHA8_ADDSKTX_10x5_KHR, DDSKTX__KTX_COMPRESSED_RGBA_ADDSKTX_10x5_KHR, DDSKTX__KTX_ZERO, }, // ASTC10x5
806 | { DDSKTX__KTX_ZERO, DDSKTX__KTX_ZERO, DDSKTX__KTX_ZERO, DDSKTX__KTX_ZERO, }, // Unknown
807 | { DDSKTX__KTX_ALPHA, DDSKTX__KTX_ZERO, DDSKTX__KTX_ALPHA, DDSKTX__KTX_UNSIGNED_BYTE, }, // A8
808 | { DDSKTX__KTX_R8, DDSKTX__KTX_ZERO, DDSKTX__KTX_RED, DDSKTX__KTX_UNSIGNED_BYTE, }, // R8
809 | { DDSKTX__KTX_RGBA8, DDSKTX__KTX_SRGB8_ALPHA8, DDSKTX__KTX_RGBA, DDSKTX__KTX_UNSIGNED_BYTE, }, // RGBA8
810 | { DDSKTX__KTX_RGBA8_SNORM, DDSKTX__KTX_ZERO, DDSKTX__KTX_RGBA, DDSKTX__KTX_BYTE, }, // RGBA8S
811 | { DDSKTX__KTX_RG16, DDSKTX__KTX_ZERO, DDSKTX__KTX_RG, DDSKTX__KTX_UNSIGNED_SHORT, }, // RG16
812 | { DDSKTX__KTX_RGB8, DDSKTX__KTX_SRGB8, DDSKTX__KTX_RGB, DDSKTX__KTX_UNSIGNED_BYTE, }, // RGB8
813 | { DDSKTX__KTX_R16, DDSKTX__KTX_ZERO, DDSKTX__KTX_RED, DDSKTX__KTX_UNSIGNED_SHORT, }, // R16
814 | { DDSKTX__KTX_R32F, DDSKTX__KTX_ZERO, DDSKTX__KTX_RED, DDSKTX__KTX_FLOAT, }, // R32F
815 | { DDSKTX__KTX_R16F, DDSKTX__KTX_ZERO, DDSKTX__KTX_RED, DDSKTX__KTX_HALF_FLOAT, }, // R16F
816 | { DDSKTX__KTX_RG16F, DDSKTX__KTX_ZERO, DDSKTX__KTX_RG, DDSKTX__KTX_FLOAT, }, // RG16F
817 | { DDSKTX__KTX_RG16_SNORM, DDSKTX__KTX_ZERO, DDSKTX__KTX_RG, DDSKTX__KTX_SHORT, }, // RG16S
818 | { DDSKTX__KTX_RGBA16F, DDSKTX__KTX_ZERO, DDSKTX__KTX_RGBA, DDSKTX__KTX_HALF_FLOAT, }, // RGBA16F
819 | { DDSKTX__KTX_RGBA16, DDSKTX__KTX_ZERO, DDSKTX__KTX_RGBA, DDSKTX__KTX_UNSIGNED_SHORT, }, // RGBA16
820 | { DDSKTX__KTX_BGRA, DDSKTX__KTX_SRGB8_ALPHA8, DDSKTX__KTX_BGRA, DDSKTX__KTX_UNSIGNED_BYTE, }, // BGRA8
821 | { DDSKTX__KTX_RGB10_A2, DDSKTX__KTX_ZERO, DDSKTX__KTX_RGBA, DDSKTX__KTX_UNSIGNED_INT_2_10_10_10_REV, }, // RGB10A2
822 | { DDSKTX__KTX_R11F_G11F_B10F, DDSKTX__KTX_ZERO, DDSKTX__KTX_RGB, DDSKTX__KTX_UNSIGNED_INT_10F_11F_11F_REV, }, // RG11B10F
823 | { DDSKTX__KTX_RG8, DDSKTX__KTX_ZERO, DDSKTX__KTX_RG, DDSKTX__KTX_UNSIGNED_BYTE, }, // RG8
824 | { DDSKTX__KTX_RG8_SNORM, DDSKTX__KTX_ZERO, DDSKTX__KTX_RG, DDSKTX__KTX_BYTE, }, // RG8S
825 | { DDSKTX__KTX_R16I, DDSKTX__KTX_ZERO, DDSKTX__KTX_RED, DDSKTX__KTX_UNSIGNED_SHORT, }, // R16I
826 | { DDSKTX__KTX_R16UI, DDSKTX__KTX_ZERO, DDSKTX__KTX_RED, DDSKTX__KTX_UNSIGNED_SHORT, }, // R16UI
827 | };
828 |
829 | static const ddsktx__ktx_format_info2 k__translate_ktx_fmt2[] =
830 | {
831 | { DDSKTX__KTX_A8, DDSKTX_FORMAT_A8 },
832 | { DDSKTX__KTX_RED, DDSKTX_FORMAT_R8 },
833 | { DDSKTX__KTX_RGB, DDSKTX_FORMAT_RGB8 },
834 | { DDSKTX__KTX_RGBA, DDSKTX_FORMAT_RGBA8 },
835 | { DDSKTX__KTX_COMPRESSED_RGB_S3TC_DXT1_EXT, DDSKTX_FORMAT_BC1 },
836 | };
837 |
838 | typedef struct ddsktx__format_info
839 | {
840 | const char* name;
841 | bool has_alpha;
842 | } ddsktx__format_info;
843 |
844 | static const ddsktx__format_info k__formats_info[] = {
845 | {"BC1", false},
846 | {"BC2", true},
847 | {"BC3", true},
848 | {"BC4", false},
849 | {"BC5", false},
850 | {"BC6H", false},
851 | {"BC7", true},
852 | {"ETC1", false},
853 | {"ETC2", false},
854 | {"ETC2A", true},
855 | {"ETC2A1", true},
856 | {"PTC12", false},
857 | {"PTC14", false},
858 | {"PTC12A", true},
859 | {"PTC14A", true},
860 | {"PTC22", true},
861 | {"PTC24", true},
862 | {"ATC", false},
863 | {"ATCE", false},
864 | {"ATCI", false},
865 | {"ASTC4x4", true},
866 | {"ASTC5x5", true},
867 | {"ASTC6x6", false},
868 | {"ASTC8x5", true},
869 | {"ASTC8x6", false},
870 | {"ASTC10x5", false},
871 | {"", false},
872 | {"A8", true},
873 | {"R8", false},
874 | {"RGBA8", true},
875 | {"RGBA8S", true},
876 | {"RG16", false},
877 | {"RGB8", false},
878 | {"R16", false},
879 | {"R32F", false},
880 | {"R16F", false},
881 | {"RG16F", false},
882 | {"RG16S", false},
883 | {"RGBA16F", true},
884 | {"RGBA16",true},
885 | {"BGRA8", true},
886 | {"RGB10A2", true},
887 | {"RG11B10F", false},
888 | {"RG8", false},
889 | {"RG8S", false}
890 | };
891 |
892 |
893 | static inline int ddsktx__read(ddsktx__mem_reader* reader, void* buff, int size)
894 | {
895 | int read_bytes = (reader->offset + size) <= reader->total ? size : (reader->total - reader->offset);
896 | ddsktx_memcpy(buff, reader->buff + reader->offset, read_bytes);
897 | reader->offset += read_bytes;
898 | return read_bytes;
899 | }
900 |
901 | static bool ddsktx__parse_ktx(ddsktx_texture_info* tc, const void* file_data, int size, ddsktx_error* err)
902 | {
903 | static const uint8_t ktx__id[] = { 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
904 |
905 | ddsktx_memset(tc, 0x0, sizeof(ddsktx_texture_info));
906 |
907 | ddsktx__mem_reader r = {(const uint8_t*)file_data, size, sizeof(uint32_t)};
908 | ddsktx__ktx_header header;
909 | if (ddsktx__read(&r, &header, sizeof(header)) != DDSKTX__KTX_HEADER_SIZE) {
910 | ddsktx__err(err, "ktx; header size does not match");
911 | }
912 |
913 | if (ddsktx_memcmp(header.id, ktx__id, sizeof(header.id)) != 0) {
914 | ddsktx__err(err, "ktx: invalid file header");
915 | }
916 |
917 | // TODO: support big endian
918 | if (header.endianess != 0x04030201) {
919 | ddsktx__err(err, "ktx: big-endian format is not supported");
920 | }
921 |
922 | tc->metadata_offset = r.offset;
923 | tc->metadata_size = (int)header.metadata_size;
924 | r.offset += (int)header.metadata_size;
925 |
926 | ddsktx_format format = _DDSKTX_FORMAT_COUNT;
927 |
928 | int count = sizeof(k__translate_ktx_fmt)/sizeof(ddsktx__ktx_format_info);
929 | for (int i = 0; i < count; i++) {
930 | if (k__translate_ktx_fmt[i].internal_fmt == header.internal_format) {
931 | format = (ddsktx_format)i;
932 | break;
933 | }
934 | }
935 |
936 | if (format == _DDSKTX_FORMAT_COUNT) {
937 | count = sizeof(k__translate_ktx_fmt2)/sizeof(ddsktx__ktx_format_info2);
938 | for (int i = 0; i < count; i++) {
939 | if (k__translate_ktx_fmt2[i].internal_fmt == header.internal_format) {
940 | format = (ddsktx_format)k__translate_ktx_fmt2[i].format;
941 | break;
942 | }
943 | }
944 | }
945 |
946 | if (format == _DDSKTX_FORMAT_COUNT) {
947 | ddsktx__err(err, "ktx: unsupported format");
948 | }
949 |
950 | if (header.face_count > 1 && header.face_count != DDSKTX_CUBE_FACE_COUNT) {
951 | ddsktx__err(err, "ktx: incomplete cubemap");
952 | }
953 |
954 | tc->data_offset = r.offset;
955 | tc->size_bytes = r.total - r.offset;
956 | tc->format = format;
957 | tc->width = (int)header.width;
958 | tc->height = (int)header.height;
959 | tc->depth = ddsktx__max((int)header.depth, 1);
960 | tc->num_layers = ddsktx__max((int)header.array_count, 1);
961 | tc->num_mips = ddsktx__max((int)header.mip_count, 1);
962 | tc->bpp = k__block_info[format].bpp;
963 |
964 | if (header.face_count == 6)
965 | tc->flags |= DDSKTX_TEXTURE_FLAG_CUBEMAP;
966 | tc->flags |= k__formats_info[format].has_alpha ? DDSKTX_TEXTURE_FLAG_ALPHA : 0;
967 | tc->flags |= DDSKTX_TEXTURE_FLAG_KTX;
968 |
969 | return true;
970 | }
971 |
972 | static bool ddsktx__parse_dds(ddsktx_texture_info* tc, const void* file_data, int size, ddsktx_error* err)
973 | {
974 | ddsktx__mem_reader r = {(const uint8_t*)file_data, size, sizeof(uint32_t)};
975 | ddsktx__dds_header header;
976 | if (ddsktx__read(&r, &header, sizeof(header)) < DDSKTX__DDS_HEADER_SIZE ||
977 | header.size != DDSKTX__DDS_HEADER_SIZE)
978 | {
979 | ddsktx__err(err, "dds: header size does not match");
980 | }
981 |
982 | uint32_t required_flags = (DDSKTX__DDSD_HEIGHT|DDSKTX__DDSD_WIDTH);
983 | if ((header.flags & required_flags) != required_flags) {
984 | ddsktx__err(err, "dds: have invalid flags");
985 | }
986 |
987 | if (header.pixel_format.size != sizeof(ddsktx__dds_pixel_format)) {
988 | ddsktx__err(err, "dds: pixel format header is invalid");
989 | }
990 |
991 | uint32_t dxgi_format = 0;
992 | uint32_t array_size = 1;
993 | if (DDSKTX__DDPF_FOURCC == (header.flags & DDSKTX__DDPF_FOURCC) &&
994 | header.pixel_format.fourcc == DDSKTX__DDS_DX10)
995 | {
996 | ddsktx__dds_header_dxgi dxgi_header;
997 | ddsktx__read(&r, &dxgi_header, sizeof(dxgi_header));
998 | dxgi_format = dxgi_header.dxgi_format;
999 | array_size = dxgi_header.array_size;
1000 | }
1001 |
1002 | if ((header.caps1 & DDSKTX__DDSCAPS_TEXTURE) == 0) {
1003 | ddsktx__err(err, "dds: unsupported caps");
1004 | }
1005 |
1006 | bool cubemap = (header.caps2 & DDSKTX__DDSCAPS2_CUBEMAP) != 0;
1007 | if (cubemap && (header.caps2 & DDSKTX__DDSCAPS2_CUBEMAP_ALLSIDES) != DDSKTX__DDSCAPS2_CUBEMAP_ALLSIDES) {
1008 | ddsktx__err(err, "dds: incomplete cubemap");
1009 | }
1010 | bool volume = (header.caps2 & DDSKTX__DDSCAPS2_VOLUME) != 0;
1011 |
1012 | ddsktx_format format = _DDSKTX_FORMAT_COUNT;
1013 | bool has_alpha = (header.pixel_format.flags & DDSKTX__DDPF_ALPHA) != 0;
1014 | bool srgb = false;
1015 |
1016 | if (dxgi_format == 0) {
1017 | if ((header.pixel_format.flags & DDSKTX__DDPF_FOURCC) == DDSKTX__DDPF_FOURCC) {
1018 | int count = sizeof(k__translate_dds_fourcc)/sizeof(ddsktx__dds_translate_fourcc_format);
1019 | for (int i = 0; i < count; i++) {
1020 | if (k__translate_dds_fourcc[i].dds_format == header.pixel_format.fourcc) {
1021 | format = k__translate_dds_fourcc[i].format;
1022 | break;
1023 | }
1024 | }
1025 | } else {
1026 | int count = sizeof(k__translate_dds_pixel)/sizeof(ddsktx__dds_translate_pixel_format);
1027 | for (int i = 0; i < count; i++) {
1028 | const ddsktx__dds_translate_pixel_format* f = &k__translate_dds_pixel[i];
1029 | if (f->bit_count == header.pixel_format.rgb_bit_count &&
1030 | f->flags == header.pixel_format.flags &&
1031 | f->bit_mask[0] == header.pixel_format.bit_mask[0] &&
1032 | f->bit_mask[1] == header.pixel_format.bit_mask[1] &&
1033 | f->bit_mask[2] == header.pixel_format.bit_mask[2] &&
1034 | f->bit_mask[3] == header.pixel_format.bit_mask[3])
1035 | {
1036 | format = f->format;
1037 | break;
1038 | }
1039 | }
1040 | }
1041 | } else {
1042 | int count = sizeof(k__translate_dxgi)/sizeof(ddsktx__dds_translate_fourcc_format);
1043 | for (int i = 0; i < count; i++) {
1044 | if (k__translate_dxgi[i].dds_format == dxgi_format) {
1045 | format = k__translate_dxgi[i].format;
1046 | srgb = k__translate_dxgi[i].srgb;
1047 | break;
1048 | }
1049 | }
1050 | }
1051 |
1052 | if (format == _DDSKTX_FORMAT_COUNT) {
1053 | ddsktx__err(err, "dds: unknown format");
1054 | }
1055 |
1056 | ddsktx_memset(tc, 0x0, sizeof(ddsktx_texture_info));
1057 | tc->data_offset = r.offset;
1058 | tc->size_bytes = r.total - r.offset;
1059 | tc->format = format;
1060 | tc->width = (int)header.width;
1061 | tc->height = (int)header.height;
1062 | tc->depth = ddsktx__max(1, (int)header.depth);
1063 | tc->num_layers = ddsktx__max(1, (int)array_size);
1064 | tc->num_mips = (header.caps1 & DDSKTX__DDSCAPS_MIPMAP) ? (int)header.mip_count : 1;
1065 | tc->bpp = k__block_info[format].bpp;
1066 | if (has_alpha || k__formats_info[format].has_alpha)
1067 | tc->flags |= DDSKTX_TEXTURE_FLAG_ALPHA;
1068 | if (cubemap)
1069 | tc->flags |= DDSKTX_TEXTURE_FLAG_CUBEMAP;
1070 | if (volume)
1071 | tc->flags |= DDSKTX_TEXTURE_FLAG_VOLUME;
1072 | if (srgb)
1073 | tc->flags |= DDSKTX_TEXTURE_FLAG_SRGB;
1074 | tc->flags |= DDSKTX_TEXTURE_FLAG_DDS;
1075 |
1076 | return true;
1077 | }
1078 |
1079 | void ddsktx_get_sub(const ddsktx_texture_info* tc, ddsktx_sub_data* sub_data,
1080 | const void* file_data, int size,
1081 | int array_idx, int slice_face_idx, int mip_idx)
1082 | {
1083 | ddsktx_assert(tc);
1084 | ddsktx_assert(sub_data);
1085 | ddsktx_assert(file_data);
1086 | ddsktx_assert(size > 0);
1087 | ddsktx_assert(array_idx < tc->num_layers);
1088 | ddsktx_assert(!((tc->flags&DDSKTX_TEXTURE_FLAG_CUBEMAP) && (slice_face_idx >= DDSKTX_CUBE_FACE_COUNT)) && "invalid cube-face index");
1089 | ddsktx_assert(!(!(tc->flags&DDSKTX_TEXTURE_FLAG_CUBEMAP) && (slice_face_idx >= tc->depth)) && "invalid depth-slice index");
1090 | ddsktx_assert(mip_idx < tc->num_mips);
1091 |
1092 | ddsktx__mem_reader r = { (uint8_t*)file_data, size, tc->data_offset };
1093 | ddsktx_format format = tc->format;
1094 |
1095 | ddsktx_assert(format < _DDSKTX_FORMAT_COUNT && format != _DDSKTX_FORMAT_COMPRESSED);
1096 | const ddsktx__block_info* binfo = &k__block_info[format];
1097 | const int bpp = binfo->bpp;
1098 | const int block_size = binfo->block_size;
1099 | const int min_block_x = binfo->min_block_x;
1100 | const int min_block_y = binfo->min_block_y;
1101 |
1102 | int num_faces;
1103 |
1104 | ddsktx_assert(!((tc->flags & DDSKTX_TEXTURE_FLAG_CUBEMAP) && tc->depth > 1) && "textures must be either Cube or 3D");
1105 | int slice_idx, face_idx, num_slices;
1106 | if (tc->flags & DDSKTX_TEXTURE_FLAG_CUBEMAP) {
1107 | slice_idx = 0;
1108 | face_idx = slice_face_idx;
1109 | num_faces = DDSKTX_CUBE_FACE_COUNT;
1110 | num_slices = 1;
1111 | } else {
1112 | slice_idx = slice_face_idx;
1113 | face_idx = 0;
1114 | num_faces = 1;
1115 | num_slices = tc->depth;
1116 | }
1117 |
1118 | if (tc->flags & DDSKTX_TEXTURE_FLAG_DDS) {
1119 | for (int layer = 0, num_layers = tc->num_layers; layer < num_layers; layer++) {
1120 | for (int face = 0; face < num_faces; face++) {
1121 | int width = tc->width;
1122 | int height = tc->height;
1123 |
1124 | for (int mip = 0, mip_count = tc->num_mips; mip < mip_count; mip++) {
1125 | int row_bytes, mip_size;
1126 |
1127 | if (format < _DDSKTX_FORMAT_COMPRESSED) {
1128 | int num_blocks_wide = width > 0 ? ddsktx__max(1, (width + 3)/4) : 0;
1129 | num_blocks_wide = ddsktx__max(min_block_x, num_blocks_wide);
1130 |
1131 | int num_blocks_high = height > 0 ? ddsktx__max(1, (height + 3)/4) : 0;
1132 | num_blocks_high = ddsktx__max(min_block_y, num_blocks_high);
1133 |
1134 | row_bytes = num_blocks_wide * block_size;
1135 | mip_size = row_bytes * num_blocks_high;
1136 | } else {
1137 | row_bytes = (width*bpp + 7)/8; // round to nearest byte
1138 | mip_size = row_bytes * height;
1139 | }
1140 |
1141 | for (int slice = 0; slice < num_slices; slice++) {
1142 | if (layer == array_idx && mip == mip_idx &&
1143 | slice == slice_idx && face_idx == face)
1144 | {
1145 | sub_data->buff = r.buff + r.offset;
1146 | sub_data->width = width;
1147 | sub_data->height = height;
1148 | sub_data->size_bytes = mip_size;
1149 | sub_data->row_pitch_bytes = row_bytes;
1150 | return;
1151 | }
1152 |
1153 | r.offset += mip_size;
1154 | ddsktx_assert(r.offset <= r.total && "texture buffer overflow");
1155 | } // foreach slice
1156 |
1157 | width >>= 1;
1158 | height >>= 1;
1159 |
1160 | if (width == 0) {
1161 | width = 1;
1162 | }
1163 | if (height == 0) {
1164 | height = 1;
1165 | }
1166 | } // foreach mip
1167 | } // foreach face
1168 | } // foreach array-item
1169 | } else if (tc->flags & DDSKTX_TEXTURE_FLAG_KTX) {
1170 | int width = tc->width;
1171 | int height = tc->height;
1172 |
1173 | for (int mip = 0, c = tc->num_mips; mip < c; mip++) {
1174 | int row_bytes, mip_size;
1175 |
1176 | if (format < _DDSKTX_FORMAT_COMPRESSED) {
1177 | int num_blocks_wide = width > 0 ? ddsktx__max(1, (width + 3)/4) : 0;
1178 | num_blocks_wide = ddsktx__max(min_block_x, num_blocks_wide);
1179 |
1180 | int num_blocks_high = height > 0 ? ddsktx__max(1, (height + 3)/4) : 0;
1181 | num_blocks_high = ddsktx__max(min_block_y, num_blocks_high);
1182 |
1183 | row_bytes = num_blocks_wide * block_size;
1184 | mip_size = row_bytes * num_blocks_high;
1185 | }
1186 | else {
1187 | row_bytes = (width*bpp + 7)/8; // round to nearest byte
1188 | mip_size = row_bytes * height;
1189 | }
1190 |
1191 | int image_size;
1192 | ddsktx__read(&r, &image_size, sizeof(image_size));
1193 | ddsktx_assert(image_size == (mip_size*num_faces*num_slices) && "image size mismatch");
1194 |
1195 | for (int layer = 0, num_layers = tc->num_layers; layer < num_layers; layer++) {
1196 | for (int face = 0; face < num_faces; face++) {
1197 | for (int slice = 0; slice < num_slices; slice++) {
1198 | if (layer == array_idx && mip == mip_idx &&
1199 | slice == slice_idx && face_idx == face)
1200 | {
1201 | sub_data->buff = r.buff + r.offset;
1202 | sub_data->width = width;
1203 | sub_data->height = height;
1204 | sub_data->size_bytes = mip_size;
1205 | sub_data->row_pitch_bytes = row_bytes;
1206 | return;
1207 | }
1208 |
1209 | r.offset += mip_size;
1210 | ddsktx_assert(r.offset <= r.total && "texture buffer overflow");
1211 | } // foreach slice
1212 |
1213 |
1214 | r.offset = ddsktx__align_mask(r.offset, 3); // cube-padding
1215 | } // foreach face
1216 | } // foreach array-item
1217 |
1218 | width >>= 1;
1219 | height >>= 1;
1220 |
1221 | if (width == 0) {
1222 | width = 1;
1223 | }
1224 | if (height == 0) {
1225 | height = 1;
1226 | }
1227 |
1228 | r.offset = ddsktx__align_mask(r.offset, 3); // mip-padding
1229 | } // foreach mip
1230 | } else {
1231 | ddsktx_assert(0 && "invalid file format");
1232 | }
1233 | }
1234 |
1235 | bool ddsktx_parse(ddsktx_texture_info* tc, const void* file_data, int size, ddsktx_error* err)
1236 | {
1237 | ddsktx_assert(tc);
1238 | ddsktx_assert(file_data);
1239 | ddsktx_assert(size > 0);
1240 |
1241 | ddsktx__mem_reader r = {(const uint8_t*)file_data, size, 0};
1242 |
1243 | // Read file flag and determine the file type
1244 | uint32_t file_flag = 0;
1245 | if (ddsktx__read(&r, &file_flag, sizeof(file_flag)) != sizeof(file_flag)) {
1246 | ddsktx__err(err, "invalid texture file");
1247 | }
1248 |
1249 | switch (file_flag) {
1250 | case DDSKTX__DDS_MAGIC:
1251 | return ddsktx__parse_dds(tc, file_data, size, err);
1252 | case DDSKTX__KTX_MAGIC:
1253 | return ddsktx__parse_ktx(tc, file_data, size, err);
1254 | default:
1255 | ddsktx__err(err, "unknown texture format");
1256 | }
1257 | }
1258 |
1259 | const char* ddsktx_format_str(ddsktx_format format)
1260 | {
1261 | return k__formats_info[format].name;
1262 | }
1263 |
1264 | bool ddsktx_format_compressed(ddsktx_format format)
1265 | {
1266 | ddsktx_assert(format != _DDSKTX_FORMAT_COMPRESSED && format != _DDSKTX_FORMAT_COUNT);
1267 | return format < _DDSKTX_FORMAT_COMPRESSED;
1268 | }
1269 |
1270 | #endif // DDSKTX_IMPLEMENT
1271 |
1272 |
--------------------------------------------------------------------------------