mirror of
https://github.com/love2d/love.git
synced 2026-08-16 16:20:42 +02:00
Move some Canvas code to Texture, devirtualize Texture::draw.
This commit is contained in:
@@ -27,13 +27,15 @@ namespace graphics
|
||||
{
|
||||
|
||||
love::Type Canvas::type("Canvas", &Texture::type);
|
||||
int Canvas::canvasCount = 0;
|
||||
|
||||
Canvas::Canvas(const Settings &settings)
|
||||
: Texture(settings.type)
|
||||
{
|
||||
this->settings = settings;
|
||||
|
||||
renderTarget = true;
|
||||
sRGB = false;
|
||||
|
||||
width = settings.width;
|
||||
height = settings.height;
|
||||
pixelWidth = (int) ((width * settings.dpiScale) + 0.5);
|
||||
@@ -69,7 +71,7 @@ Canvas::Canvas(const Settings &settings)
|
||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
const Graphics::Capabilities &caps = gfx->getCapabilities();
|
||||
|
||||
if (!gfx->isPixelFormatSupported(format, true, readable, false))
|
||||
if (!gfx->isPixelFormatSupported(format, renderTarget, readable, sRGB))
|
||||
{
|
||||
const char *fstr = "rgba8";
|
||||
const char *readablestr = "";
|
||||
@@ -93,13 +95,10 @@ Canvas::Canvas(const Settings &settings)
|
||||
}
|
||||
|
||||
validateDimensions(true);
|
||||
|
||||
canvasCount++;
|
||||
}
|
||||
|
||||
Canvas::~Canvas()
|
||||
{
|
||||
canvasCount--;
|
||||
}
|
||||
|
||||
Canvas::MipmapMode Canvas::getMipmapMode() const
|
||||
@@ -131,12 +130,10 @@ love::image::ImageData *Canvas::newImageData(love::image::Image *module, int sli
|
||||
}
|
||||
|
||||
Graphics *gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr && gfx->isCanvasActive(this))
|
||||
if (gfx != nullptr && gfx->isRenderTargetActive(this))
|
||||
throw love::Exception("Canvas:newImageData cannot be called while that Canvas is currently active.");
|
||||
|
||||
PixelFormat dataformat = getPixelFormat();
|
||||
if (dataformat == PIXELFORMAT_sRGBA8_UNORM)
|
||||
dataformat = PIXELFORMAT_RGBA8_UNORM;
|
||||
PixelFormat dataformat = getLinearPixelFormat(getPixelFormat());
|
||||
|
||||
if (!image::ImageData::validPixelFormat(dataformat))
|
||||
{
|
||||
@@ -148,22 +145,6 @@ love::image::ImageData *Canvas::newImageData(love::image::Image *module, int sli
|
||||
return module->newImageData(r.w, r.h, dataformat);
|
||||
}
|
||||
|
||||
void Canvas::draw(Graphics *gfx, Quad *q, const Matrix4 &t)
|
||||
{
|
||||
if (gfx->isCanvasActive(this))
|
||||
throw love::Exception("Cannot render a Canvas to itself!");
|
||||
|
||||
Texture::draw(gfx, q, t);
|
||||
}
|
||||
|
||||
void Canvas::drawLayer(Graphics *gfx, int layer, Quad *quad, const Matrix4 &m)
|
||||
{
|
||||
if (gfx->isCanvasActive(this, layer))
|
||||
throw love::Exception("Cannot render a Canvas to itself!");
|
||||
|
||||
Texture::drawLayer(gfx, layer, quad, m);
|
||||
}
|
||||
|
||||
bool Canvas::getConstant(const char *in, MipmapMode &out)
|
||||
{
|
||||
return mipmapModes.find(in, out);
|
||||
|
||||
@@ -81,16 +81,10 @@ public:
|
||||
int getRequestedMSAA() const;
|
||||
|
||||
virtual love::image::ImageData *newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect);
|
||||
virtual void generateMipmaps() = 0;
|
||||
|
||||
virtual int getMSAA() const = 0;
|
||||
virtual ptrdiff_t getRenderTargetHandle() const = 0;
|
||||
|
||||
void draw(Graphics *gfx, Quad *q, const Matrix4 &t) override;
|
||||
void drawLayer(Graphics *gfx, int layer, Quad *q, const Matrix4 &t) override;
|
||||
|
||||
static int canvasCount;
|
||||
|
||||
static bool getConstant(const char *in, MipmapMode &out);
|
||||
static bool getConstant(MipmapMode in, const char *&out);
|
||||
static std::vector<std::string> getConstants(MipmapMode);
|
||||
|
||||
@@ -761,33 +761,33 @@ bool Graphics::isCanvasActive() const
|
||||
return !rts.colors.empty() || rts.depthStencil.canvas != nullptr;
|
||||
}
|
||||
|
||||
bool Graphics::isCanvasActive(love::graphics::Canvas *canvas) const
|
||||
bool Graphics::isRenderTargetActive(Texture *texture) const
|
||||
{
|
||||
const auto &rts = states.back().renderTargets;
|
||||
|
||||
for (const auto &rt : rts.colors)
|
||||
{
|
||||
if (rt.canvas.get() == canvas)
|
||||
if (rt.canvas.get() == texture)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rts.depthStencil.canvas.get() == canvas)
|
||||
if (rts.depthStencil.canvas.get() == texture)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Graphics::isCanvasActive(Canvas *canvas, int slice) const
|
||||
bool Graphics::isRenderTargetActive(Texture *texture, int slice) const
|
||||
{
|
||||
const auto &rts = states.back().renderTargets;
|
||||
|
||||
for (const auto &rt : rts.colors)
|
||||
{
|
||||
if (rt.canvas.get() == canvas && rt.slice == slice)
|
||||
if (rt.canvas.get() == texture && rt.slice == slice)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rts.depthStencil.canvas.get() == canvas && rts.depthStencil.slice == slice)
|
||||
if (rts.depthStencil.canvas.get() == texture && rts.depthStencil.slice == slice)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1593,8 +1593,7 @@ Graphics::Stats Graphics::getStats() const
|
||||
|
||||
stats.canvasSwitches = canvasSwitchCount;
|
||||
stats.drawCallsBatched = drawCallsBatched;
|
||||
stats.canvases = Canvas::canvasCount;
|
||||
stats.images = Image::imageCount;
|
||||
stats.textures = Texture::textureCount;
|
||||
stats.fonts = Font::fontCount;
|
||||
stats.textureMemory = Texture::totalGraphicsMemory;
|
||||
|
||||
|
||||
@@ -202,8 +202,7 @@ public:
|
||||
int drawCallsBatched;
|
||||
int canvasSwitches;
|
||||
int shaderSwitches;
|
||||
int canvases;
|
||||
int images;
|
||||
int textures;
|
||||
int fonts;
|
||||
int64 textureMemory;
|
||||
};
|
||||
@@ -551,8 +550,8 @@ public:
|
||||
|
||||
RenderTargets getCanvas() const;
|
||||
bool isCanvasActive() const;
|
||||
bool isCanvasActive(Canvas *canvas) const;
|
||||
bool isCanvasActive(Canvas *canvas, int slice) const;
|
||||
bool isRenderTargetActive(Texture *texture) const;
|
||||
bool isRenderTargetActive(Texture *texture, int slice) const;
|
||||
|
||||
/**
|
||||
* Scissor defines a box such that everything outside that box is discarded
|
||||
@@ -781,7 +780,7 @@ public:
|
||||
/**
|
||||
* Converts PIXELFORMAT_NORMAL and PIXELFORMAT_HDR into a real format.
|
||||
**/
|
||||
virtual PixelFormat getSizedFormat(PixelFormat format) const = 0;
|
||||
virtual PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable, bool sRGB) const = 0;
|
||||
|
||||
/**
|
||||
* Gets whether the specified pixel format is supported.
|
||||
|
||||
@@ -31,15 +31,14 @@ namespace graphics
|
||||
|
||||
love::Type Image::type("Image", &Texture::type);
|
||||
|
||||
int Image::imageCount = 0;
|
||||
|
||||
Image::Image(const Slices &data, const Settings &settings, bool validatedata)
|
||||
: Texture(data.getTextureType())
|
||||
, settings(settings)
|
||||
, mipmapsType(settings.mipmaps ? MIPMAPS_GENERATED : MIPMAPS_NONE)
|
||||
, sRGB(isGammaCorrect() && !settings.linear)
|
||||
, usingDefaultTexture(false)
|
||||
{
|
||||
renderTarget = false;
|
||||
sRGB = isGammaCorrect() && !settings.linear;
|
||||
if (validatedata && data.validate() && data.getMipmapCount() > 1)
|
||||
mipmapsType = MIPMAPS_DATA;
|
||||
}
|
||||
@@ -72,13 +71,12 @@ Image::Image(const Slices &slices, const Settings &settings)
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
--imageCount;
|
||||
}
|
||||
|
||||
void Image::init(PixelFormat fmt, int w, int h, const Settings &settings)
|
||||
{
|
||||
Graphics *gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr && !gfx->isPixelFormatSupported(fmt, false, true, sRGB))
|
||||
if (gfx != nullptr && !gfx->isPixelFormatSupported(fmt, renderTarget, readable, sRGB))
|
||||
{
|
||||
const char *str;
|
||||
if (love::getConstant(fmt, str))
|
||||
@@ -104,8 +102,6 @@ void Image::init(PixelFormat fmt, int w, int h, const Settings &settings)
|
||||
mipmapCount = mipmapsType == MIPMAPS_NONE ? 1 : getTotalMipmapCount(w, h, depth);
|
||||
|
||||
initQuad();
|
||||
|
||||
++imageCount;
|
||||
}
|
||||
|
||||
void Image::uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y)
|
||||
@@ -172,16 +168,6 @@ void Image::replacePixels(const void *data, size_t size, int slice, int mipmap,
|
||||
generateMipmaps();
|
||||
}
|
||||
|
||||
bool Image::isCompressed() const
|
||||
{
|
||||
return isPixelFormatCompressed(format);
|
||||
}
|
||||
|
||||
bool Image::isFormatLinear() const
|
||||
{
|
||||
return isGammaCorrect() && !sRGB && format != PIXELFORMAT_sRGBA8_UNORM;
|
||||
}
|
||||
|
||||
Image::MipmapsType Image::getMipmapsType() const
|
||||
{
|
||||
return mipmapsType;
|
||||
|
||||
@@ -58,11 +58,8 @@ public:
|
||||
void replacePixels(const void *data, size_t size, int slice, int mipmap, const Rect &rect, bool reloadmipmaps);
|
||||
|
||||
bool isFormatLinear() const;
|
||||
bool isCompressed() const;
|
||||
MipmapsType getMipmapsType() const;
|
||||
|
||||
static int imageCount;
|
||||
|
||||
static bool getConstant(const char *in, SettingType &out);
|
||||
static bool getConstant(SettingType in, const char *&out);
|
||||
static const char *getConstant(SettingType in);
|
||||
@@ -76,13 +73,10 @@ protected:
|
||||
void uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y);
|
||||
virtual void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) = 0;
|
||||
|
||||
virtual void generateMipmaps() = 0;
|
||||
|
||||
// The settings used to initialize this Image.
|
||||
Settings settings;
|
||||
|
||||
MipmapsType mipmapsType;
|
||||
bool sRGB;
|
||||
|
||||
// True if the image wasn't able to be properly created and it had to fall
|
||||
// back to a default texture.
|
||||
|
||||
@@ -156,12 +156,15 @@ std::vector<std::string> SamplerState::getConstants(WrapMode)
|
||||
}
|
||||
|
||||
love::Type Texture::type("Texture", &Drawable::type);
|
||||
int Texture::textureCount = 0;
|
||||
int64 Texture::totalGraphicsMemory = 0;
|
||||
|
||||
Texture::Texture(TextureType texType)
|
||||
: texType(texType)
|
||||
, format(PIXELFORMAT_UNKNOWN)
|
||||
, renderTarget(false)
|
||||
, readable(true)
|
||||
, sRGB(false)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, depth(1)
|
||||
@@ -175,10 +178,12 @@ Texture::Texture(TextureType texType)
|
||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
samplerState = gfx->getDefaultSamplerState();
|
||||
++textureCount;
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
--textureCount;
|
||||
setGraphicsMemorySize(0);
|
||||
}
|
||||
|
||||
@@ -207,11 +212,26 @@ PixelFormat Texture::getPixelFormat() const
|
||||
return format;
|
||||
}
|
||||
|
||||
bool Texture::isRenderTarget() const
|
||||
{
|
||||
return renderTarget;
|
||||
}
|
||||
|
||||
bool Texture::isReadable() const
|
||||
{
|
||||
return readable;
|
||||
}
|
||||
|
||||
bool Texture::isCompressed() const
|
||||
{
|
||||
return isPixelFormatCompressed(format);
|
||||
}
|
||||
|
||||
bool Texture::isFormatLinear() const
|
||||
{
|
||||
return isGammaCorrect() && !sRGB && format != PIXELFORMAT_sRGBA8_UNORM;
|
||||
}
|
||||
|
||||
bool Texture::isValidSlice(int slice) const
|
||||
{
|
||||
if (slice < 0)
|
||||
@@ -241,6 +261,9 @@ void Texture::draw(Graphics *gfx, Quad *q, const Matrix4 &localTransform)
|
||||
if (!readable)
|
||||
throw love::Exception("Textures with non-readable formats cannot be drawn.");
|
||||
|
||||
if (renderTarget && gfx->isRenderTargetActive(this))
|
||||
throw love::Exception("Cannot render a Texture to itself.");
|
||||
|
||||
if (texType == TEXTURE_2D_ARRAY)
|
||||
{
|
||||
drawLayer(gfx, q->getLayer(), q, localTransform);
|
||||
@@ -291,6 +314,9 @@ void Texture::drawLayer(Graphics *gfx, int layer, Quad *q, const Matrix4 &m)
|
||||
if (!readable)
|
||||
throw love::Exception("Textures with non-readable formats cannot be drawn.");
|
||||
|
||||
if (renderTarget && gfx->isRenderTargetActive(this, layer))
|
||||
throw love::Exception("Cannot render a Texture to itself.");
|
||||
|
||||
if (texType != TEXTURE_2D_ARRAY)
|
||||
throw love::Exception("drawLayer can only be used with Array Textures!");
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ class Texture : public Drawable, public Resource
|
||||
public:
|
||||
|
||||
static love::Type type;
|
||||
static int textureCount;
|
||||
|
||||
enum MipmapsType
|
||||
{
|
||||
@@ -175,16 +176,20 @@ public:
|
||||
/**
|
||||
* Draws the texture using the specified transformation with a Quad applied.
|
||||
**/
|
||||
virtual void draw(Graphics *gfx, Quad *quad, const Matrix4 &m);
|
||||
void draw(Graphics *gfx, Quad *quad, const Matrix4 &m);
|
||||
|
||||
void drawLayer(Graphics *gfx, int layer, const Matrix4 &m);
|
||||
virtual void drawLayer(Graphics *gfx, int layer, Quad *quad, const Matrix4 &m);
|
||||
void drawLayer(Graphics *gfx, int layer, Quad *quad, const Matrix4 &m);
|
||||
|
||||
TextureType getTextureType() const;
|
||||
PixelFormat getPixelFormat() const;
|
||||
|
||||
bool isRenderTarget() const;
|
||||
bool isReadable() const;
|
||||
|
||||
bool isCompressed() const;
|
||||
bool isFormatLinear() const;
|
||||
|
||||
bool isValidSlice(int slice) const;
|
||||
|
||||
int getWidth(int mip = 0) const;
|
||||
@@ -201,6 +206,8 @@ public:
|
||||
virtual void setSamplerState(const SamplerState &s);
|
||||
const SamplerState &getSamplerState() const;
|
||||
|
||||
virtual void generateMipmaps() = 0;
|
||||
|
||||
Quad *getQuad() const;
|
||||
|
||||
static int getTotalMipmapCount(int w, int h);
|
||||
@@ -220,8 +227,11 @@ protected:
|
||||
TextureType texType;
|
||||
|
||||
PixelFormat format;
|
||||
bool renderTarget;
|
||||
bool readable;
|
||||
|
||||
bool sRGB;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat format, GLuint texture, int layers, int nb_mips)
|
||||
static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat format, GLuint texture, int layers)
|
||||
{
|
||||
// get currently bound fbo to reset to it later
|
||||
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
|
||||
@@ -60,42 +60,35 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
||||
// Make sure all faces and layers of the texture are initialized to
|
||||
// transparent black. This is unfortunately probably pretty slow for
|
||||
// 2D-array and 3D textures with a lot of layers...
|
||||
for (int mip = nb_mips - 1; mip >= 0; mip--)
|
||||
for (int layer = layers - 1; layer >= 0; layer--)
|
||||
{
|
||||
int nlayers = layers;
|
||||
if (texType == TEXTURE_VOLUME)
|
||||
nlayers = std::max(layers >> mip, 1);
|
||||
|
||||
for (int layer = nlayers - 1; layer >= 0; layer--)
|
||||
for (int face = faces - 1; face >= 0; face--)
|
||||
{
|
||||
for (int face = faces - 1; face >= 0; face--)
|
||||
for (GLenum attachment : fmt.framebufferAttachments)
|
||||
{
|
||||
for (GLenum attachment : fmt.framebufferAttachments)
|
||||
{
|
||||
if (attachment == GL_NONE)
|
||||
continue;
|
||||
if (attachment == GL_NONE)
|
||||
continue;
|
||||
|
||||
gl.framebufferTexture(attachment, texType, texture, mip, layer, face);
|
||||
}
|
||||
gl.framebufferTexture(attachment, texType, texture, 0, layer, face);
|
||||
}
|
||||
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
{
|
||||
bool hadDepthWrites = gl.hasDepthWrites();
|
||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||
gl.setDepthWrites(true);
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
{
|
||||
bool hadDepthWrites = gl.hasDepthWrites();
|
||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||
gl.setDepthWrites(true);
|
||||
|
||||
gl.clearDepth(1.0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
gl.clearDepth(1.0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
if (!hadDepthWrites)
|
||||
gl.setDepthWrites(hadDepthWrites);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
if (!hadDepthWrites)
|
||||
gl.setDepthWrites(hadDepthWrites);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,7 +191,7 @@ Canvas::Canvas(const Settings &settings)
|
||||
{
|
||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
format = gfx->getSizedFormat(format);
|
||||
format = gfx->getSizedFormat(format, renderTarget, readable, sRGB);
|
||||
|
||||
initQuad();
|
||||
loadVolatile();
|
||||
@@ -259,8 +252,8 @@ bool Canvas::loadVolatile()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a canvas-local FBO used for glReadPixels as well as MSAA blitting.
|
||||
status = createFBO(fbo, texType, format, texture, texType == TEXTURE_VOLUME ? depth : layers, mipmapCount);
|
||||
// Create a local FBO used for glReadPixels as well as MSAA blitting.
|
||||
status = createFBO(fbo, texType, format, texture, texType == TEXTURE_VOLUME ? depth : layers);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
@@ -287,6 +280,9 @@ bool Canvas::loadVolatile()
|
||||
|
||||
setGraphicsMemorySize(memsize);
|
||||
|
||||
if (getMipmapCount() > 1)
|
||||
generateMipmaps();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -390,11 +386,6 @@ void Canvas::generateMipmaps()
|
||||
glGenerateMipmap(gltextype);
|
||||
}
|
||||
|
||||
bool Canvas::isMultiFormatMultiCanvasSupported()
|
||||
{
|
||||
return gl.getMaxRenderTargets() > 1 && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
|
||||
}
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -68,8 +68,6 @@ public:
|
||||
return fbo;
|
||||
}
|
||||
|
||||
static bool isMultiFormatMultiCanvasSupported();
|
||||
|
||||
private:
|
||||
|
||||
GLuint fbo;
|
||||
|
||||
@@ -1362,7 +1362,7 @@ void Graphics::getAPIStats(int &shaderswitches) const
|
||||
|
||||
void Graphics::initCapabilities()
|
||||
{
|
||||
capabilities.features[FEATURE_MULTI_CANVAS_FORMATS] = Canvas::isMultiFormatMultiCanvasSupported();
|
||||
capabilities.features[FEATURE_MULTI_CANVAS_FORMATS] = gl.isMultiFormatMRTSupported();
|
||||
capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported();
|
||||
capabilities.features[FEATURE_BLENDMINMAX] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax;
|
||||
capabilities.features[FEATURE_LIGHTEN] = capabilities.features[FEATURE_BLENDMINMAX];
|
||||
@@ -1388,14 +1388,14 @@ void Graphics::initCapabilities()
|
||||
capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
|
||||
}
|
||||
|
||||
PixelFormat Graphics::getSizedFormat(PixelFormat format) const
|
||||
PixelFormat Graphics::getSizedFormat(PixelFormat format, bool rendertarget, bool readable, bool sRGB) const
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case PIXELFORMAT_NORMAL:
|
||||
if (isGammaCorrect())
|
||||
return PIXELFORMAT_sRGBA8_UNORM;
|
||||
else if (!OpenGL::isPixelFormatSupported(PIXELFORMAT_RGBA8_UNORM, true, true, false))
|
||||
else if (!OpenGL::isPixelFormatSupported(PIXELFORMAT_RGBA8_UNORM, rendertarget, readable, sRGB))
|
||||
// 32-bit render targets don't have guaranteed support on GLES2.
|
||||
return PIXELFORMAT_RGBA4_UNORM;
|
||||
else
|
||||
@@ -1409,14 +1409,14 @@ PixelFormat Graphics::getSizedFormat(PixelFormat format) const
|
||||
|
||||
bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, bool readable, bool sRGB)
|
||||
{
|
||||
format = getSizedFormat(format);
|
||||
|
||||
if (sRGB && format == PIXELFORMAT_RGBA8_UNORM)
|
||||
{
|
||||
format = PIXELFORMAT_sRGBA8_UNORM;
|
||||
sRGB = false;
|
||||
}
|
||||
|
||||
format = getSizedFormat(format, rendertarget, readable, sRGB);
|
||||
|
||||
OptionalBool &supported = supportedFormats[format][rendertarget ? 1 : 0][readable ? 1 : 0][sRGB ? 1 : 0];
|
||||
|
||||
if (supported.hasValue)
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
|
||||
void setWireframe(bool enable) override;
|
||||
|
||||
PixelFormat getSizedFormat(PixelFormat format) const override;
|
||||
PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable, bool sRGB) const override;
|
||||
bool isPixelFormatSupported(PixelFormat format, bool rendertarget, bool readable, bool sRGB = false) override;
|
||||
Renderer getRenderer() const override;
|
||||
RendererInfo getRendererInfo() const override;
|
||||
|
||||
@@ -105,9 +105,6 @@ void Image::loadData()
|
||||
if (!isCompressed())
|
||||
gl.rawTexStorage(texType, mipcount, format, sRGB, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers);
|
||||
|
||||
if (mipmapsType == MIPMAPS_GENERATED)
|
||||
mipcount = 1;
|
||||
|
||||
int w = pixelWidth;
|
||||
int h = pixelHeight;
|
||||
int d = depth;
|
||||
@@ -123,17 +120,23 @@ void Image::loadData()
|
||||
if (texType == TEXTURE_2D_ARRAY || texType == TEXTURE_VOLUME)
|
||||
{
|
||||
for (int slice = 0; slice < slices.getSliceCount(mip); slice++)
|
||||
mipsize += slices.get(slice, mip)->getSize();
|
||||
{
|
||||
auto id = slices.get(slice, mip);
|
||||
if (id != nullptr)
|
||||
mipsize += id->getSize();
|
||||
}
|
||||
}
|
||||
|
||||
GLenum gltarget = OpenGL::getGLTextureType(texType);
|
||||
glCompressedTexImage3D(gltarget, mip, fmt.internalformat, w, h, d, 0, mipsize, nullptr);
|
||||
if (mipsize > 0)
|
||||
{
|
||||
GLenum gltarget = OpenGL::getGLTextureType(texType);
|
||||
glCompressedTexImage3D(gltarget, mip, fmt.internalformat, w, h, d, 0, mipsize, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (int slice = 0; slice < slicecount; slice++)
|
||||
{
|
||||
love::image::ImageDataBase *id = slices.get(slice, mip);
|
||||
|
||||
if (id != nullptr)
|
||||
uploadImageData(id, mip, slice, 0, 0);
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@ public:
|
||||
ptrdiff_t getHandle() const override;
|
||||
|
||||
void setSamplerState(const SamplerState &s) override;
|
||||
void generateMipmaps() override;
|
||||
|
||||
private:
|
||||
|
||||
void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r, love::image::ImageDataBase *imgd = nullptr) override;
|
||||
void generateMipmaps() override;
|
||||
|
||||
void loadDefaultTexture();
|
||||
void loadData();
|
||||
|
||||
@@ -1328,6 +1328,11 @@ bool OpenGL::isBaseVertexSupported() const
|
||||
return baseVertexSupported;
|
||||
}
|
||||
|
||||
bool OpenGL::isMultiFormatMRTSupported() const
|
||||
{
|
||||
return getMaxRenderTargets() > 1 && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
|
||||
}
|
||||
|
||||
int OpenGL::getMax2DTextureSize() const
|
||||
{
|
||||
return std::max(max2DTextureSize, 1);
|
||||
|
||||
@@ -347,6 +347,7 @@ public:
|
||||
bool isDepthCompareSampleSupported() const;
|
||||
bool isSamplerLODBiasSupported() const;
|
||||
bool isBaseVertexSupported() const;
|
||||
bool isMultiFormatMRTSupported() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum supported width or height of a texture.
|
||||
|
||||
@@ -2394,11 +2394,8 @@ int w_getStats(lua_State *L)
|
||||
lua_pushinteger(L, stats.shaderSwitches);
|
||||
lua_setfield(L, -2, "shaderswitches");
|
||||
|
||||
lua_pushinteger(L, stats.canvases);
|
||||
lua_setfield(L, -2, "canvases");
|
||||
|
||||
lua_pushinteger(L, stats.images);
|
||||
lua_setfield(L, -2, "images");
|
||||
lua_pushinteger(L, stats.textures);
|
||||
lua_setfield(L, -2, "textures");
|
||||
|
||||
lua_pushinteger(L, stats.fonts);
|
||||
lua_setfield(L, -2, "fonts");
|
||||
|
||||
Reference in New Issue
Block a user