Bladeren bron

support more texture formats, fix #25

Ivan Avdeev 6 jaren geleden
bovenliggende
commit
08e27bf22d
3 gewijzigde bestanden met toevoegingen van 74 en 5 verwijderingen
  1. 1 1
      src/OpenSource.c
  2. 3 2
      src/collection.c
  3. 70 2
      src/texture.c

+ 1 - 1
src/OpenSource.c

@@ -171,7 +171,7 @@ static void opensrcResize(ATimeUs timestamp, unsigned int old_w, unsigned int ol
 	(void)(timestamp); (void)(old_w); (void)(old_h);
 	renderResize(a_app_state->width, a_app_state->height);
 
-	cameraProjection(&g.camera, 1.f, g.R * 10.f, 3.1415926f/2.f, (float)a_app_state->width / (float)a_app_state->height);
+	cameraProjection(&g.camera, 1.f, g.R * 20.f, 3.1415926f/2.f, (float)a_app_state->width / (float)a_app_state->height);
 	cameraRecompute(&g.camera);
 }
 

+ 3 - 2
src/collection.c

@@ -391,13 +391,14 @@ struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dir_fi
 				memcpy(filename_temp + path.len + 1 + filename.len + 1, ext.s, ext.len);
 				filename_temp[filename_len-1] = '\0';
 
-				/*
+#define DUMP_VPK_CONTENTS 0
+#if DUMP_VPK_CONTENTS
 				PRINTF("%s crc=%08x pre=%d arc=%d(%04x) off=%d len=%d",
 					filename_temp,
 					entry->crc,
 					entry->preloadBytes, entry->archive, entry->archive,
 					entry->archiveOffset, entry->archiveLength);
-				*/
+#endif
 
 				struct VPKFileMetadata *file = stackAlloc(mem->persistent, sizeof(struct VPKFileMetadata));
 				if (!file) {

+ 70 - 2
src/texture.c

@@ -104,7 +104,7 @@ static void textureUnpackDXTto565(uint8_t *src, uint16_t *dst, int width, int he
 		dxt5Unpack(dxt_ctx);
 }
 
-static void textureUnpack888to565(uint8_t *src, uint16_t *dst, int width, int height) {
+static void textureUnpackBGR8to565(uint8_t *src, uint16_t *dst, int width, int height) {
 	const int pixels = width * height;
 	for (int i = 0; i < pixels; ++i, src+=3) {
 		const int r = (src[0] >> 3) << 11;
@@ -114,6 +114,63 @@ static void textureUnpack888to565(uint8_t *src, uint16_t *dst, int width, int he
 	}
 }
 
+static void textureUnpackBGRX8to565(uint8_t *src, uint16_t *dst, int width, int height) {
+	const int pixels = width * height;
+	for (int i = 0; i < pixels; ++i, src+=4) {
+		const int r = (src[0] & 0xf8) << 8;
+		const int g = (src[1] & 0xfc) << 3;
+		const int b = (src[2] >> 3);
+		dst[i] = r | g | b;
+	}
+}
+
+static void textureUnpackBGRA8to565(uint8_t *src, uint16_t *dst, int width, int height) {
+	const int pixels = width * height;
+	for (int i = 0; i < pixels; ++i, src+=4) {
+		const int a = src[3] * 8; /* FIXME this is likely HDR and need proper color correction */
+		const int r = ((a * src[0]) >> 11);
+		const int g = ((a * src[1]) >> 10);
+		const int b = (a * src[2]) >> 11;
+
+		dst[i] = ((r>31?31:r) << 11) | ((g>63?63:g) << 5) | (b>31?31:b);
+	}
+}
+
+/* FIXME: taken from internets: https://gist.github.com/martinkallman/5049614 */
+float float32(const uint16_t in) {
+	uint32_t t1;
+	uint32_t t2;
+	uint32_t t3;
+
+	t1 = in & 0x7fff;                       // Non-sign bits
+	t2 = in & 0x8000;                       // Sign bit
+	t3 = in & 0x7c00;                       // Exponent
+
+	t1 <<= 13;                              // Align mantissa on MSB
+	t2 <<= 16;                              // Shift sign bit into position
+
+	t1 += 0x38000000;                       // Adjust bias
+
+	t1 = (t3 == 0 ? 0 : t1);                // Denormals-as-zero
+
+	t1 |= t2;                               // Re-insert sign bit
+
+	float ret;
+	memcpy(&ret, &t1, sizeof(ret));
+	return ret;
+}
+
+static void textureUnpackRGBA16Fto565(const uint16_t *src, uint16_t *dst, int width, int height) {
+	const int pixels = width * height;
+	for (int i = 0; i < pixels; ++i, src+=4) {
+		const float scale = 255.f * 1.5f;
+		const int rf = (int)(sqrtf(float32(src[0])) * scale) >> 3;
+		const int gf = (int)(sqrtf(float32(src[1])) * scale) >> 2;
+		const int bf = (int)(sqrtf(float32(src[2])) * scale) >> 3;
+		dst[i] = ((rf>31?31:rf) << 11) | ((gf>63?63:gf) << 5) | (bf>31?31:bf);
+	}
+}
+
 static uint16_t *textureUnpackToTemp(struct Stack *tmp, struct IFile *file, size_t cursor,
 		int width, int height, enum VTFImageFormat format) {
 
@@ -141,7 +198,16 @@ static uint16_t *textureUnpackToTemp(struct Stack *tmp, struct IFile *file, size
 			textureUnpackDXTto565(src_texture, dst_texture, width, height, format);
 			break;
 		case VTFImage_BGR8:
-			textureUnpack888to565(src_texture, dst_texture, width, height);
+			textureUnpackBGR8to565(src_texture, dst_texture, width, height);
+			break;
+		case VTFImage_BGRA8:
+			textureUnpackBGRA8to565(src_texture, dst_texture, width, height);
+			break;
+		case VTFImage_BGRX8:
+			textureUnpackBGRX8to565(src_texture, dst_texture, width, height);
+			break;
+		case VTFImage_RGBA16F:
+			textureUnpackRGBA16Fto565(src_texture, dst_texture, width, height);
 			break;
 		default:
 			PRINTF("Unsupported texture format %s", vtfFormatStr(format));
@@ -211,10 +277,12 @@ static int textureLoad(struct IFile *file, Texture *tex, struct Stack *tmp, RTex
 	//PRINTF("Texture: %dx%d, %s",
 	//	hdr.width, hdr.height, vtfFormatStr(hdr.hires_format));
 
+	/*
 	if (hdr.hires_format != VTFImage_DXT1 && hdr.hires_format != VTFImage_DXT5 && hdr.hires_format != VTFImage_BGR8) {
 		PRINTF("Not implemented texture format: %s", vtfFormatStr(hdr.hires_format));
 		return 0;
 	}
+	*/
 
 	cursor += hdr.header_size;