|
@@ -91,76 +91,43 @@ static int vtfImageSize(enum VTFImageFormat fmt, int width, int height) {
|
|
|
return width * height * pixel_bits / 8;
|
|
|
}
|
|
|
|
|
|
-static int textureLoad(struct IFile *file, Texture *tex, struct Stack *tmp) {
|
|
|
- struct VTFHeader hdr;
|
|
|
- size_t cursor = 0;
|
|
|
- int retval = 0;
|
|
|
- if (file->read(file, 0, sizeof(hdr), &hdr) != sizeof(hdr)) {
|
|
|
- PRINT("Cannot read texture");
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- if (hdr.signature[0] != 'V' || hdr.signature[1] != 'T' ||
|
|
|
- hdr.signature[2] != 'F' || hdr.signature[3] != '\0') {
|
|
|
- PRINT("Invalid file signature");
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- PRINTF("Texture: %dx%d, %s",
|
|
|
- hdr.width, hdr.height, vtfFormatStr(hdr.hires_format));
|
|
|
-
|
|
|
- if (hdr.hires_format != VTFImage_DXT1 && hdr.hires_format != VTFImage_DXT5) {
|
|
|
- PRINTF("Not implemented texture format: %s", vtfFormatStr(hdr.hires_format));
|
|
|
- goto exitNoStack;
|
|
|
- }
|
|
|
-
|
|
|
- cursor += hdr.header_size;
|
|
|
-
|
|
|
- if (hdr.lores_format != (unsigned)VTFImage_None)
|
|
|
- cursor += vtfImageSize(hdr.lores_format, hdr.lores_width, hdr.lores_height);
|
|
|
-
|
|
|
- /*
|
|
|
- PRINTF("Texture lowres: %dx%d, %s; mips %d; header_size: %u",
|
|
|
- hdr.lores_width, hdr.lores_height, vtfFormatStr(hdr.lores_format), hdr.mipmap_count, hdr.header_size);
|
|
|
- */
|
|
|
-
|
|
|
- /* TODO don't skip all mipmaps */
|
|
|
- for (int mip = hdr.mipmap_count - 1; mip > 0; --mip) {
|
|
|
- const unsigned int mip_width = hdr.width >> mip;
|
|
|
- const unsigned int mip_height = hdr.height >> mip;
|
|
|
- const int mip_image_size = vtfImageSize(hdr.hires_format, mip_width, mip_height);
|
|
|
- cursor += mip_image_size * hdr.frames;
|
|
|
+static int textureUploadMipmap(struct Stack *tmp, struct IFile *file, size_t cursor,
|
|
|
+ const struct VTFHeader *hdr, int miplevel, AGLTexture *tex) {
|
|
|
+ for (int mip = hdr->mipmap_count - 1; mip > miplevel; --mip) {
|
|
|
+ const unsigned int mip_width = hdr->width >> mip;
|
|
|
+ const unsigned int mip_height = hdr->height >> mip;
|
|
|
+ const int mip_image_size = vtfImageSize(hdr->hires_format, mip_width, mip_height);
|
|
|
+ cursor += mip_image_size * hdr->frames;
|
|
|
|
|
|
/*PRINTF("cur: %d; size: %d, mip: %d, %dx%d",
|
|
|
cursor, mip_image_size, mip, mip_width, mip_height);
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
- void *pre_alloc_cursor = stackGetCursor(tmp);
|
|
|
- const int src_texture_size = vtfImageSize(hdr.hires_format, hdr.width, hdr.height);
|
|
|
+ const int src_texture_size = vtfImageSize(hdr->hires_format, hdr->width, hdr->height);
|
|
|
void *src_texture = stackAlloc(tmp, src_texture_size);
|
|
|
if (!src_texture) {
|
|
|
PRINTF("Cannot allocate %d bytes for texture", src_texture_size);
|
|
|
- goto exit;
|
|
|
+ return 0;
|
|
|
}
|
|
|
- const int dst_texture_size = sizeof(uint16_t) * hdr.width * hdr.height;
|
|
|
+ const int dst_texture_size = sizeof(uint16_t) * hdr->width * hdr->height;
|
|
|
void *dst_texture = stackAlloc(tmp, dst_texture_size);
|
|
|
if (!dst_texture) {
|
|
|
PRINTF("Cannot allocate %d bytes for texture", dst_texture_size);
|
|
|
- goto exit;
|
|
|
+ return 0;
|
|
|
}
|
|
|
if (src_texture_size != (int)file->read(file, cursor, src_texture_size, src_texture)) {
|
|
|
PRINT("Cannot read texture data");
|
|
|
- goto exit;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
const struct DXTUnpackContext dxt_ctx = {
|
|
|
- .width = hdr.width,
|
|
|
- .height = hdr.height,
|
|
|
+ .width = hdr->width,
|
|
|
+ .height = hdr->height,
|
|
|
.packed = src_texture,
|
|
|
.output = dst_texture
|
|
|
};
|
|
|
- if (hdr.hires_format == VTFImage_DXT1)
|
|
|
+ if (hdr->hires_format == VTFImage_DXT1)
|
|
|
dxt1Unpack(dxt_ctx);
|
|
|
else
|
|
|
dxt5Unpack(dxt_ctx);
|
|
@@ -168,20 +135,57 @@ static int textureLoad(struct IFile *file, Texture *tex, struct Stack *tmp) {
|
|
|
const AGLTextureUploadData data = {
|
|
|
.x = 0,
|
|
|
.y = 0,
|
|
|
- .width = hdr.width,
|
|
|
- .height = hdr.height,
|
|
|
+ .width = hdr->width,
|
|
|
+ .height = hdr->height,
|
|
|
.format = AGLTF_U565_RGB,
|
|
|
.pixels = dst_texture
|
|
|
};
|
|
|
|
|
|
- tex->gltex = aGLTextureCreate();
|
|
|
- aGLTextureUpload(&tex->gltex, &data);
|
|
|
- retval = 1;
|
|
|
+ aGLTextureUpload(tex, &data);
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+static int textureLoad(struct IFile *file, Texture *tex, struct Stack *tmp) {
|
|
|
+ struct VTFHeader hdr;
|
|
|
+ size_t cursor = 0;
|
|
|
+ int retval = 0;
|
|
|
+ if (file->read(file, 0, sizeof(hdr), &hdr) != sizeof(hdr)) {
|
|
|
+ PRINT("Cannot read texture");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hdr.signature[0] != 'V' || hdr.signature[1] != 'T' ||
|
|
|
+ hdr.signature[2] != 'F' || hdr.signature[3] != '\0') {
|
|
|
+ PRINT("Invalid file signature");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ PRINTF("Texture: %dx%d, %s",
|
|
|
+ hdr.width, hdr.height, vtfFormatStr(hdr.hires_format));
|
|
|
|
|
|
-exit:
|
|
|
+ if (hdr.hires_format != VTFImage_DXT1 && hdr.hires_format != VTFImage_DXT5) {
|
|
|
+ PRINTF("Not implemented texture format: %s", vtfFormatStr(hdr.hires_format));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ cursor += hdr.header_size;
|
|
|
+
|
|
|
+ if (hdr.lores_format != (unsigned)VTFImage_None)
|
|
|
+ cursor += vtfImageSize(hdr.lores_format, hdr.lores_width, hdr.lores_height);
|
|
|
+
|
|
|
+ /*
|
|
|
+ PRINTF("Texture lowres: %dx%d, %s; mips %d; header_size: %u",
|
|
|
+ hdr.lores_width, hdr.lores_height, vtfFormatStr(hdr.lores_format), hdr.mipmap_count, hdr.header_size);
|
|
|
+ */
|
|
|
+
|
|
|
+ tex->gltex = aGLTextureCreate();
|
|
|
+ void *pre_alloc_cursor = stackGetCursor(tmp);
|
|
|
+ retval = textureUploadMipmap(tmp, file, cursor, &hdr, 0, &tex->gltex);
|
|
|
stackFreeUpToPosition(tmp, pre_alloc_cursor);
|
|
|
|
|
|
-exitNoStack:
|
|
|
+ if(!retval)
|
|
|
+ aGLTextureDestroy(&tex->gltex);
|
|
|
+
|
|
|
return retval;
|
|
|
}
|
|
|
|