mirror of
https://github.com/bkaradzic/bimg.git
synced 2026-02-17 20:52:38 +01:00
Add scaled mip-chain for sdf textures
This commit is contained in:
@@ -113,6 +113,7 @@ namespace bimg
|
||||
, const void* _src
|
||||
, float _alphaRef
|
||||
, float _scale = 1.0f
|
||||
, uint32_t _upscale = 1
|
||||
);
|
||||
|
||||
///
|
||||
@@ -124,6 +125,7 @@ namespace bimg
|
||||
, void* _src
|
||||
, float _coverage
|
||||
, float _alphaRef
|
||||
, uint32_t _upscale = 1
|
||||
);
|
||||
|
||||
///
|
||||
|
||||
@@ -1060,7 +1060,7 @@ namespace bimg
|
||||
{ NULL, NULL }, // ASTC10x5
|
||||
{ NULL, NULL }, // Unknown
|
||||
{ NULL, NULL }, // R1
|
||||
{ bx::packR8, bx::unpackR8 }, // A8
|
||||
{ bx::packA8, bx::unpackA8 }, // A8
|
||||
{ bx::packR8, bx::unpackR8 }, // R8
|
||||
{ bx::packR8I, bx::unpackR8I }, // R8I
|
||||
{ bx::packR8U, bx::unpackR8U }, // R8U
|
||||
|
||||
@@ -490,7 +490,7 @@ namespace bimg
|
||||
return rgba[3];
|
||||
}
|
||||
|
||||
float imageAlphaTestCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, float _alphaRef, float _scale)
|
||||
float imageAlphaTestCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, float _alphaRef, float _scale, uint32_t _upscale)
|
||||
{
|
||||
UnpackFn unpack = getUnpack(_format);
|
||||
if (NULL == unpack)
|
||||
@@ -501,7 +501,8 @@ namespace bimg
|
||||
float coverage = 0.0f;
|
||||
const uint8_t* src = (const uint8_t*)_src;
|
||||
const uint32_t xstep = getBitsPerPixel(_format) / 8;
|
||||
const float numSamples = 8.0f;
|
||||
const uint32_t numSamples = _upscale;
|
||||
const float sampleStep = 1.0f / numSamples;
|
||||
|
||||
for (uint32_t yy = 0, ystep = _srcPitch; yy < _height-1; ++yy, src += ystep)
|
||||
{
|
||||
@@ -513,9 +514,9 @@ namespace bimg
|
||||
float alpha01 = _scale * getAlpha(unpack, data+ystep);
|
||||
float alpha11 = _scale * getAlpha(unpack, data+ystep+xstep);
|
||||
|
||||
for (float fy = 0.5f/numSamples; fy < 1.0f; fy += 1.0f)
|
||||
for (float fy = 0.0f; fy < 1.0f; fy += sampleStep)
|
||||
{
|
||||
for (float fx = 0.5f/numSamples; fx < 1.0f; fx += 1.0f)
|
||||
for (float fx = 0.0f; fx < 1.0f; fx += sampleStep)
|
||||
{
|
||||
float alpha = 0.0f
|
||||
+ alpha00 * (1.0f - fx) * (1.0f - fy)
|
||||
@@ -536,7 +537,7 @@ namespace bimg
|
||||
return coverage / float(_width*_height*numSamples*numSamples);
|
||||
}
|
||||
|
||||
void imageScaleAlphaToCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, void* _src, float _desiredCoverage, float _alphaRef)
|
||||
void imageScaleAlphaToCoverage(TextureFormat::Enum _format, uint32_t _width, uint32_t _height, uint32_t _srcPitch, void* _src, float _desiredCoverage, float _alphaRef, uint32_t _upscale)
|
||||
{
|
||||
PackFn pack = getPack(_format);
|
||||
UnpackFn unpack = getUnpack(_format);
|
||||
@@ -550,7 +551,7 @@ namespace bimg
|
||||
float max = 4.0f;
|
||||
float scale = 1.0f;
|
||||
|
||||
for (uint32_t ii = 0; ii < 8; ++ii)
|
||||
for (uint32_t ii = 0; ii < 10; ++ii)
|
||||
{
|
||||
float coverage = imageAlphaTestCoverage(
|
||||
_format
|
||||
@@ -560,6 +561,7 @@ namespace bimg
|
||||
, _src
|
||||
, _alphaRef
|
||||
, scale
|
||||
, _upscale
|
||||
);
|
||||
|
||||
if (coverage < _desiredCoverage)
|
||||
|
||||
@@ -620,10 +620,10 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
||||
, bimg::TextureFormat::R8
|
||||
);
|
||||
temp = BX_ALLOC(_allocator, size);
|
||||
uint8_t* rgba = (uint8_t*)temp;
|
||||
uint8_t* r8 = (uint8_t*)temp;
|
||||
|
||||
bimg::imageDecodeToR8(_allocator
|
||||
, rgba
|
||||
, r8
|
||||
, mip.m_data
|
||||
, mip.m_width
|
||||
, mip.m_height
|
||||
@@ -640,8 +640,85 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
|
||||
, mip.m_width
|
||||
, mip.m_height
|
||||
, mip.m_width
|
||||
, rgba
|
||||
, r8
|
||||
);
|
||||
|
||||
if (_options.mips) {
|
||||
const float alphaRef = 0.5f;
|
||||
float coverage = bimg::imageAlphaTestCoverage(bimg::TextureFormat::A8
|
||||
, mip.m_width
|
||||
, mip.m_height
|
||||
, mip.m_width
|
||||
, r8
|
||||
, alphaRef
|
||||
);
|
||||
|
||||
size = bimg::imageGetSize(
|
||||
NULL
|
||||
, uint16_t(dstMip.m_width)
|
||||
, uint16_t(dstMip.m_height)
|
||||
, uint16_t(dstMip.m_depth)
|
||||
, false
|
||||
, false
|
||||
, 1
|
||||
, bimg::TextureFormat::RGBA8
|
||||
);
|
||||
void* rgbaTemp = BX_ALLOC(_allocator, size);
|
||||
uint8_t* rgba = (uint8_t*)rgbaTemp;
|
||||
|
||||
bimg::imageDecodeToRgba8(
|
||||
_allocator
|
||||
, rgba
|
||||
, dstMip.m_data
|
||||
, dstMip.m_width
|
||||
, dstMip.m_height
|
||||
, dstMip.m_width * 4
|
||||
, bimg::TextureFormat::A8
|
||||
);
|
||||
|
||||
for (uint8_t lod = 1; lod < numMips && _err->isOk(); ++lod) {
|
||||
bimg::imageRgba8Downsample2x2(rgba
|
||||
, dstMip.m_width
|
||||
, dstMip.m_height
|
||||
, dstMip.m_depth
|
||||
, dstMip.m_width * 4
|
||||
, bx::strideAlign(dstMip.m_width / 2, blockWidth) * 4
|
||||
, rgba
|
||||
);
|
||||
|
||||
// For each mip, upscale to original size,
|
||||
// scale image alpha to get same coverage as mip0
|
||||
uint32_t upsample = 1 << lod;
|
||||
uint32_t destWidth = dstMip.m_width / 2;
|
||||
uint32_t destHeight = dstMip.m_height / 2;
|
||||
bimg::imageScaleAlphaToCoverage(bimg::TextureFormat::RGBA8
|
||||
, destWidth
|
||||
, destHeight
|
||||
, destWidth * 4
|
||||
, rgba
|
||||
, coverage
|
||||
, alphaRef
|
||||
, upsample
|
||||
);
|
||||
|
||||
bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
|
||||
dstData = const_cast<uint8_t*>(dstMip.m_data);
|
||||
|
||||
bimg::imageEncodeFromRgba8(
|
||||
_allocator
|
||||
, dstData
|
||||
, rgba
|
||||
, dstMip.m_width
|
||||
, dstMip.m_height
|
||||
, dstMip.m_depth
|
||||
, bimg::TextureFormat::A8
|
||||
, _options.quality
|
||||
, _err
|
||||
);
|
||||
}
|
||||
|
||||
BX_FREE(_allocator, rgbaTemp);
|
||||
}
|
||||
}
|
||||
// RGBA8
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user