mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Drop support for storing mipmap data alongside IImage
This commit is contained in:
parent
03affa1bbb
commit
38c3876c4e
4 changed files with 19 additions and 164 deletions
|
@ -25,7 +25,7 @@ class IImage : public virtual IReferenceCounted
|
|||
public:
|
||||
//! constructor
|
||||
IImage(ECOLOR_FORMAT format, const core::dimension2d<u32> &size, bool deleteMemory) :
|
||||
Format(format), Size(size), Data(0), MipMapsData(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory), DeleteMipMapsMemory(false)
|
||||
Format(format), Size(size), Data(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory)
|
||||
{
|
||||
BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8;
|
||||
Pitch = BytesPerPixel * Size.Width;
|
||||
|
@ -36,9 +36,6 @@ public:
|
|||
{
|
||||
if (DeleteMemory)
|
||||
delete[] Data;
|
||||
|
||||
if (DeleteMipMapsMemory)
|
||||
delete[] MipMapsData;
|
||||
}
|
||||
|
||||
//! Returns the color format
|
||||
|
@ -188,87 +185,6 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
//! Get mipmaps data.
|
||||
/** Note that different mip levels are just behind each other in memory block.
|
||||
So if you just get level 1 you also have the data for all other levels.
|
||||
There is no level 0 - use getData to get the original image data.
|
||||
*/
|
||||
void *getMipMapsData(irr::u32 mipLevel = 1) const
|
||||
{
|
||||
if (MipMapsData && mipLevel > 0) {
|
||||
size_t dataSize = 0;
|
||||
core::dimension2du mipSize(Size);
|
||||
u32 i = 1; // We want the start of data for this level, not end.
|
||||
|
||||
while (i != mipLevel) {
|
||||
if (mipSize.Width > 1)
|
||||
mipSize.Width >>= 1;
|
||||
|
||||
if (mipSize.Height > 1)
|
||||
mipSize.Height >>= 1;
|
||||
|
||||
dataSize += getDataSizeFromFormat(Format, mipSize.Width, mipSize.Height);
|
||||
|
||||
++i;
|
||||
if (mipSize.Width == 1 && mipSize.Height == 1 && i < mipLevel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MipMapsData + dataSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Set mipmaps data.
|
||||
/** This method allows you to put custom mipmaps data for
|
||||
image.
|
||||
\param data A byte array with pixel color information
|
||||
\param ownForeignMemory If true, the image will use the data
|
||||
pointer directly and own it afterward. If false, the memory
|
||||
will by copied internally.
|
||||
\param deleteMemory Whether the memory is deallocated upon
|
||||
destruction. */
|
||||
void setMipMapsData(void *data, bool ownForeignMemory)
|
||||
{
|
||||
if (data != MipMapsData) {
|
||||
if (DeleteMipMapsMemory) {
|
||||
delete[] MipMapsData;
|
||||
|
||||
DeleteMipMapsMemory = false;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
if (ownForeignMemory) {
|
||||
MipMapsData = static_cast<u8 *>(data);
|
||||
|
||||
DeleteMipMapsMemory = false;
|
||||
} else {
|
||||
u32 dataSize = 0;
|
||||
u32 width = Size.Width;
|
||||
u32 height = Size.Height;
|
||||
|
||||
do {
|
||||
if (width > 1)
|
||||
width >>= 1;
|
||||
|
||||
if (height > 1)
|
||||
height >>= 1;
|
||||
|
||||
dataSize += getDataSizeFromFormat(Format, width, height);
|
||||
} while (width != 1 || height != 1);
|
||||
|
||||
MipMapsData = new u8[dataSize];
|
||||
memcpy(MipMapsData, data, dataSize);
|
||||
|
||||
DeleteMipMapsMemory = true;
|
||||
}
|
||||
} else {
|
||||
MipMapsData = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns a pixel
|
||||
virtual SColor getPixel(u32 x, u32 y) const = 0;
|
||||
|
||||
|
@ -276,30 +192,24 @@ public:
|
|||
virtual void setPixel(u32 x, u32 y, const SColor &color, bool blend = false) = 0;
|
||||
|
||||
//! Copies this surface into another, if it has the exact same size and format.
|
||||
/** NOTE: mipmaps are ignored
|
||||
\return True if it was copied, false otherwise.
|
||||
/** \return True if it was copied, false otherwise.
|
||||
*/
|
||||
virtual bool copyToNoScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format = ECF_A8R8G8B8, u32 pitch = 0) const = 0;
|
||||
|
||||
//! Copies the image into the target, scaling the image to fit
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyToScaling(void *target, u32 width, u32 height, ECOLOR_FORMAT format = ECF_A8R8G8B8, u32 pitch = 0) = 0;
|
||||
|
||||
//! Copies the image into the target, scaling the image to fit
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyToScaling(IImage *target) = 0;
|
||||
|
||||
//! copies this surface into another
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyTo(IImage *target, const core::position2d<s32> &pos = core::position2d<s32>(0, 0)) = 0;
|
||||
|
||||
//! copies this surface into another
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyTo(IImage *target, const core::position2d<s32> &pos, const core::rect<s32> &sourceRect, const core::rect<s32> *clipRect = 0) = 0;
|
||||
|
||||
//! copies this surface into another, using the alpha mask and cliprect and a color to add with
|
||||
/** NOTE: mipmaps are ignored
|
||||
\param combineAlpha - When true then combine alpha channels. When false replace target image alpha with source image alpha.
|
||||
/** \param combineAlpha - When true then combine alpha channels. When false replace target image alpha with source image alpha.
|
||||
*/
|
||||
virtual void copyToWithAlpha(IImage *target, const core::position2d<s32> &pos,
|
||||
const core::rect<s32> &sourceRect, const SColor &color,
|
||||
|
@ -307,7 +217,6 @@ public:
|
|||
bool combineAlpha = false) = 0;
|
||||
|
||||
//! copies this surface into another, scaling it to fit, applying a box filter
|
||||
/** NOTE: mipmaps are ignored */
|
||||
virtual void copyToScalingBoxFilter(IImage *target, s32 bias = 0, bool blend = false) = 0;
|
||||
|
||||
//! fills the surface with given color
|
||||
|
@ -415,13 +324,11 @@ protected:
|
|||
core::dimension2d<u32> Size;
|
||||
|
||||
u8 *Data;
|
||||
u8 *MipMapsData;
|
||||
|
||||
u32 BytesPerPixel;
|
||||
u32 Pitch;
|
||||
|
||||
bool DeleteMemory;
|
||||
bool DeleteMipMapsMemory;
|
||||
};
|
||||
|
||||
} // end namespace video
|
||||
|
|
|
@ -166,9 +166,7 @@ public:
|
|||
only mode or read from in write only mode.
|
||||
Support for this feature depends on the driver, so don't rely on the
|
||||
texture being write-protected when locking with read-only, etc.
|
||||
\param mipmapLevel NOTE: Currently broken, sorry, we try if we can repair it for 1.9 release.
|
||||
Number of the mipmapLevel to lock. 0 is main texture.
|
||||
Non-existing levels will silently fail and return 0.
|
||||
\param mipmapLevel Number of the mipmapLevel to lock. 0 is main texture.
|
||||
\param layer It determines which cubemap face or texture array layer should be locked.
|
||||
\param lockFlags See E_TEXTURE_LOCK_FLAGS documentation.
|
||||
\return Returns a pointer to the pixel data. The format of the pixel can
|
||||
|
@ -184,14 +182,9 @@ public:
|
|||
|
||||
//! Regenerates the mip map levels of the texture.
|
||||
/** Required after modifying the texture, usually after calling unlock().
|
||||
\param data Optional parameter to pass in image data which will be
|
||||
used instead of the previously stored or automatically generated mipmap
|
||||
data. The data has to be a continuous pixel data for all mipmaps until
|
||||
1x1 pixel. Each mipmap has to be half the width and height of the previous
|
||||
level. At least one pixel will be always kept.
|
||||
\param layer It informs a texture about which cubemap or texture array layer
|
||||
needs mipmap regeneration. */
|
||||
virtual void regenerateMipMapLevels(void *data = 0, u32 layer = 0) = 0;
|
||||
virtual void regenerateMipMapLevels(u32 layer = 0) = 0;
|
||||
|
||||
//! Get original size of the texture.
|
||||
/** The texture is usually scaled, if it was created with an unoptimal
|
||||
|
|
|
@ -616,7 +616,7 @@ protected:
|
|||
|
||||
void *lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0, u32 layer = 0, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) override { return 0; }
|
||||
void unlock() override {}
|
||||
void regenerateMipMapLevels(void *data = 0, u32 layer = 0) override {}
|
||||
void regenerateMipMapLevels(u32 layer = 0) override {}
|
||||
};
|
||||
core::array<SSurface> Textures;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
COpenGLCoreTexture(const io::path &name, const std::vector<IImage *> &srcImages, E_TEXTURE_TYPE type, TOpenGLDriver *driver) :
|
||||
ITexture(name, type), Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), MSAA(0), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0),
|
||||
KeepImage(false), MipLevelStored(0), LegacyAutoGenerateMipMaps(false)
|
||||
KeepImage(false), MipLevelStored(0)
|
||||
{
|
||||
_IRR_DEBUG_BREAK_IF(srcImages.empty())
|
||||
|
||||
|
@ -82,15 +82,6 @@ public:
|
|||
srcImages[i]->copyTo(Images[i]);
|
||||
else
|
||||
srcImages[i]->copyToScaling(Images[i]);
|
||||
|
||||
if (srcImages[i]->getMipMapsData()) {
|
||||
if (OriginalSize == Size && OriginalColorFormat == ColorFormat) {
|
||||
Images[i]->setMipMapsData(srcImages[i]->getMipMapsData(), false);
|
||||
} else {
|
||||
// TODO: handle at least mipmap with changing color format
|
||||
os::Printer::log("COpenGLCoreTexture: Can't handle format changes for mipmap data. Mipmap data dropped", ELL_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tmpImages = &Images;
|
||||
|
@ -122,12 +113,9 @@ public:
|
|||
for (size_t i = 0; i < tmpImages->size(); ++i)
|
||||
uploadTexture(true, i, 0, (*tmpImages)[i]->getData());
|
||||
|
||||
if (HasMipMaps && !LegacyAutoGenerateMipMaps) {
|
||||
// Create mipmaps (either from image mipmaps or generate them)
|
||||
for (size_t i = 0; i < tmpImages->size(); ++i) {
|
||||
void *mipmapsData = (*tmpImages)[i]->getMipMapsData();
|
||||
regenerateMipMapLevels(mipmapsData, i);
|
||||
}
|
||||
if (HasMipMaps) {
|
||||
for (size_t i = 0; i < tmpImages->size(); ++i)
|
||||
regenerateMipMapLevels(i);
|
||||
}
|
||||
|
||||
if (!KeepImage) {
|
||||
|
@ -149,7 +137,7 @@ public:
|
|||
ITexture(name, type),
|
||||
Driver(driver), TextureType(GL_TEXTURE_2D),
|
||||
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA), PixelType(GL_UNSIGNED_BYTE), MSAA(msaa), Converter(0), LockReadOnly(false), LockImage(0), LockLayer(0), KeepImage(false),
|
||||
MipLevelStored(0), LegacyAutoGenerateMipMaps(false)
|
||||
MipLevelStored(0)
|
||||
{
|
||||
DriverType = Driver->getDriverType();
|
||||
TextureType = TextureTypeIrrToGL(Type);
|
||||
|
@ -279,7 +267,7 @@ public:
|
|||
void *lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel = 0, u32 layer = 0, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) override
|
||||
{
|
||||
if (LockImage)
|
||||
return getLockImageData(MipLevelStored);
|
||||
return LockImage->getData();
|
||||
|
||||
if (IImage::isCompressedFormat(ColorFormat))
|
||||
return 0;
|
||||
|
@ -291,7 +279,7 @@ public:
|
|||
if (KeepImage) {
|
||||
_IRR_DEBUG_BREAK_IF(LockLayer > Images.size())
|
||||
|
||||
if (mipmapLevel == 0 || (Images[LockLayer] && Images[LockLayer]->getMipMapsData(mipmapLevel))) {
|
||||
if (mipmapLevel == 0) {
|
||||
LockImage = Images[LockLayer];
|
||||
LockImage->grab();
|
||||
}
|
||||
|
@ -301,7 +289,6 @@ public:
|
|||
core::dimension2d<u32> lockImageSize(IImage::getMipMapsSize(Size, MipLevelStored));
|
||||
_IRR_DEBUG_BREAK_IF(lockImageSize.Width == 0 || lockImageSize.Height == 0)
|
||||
|
||||
// note: we save mipmap data also in the image because IImage doesn't allow saving single mipmap levels to the mipmap data
|
||||
LockImage = Driver->createImage(ColorFormat, lockImageSize);
|
||||
|
||||
if (LockImage && mode != ETLM_WRITE_ONLY) {
|
||||
|
@ -403,7 +390,7 @@ public:
|
|||
TEST_GL_ERROR(Driver);
|
||||
}
|
||||
|
||||
return (LockImage) ? getLockImageData(MipLevelStored) : 0;
|
||||
return (LockImage) ? LockImage->getData() : 0;
|
||||
}
|
||||
|
||||
void unlock() override
|
||||
|
@ -415,7 +402,7 @@ public:
|
|||
const COpenGLCoreTexture *prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, this);
|
||||
|
||||
uploadTexture(false, LockLayer, MipLevelStored, getLockImageData(MipLevelStored));
|
||||
uploadTexture(false, LockLayer, MipLevelStored, LockImage->getData());
|
||||
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
|
||||
}
|
||||
|
@ -427,39 +414,16 @@ public:
|
|||
LockLayer = 0;
|
||||
}
|
||||
|
||||
void regenerateMipMapLevels(void *data = 0, u32 layer = 0) override
|
||||
void regenerateMipMapLevels(u32 layer = 0) override
|
||||
{
|
||||
if (!HasMipMaps || LegacyAutoGenerateMipMaps || (Size.Width <= 1 && Size.Height <= 1))
|
||||
if (!HasMipMaps || (Size.Width <= 1 && Size.Height <= 1))
|
||||
return;
|
||||
|
||||
const COpenGLCoreTexture *prevTexture = Driver->getCacheHandler()->getTextureCache().get(0);
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, this);
|
||||
|
||||
if (data) {
|
||||
u32 width = Size.Width;
|
||||
u32 height = Size.Height;
|
||||
u8 *tmpData = static_cast<u8 *>(data);
|
||||
u32 dataSize = 0;
|
||||
u32 level = 0;
|
||||
|
||||
do {
|
||||
if (width > 1)
|
||||
width >>= 1;
|
||||
|
||||
if (height > 1)
|
||||
height >>= 1;
|
||||
|
||||
dataSize = IImage::getDataSizeFromFormat(ColorFormat, width, height);
|
||||
++level;
|
||||
|
||||
uploadTexture(true, layer, level, tmpData);
|
||||
|
||||
tmpData += dataSize;
|
||||
} while (width != 1 || height != 1);
|
||||
} else {
|
||||
Driver->irrGlGenerateMipmap(TextureType);
|
||||
TEST_GL_ERROR(Driver);
|
||||
}
|
||||
Driver->irrGlGenerateMipmap(TextureType);
|
||||
TEST_GL_ERROR(Driver);
|
||||
|
||||
Driver->getCacheHandler()->getTextureCache().set(0, prevTexture);
|
||||
}
|
||||
|
@ -480,14 +444,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void *getLockImageData(irr::u32 miplevel) const
|
||||
{
|
||||
if (KeepImage && MipLevelStored > 0 && LockImage->getMipMapsData(MipLevelStored)) {
|
||||
return LockImage->getMipMapsData(MipLevelStored);
|
||||
}
|
||||
return LockImage->getData();
|
||||
}
|
||||
|
||||
ECOLOR_FORMAT getBestColorFormat(ECOLOR_FORMAT format)
|
||||
{
|
||||
// We only try for to adapt "simple" formats
|
||||
|
@ -671,7 +627,6 @@ protected:
|
|||
std::vector<IImage*> Images;
|
||||
|
||||
u8 MipLevelStored;
|
||||
bool LegacyAutoGenerateMipMaps;
|
||||
|
||||
mutable SStatesCache StatesCache;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue