Przeglądaj źródła

DDS support for 8-bit uncompressed formats.

bkaradzic 13 lat temu
rodzic
commit
fb37505a8a
4 zmienionych plików z 59 dodań i 28 usunięć
  1. 29 14
      src/dds.cpp
  2. 2 0
      src/dds.h
  3. 20 12
      src/renderer_d3d9.cpp
  4. 8 2
      src/renderer_gl.cpp

+ 29 - 14
src/dds.cpp

@@ -286,24 +286,16 @@ void Mip::decode(uint8_t* _dst)
 	{
 		uint32_t width = m_width;
 		uint32_t height = m_height;
-		uint32_t pitch = m_width*4;
 
-		if (m_hasAlpha)
+		if (m_bpp == 1
+		||  m_bpp == 4)
 		{
-			for (uint32_t yy = 0; yy < height; ++yy)
-			{
-				uint8_t* dst = &_dst[yy*pitch];
-
-				for (uint32_t xx = 0; xx < width; ++xx)
-				{
-					memcpy(dst, src, 4);
-					dst += 4;
-					src += 4;
-				}
-			}
+			uint32_t pitch = m_width*m_bpp;
+			memcpy(_dst, src, pitch*height);
 		}
 		else
 		{
+			uint32_t pitch = m_width*4;
 			for (uint32_t yy = 0; yy < height; ++yy)
 			{
 				uint8_t* dst = &_dst[yy*pitch];
@@ -398,6 +390,7 @@ bool parseDds(Dds& _dds, const Memory* _mem)
 
 	stream.skip(4); // reserved
 
+	uint8_t bpp = 1;
 	uint8_t blockSize = 1;
 	uint8_t type = 0;
 	bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
@@ -426,7 +419,26 @@ bool parseDds(Dds& _dds, const Memory* _mem)
 	}
 	else
 	{
-		blockSize *= hasAlpha ? 4 : 3;
+		switch (pixelFlags)
+		{
+		case DDPF_RGB:
+			blockSize *= 3;
+			break;
+
+		case DDPF_RGB|DDPF_ALPHAPIXELS:
+			blockSize *= 4;
+			break;
+
+		case DDPF_LUMINANCE:
+		case DDPF_INDEXED:
+		case DDPF_ALPHA:
+			bpp = 1;
+			break;
+
+		default:
+			bpp = 0;
+			break;
+		}
 	}
 
 	_dds.m_width = width;
@@ -434,6 +446,7 @@ bool parseDds(Dds& _dds, const Memory* _mem)
 	_dds.m_depth = depth;
 	_dds.m_blockSize = blockSize;
 	_dds.m_numMips = (caps[0] & DDSCAPS_MIPMAP) ? mips : 1;
+	_dds.m_bpp = bpp;
 	_dds.m_type = type;
 	_dds.m_hasAlpha = hasAlpha;
 
@@ -446,6 +459,7 @@ bool getRawImageData(const Dds& _dds, uint8_t _index, const Memory* _mem, Mip& _
 	uint32_t height = _dds.m_height;
 	uint32_t blockSize = _dds.m_blockSize;
 	uint32_t offset = DDS_IMAGE_DATA_OFFSET;
+	uint8_t bpp = _dds.m_bpp;
 	uint8_t type = _dds.m_type;
 	bool hasAlpha = _dds.m_hasAlpha;
 
@@ -472,6 +486,7 @@ bool getRawImageData(const Dds& _dds, uint8_t _index, const Memory* _mem, Mip& _
 			_mip.m_blockSize = blockSize;
 			_mip.m_size = size;
 			_mip.m_data = _mem->data + offset;
+			_mip.m_bpp = bpp;
 			_mip.m_type = type;
 			_mip.m_hasAlpha = hasAlpha;
 			return true;

+ 2 - 0
src/dds.h

@@ -17,6 +17,7 @@ namespace bgfx
 		uint32_t m_depth;
 		uint8_t m_blockSize;
 		uint8_t m_numMips;
+		uint8_t m_bpp;
 		uint8_t m_type;
 		bool m_hasAlpha;
 	};
@@ -27,6 +28,7 @@ namespace bgfx
 		uint32_t m_height;
 		uint32_t m_blockSize;
 		uint32_t m_size;
+		uint8_t m_bpp;
 		uint8_t m_type;
 		bool m_hasAlpha;
 		const uint8_t* m_data;

+ 20 - 12
src/renderer_d3d9.cpp

@@ -848,9 +848,22 @@ namespace bgfx
 			bool decompress = false;
 
 			if (decompress
-			|| (0 == dds.m_type	&&  dds.m_hasAlpha) )
+			|| (0 == dds.m_type) )
 			{
-				fmt = D3DFMT_A8R8G8B8;
+				switch (dds.m_bpp)
+				{
+				case 1:
+					fmt = D3DFMT_L8;
+					break;
+
+				case 4:
+					fmt = D3DFMT_A8R8G8B8;
+					break;
+
+				default:
+					fmt = D3DFMT_X8R8G8B8;
+					break;
+				}
 			}
 
 			DX_CHECK(s_renderCtx.m_device->CreateTexture(dds.m_width
@@ -884,22 +897,17 @@ namespace bgfx
 						if (width != mip.m_width
 						||  height != mip.m_height)
 						{
-							uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*4);
+							uint32_t srcpitch = mip.m_width*mip.m_bpp;
+
+							uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
 							mip.decode(temp);
-							uint32_t srcpitch = mip.m_width*4;
-							uint32_t dstpitch = rect.Pitch;
 
+							uint32_t dstpitch = rect.Pitch;
 							for (uint32_t yy = 0; yy < height; ++yy)
 							{
 								uint8_t* src = &temp[yy*srcpitch];
 								uint8_t* dst = &bits[yy*dstpitch];
-
-								for (uint32_t xx = 0; xx < width; ++xx)
-								{
-									memcpy(dst, src, 4);
-									dst += 4;
-									src += 4;
-								}
+								memcpy(dst, src, srcpitch);
 							}
 
 							g_free(temp);

+ 8 - 2
src/renderer_gl.cpp

@@ -631,6 +631,11 @@ namespace bgfx
 			{
 				fmt = s_extension[Extension::GL_EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
 
+				if (dds.m_bpp == 1)
+				{
+					fmt = GL_LUMINANCE;
+				}
+
 				for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
 				{
 					width = uint32_max(1, width);
@@ -639,13 +644,14 @@ namespace bgfx
 					Mip mip;
 					if (getRawImageData(dds, lod, _mem, mip) )
 					{
-						uint8_t* bits = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*4);
+						uint32_t srcpitch = mip.m_width*mip.m_bpp;
+						uint8_t* bits = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
 
 						mip.decode(bits);
-						uint32_t dstpitch = width*4;
 
 						if (GL_RGBA == fmt)
 						{
+							uint32_t dstpitch = width*4;
 							for (uint32_t yy = 0; yy < height; ++yy)
 							{
 								uint8_t* dst = &bits[yy*dstpitch];