mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Move more backend-agnostic code out of the love.graphics opengl implementation files.
--HG-- branch : minor
This commit is contained in:
@@ -39,6 +39,8 @@ Image::Image(const Slices &data, const Settings &settings, bool validatedata)
|
||||
, data(data)
|
||||
, mipmapsType(settings.mipmaps ? MIPMAPS_GENERATED : MIPMAPS_NONE)
|
||||
, sRGB(isGammaCorrect() && !settings.linear)
|
||||
, usingDefaultTexture(false)
|
||||
, textureMemorySize(0)
|
||||
{
|
||||
if (validatedata && data.validate() == MIPMAPS_DATA)
|
||||
mipmapsType = MIPMAPS_DATA;
|
||||
@@ -46,11 +48,137 @@ Image::Image(const Slices &data, const Settings &settings, bool validatedata)
|
||||
++imageCount;
|
||||
}
|
||||
|
||||
Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
|
||||
: Image(Slices(textype), settings, false)
|
||||
{
|
||||
if (isPixelFormatCompressed(format))
|
||||
throw love::Exception("This constructor is only supported for non-compressed pixel formats.");
|
||||
|
||||
if (textype == TEXTURE_2D_ARRAY)
|
||||
layers = slices;
|
||||
else if (textype == TEXTURE_VOLUME)
|
||||
depth = slices;
|
||||
|
||||
init(format, width, height, settings);
|
||||
}
|
||||
|
||||
Image::Image(const Slices &slices, const Settings &settings)
|
||||
: Image(slices, settings, true)
|
||||
{
|
||||
if (texType == TEXTURE_2D_ARRAY)
|
||||
this->layers = data.getSliceCount();
|
||||
else if (texType == TEXTURE_VOLUME)
|
||||
this->depth = data.getSliceCount();
|
||||
|
||||
love::image::ImageDataBase *slice = data.get(0, 0);
|
||||
init(slice->getFormat(), slice->getWidth(), slice->getHeight(), settings);
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
--imageCount;
|
||||
}
|
||||
|
||||
void Image::init(PixelFormat fmt, int w, int h, const Settings &settings)
|
||||
{
|
||||
pixelWidth = w;
|
||||
pixelHeight = h;
|
||||
|
||||
width = (int) (pixelWidth / settings.pixeldensity + 0.5);
|
||||
height = (int) (pixelHeight / settings.pixeldensity + 0.5);
|
||||
|
||||
mipmapCount = mipmapsType == MIPMAPS_NONE ? 1 : getMipmapCount(w, h);
|
||||
format = fmt;
|
||||
|
||||
if (isCompressed() && mipmapsType == MIPMAPS_GENERATED)
|
||||
mipmapsType = MIPMAPS_NONE;
|
||||
|
||||
if (getMipmapCount() > 1)
|
||||
filter.mipmap = defaultMipmapFilter;
|
||||
|
||||
initQuad();
|
||||
}
|
||||
|
||||
void Image::uploadImageData(love::image::ImageDataBase *d, int level, int slice)
|
||||
{
|
||||
love::image::ImageData *id = dynamic_cast<love::image::ImageData *>(d);
|
||||
|
||||
love::thread::EmptyLock lock;
|
||||
if (id != nullptr)
|
||||
lock.setLock(id->getMutex());
|
||||
|
||||
Rect rect = {0, 0, d->getWidth(), d->getHeight()};
|
||||
uploadByteData(d->getFormat(), d->getData(), d->getSize(), rect, level, slice);
|
||||
}
|
||||
|
||||
void Image::replacePixels(love::image::ImageDataBase *d, int slice, int mipmap, bool reloadmipmaps)
|
||||
{
|
||||
// No effect if the texture hasn't been created yet.
|
||||
if (getHandle() == 0 || usingDefaultTexture)
|
||||
return;
|
||||
|
||||
if (d->getFormat() != getPixelFormat())
|
||||
throw love::Exception("Pixel formats must match.");
|
||||
|
||||
if (mipmap < 0 || (mipmapsType != MIPMAPS_DATA && mipmap > 0) || mipmap >= getMipmapCount())
|
||||
throw love::Exception("Invalid image mipmap index.");
|
||||
|
||||
if (slice < 0 || (texType == TEXTURE_CUBE && slice >= 6)
|
||||
|| (texType == TEXTURE_VOLUME && slice >= std::max(getDepth() >> mipmap, 1))
|
||||
|| (texType == TEXTURE_2D_ARRAY && slice >= getLayerCount()))
|
||||
{
|
||||
throw love::Exception("Invalid image slice index.");
|
||||
}
|
||||
|
||||
love::image::ImageDataBase *oldd = data.get(slice, mipmap);
|
||||
|
||||
if (oldd == nullptr)
|
||||
throw love::Exception("Image does not store ImageData!");
|
||||
|
||||
int w = d->getWidth();
|
||||
int h = d->getHeight();
|
||||
|
||||
if (w != oldd->getWidth() || h != oldd->getHeight())
|
||||
throw love::Exception("Dimensions must match the texture's dimensions for the specified mipmap level.");
|
||||
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
d->retain();
|
||||
oldd->release();
|
||||
|
||||
data.set(slice, mipmap, d);
|
||||
|
||||
uploadImageData(d, mipmap, slice);
|
||||
|
||||
if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
|
||||
generateMipmaps();
|
||||
}
|
||||
|
||||
void Image::replacePixels(const void *data, size_t size, const Rect &rect, int slice, int mipmap, bool reloadmipmaps)
|
||||
{
|
||||
Graphics::flushStreamDrawsGlobal();
|
||||
|
||||
uploadByteData(format, data, size, rect, mipmap, slice);
|
||||
|
||||
if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
|
||||
generateMipmaps();
|
||||
}
|
||||
|
||||
bool Image::isCompressed() const
|
||||
{
|
||||
return isPixelFormatCompressed(format);
|
||||
}
|
||||
|
||||
bool Image::isFormatLinear() const
|
||||
{
|
||||
return isGammaCorrect() && !sRGB;
|
||||
}
|
||||
|
||||
Image::MipmapsType Image::getMipmapsType() const
|
||||
{
|
||||
return mipmapsType;
|
||||
}
|
||||
|
||||
Image::Slices::Slices(TextureType textype)
|
||||
: textureType(textype)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user