|
@@ -34,37 +34,17 @@ namespace opengl
|
|
|
{
|
|
|
|
|
|
Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings)
|
|
|
- : love::graphics::Image(Slices(textype), settings, false)
|
|
|
+ : love::graphics::Image(textype, format, width, height, slices, settings)
|
|
|
, texture(0)
|
|
|
- , compressed(false)
|
|
|
- , usingDefaultTexture(false)
|
|
|
- , textureMemorySize(0)
|
|
|
{
|
|
|
- if (isPixelFormatCompressed(format))
|
|
|
- throw love::Exception("This constructor is only supported for non-compressed pixel formats.");
|
|
|
-
|
|
|
- if (textype == TEXTURE_VOLUME)
|
|
|
- depth = slices;
|
|
|
- else if (textype == TEXTURE_2D_ARRAY)
|
|
|
- layers = slices;
|
|
|
-
|
|
|
- init(format, width, height, settings);
|
|
|
+ loadVolatile();
|
|
|
}
|
|
|
|
|
|
Image::Image(const Slices &slices, const Settings &settings)
|
|
|
- : love::graphics::Image(slices, settings, true)
|
|
|
+ : love::graphics::Image(slices, settings)
|
|
|
, texture(0)
|
|
|
- , compressed(false)
|
|
|
- , usingDefaultTexture(false)
|
|
|
- , textureMemorySize(0)
|
|
|
{
|
|
|
- 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);
|
|
|
+ loadVolatile();
|
|
|
}
|
|
|
|
|
|
Image::~Image()
|
|
@@ -72,33 +52,13 @@ Image::~Image()
|
|
|
unloadVolatile();
|
|
|
}
|
|
|
|
|
|
-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;
|
|
|
- compressed = isPixelFormatCompressed(format);
|
|
|
-
|
|
|
- if (compressed && mipmapsType == MIPMAPS_GENERATED)
|
|
|
- mipmapsType = MIPMAPS_NONE;
|
|
|
-
|
|
|
- if (getMipmapCount() > 1)
|
|
|
- filter.mipmap = defaultMipmapFilter;
|
|
|
-
|
|
|
- initQuad();
|
|
|
- loadVolatile();
|
|
|
-}
|
|
|
-
|
|
|
void Image::generateMipmaps()
|
|
|
{
|
|
|
if (getMipmapCount() > 1 && !isCompressed() &&
|
|
|
(GLAD_ES_VERSION_2_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_EXT_framebuffer_object))
|
|
|
{
|
|
|
+ gl.bindTextureToUnit(this, 0, false);
|
|
|
+
|
|
|
GLenum gltextype = OpenGL::getGLTextureType(texType);
|
|
|
|
|
|
if (gl.bugs.generateMipmapsRequiresTexture2DEnable)
|
|
@@ -189,6 +149,10 @@ void Image::loadData()
|
|
|
|
|
|
void Image::uploadByteData(PixelFormat pixelformat, const void *data, size_t size, const Rect &r, int level, int slice)
|
|
|
{
|
|
|
+ OpenGL::TempDebugGroup debuggroup("Image data upload");
|
|
|
+
|
|
|
+ gl.bindTextureToUnit(this, 0, false);
|
|
|
+
|
|
|
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat, false, sRGB);
|
|
|
GLenum gltarget = OpenGL::getGLTextureType(texType);
|
|
|
|
|
@@ -214,18 +178,6 @@ void Image::uploadByteData(PixelFormat pixelformat, const void *data, size_t siz
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-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);
|
|
|
-}
|
|
|
-
|
|
|
bool Image::loadVolatile()
|
|
|
{
|
|
|
if (texture != 0)
|
|
@@ -343,67 +295,6 @@ void Image::unloadVolatile()
|
|
|
textureMemorySize = 0;
|
|
|
}
|
|
|
|
|
|
-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);
|
|
|
-
|
|
|
- OpenGL::TempDebugGroup debuggroup("Image replace pixels");
|
|
|
-
|
|
|
- gl.bindTextureToUnit(this, 0, false);
|
|
|
-
|
|
|
- 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();
|
|
|
-
|
|
|
- OpenGL::TempDebugGroup debuggroup("Image replace pixels");
|
|
|
-
|
|
|
- gl.bindTextureToUnit(this, 0, false);
|
|
|
-
|
|
|
- uploadByteData(format, data, size, rect, mipmap, slice);
|
|
|
-
|
|
|
- if (reloadmipmaps && mipmap == 0 && getMipmapCount() > 1)
|
|
|
- generateMipmaps();
|
|
|
-}
|
|
|
-
|
|
|
ptrdiff_t Image::getHandle() const
|
|
|
{
|
|
|
return texture;
|
|
@@ -476,8 +367,9 @@ bool Image::setMipmapSharpness(float sharpness)
|
|
|
Graphics::flushStreamDrawsGlobal();
|
|
|
|
|
|
float maxbias = gl.getMaxLODBias();
|
|
|
+
|
|
|
if (maxbias > 0.01f)
|
|
|
- maxbias -= 0.0f;
|
|
|
+ maxbias -= 0.01f;
|
|
|
|
|
|
mipmapSharpness = std::min(std::max(sharpness, -maxbias), maxbias);
|
|
|
|
|
@@ -489,21 +381,6 @@ bool Image::setMipmapSharpness(float sharpness)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool Image::isFormatLinear() const
|
|
|
-{
|
|
|
- return isGammaCorrect() && !sRGB;
|
|
|
-}
|
|
|
-
|
|
|
-bool Image::isCompressed() const
|
|
|
-{
|
|
|
- return compressed;
|
|
|
-}
|
|
|
-
|
|
|
-Image::MipmapsType Image::getMipmapsType() const
|
|
|
-{
|
|
|
- return mipmapsType;
|
|
|
-}
|
|
|
-
|
|
|
bool Image::isFormatSupported(PixelFormat pixelformat)
|
|
|
{
|
|
|
return OpenGL::isPixelFormatSupported(pixelformat, false, true, false);
|