diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-08-24 13:41:12 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-08-24 13:41:31 +0200 |
commit | 4593b97f2aa9d9d445651846ec64712a69fcb43c (patch) | |
tree | 53878e611329897a1d079ec35f5dec8c6ddbe5af | |
parent | 654ba6e376db007ebb3e1d12bd02efebb3a5e6d1 (diff) |
fb: add tests for A8 and L8 texture formats
Try to find glquake lightmap bug...
-rw-r--r-- | native/fb/mip_cube.c | 52 | ||||
-rw-r--r-- | native/lib/dds.c | 122 | ||||
-rw-r--r-- | native/lib/dds.h | 7 | ||||
-rw-r--r-- | native/resources/attribution.txt | 4 | ||||
-rw-r--r-- | native/resources/wall1_a8.dds | bin | 0 -> 87509 bytes | |||
-rw-r--r-- | native/resources/wall1_l8.dds | bin | 0 -> 87509 bytes | |||
-rwxr-xr-x | tools/genmipmaps_l8.py | 109 |
7 files changed, 228 insertions, 66 deletions
diff --git a/native/fb/mip_cube.c b/native/fb/mip_cube.c index 42f0f95..b1e6adb 100644 --- a/native/fb/mip_cube.c +++ b/native/fb/mip_cube.c @@ -149,7 +149,7 @@ float vNormals[] = { #define COMPONENTS_PER_VERTEX (3) #define NUM_VERTICES (6*4) -static const char mip_cube_vert[] = +static const char mip_cube_vert[] = "VERT\n" "DCL IN[0]\n" "DCL IN[1]\n" @@ -187,7 +187,7 @@ static const char mip_cube_vert[] = " 24: MOV OUT[2], TEMP[1]\n" " 25: END\n"; -static const char mip_cube_frag[] = +static const char mip_cube_frag[] = "FRAG\n" "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" "DCL IN[0], GENERIC[0], PERSPECTIVE\n" @@ -226,16 +226,19 @@ int main(int argc, char **argv) case FMT_DXT3: tex_format = PIPE_FORMAT_DXT3_RGBA; break; case FMT_DXT5: tex_format = PIPE_FORMAT_DXT5_RGBA; break; case FMT_ETC1: tex_format = PIPE_FORMAT_ETC1_RGB8; break; + case FMT_A8: tex_format = PIPE_FORMAT_A8_UNORM; break; + case FMT_L8: tex_format = PIPE_FORMAT_L8_UNORM; break; + case FMT_A8L8: tex_format = PIPE_FORMAT_L8A8_UNORM; break; default: printf("Unknown texture format\n"); exit(1); } - - struct pipe_resource *tex_resource = fbdemo_create_2d(fbs->screen, PIPE_BIND_SAMPLER_VIEW, tex_format, tex_base_width, tex_base_height, + + struct pipe_resource *tex_resource = fbdemo_create_2d(fbs->screen, PIPE_BIND_SAMPLER_VIEW, tex_format, tex_base_width, tex_base_height, dds->num_mipmaps - 1); - + printf("Loading compressed texture (format %i, %ix%i)\n", dds->fmt, tex_base_width, tex_base_height); - + for(int ix=0; ix<dds->num_mipmaps; ++ix) { printf("%08x: Uploading mipmap %i (%ix%i)\n", dds->slices[0][ix].offset, ix, dds->slices[0][ix].width, dds->slices[0][ix].height); @@ -271,7 +274,23 @@ int main(int argc, char **argv) pipe_buffer_unmap(pipe, vtx_transfer); /* compile gallium3d states */ - void *blend = pipe->create_blend_state(pipe, &(struct pipe_blend_state) { + void *blend = NULL; + if(tex_format == PIPE_FORMAT_A8_UNORM || tex_format == PIPE_FORMAT_L8A8_UNORM) /* if alpha texture, enable blending */ + { + blend = pipe->create_blend_state(pipe, &(struct pipe_blend_state) { + .rt[0] = { + .blend_enable = 1, + .rgb_func = PIPE_BLEND_ADD, + .rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA, + .rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA, + .alpha_func = PIPE_BLEND_ADD, + .alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA, + .alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA, + .colormask = 0xf + } + }); + } else { + blend = pipe->create_blend_state(pipe, &(struct pipe_blend_state) { .rt[0] = { .blend_enable = 0, .rgb_func = PIPE_BLEND_ADD, @@ -283,6 +302,7 @@ int main(int argc, char **argv) .colormask = 0xf } }); + } void *sampler = pipe->create_sampler_state(pipe, &(struct pipe_sampler_state) { .wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE, @@ -356,13 +376,13 @@ int main(int argc, char **argv) .src_offset = 0, .instance_divisor = 0, .vertex_buffer_index = 0, - .src_format = PIPE_FORMAT_R32G32B32_FLOAT + .src_format = PIPE_FORMAT_R32G32B32_FLOAT }, { /* normals */ .src_offset = 0xc, .instance_divisor = 0, .vertex_buffer_index = 0, - .src_format = PIPE_FORMAT_R32G32B32_FLOAT + .src_format = PIPE_FORMAT_R32G32B32_FLOAT }, { /* texture coord */ .src_offset = 0x18, @@ -371,7 +391,7 @@ int main(int argc, char **argv) .src_format = PIPE_FORMAT_R32G32_FLOAT } }; - void *vertex_elements = pipe->create_vertex_elements_state(pipe, + void *vertex_elements = pipe->create_vertex_elements_state(pipe, sizeof(pipe_vertex_elements)/sizeof(pipe_vertex_elements[0]), pipe_vertex_elements); struct pipe_sampler_view *sampler_view = pipe->create_sampler_view(pipe, tex_resource, &(struct pipe_sampler_view){ .format = tex_format, @@ -392,7 +412,7 @@ int main(int argc, char **argv) .format = z_resource->format, .u.tex.level = 0 }); - + /* bind */ pipe->bind_blend_state(pipe, blend); pipe->bind_fragment_sampler_states(pipe, 1, &sampler); @@ -438,7 +458,7 @@ int main(int argc, char **argv) .buffer = 0, .user_buffer = 0 });*/ /* non-indexed rendering */ - + void *vtx_shader = graw_parse_vertex_shader(pipe, mip_cube_vert); void *frag_shader = graw_parse_fragment_shader(pipe, mip_cube_frag); pipe->bind_vs_state(pipe, vtx_shader); @@ -449,9 +469,9 @@ int main(int argc, char **argv) float vs_const[11*4]; if(frame%50 == 0) printf("*** FRAME %i ****\n", frame); - /* Compute transform matrices in the same way as cube egl demo */ + /* Compute transform matrices in the same way as cube egl demo */ ESMatrix modelview, projection, modelviewprojection; - ESMatrix inverse, normal; + ESMatrix inverse, normal; esMatrixLoadIdentity(&modelview); esTranslate(&modelview, 0.0f, 0.0f, -8.0f); esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f); @@ -464,12 +484,12 @@ int main(int argc, char **argv) esMatrixMultiply(&modelviewprojection, &modelview, &projection); esMatrixInverse3x3(&inverse, &modelview); esMatrixTranspose(&normal, &inverse); - + /* Clear render target */ pipe->clear(pipe, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, &(const union pipe_color_union) { .f = {0.2, 0.2, 0.2, 1.0} }, 1.0, 0xff); - + memcpy(&vs_const[0*4], &normal.m[0][0], 3*4); /* CONST[0] */ memcpy(&vs_const[1*4], &normal.m[1][0], 3*4); /* CONST[1] */ memcpy(&vs_const[2*4], &normal.m[2][0], 3*4); /* CONST[2] */ diff --git a/native/lib/dds.c b/native/lib/dds.c index 0afba5e..5ae4c26 100644 --- a/native/lib/dds.c +++ b/native/lib/dds.c @@ -42,35 +42,37 @@ #define DDS_MAGIC 0x20534444 // DDS_header.dwFlags -#define DDSD_CAPS 0x00000001 -#define DDSD_HEIGHT 0x00000002 -#define DDSD_WIDTH 0x00000004 -#define DDSD_PITCH 0x00000008 -#define DDSD_PIXELFORMAT 0x00001000 -#define DDSD_MIPMAPCOUNT 0x00020000 -#define DDSD_LINEARSIZE 0x00080000 -#define DDSD_DEPTH 0x00800000 +#define DDSD_CAPS 0x00000001 +#define DDSD_HEIGHT 0x00000002 +#define DDSD_WIDTH 0x00000004 +#define DDSD_PITCH 0x00000008 +#define DDSD_PIXELFORMAT 0x00001000 +#define DDSD_MIPMAPCOUNT 0x00020000 +#define DDSD_LINEARSIZE 0x00080000 +#define DDSD_DEPTH 0x00800000 // DDS_header.sPixelFormat.dwFlags -#define DDPF_ALPHAPIXELS 0x00000001 -#define DDPF_FOURCC 0x00000004 -#define DDPF_INDEXED 0x00000020 -#define DDPF_RGB 0x00000040 +#define DDPF_ALPHAPIXELS 0x00000001 +#define DDPF_ALPHA 0x00000002 +#define DDPF_FOURCC 0x00000004 +#define DDPF_INDEXED 0x00000020 +#define DDPF_RGB 0x00000040 +#define DDPF_LUMINANCE 0x00020000 // DDS_header.sCaps.dwCaps1 -#define DDSCAPS_COMPLEX 0x00000008 -#define DDSCAPS_TEXTURE 0x00001000 -#define DDSCAPS_MIPMAP 0x00400000 +#define DDSCAPS_COMPLEX 0x00000008 +#define DDSCAPS_TEXTURE 0x00001000 +#define DDSCAPS_MIPMAP 0x00400000 // DDS_header.sCaps.dwCaps2 -#define DDSCAPS2_CUBEMAP 0x00000200 -#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400 -#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800 -#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000 -#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000 -#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000 -#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000 -#define DDSCAPS2_VOLUME 0x00200000 +#define DDSCAPS2_CUBEMAP 0x00000200 +#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400 +#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800 +#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000 +#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000 +#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000 +#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000 +#define DDSCAPS2_VOLUME 0x00200000 #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ (uint32_t)( \ @@ -79,11 +81,11 @@ (((uint32_t)(uint8_t)(ch1) << 8) & 0x0000FF00) | \ ((uint32_t)(uint8_t)(ch0) & 0x000000FF) ) -#define D3DFMT_DXT1 MAKEFOURCC('D','X','T','1') // DXT1 compression texture format -#define D3DFMT_DXT2 MAKEFOURCC('D','X','T','2') // DXT2 compression texture format -#define D3DFMT_DXT3 MAKEFOURCC('D','X','T','3') // DXT3 compression texture format -#define D3DFMT_DXT4 MAKEFOURCC('D','X','T','4') // DXT4 compression texture format -#define D3DFMT_DXT5 MAKEFOURCC('D','X','T','5') // DXT5 compression texture format +#define D3DFMT_DXT1 MAKEFOURCC('D','X','T','1') // DXT1 compression texture format +#define D3DFMT_DXT2 MAKEFOURCC('D','X','T','2') // DXT2 compression texture format +#define D3DFMT_DXT3 MAKEFOURCC('D','X','T','3') // DXT3 compression texture format +#define D3DFMT_DXT4 MAKEFOURCC('D','X','T','4') // DXT4 compression texture format +#define D3DFMT_DXT5 MAKEFOURCC('D','X','T','5') // DXT5 compression texture format #define D3DFMT_ETC1 MAKEFOURCC('E','T','C','1') // Custom (Ericcson Texture Compression) struct _DDS_pixelformat { @@ -128,6 +130,7 @@ typedef struct _DdsLoadInfo { bool compressed; unsigned int divSize; unsigned int blockBytes; + uint32_t flags; int bitcount; uint32_t rmask; uint32_t gmask; @@ -136,16 +139,19 @@ typedef struct _DdsLoadInfo { } DdsLoadInfo; static DdsLoadInfo loadInfo[] = { - [FMT_A8R8G8B8] = {false, 1, 4, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, - [FMT_X8R8G8B8] = {false, 1, 4, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, - [FMT_R8G8B8] = {false, 1, 3, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, - [FMT_A1R5G5B5] = {false, 1, 2, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000}, - [FMT_X1R5G5B5] = {false, 1, 2, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00000000}, - [FMT_R5G6B5] = {false, 1, 2, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000}, - [FMT_DXT1] = {true, 4, 8, 0, D3DFMT_DXT1}, - [FMT_DXT3] = {true, 4, 16, 0, D3DFMT_DXT3}, - [FMT_DXT5] = {true, 4, 16, 0, D3DFMT_DXT5}, - [FMT_ETC1] = {true, 4, 8, 0, D3DFMT_ETC1} + [FMT_A8R8G8B8] = {false, 1, 4, DDPF_RGB, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, + [FMT_X8R8G8B8] = {false, 1, 4, DDPF_RGB, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, + [FMT_R8G8B8] = {false, 1, 3, DDPF_RGB, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, + [FMT_A1R5G5B5] = {false, 1, 2, DDPF_RGB, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000}, + [FMT_X1R5G5B5] = {false, 1, 2, DDPF_RGB, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00000000}, + [FMT_R5G6B5] = {false, 1, 2, DDPF_RGB, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000}, + [FMT_A8] = {false, 1, 1, DDPF_ALPHA, 8, 0x00000000, 0, 0, 0x000000ff}, + [FMT_L8] = {false, 1, 1, DDPF_LUMINANCE, 8, 0x000000ff, 0, 0, 0x00000000}, + [FMT_A8L8] = {false, 1, 2, DDPF_LUMINANCE, 16, 0x000000ff, 0, 0, 0x0000ff00}, + [FMT_DXT1] = {true, 4, 8, DDPF_FOURCC, 0, D3DFMT_DXT1}, + [FMT_DXT3] = {true, 4, 16, DDPF_FOURCC, 0, D3DFMT_DXT3}, + [FMT_DXT5] = {true, 4, 16, DDPF_FOURCC, 0, D3DFMT_DXT5}, + [FMT_ETC1] = {true, 4, 8, DDPF_FOURCC, 0, D3DFMT_ETC1} }; #define NUM_FORMATS (sizeof(loadInfo) / sizeof(DdsLoadInfo)) @@ -160,20 +166,40 @@ static int find_fmt(struct _DDS_pixelformat *pf) DdsLoadInfo *li = &loadInfo[fmt]; if(pf->dwFlags & DDPF_FOURCC) { - if(li->bitcount == 0 && li->rmask == pf->dwFourCC) + if(li->flags == DDPF_FOURCC && li->bitcount == 0 && li->rmask == pf->dwFourCC) { return fmt; } } else if(pf->dwFlags & DDPF_RGB) { - if((li->bitcount == pf->dwRGBBitCount) && - (li->rmask == pf->dwRBitMask) && (li->gmask == pf->dwGBitMask) && + if((li->flags == DDPF_RGB) && + (li->bitcount == pf->dwRGBBitCount) && + (li->rmask == pf->dwRBitMask) && (li->gmask == pf->dwGBitMask) && (li->bmask == pf->dwBBitMask) && (li->amask == ((pf->dwFlags & DDPF_ALPHAPIXELS)?pf->dwAlphaBitMask:0))) { return fmt; } } + else if(pf->dwFlags & DDPF_LUMINANCE) + { + bool formatHasAlpha = pf->dwAlphaBitMask != 0; + bool ddsHasAlpha = (pf->dwFlags & DDPF_ALPHAPIXELS) != 0; + if(li->flags == DDPF_LUMINANCE && + li->bitcount == pf->dwRGBBitCount && + formatHasAlpha == ddsHasAlpha) + { + return fmt; + } + } + else if(pf->dwFlags & DDPF_ALPHA) + { + if(li->flags == DDPF_ALPHA && + li->bitcount == pf->dwRGBBitCount) + { + return fmt; + } + } } return -1; } @@ -209,7 +235,7 @@ bool dds_load_file(FILE *f, dds_texture **out) } DdsLoadInfo *li = &loadInfo[fmt]; dds_texture *rv = (dds_texture*)malloc(sizeof(dds_texture)); - if(!rv) + if(!rv) goto failure; //fixme: do cube maps later @@ -232,7 +258,7 @@ bool dds_load_file(FILE *f, dds_texture **out) } if((hdr.dwFlags & DDSD_PITCH) && (hdr.dwPitchOrLinearSize != x*li->blockBytes)) goto failure; - + rv->fmt = fmt; rv->num_slices = 1; rv->num_mipmaps = mipMapCount; @@ -246,7 +272,7 @@ bool dds_load_file(FILE *f, dds_texture **out) /* compute offsets */ size_t offset = 0; - for(unsigned int ix = 0; ix < mipMapCount; ++ix) + for(unsigned int ix = 0; ix < mipMapCount; ++ix) { dds_mipmap *mip = &rv->slices[0][ix]; mip->width = x; @@ -255,7 +281,7 @@ bool dds_load_file(FILE *f, dds_texture **out) mip->offset = offset; mip->size = size; #ifdef DEBUG - printf("%08x Loading mipmap %i: %ix%i (%i) stride=%i\n", + printf("%08x Loading mipmap %i: %ix%i (%i) stride=%i\n", (int)mip->offset, ix, (int)mip->width, (int)mip->height, (int)mip->size, (int)mip->stride); #endif @@ -266,10 +292,10 @@ bool dds_load_file(FILE *f, dds_texture **out) } rv->data = malloc(offset); rv->size = offset; - if(!rv->data) + if(!rv->data) goto failure; fread(rv->data, rv->size, 1, f); - for(unsigned int ix = 0; ix < mipMapCount; ++ix) + for(unsigned int ix = 0; ix < mipMapCount; ++ix) { rv->slices[0][ix].data = (void*)((size_t)rv->data + rv->slices[0][ix].offset); } @@ -283,7 +309,7 @@ failure: bool dds_load(const char *filename, dds_texture **out) { FILE *f = fopen(filename, "rb"); - if(f == NULL) + if(f == NULL) { #ifdef DEBUG printf("Cannot open texture file\n"); diff --git a/native/lib/dds.h b/native/lib/dds.h index 4db48fa..851ec60 100644 --- a/native/lib/dds.h +++ b/native/lib/dds.h @@ -38,6 +38,9 @@ #define FMT_DXT3 7 #define FMT_DXT5 8 #define FMT_ETC1 9 +#define FMT_A8 10 +#define FMT_L8 11 +#define FMT_A8L8 12 typedef struct _dds_mipmap { @@ -46,7 +49,7 @@ typedef struct _dds_mipmap size_t offset; } dds_mipmap; -typedef struct _dds_texture +typedef struct _dds_texture { int fmt; unsigned int div_size; @@ -62,5 +65,5 @@ bool dds_load(const char *filename, dds_texture **out); bool dds_load_file(FILE *f, dds_texture **out); void dds_free(dds_texture *tex); -#endif +#endif diff --git a/native/resources/attribution.txt b/native/resources/attribution.txt new file mode 100644 index 0000000..9efcc92 --- /dev/null +++ b/native/resources/attribution.txt @@ -0,0 +1,4 @@ +wall1_l8.dds / wall1_a8.dds +CC-BY: brightretro +http://opengameart.org/node/17576 + diff --git a/native/resources/wall1_a8.dds b/native/resources/wall1_a8.dds Binary files differnew file mode 100644 index 0000000..8eaf1f7 --- /dev/null +++ b/native/resources/wall1_a8.dds diff --git a/native/resources/wall1_l8.dds b/native/resources/wall1_l8.dds Binary files differnew file mode 100644 index 0000000..a00aa2a --- /dev/null +++ b/native/resources/wall1_l8.dds diff --git a/tools/genmipmaps_l8.py b/tools/genmipmaps_l8.py new file mode 100755 index 0000000..d810d05 --- /dev/null +++ b/tools/genmipmaps_l8.py @@ -0,0 +1,109 @@ +#!/usr/bin/python +''' +Generate 'ETC1' texture with mipmaps in dds format from an image file. +''' +# Copyright (c) 2012-2013 Wladimir J. van der Laan +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sub license, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +from __future__ import print_function, division, unicode_literals +import struct, sys, PIL, os +from PIL import Image +import argparse, tempfile +from subprocess import call + +DDS_MAGIC = 0x20534444 +DDS_UINT32 = b'<I' +FOURCC_ETC1 = struct.unpack(DDS_UINT32, b'ETC1')[0] # custom FOURCC +ETC1TOOL = 'etc1tool' # Android ETC1 tool, needs to be in PATH + +def main(): + parser = argparse.ArgumentParser(description='Generate mipmaps from image and compress to ETC1 dds.') + parser.add_argument('input', metavar='INFILE', type=str, + help='Input file (usually .png or .jpg)') + parser.add_argument('output', metavar='OUTFILE', type=str, + help='Output file (.dds)') + parser.add_argument('--a8', default=False, action='store_const', const=True, + help='Use A8 instead of L8 output') + args = parser.parse_args() + + img = Image.open(args.input) + orig_width = width = img.size[0] + orig_height = height = img.size[1] + img = img.convert('L') + assert(width > 0 and height > 0) + + (fd, tmpout) = tempfile.mkstemp(suffix='.png') + os.close(fd) # won't be using the already-opened fd + (fd, tmpout2) = tempfile.mkstemp(suffix='.pkm') + os.close(fd) + mip = 0 + mips = [] + while True: + print('Generating mip %i: %ix%i' % (mip, width, height)) + + data = img.tostring() + print(' size: %i' % len(data)) + mips.append(data) + + # Go to next mip level + if width == 1 and height == 1: # 1x1 reached + break + width = (width+1) >> 1 + height = (height+1) >> 1 + mip += 1 + img = img.resize((width, height), PIL.Image.ANTIALIAS) + + with open(args.output, 'wb') as f: + # Write dds header + hdrdata = [0] * (128//4) + hdrdata[0] = DDS_MAGIC # dwMagic + hdrdata[1] = 124 # dwSize + hdrdata[2] = 0x000A1007 # dwFlags (CAPS, WIDTH, HEIGHT, PIXELFORMAT, MIPMAPCOUNT, LINEARSIZE) + #hdrdata[2] = 0x0002100F # dwFlags gimp (CAPS, WIDTH, HEIGHT, PITCH, PIXELFORMAT, MIPMAPCOUNT) + hdrdata[3] = orig_height # dwHeight + hdrdata[4] = orig_width # dwWidth + hdrdata[5] = len(mips[0]) # dwPitchOrLinearSize + hdrdata[6] = 0 # dwDepth + hdrdata[7] = len(mips) # dwMipMapCount + hdrdata[19] = 32 # sPixelFormat.dwSize + if args.a8: + hdrdata[20] = 0x00000002 # sPixelFormat.dwFlags = DDPF_ALPHA + else: + hdrdata[20] = 0x00020000 # sPixelFormat.dwFlags = DDPF_LUMINANCE + hdrdata[21] = 0 # sPixelFormat.dwFourCC + hdrdata[22] = 8 # sPixelFormat.dwRGBBitCount + if args.a8: + hdrdata[23] = 0x00000000 # sPixelFormat.dwRBitMask + hdrdata[24] = 0 # sPixelFormat.dwGBitMask + hdrdata[25] = 0 # sPixelFormat.dwBBitMask + hdrdata[26] = 0x000000ff # sPixelFormat.dwAlphaBitMask + else: + hdrdata[23] = 0x000000ff # sPixelFormat.dwRBitMask + hdrdata[24] = 0 # sPixelFormat.dwGBitMask + hdrdata[25] = 0 # sPixelFormat.dwBBitMask + hdrdata[26] = 0x00000000 # sPixelFormat.dwAlphaBitMask + hdrdata[27] = 0x00401008 # sCaps.dwCaps1 (COMPLEX, TEXTURE, MIPMAP) + f.write(struct.pack(b'<32I', *hdrdata)) + for mip in mips: + f.write(mip) + +if __name__ == '__main__': + main() + |