diff --git a/src/dds.cpp b/src/dds.cpp index 9a56ab02d..9e92cf2b3 100644 --- a/src/dds.cpp +++ b/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; diff --git a/src/dds.h b/src/dds.h index eed8e6dfb..7b921f4fd 100644 --- a/src/dds.h +++ b/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; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 3fca55a89..21de214e0 100644 --- a/src/renderer_d3d9.cpp +++ b/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); - mip.decode(temp); - uint32_t srcpitch = mip.m_width*4; - uint32_t dstpitch = rect.Pitch; + 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 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); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index c614ac087..5a6767af6 100644 --- a/src/renderer_gl.cpp +++ b/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];